20.2. Beeping Last things first: Causing the console to beep for a certain amount of time at a certain frequency is fairly simple. There are two ways to make the console beep. The first is to turn on or off a constant tone. KIOCSOUND turns off the sound if its argument is zero; if its argument is nonzero, it specifies the frequency in a rather bizarre way, as this code shows: void turn_tone_on(int fd, int hertz) { ioctl(fd, KIOCSOUND, 1193180/hertz) } void turn_tone_off(int fd) { ioctl(fd, KIOCSOUND, 0) } The second way to cause the console to beep is to use the KDMKTONE ioctl to turn on a tone for a period specified in jiffies, which are ticks of the system clock. Unfortunately, the time per tick varies from architecture to architecture; the HZ macro defined by sys/param.h gives ticks per second. The tone() function below shows how to derive the number of ticks from hundredths of a second and the value of HZ:[3] [3] This interface is flawed; it should have been specified in some constant fraction of a second and converted. HZ is no longer constant even on a particular platform, but at least for the Intel i86 architecture, Linus Torvalds has decreed that all interfaces specified in regard to HZ shall present a synthetic 100Hz interface. It is possible that in the future, there will be no periodic system clock, in which case jiffies will become a completely synthetic concept. #include <sys/param.h> void tone(int fd, int hertz, int hundredths) { unsigned int ticks = hundredths * HZ / 100; /* ticks & 0xffff will not work if ticks == 0xf0000 * need to round off to highest legal value instead */ if (ticks > 0xffff) ticks = 0xffff; /* now the other rounding error */ if (hundredths && ticks == 0) ticks = 1; ioctl(fd, KDMKTONE, (ticks<<16 | (1193180/hertz))); } |