/* * $Id$ */ /* * Harbour Project source code: * TONE() function * * Copyright 1999 Chen Kedem * www - http://www.harbour-project.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version, with one exception: * * The exception is that if you link the Harbour Runtime Library (HRL) * and/or the Harbour Virtual Machine (HVM) with other files to produce * an executable, this does not by itself cause the resulting executable * to be covered by the GNU General Public License. Your use of that * executable is in no way restricted on account of linking the HRL * and/or HVM code into it. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit * their web site at http://www.gnu.org/). * */ /* * ChangeLog: * * V 1.10 David G. Holm Added __MINGW32__ support * V 1.8 David G. Holm Added '&& ! defined(_Windows)' * check to all __BORLANDC__ checks. * V 1.6 David G. Holm Added Win32 Beep(), thanks to * Chen Kedem. * V 1.4 David G. Holm Upper limit for frequency for OS/2 * DosBeep() is 32767. The CA-Clipper * Tone() function does not have an * upper limit on the duration, so I * had to add an inner loop to deal * with very long durations. There are * actually 18.2 Clipper (PC) timer * ticks per second. * V 1.2 David G. Holm Added OS/2 GCC/EMX support. * V 1.1 David G. Holm Split machine dependent code into * hb_tone() function for internal use * by other Harbour C functions. * V 1.0 Chen Kedem Initial version (only OS/2 support). * */ #if defined(__DJGPP__) #include #include #elif defined(_Windows) #elif defined(__MINGW32__) #include #elif defined(__BORLANDC__) #include #include #elif defined(OS2) #include #elif defined(__CYGWIN__) #include #include #include #include #define HB_DONT_DEFINE_BASIC_TYPES #endif #include "extend.h" #include "inkey.h" /* For hb_releaseCPU() */ #if defined(HARBOUR_GCC_OS2) ULONG DosBeep( ULONG ulFrequency, ULONG ulDuration ); #endif /* $DOC$ * $FUNCNAME$ * TONE() * $CATEGORY$ * Misc. * $ONELINER$ * Sound a tone with a specifies frequency and duration * $SYNTAX$ * TONE( , ) --> NIL * $ARGUMENTS$ * is a non-negative numeric value that specifies the * frequency of the tone in hertz. * is a positive numeric value which specifies the duration * of the tone in 1/18 of a second units. * $RETURNS$ * TONE() always return NIL. * $DESCRIPTION$ * TONE() is a sound function that could be used to irritate the end * user, his or her dog, and the surrounding neighborhood. The frequency * is clamped to the range 0 to 32767 Hz. * $EXAMPLES$ * If lOk // Good Sound * TONE( 500, 1 ) * TONE( 4000, 1 ) * TONE( 2500, 1 ) * Else // Bad Sound * TONE( 300, 1 ) * TONE( 499, 5 ) * TONE( 700, 5 ) * EndIf * $TESTS$ * TONE( 800, 1 ) // same as ? CHR(7) * TONE( 32000, 200 ) // any dogs around yet? * TONE( 130.80, 1 ) // musical note - C * TONE( 400, 0 ) // short beep * TONE( 700 ) // short beep * TONE( 10, 18.2 ) // 1 second delay * TONE( -1 ) // 1/18.2 second delay * TONE( ) // 1/18.2 second delay * $STATUS$ * * $COMPLIANCE$ * TONE() works exactly like CA-Clipper's TONE(). * $SEEALSO$ * CHR(), SET BELL * $END$ */ void hb_tone( double dFrequency, double dDuration ) { /* platform specific code */ /* The conversion from Clipper timer tick units to milliseconds is * 1000.0 / 18.2. */ /* TODO: add more platform support */ #if defined(HARBOUR_GCC_OS2) ULONG temp; #elif defined(WINNT) || defined(_Windows) ULONG temp; #elif defined(OS2) || defined(__MINGW32__) USHORT temp; #elif defined(__DJGPP__) || defined(__BORLANDC__) USHORT temp; /* Use USHORT, because this variable gets added to clock() to form end_clock and we want to minimize overflow risk */ clock_t end_clock; #else /* Unsupported platform. */ ULONG temp; /* Avoid unreferenced temp */ dDuration = -1.0; /* Exit without delay */ #endif HB_TRACE(HB_TR_DEBUG, ("hb_tone(%lf, %lf)", dFrequency, dDuration)); #if defined(HARBOUR_GCC_OS2) || defined(OS2) || defined(WINNT) || defined(_Windows) || defined(__MINGW32__) dFrequency = HB_MIN_( HB_MAX_( 0.0, dFrequency ), 32767.0 ); dDuration = dDuration * 1000.0 / 18.2; /* milliseconds */ #elif defined(__DJGPP__) || defined(__BORLANDC__) dFrequency = HB_MIN_( HB_MAX_( 0.0, dFrequency ), 32767.0 ); dDuration = dDuration * CLOCKS_PER_SEC / 18.2 ; /* clocks */ #endif #if defined(__BORLANDC__) && ! defined(_Windows) && ! defined(WINNT) sound( ( unsigned ) dFrequency ); #elif defined(__DJGPP__) sound( ( int ) dFrequency ); #endif while( dDuration > 0.0 ) { #if defined(HARBOUR_GCC_OS2) || defined(_Windows) || defined(__CYGWIN__) || defined(WINNT) temp = HB_MIN_( HB_MAX_( 0, dDuration ), ULONG_MAX ); #elif defined(OS2) || defined(__BORLANDC__) || defined(__DJGPP__) || defined(__MINGW32__) temp = HB_MIN_( HB_MAX_( 0, dDuration ), USHRT_MAX ); #endif dDuration -= temp; if( temp <= 0 ) { /* Ensure that the loop gets terminated when only a fraction of the delay time remains. */ dDuration = -1.0; } else { #if defined(HARBOUR_GCC_OS2) DosBeep( ( ULONG ) dFrequency, temp ); #elif defined(OS2) DosBeep( ( USHORT ) dFrequency, temp ); #elif defined(__MINGW32__) beep( dFrequency, temp ); #elif defined(WINNT) Beep( ( ULONG ) dFrequency, temp ); #elif defined(_Windows) && ! defined(_Windows) /* Bad news for non-NT Windows platforms: Beep() ignores both parameters and either generates the default sound event or the standard system beep. */ Beep( ( ULONG ) dFrequency, temp ); #elif defined(__DJGPP__) || ( defined(__BORLANDC__) && ! defined(_Windows) ) /* Note: delay() in for DJGPP does not work and delay() in for BORLANDC is not multi- tasking friendly. */ end_clock = clock() + temp; while( clock() < end_clock ) hb_releaseCPU(); #endif } } #if defined(__BORLANDC__) && ! defined(_Windows) nosound(); #elif defined(__DJGPP__) sound( 0 ); #endif } HARBOUR HB_TONE( void ) { if( ISNUM( 1 ) ) hb_tone( hb_parnd( 1 ), ( ISNUM( 2 ) ? hb_parnd( 2 ) : 1.0 ) ); }