c++ - beep not working (linux) - c++

I'm trying to beep, but I simply can't. I've already tried:
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
cout << '\a' << flush;
return 0;
}
I have also tried using this: http://www.johnath.com/beep/
But simply doesn't beep.
(If I run $ speaker-test -t sine -f 500 -l 2 2>&1 on the terminal, it beeps, but I would like to beep with c++ to study low-level sound programming)
And I would like to be able to control frequency and duration.

Unless you're logged in from the console, cout will not refer to the system console. You need to open /dev/console and send the \a there.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int s = open ("/dev/console", O_WRONLY);
if (s < 0)
perror ("unable to open console");
else
{
if (write (s, "\a", 1) != 1)
perror ("unable to beep");
}
}

This depends on terminal emulator are you using. KDE's Konsole, for example, doesn't support beeping with buzzer at all AFAICT. First check that echo -e \\a works in your shell. If it doesn't, your C++ code won't work too. You can use xterm — it does support this.
But even in xterm it may not work if you don't have pcspkr (or snd_pcsp) kernel module loaded. This is often the case when distros blacklist it by default. In this case your bet is looking for a terminal which uses your sound card to emit beeps, not PC speaker AKA buzzer.

You're asking about "low level sound generation", typically, the lowest level of sound generation would involve constructing a wave form and passing it to the audio device in an appropriate format. Of course, then it comes out from your sound card rather than the PC speaker. The best advice I can give would be to read up on the APIs associated with pulse audio, alsa, or even the kernel sound drivers. Last time I played with this (~1996), it basically meant allocating an array of samples, and then computing values to put in there that approximated a sine wave with the appropriate frequency and amplitude, then writing that buffer to the output device. There may have even been some calls to ioctl to set the parameters on the device (sample rate, stereo vs. mono, bit rate, etc). If your audio device supports midi commands, it may be easier to send those in some form that is closer to "play these notes for this long using this instrument".
You may find these articles helpful:
https://jan.newmarch.name/LinuxSound/
http://www.linuxjournal.com/article/6735

Have you tried system call in your application?
system("echo -e '\a'");

Related

How to use windows.h in C/C++ to control other programs' volume control

I'm looking for a way to be able to control the volume of different programs without using the Volume Mixer but with C/C++ code. I know the windows.h library should be able to do it. But it's huge, and I have no idea where to even start to look.
I've already found that nircmd does exactly what I need with:
nircmd setappvolume chrome.exe 0.15
Although I could use that command, I would like to write my own and use a hardware device for controlling those volumes.
If anyone has a few links or tips to get me started, I would appreciate it!
EDIT:
I've now used system() in C together with nircmd, and it works very well. This code just uses a sinus to change the volume starting from 50% going to 100% and 0%.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
char command[100];
char appName[] = "chrome.exe";
int i = 0;
while(1){
i++;
sprintf(command, "nircmd setappvolume %s %f", appName, sin(i/10.0)/2+0.5);
printf("%d %% \n", i);
system(command);
}
}
Microsoft has the WASPI for controlling audio volume of various clients and output devices.
You get the IAudioVolumeLevel interface for a the client, and manipulate each channel using SetLevel.
You may need IMMDeviceEnumerator, IDeviceTopology, IAudioSessionControl2, ISimpleAudioVolume and other interfaces to do what you want.
So, it's possible, it is documented, but it is non-trivial.
https://learn.microsoft.com/en-us/windows/win32/coreaudio/wasapi

Sending Keystrokes to a X Window

I am currently experimenting with xdotool to send keys to a process (I understand that it may not work for all processes that does not set _NET_WM_PID). I have trouble sending keystrokes to windows other from the focus. It does work if you are sending keystrokes to the CURRENTWINDOW. Below is the snippet that I used to test xdotool's functionality.
extern "C"{
#include <xdo.h>
}
//extern "C" xdo_window_search
#include <iostream>
#include <string.h>
using namespace std;
int main(){
xdo_t* p_xdo = xdo_new(NULL);
// Allocate memory for search query.
xdo_search_t s;
// Clear the allocated memory.
memset(&s, 0, sizeof(xdo_search_t));
// Set the search query.
s.pid = 1916;
s.max_depth = -1;
s.searchmask = SEARCH_PID;
s.require = xdo_search::SEARCH_ANY;
// Allocate memory for output
Window* windows;
int no_windows;
xdo_window_search(p_xdo,&s,&windows,&no_windows);
cout << no_windows << endl;
// Prints all windows' names with matching criteria
for( int i=0;i<no_windows;i++ ){
unsigned char * name;
int size;
int type;
xdo_get_window_name(p_xdo,windows[i],&name,&size,&type);
cout << i << ":" << name << endl;
}
for( int i=0;i<no_windows;i++ ){
xdo_type(p_xdo,windows[i],"Hello World",0);
}
//xdo_type(p_xdo,CURRENTWINDOW,"Hello World",0); // This does work.
return 0;
}
In additional to testing xdotool's functionality, I've looked into xdotool's source code. Interestingly, I found that they are using Xtest to send keystrokes to the focused window (CURRENTWINDOW) and X11's XSendEvent for other windows. I turned to xdotool because I couldn't get XSendEvent to work and Xtest cannot send keys to any other windows than the focused window.
Am I not using the xdotool correctly? Does xdotool not work with all *nix OS with X11?
[I am running this on Ubuntu 13.04.]
EDIT
So, it looks like that does work but not for all windows that it finds. For example, it works for firefox but not gedit and gnome-terminal although it found gedit and gnome-terminal by its pid. It behaves differently if I used CURRENTWINDOW.
So, it would be great if someone can explain why is this so. Like, is it related the force send flag in an XEvent?
Directly from the xdotool manual:
SENDEVENT NOTES
If you are trying to send key input to a specific window, and it does
not appear to be working, then it's likely your application is ignoring
the events xdotool is generating. This is fairly common.
Sending keystrokes to a specific window uses a different API than
simply typing to the active window. If you specify 'xdotool type
--window 12345 hello' xdotool will generate key events and send them
directly to window 12345. However, X11 servers will set a special flag
on all events generated in this way (see XEvent.xany.send_event in
X11's manual). Many programs observe this flag and reject these events.
It is important to note that for key and mouse events, we only use
XSendEvent when a specific window is targeted. Otherwise, we use XTEST.
Some programs can be configured to accept events even if they are
generated by xdotool. Seek the documentation of your application for
help.
Specific application notes (from the author's testing): * Firefox 3
seems to ignore all input when it does not have focus. * xterm can be
configured while running with ctrl+leftclick, 'Allow SendEvents' *
gnome-terminal appears to accept generated input by default.

Can ofstream be used for printing on a printer

Can ofstream be used to write on a printer?
eg:
string nameOfPrinter = "xyz";
ofstream onPrinter(nameOfPrinter);
onPrinter << "Printing.... ";
If I do as above will I get the output by the printer (on the paper) ?
If not, why I won't get the output? Please suggest a way to print using a printer.
I am targeting the Windows platform (32bit)
If you happen to have your printer associated with LPT1 and a printer which support formfeeds.
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
ofstream printer ("LPT1");
if(!printer)
{ return 1;
}
printer.puts("Test Test Test\n");
printer.putc('\f');
printer.close();
return 0;
}
LPT1 is also a file name in windows. But as known it is a reserved filename. So it will not be possible to have more than one file with the name LPT1. And this file is already managed by windows.
See for reserved filenames
Yes you can, Your code should be:
ofstream printer;
printer.open("lpt1");
I believe it's case sensitive(not sure "lpt1" or "LPT1"). Also, you'll need to write a page eject command.
EDIT:
LPT (Line Print Terminal) is name of the parallel port interface on IBM PC-compatible computers. Over the years, the parallel port interface has decreased use because of the rise of Universal Serial Bus.
In DOS, the parallel ports could be accessed directly on the command line. For example, the command type c:\autoexec.bat > LPT1 would direct the contents of the autoexec.bat file to the printer port(recognized by the reserved word LPT1"). A PRN device was also available as an alias for LPT1.
Microsoft Windows still refers to the ports in this manner in many cases, though this is often fairly hidden.
In the Linux operating system the first LPT port is available via the filesystem as /dev/lp0.
To write to a printer, one should simply open the printer as if it were a file (the printer name is system-dependent; on Windows machines, it will be lpt1 or prn, while on unix machines, it will be something like /dev/lp), then write whatever text has to be written.
Sample program could be as simple as:
std::ofstream print;
print.open("LPT1");
if (!print)
return 0;
print << data;
print.close();
How would the file stream know the difference between the name of a printer and a file that just happened to share the name of a printer? So no; you can't print to a printer by specifying the name of a printer.
Printing in Win32 is not a trivial task. You can't simply shove some characters at a printer; it needs to know about page layout, fonts, etc. Basically, the way to do it from Win32 is to "draw" to the printer with GDI commands. Beginner-level info can be found here.
Correction: apparently, you can stream output to the printer with a stream. However, it requires that the user has enabled some legacy functionality, so it isn't necessarily always available.

How to redirect printf output back into code?

i'm writing a little c++ app to wrap around the opencv haar training function (namely cvCreateTreeCascadeClassifier). The function throws a whole load of output to the console and I wish to parse this output so that I can populate various variables in my code.
The function I wish to use is not part of the actual openCV library; instead it has to be built with my code as part of the project. All of the output from the the function is via printf.
Question: Is it possible to intercept the printf statements before they end up on the console? I've managed to redirect them using freopen but this seems a little clumsy as I then need to parse the file and then delete it when the function call is finished. Also, the function is likely to be running for several hours (and possibly even weeks!) so the size of the file might be an issue if its constantly being appended too.
Requirements: I need this app to be c++ and to run on both windows and linux (but have no problem with conditional compile statements if need be). I would also like to be able to still see my cout and cerr messages on the console (just not the printf).
My googling has removed my will to live! Can anyone help with a solution via either code example or pointers to places I should be looking for an answer?
Thanks
What you can do is:
create a pipe
make the writable end of the pipe the new stdout
read from the readable part of the pipe
Reading and writing should happen in different threads or you risk that your program starves on one end of the pipe.
Here's a sample how to do the redirection in unix & windows:
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
/* gcc defined unix */
#ifdef unix
#include <unistd.h>
#endif
#ifdef WIN32
#include <io.h>
#define pipe(X) _pipe(X,4096,O_BINARY)
#define fileno _fileno
#define dup2 _dup2
#define read _read
#endif
#include <assert.h>
int main()
{
int fds[2];
int res;
char buf[256];
int so;
res=pipe(fds);
assert(res==0);
so=fileno(stdout);
// close stdout handle and make the writable part of fds the new stdout.
res=dup2(fds[1],so);
assert(res!=-1);
printf("Hi there\n");
fflush(stdout);
// reading should happen in a different thread
res=read(fds[0],buf,sizeof(buf)-1);
assert(res>=0 && res<sizeof(buf));
buf[res]=0;
fprintf(stderr,"buf=>%s\n",buf);
return 0;
}
This code should print
buf=>Hi there
(I'm using assert here, because I am too lazy to do real error checking for this example)
Encapsulate the lib into an application, and pipe the application's output to your application. Now write a script so that you don't have to run the apps together every time with a pipe.
Take a look at: http://www.unix.com/programming/136225-reading-stdout-pipe.html it seems promising, but i never tried it.

Redirecting standard output to syslog

I'm planning to package OpenTibia Server for Debian. One of the things I want to do is add startup via /etc/init.d and daemonization of the otserv process.
Thing is, we should probably redirect output to syslog. This is usually done via the syslog() function. Currently, the code is swarmed with:
std::cout << "Stuff to printout" << std::endl;
Is there a proper, easy to add, way to redirect standard output and standard error output into syslog without replacing every single "call" to std::cout and friends?
You can pipe your stdout to syslog with the logger command:
NAME
logger - a shell command interface to the syslog(3) system log module
SYNOPSIS
logger [-isd] [-f file] [-p pri] [-t tag] [-u socket] [message ...]
DESCRIPTION
Logger makes entries in the system log. It provides a shell command
interface to the syslog(3) system log module.
If you don't supply a message on the command line it reads stdin
You can redirect any stream in C++ via the rdbuf() command. This is a bit convoluted to implement but not that hard.
You need to write a streambuf that would output to syslog on overflow(), and replace the std::cout rdbuf with your streambuf.
An example, that would output to a file (no error handling, untested code)
#include <iostream>
#include <fstream>
using namespace std;
int main (int argc, char** argv) {
streambuf * yourStreamBuffer = NULL;
ofstream outputFileStream;
outputFileStream.open ("theOutputFile.txt");
yourStreamBuffer = outputFileStream.rdbuf();
cout.rdbuf(yourStreamBuffer);
cout << "Ends up in the file, not std::cout!";
outputFileStream.close();
return 0;
}
Not sure whether a straight "C" answer suffices; but in "C" you can use underlying stdio features to plug the (FILE*) directly into syslog calls, without an intervening "logger" process. Check out
http://mischasan.wordpress.com/2011/05/25/redirecting-stderr-to-syslog/
Try wrapping the execution of the binary with a suitable script, that just reads stdout and stderr, and send any data read from them on using syslog(). That should work without any code changes in the wrapped application, and be pretty easy.
Not sure if there are existing scripts to pipe into, but writing one shouldn't be hard if not.
I just wrote some code that will do this. It's using ASL instead of syslog, and it's using kevents, so you may need to port it to different APIs for your system (syslog instead of ASL and poll/select instead of kevent)
http://cgit.freedesktop.org/xorg/app/xinit/tree/launchd/console_redirect.c
Furthermore, I basically added this to libsystem_asl on Mountain Lion. Check out the man page for asl_log_descriptor.
Example:
#include <asl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
asl_log_descriptor(NULL, NULL, ASL_LEVEL_INFO, STDOUT_FILENO, ASL_LOG_DESCRIPTOR_WRITE);
asl_log_descriptor(NULL, NULL, ASL_LEVEL_NOTICE, STDERR_FILENO, ASL_LOG_DESCRIPTOR_WRITE);
fprintf(stdout, "This is written to stdout which will be at log level info.");
fprintf(stderr, "This is written to stderr which will be at log level notice.");
return 0;
}