diff --git a/src/xpdev/xpbeep.c b/src/xpdev/xpbeep.c index 57068070e01c15d88467a4801fa16f85611077f2..bda3bf50edfd760c3aa1fea66c9f01766313bed0 100644 --- a/src/xpdev/xpbeep.c +++ b/src/xpdev/xpbeep.c @@ -1,10 +1,10 @@ +/* standard headers */ #include <math.h> -#ifdef _WIN32 +#if defined(_WIN32) #include <windows.h> #include <mmsystem.h> -#endif -#ifdef __unix__ +#elif defined(__unix__) #include <fcntl.h> #include <sys/soundcard.h> /* KIOCSOUND */ @@ -22,31 +22,25 @@ #include <machine/speaker.h> #endif #endif + +/* xpdev headers */ #include "genwrap.h" +#include "xpbeep.h" #define S_RATE 22050 static BOOL sound_device_open_failed=FALSE; -enum { - WAVE_SHAPE_SINE - ,WAVE_SHAPE_SAWTOOTH - ,WAVE_SHAPE_SQUARE - ,WAVE_SHAPE_SINE_SAW - ,WAVE_SHAPE_SINE_HARM - ,WAVE_SHAPE_SINE_SAW_CHORD - ,WAVE_SHAPE_SINE_SAW_HARM -}; - -#define SHAPE WAVE_SHAPE_SINE_SAW_HARM #define WAVE_PI 3.14159265358979323846 #define WAVE_TPI 6.28318530717958647692 -void makewave(double freq, unsigned char *wave, int samples) +/********************************************************************************/ +/* Calculate and generate a sound wave pattern (thanks to Deuce!) */ +/********************************************************************************/ +void makewave(double freq, unsigned char *wave, int samples, enum WAVE_SHAPE shape) { int i; int j; - int k; int midpoint; double inc; double pos; @@ -57,11 +51,10 @@ void makewave(double freq, unsigned char *wave, int samples) inc=8.0*atan(1.0); inc *= ((double)freq / (double)S_RATE); - k=127; for(i=0;i<samples;i++) { pos=(inc*(double)i); pos -= (int)(pos/WAVE_TPI)*WAVE_TPI; - switch(SHAPE) { + switch(shape) { case WAVE_SHAPE_SINE: wave[i]=(sin (pos))*127+128; break; @@ -130,9 +123,13 @@ void makewave(double freq, unsigned char *wave, int samples) #endif } -#ifdef _WIN32 +/********************************************************************************/ +/* Play a tone through the wave/DSP output device (sound card) - Deuce */ +/********************************************************************************/ -void xpbeep(double freq, DWORD duration) +#if defined(_WIN32) + +BOOL xptone(double freq, DWORD duration, enum WAVE_SHAPE shape) { WAVEFORMATEX w; WAVEHDR wh; @@ -140,6 +137,7 @@ void xpbeep(double freq, DWORD duration) unsigned char wave[S_RATE*15/2+1]; WORD* p; DWORD endTime; + BOOL success=FALSE; w.wFormatTag = WAVE_FORMAT_PCM; w.nChannels = 1; @@ -150,30 +148,81 @@ void xpbeep(double freq, DWORD duration) if(!sound_device_open_failed && waveOutOpen(&waveOut, WAVE_MAPPER, &w, 0, 0, 0)!=MMSYSERR_NOERROR) sound_device_open_failed=TRUE; - if(sound_device_open_failed) { - Beep((DWORD)(freq+.5), duration); - return; - } + if(sound_device_open_failed) + return(FALSE); + memset(&wh, 0, sizeof(wh)); wh.lpData=wave; wh.dwBufferLength=S_RATE*duration/1000; - makewave(freq,wave,wh.dwBufferLength); + makewave(freq,wave,wh.dwBufferLength,shape); if(waveOutPrepareHeader(waveOut, &wh, sizeof(wh))!=MMSYSERR_NOERROR) goto abrt; - if(waveOutWrite(waveOut, &wh, sizeof(wh))!=MMSYSERR_NOERROR) - goto abrt; + if(waveOutWrite(waveOut, &wh, sizeof(wh))==MMSYSERR_NOERROR) + success=TRUE; abrt: while(waveOutUnprepareHeader(waveOut, &wh, sizeof(wh))==WAVERR_STILLPLAYING) SLEEP(1); waveOutClose(waveOut); + + return(success); } -#endif /* _WIN32 */ +#elif defined(__unix__) + +BOOL DLLCALL xptone(double freq, DWORD duration, enum WAVE_SHAPE shape) +{ +#ifdef AFMT_U8 + int dsp; + int format=AFMT_U8; + int channels=1; + int rate=S_RATE; + int samples; + int fragsize=0x7fff0004; + int wr; + int i; + unsigned char wave[S_RATE*15/2+1]; + + samples=S_RATE*duration/1000; + makewave(freq,wave,samples,shape); + if(!sound_device_open_failed) { + if((dsp=open("/dev/dsp",O_WRONLY,0))<0) { + sound_device_open_failed=TRUE; + } + else { + ioctl(dsp, SNDCTL_DSP_SETFRAGMENT, &fragsize); + if((ioctl(dsp, SNDCTL_DSP_SETFMT, &format)==-1) || format!=AFMT_U8) { + sound_device_open_failed=TRUE; + close(dsp); + } + else if((ioctl(dsp, SNDCTL_DSP_CHANNELS, &channels)==-1) || channels!=1) { + sound_device_open_failed=TRUE; + close(dsp); + } + else if((ioctl(dsp, SNDCTL_DSP_SPEED, &rate)==-1) || rate!=S_RATE) { + sound_device_open_failed=TRUE; + close(dsp); + } + } + } + if(sound_device_open_failed) + return(FALSE); + wr=0; + while(wr<samples) { + i=write(dsp, wave+wr, samples-wr); + if(i>=0) + wr+=i; + } + close(dsp); + + return(TRUE); +#else + return(FALSE); +#endif +} -#ifdef __unix__ /****************************************************************************/ /* Generate a tone at specified frequency for specified milliseconds */ -/* Thanks to Casey Martin for this code */ +/* Thanks to Casey Martin (and Deuce) for this code */ /****************************************************************************/ void DLLCALL unix_beep(int freq, int dur) { @@ -214,55 +263,19 @@ void DLLCALL unix_beep(int freq, int dur) #endif } -void DLLCALL xpbeep(double freq, DWORD duration) -{ -#ifdef AFMT_U8 - int dsp; - int format=AFMT_U8; - int channels=1; - int rate=S_RATE; - int samples; - int fragsize=0x7fff0004; - int wr; - int i; - unsigned char wave[S_RATE*15/2+1]; +#endif - samples=S_RATE*duration/1000; - makewave(freq,wave,samples); - if(!sound_device_open_failed) { - if((dsp=open("/dev/dsp",O_WRONLY,0))<0) { - sound_device_open_failed=TRUE; - } - else { - ioctl(dsp, SNDCTL_DSP_SETFRAGMENT, &fragsize); - if((ioctl(dsp, SNDCTL_DSP_SETFMT, &format)==-1) || format!=AFMT_U8) { - sound_device_open_failed=TRUE; - close(dsp); - } - else if((ioctl(dsp, SNDCTL_DSP_CHANNELS, &channels)==-1) || channels!=1) { - sound_device_open_failed=TRUE; - close(dsp); - } - else if((ioctl(dsp, SNDCTL_DSP_SPEED, &rate)==-1) || rate!=S_RATE) { - sound_device_open_failed=TRUE; - close(dsp); - } - } - } - if(sound_device_open_failed) { - sound_device_open_failed=TRUE; - unix_beep((int)(freq+.5),duration); +/********************************************************************************/ +/* Play sound through DSP/wave device, if unsuccessful, play through PC speaker */ +/********************************************************************************/ +void xpbeep(double freq, DWORD duration) +{ + if(xptone(freq,duration,WAVE_SHAPE_SINE_SAW_HARM)) return; - } - wr=0; - while(wr<samples) { - i=write(dsp, wave+wr, samples-wr); - if(i>=0) - wr+=i; - } - close(dsp); -#else - unix_beep((int)(freq+.5),duration); + +#if defined(_WIN32) + Beep((DWORD)(freq+.5), duration); +#elif defined(__unix__) + unix_beep((int)(freq+.5),duration); #endif } -#endif diff --git a/src/xpdev/xpbeep.h b/src/xpdev/xpbeep.h index 10c2724dbe82fd7972b9fecdc3291a3a8f244e93..ce3d14a49ec8adc082735ee22566b99d07fbd6f6 100644 --- a/src/xpdev/xpbeep.h +++ b/src/xpdev/xpbeep.h @@ -4,7 +4,7 @@ #include "gen_defs.h" #if defined(_WIN32) - #if 1 + #if 0 #define BEEP(freq,dur) xpbeep((double)(freq),(DWORD)(dur)) #else #define BEEP(freq,dur) Beep((DWORD)(freq),(DWORD)(dur)) @@ -17,10 +17,22 @@ #error "Unsupported Target: Need some macros and/or function prototypes here." #endif +enum WAVE_SHAPE { + WAVE_SHAPE_SINE + ,WAVE_SHAPE_SAWTOOTH + ,WAVE_SHAPE_SQUARE + ,WAVE_SHAPE_SINE_SAW + ,WAVE_SHAPE_SINE_HARM + ,WAVE_SHAPE_SINE_SAW_CHORD + ,WAVE_SHAPE_SINE_SAW_HARM +}; + + #ifdef __cplusplus extern "C" { #endif void xpbeep(double freq, DWORD duration); +BOOL xptone(double freq, DWORD duration, enum WAVE_SHAPE); #ifdef __unix__ void unix_beep(int freq, int dur); #endif