00001 00002 /*************************************************************************** 00003 * beep.cpp - Beeper utility class 00004 * 00005 * Created: Sun Apr 11 19:41:23 2010 00006 * Copyright 2006-2010 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include "beep.h" 00025 00026 #include <cstdio> 00027 #include <cerrno> 00028 #include <termios.h> 00029 #include <sys/types.h> 00030 #include <fcntl.h> 00031 #include <cstring> 00032 #include <sys/ioctl.h> 00033 #include <linux/kd.h> 00034 #include <unistd.h> 00035 00036 00037 /* From console_ioctl man page, explained in the beep too by 00038 * Johnathan Nightingale: 00039 * This number represents the fixed frequency of the original PC XT's 00040 * timer chip (the 8254 AFAIR), which is approximately 1.193 MHz. This 00041 * number is divided with the desired frequency to obtain a counter value, 00042 * that is subsequently fed into the timer chip, tied to the PC speaker. 00043 * The chip decreases this counter at every tick (1.193 MHz) and when it 00044 * reaches zero, it toggles the state of the speaker (on/off, or in/out), 00045 * resets the counter to the original value, and starts over. The end 00046 * result of this is a tone at approximately the desired frequency. :) 00047 */ 00048 #define CLOCK_TICK_RATE 1193180 00049 00050 #define CONSOLE_FILE "/dev/console" 00051 00052 /** @class BeepController "beep.h" 00053 * Simple speaker beep controller. 00054 * @author Tim Niemueller 00055 */ 00056 00057 /** Constructor. */ 00058 BeepController::BeepController() 00059 { 00060 __disable_beeping = false; 00061 } 00062 00063 /** Enable beeping. 00064 * @param freq frequency to beep with 00065 */ 00066 void 00067 BeepController::beep_on(float freq) 00068 { 00069 if (__disable_beeping) return; 00070 00071 int beep_fd = open(CONSOLE_FILE, O_WRONLY); 00072 if (beep_fd == -1) { 00073 char errstr[1024]; 00074 strerror_r(errno, errstr, sizeof(errstr)); 00075 //logger->log_warn(name(), "Could not open console (%s). " 00076 // "Disabling warning beeps.", errstr); 00077 __disable_beeping = true; 00078 } else { 00079 if (ioctl(beep_fd, KIOCSOUND, (int)(CLOCK_TICK_RATE/freq)) < 0) { 00080 //logger->log_warn(name(), "Starting to beep failed. Disabling warning beeps."); 00081 __disable_beeping = true; 00082 } 00083 close(beep_fd); 00084 } 00085 } 00086 00087 00088 /** Disable beeping. */ 00089 void 00090 BeepController::beep_off() 00091 { 00092 if (__disable_beeping) return; 00093 00094 int beep_fd = open(CONSOLE_FILE, O_WRONLY); 00095 if (beep_fd == -1) { 00096 char errstr[1024]; 00097 strerror_r(errno, errstr, sizeof(errstr)); 00098 //logger->log_warn(name(), "Could not open console (%s) [stop]. " 00099 // "Disabling warning beeps.", errstr); 00100 __disable_beeping = true; 00101 } else { 00102 if (ioctl(beep_fd, KIOCSOUND, 0) < 0) { 00103 //logger->log_warn(name(), "Stopping beeping failed. " 00104 // "Disabling warning beeps."); 00105 __disable_beeping = true; 00106 } 00107 close(beep_fd); 00108 } 00109 }