Files
harbour-core/harbour/source/rtl/tone.c
2000-03-11 17:54:38 +00:00

180 lines
6.4 KiB
C

/*
* $Id$
*/
/*
* Harbour Project source code:
* TONE() function
*
* Copyright 1999 Chen Kedem <niki@actcom.co.il>
* 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 <pc.h>
#include <time.h>
#elif defined(_Windows)
#elif defined(__MINGW32__)
#include <stdlib.h>
#elif defined(__BORLANDC__)
#include <dos.h>
#include <time.h>
#elif defined(OS2)
#include <dos.h>
#elif defined(__CYGWIN__)
#include <Windows32/Base.h>
#include <Windows32/Defines.h>
#include <Windows32/Structures.h>
#include <Windows32/CommonFunctions.h>
#define HB_DONT_DEFINE_BASIC_TYPES
#elif defined( __WATCOMC__ )
#include <i86.h>
#include <time.h>
#endif
#include "hbapi.h"
#include "hbapigt.h" /* For hb_releaseCPU() */
#if defined(HARBOUR_GCC_OS2)
ULONG DosBeep( ULONG ulFrequency, ULONG ulDuration );
#endif
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__) || defined(__WATCOMC__)
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) ) || defined(__WATCOMC__)
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__) || defined(__WATCOMC__)
temp = HB_MIN_( HB_MAX_( 0, dDuration ), USHRT_MAX );
#else
temp = 0;
#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(__BORLANDC__)
/* 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) ) || defined(__WATCOMC__)
/* Note: delay() in <dos.h> for DJGPP does not work and
delay() in <dos.h> for BORLANDC is not multi-
tasking friendly. */
end_clock = clock() + temp;
while( clock() < end_clock )
hb_releaseCPU();
#endif
}
}
#if ( defined(__BORLANDC__) && ! defined(_Windows) ) || defined(__WATCOMC__)
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 ) );
}