diff --git a/src/xpdev/genwrap.c b/src/xpdev/genwrap.c index 64dbedd648783f4d2c00fc1b69699d7a46eceb30..feaec03ad4b3ee4192d1f4c8552e8c6bdd108f98 100644 --- a/src/xpdev/genwrap.c +++ b/src/xpdev/genwrap.c @@ -46,20 +46,6 @@ #if defined(__unix__) #include <sys/ioctl.h> /* ioctl() */ #include <sys/utsname.h> /* uname() */ - /* KIOCSOUND */ - #if defined(__FreeBSD__) - #include <sys/kbio.h> - #elif defined(__linux__) - #include <sys/kd.h> - #elif defined(__solaris__) - #include <sys/kbio.h> - #include <sys/kbd.h> - #endif - #if defined(__OpenBSD__) || defined(__NetBSD__) - #include <machine/spkr.h> - #elif defined(__FreeBSD__) - #include <machine/speaker.h> - #endif #endif /* __unix__ */ #include "genwrap.h" /* Verify prototypes */ @@ -207,49 +193,6 @@ char* strrev(char* str) } return str; } - -/****************************************************************************/ -/* Generate a tone at specified frequency for specified milliseconds */ -/* Thanks to Casey Martin for this code */ -/****************************************************************************/ -void DLLCALL unix_beep(int freq, int dur) -{ - static int console_fd=-1; - -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) - int speaker_fd=-1; - tone_t tone; - - speaker_fd = open("/dev/speaker", O_WRONLY|O_APPEND); - if(speaker_fd != -1) { - tone.frequency=freq; - tone.duration=dur/10; - ioctl(speaker_fd,SPKRTONE,&tone); - close(speaker_fd); - return; - } -#endif - -#if !defined(__GNU__) && !defined(__QNX__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) - if(console_fd == -1) - console_fd = open("/dev/console", O_NOCTTY); - - if(console_fd != -1) { -#if defined(__solaris__) - ioctl(console_fd, KIOCCMD, KBD_CMD_BELL); -#else - if(freq != 0) /* Don't divide by zero */ - ioctl(console_fd, KIOCSOUND, (int) (1193180 / freq)); -#endif /* solaris */ - SLEEP(dur); -#if defined(__solaris__) - ioctl(console_fd, KIOCCMD, KBD_CMD_NOBELL); /* turn off tone */ -#else - ioctl(console_fd, KIOCSOUND, 0); /* turn off tone */ -#endif /* solaris */ - } -#endif -} #endif /****************************************************************************/ diff --git a/src/xpdev/genwrap.h b/src/xpdev/genwrap.h index d9607cd13799d652da4d52849cfa1323bc769ebe..4b1ea4e99d03db104d0ec4e01ba557dd3e520c1d 100644 --- a/src/xpdev/genwrap.h +++ b/src/xpdev/genwrap.h @@ -204,7 +204,6 @@ DLLEXPORT int DLLCALL get_errno(void); #define YIELD() Sleep(1) /* Must sleep at least 1ms to avoid 100% CPU utilization */ #define MAYBE_YIELD() Sleep(0) #define SLEEP(x) Sleep(x) - #define BEEP(freq,dur) Beep((DWORD)(freq),(DWORD)(dur)) #define popen _popen #define pclose _pclose #define tzname _tzname @@ -214,7 +213,6 @@ DLLEXPORT int DLLCALL get_errno(void); #define YIELD() DosSleep(1) /* Must sleep at least 1ms to avoid 100% CPU utilization */ #define MAYBE_YIELD() DosSleep(0) #define SLEEP(x) DosSleep(x) - #define BEEP(freq,dur) DosBeep(freq,dur) #elif defined(__unix__) || defined(__APPLE__) @@ -259,8 +257,6 @@ DLLEXPORT int DLLCALL get_errno(void); #define FORK() fork() #endif - #define BEEP(freq,dur) unix_beep(freq,dur) - DLLEXPORT void DLLCALL unix_beep(int freq, int dur); #else /* Unsupported OS */ diff --git a/src/xpdev/objects.mk b/src/xpdev/objects.mk index 9f979ff7b7bb8d957e7422e30babeaa327325c36..befd5f3eaf3743e8ed244e0464f7213cbcda34ea 100644 --- a/src/xpdev/objects.mk +++ b/src/xpdev/objects.mk @@ -15,7 +15,8 @@ OBJS = \ $(OBJODIR)$(DIRSEP)ini_file$(OFILE) \ $(OBJODIR)$(DIRSEP)link_list$(OFILE) \ $(OBJODIR)$(DIRSEP)sockwrap$(OFILE) \ - $(OBJODIR)$(DIRSEP)str_list$(OFILE) + $(OBJODIR)$(DIRSEP)str_list$(OFILE) \ + $(OBJODIR)$(DIRSEP)xpbeep$(OFILE) MTOBJS = \ $(MTOBJODIR)$(DIRSEP)conwrap$(OFILE) \ @@ -29,4 +30,5 @@ MTOBJS = \ $(MTOBJODIR)$(DIRSEP)semwrap$(OFILE) \ $(MTOBJODIR)$(DIRSEP)sockwrap$(OFILE) \ $(MTOBJODIR)$(DIRSEP)str_list$(OFILE) \ - $(MTOBJODIR)$(DIRSEP)threadwrap$(OFILE) + $(MTOBJODIR)$(DIRSEP)threadwrap$(OFILE) \ + $(MTOBJODIR)$(DIRSEP)xpbeep$(OFILE) diff --git a/src/xpdev/xpbeep.c b/src/xpdev/xpbeep.c new file mode 100644 index 0000000000000000000000000000000000000000..d44dd6c0a0b20a6f31315d4f58ad880ef5122da9 --- /dev/null +++ b/src/xpdev/xpbeep.c @@ -0,0 +1,255 @@ +#include <math.h> + +#ifdef _WIN32 + #include <windows.h> + #include <mmsystem.h> +#endif +#ifdef __unix__ + #include <fcntl.h> + #include <machine/soundcard.h> + /* KIOCSOUND */ + #if defined(__FreeBSD__) + #include <sys/kbio.h> + #elif defined(__linux__) + #include <sys/kd.h> + #elif defined(__solaris__) + #include <sys/kbio.h> + #include <sys/kbd.h> + #endif + #if defined(__OpenBSD__) || defined(__NetBSD__) + #include <machine/spkr.h> + #elif defined(__FreeBSD__) + #include <machine/speaker.h> + #endif +#endif +#include "genwrap.h" + +#define S_RATE 11025 + +static BOOL sound_device_open_failed=FALSE; + +void makesine(double freq, unsigned char *wave, int samples) +{ + int i; + int j; + int k; + double inc; + BOOL endhigh; + BOOL starthigh; + + inc=8.0*atan(1.0); + inc *= ((double)freq / (double)S_RATE); + + for(i=0;i<samples;i++) { + wave[i]=(sin (inc * (double)i))*127+128; + } + + /* Now we have a "perfect" sine wave... + * we must clean it up now to avoid click/pop + */ + if(wave[samples-1]>127) + endhigh=TRUE; + else + endhigh=FALSE; + /* Completely remove the last wave fragment */ + for(i=samples-1;i>0;i--) { + if(endhigh && wave[i]<=127) + break; + if(!endhigh && wave[i]>=127) + break; + wave[i]=127; + } + /* Fade out */ + for(k=10;k>1;k--) { + for(;i>0;i--) { + if(!endhigh && wave[i]<=127) + break; + if(endhigh && wave[i]>=127) + break; + j=wave[i]; + j-=128; + j/=k; + wave[i]=j+128; + } + for(;i>0;i--) { + if(endhigh && wave[i]<=127) + break; + if(!endhigh && wave[i]>=127) + break; + j=wave[i]; + j-=128; + j/=k; + wave[i]=j+128; + } + } + + if(wave[0]>127) + starthigh=TRUE; + else + starthigh=FALSE; + /* Completely remove the first wave fragment */ + for(i=0;i<samples;i++) { + if(starthigh && wave[i]<=127) + break; + if(!starthigh && wave[i]>=127) + break; + wave[i]=127; + } + /* Fade in */ + for(k=10;k>1;k--) { + for(;i<samples;i--) { + if(!starthigh && wave[i]<=127) + break; + if(starthigh && wave[i]>=127) + break; + j=wave[i]; + j-=128; + j/=k; + wave[i]=j+128; + } + for(;i<samples;i--) { + if(starthigh && wave[i]<=127) + break; + if(!starthigh && wave[i]>=127) + break; + j=wave[i]; + j-=128; + j/=k; + wave[i]=j+128; + } + } +} + +#ifdef _WIN32 + +void SineBeep(double freq, DWORD duration) +{ + WAVEFORMATEX w; + WAVEHDR wh; + HWAVEOUT waveOut; + unsigned char wave[S_RATE*15/2+1]; + WORD* p; + DWORD endTime; + + w.wFormatTag = WAVE_FORMAT_PCM; + w.nChannels = 1; + w.nSamplesPerSec = S_RATE; + w.wBitsPerSample = 8; + w.nBlockAlign = (w.wBitsPerSample * w.nChannels) / 8; + w.nAvgBytesPerSec = w.nSamplesPerSec * w.nBlockAlign; + + 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; + } + memset(&wh, 0, sizeof(wh)); + wh.lpData=wave; + wh.dwBufferLength=S_RATE*duration/1000; + makesine(freq,wave,wh.dwBufferLength); + if(waveOutPrepareHeader(waveOut, &wh, sizeof(wh))!=MMSYSERR_NOERROR) + goto abrt; + if(waveOutWrite(waveOut, &wh, sizeof(wh))!=MMSYSERR_NOERROR) + goto abrt; + SLEEP(duration); +abrt: + waveOutUnprepareHeader(waveOut, &wh, sizeof(wh)); + waveOutReset(waveOut); + waveOutClose(waveOut); +} + +#endif /* _WIN32 */ + +#ifdef __unix__ +/****************************************************************************/ +/* Generate a tone at specified frequency for specified milliseconds */ +/* Thanks to Casey Martin for this code */ +/****************************************************************************/ +void DLLCALL unix_beep(int freq, int dur) +{ + static int console_fd=-1; + +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) + int speaker_fd=-1; + tone_t tone; + + speaker_fd = open("/dev/speaker", O_WRONLY|O_APPEND); + if(speaker_fd != -1) { + tone.frequency=freq; + tone.duration=dur/10; + ioctl(speaker_fd,SPKRTONE,&tone); + close(speaker_fd); + return; + } +#endif + +#if !defined(__GNU__) && !defined(__QNX__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) + if(console_fd == -1) + console_fd = open("/dev/console", O_NOCTTY); + + if(console_fd != -1) { +#if defined(__solaris__) + ioctl(console_fd, KIOCCMD, KBD_CMD_BELL); +#else + if(freq != 0) /* Don't divide by zero */ + ioctl(console_fd, KIOCSOUND, (int) (1193180 / freq)); +#endif /* solaris */ + SLEEP(dur); +#if defined(__solaris__) + ioctl(console_fd, KIOCCMD, KBD_CMD_NOBELL); /* turn off tone */ +#else + ioctl(console_fd, KIOCSOUND, 0); /* turn off tone */ +#endif /* solaris */ + } +#endif +} + +void DLLCALL SineBeep(double freq, DWORD duration) +{ + 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; + makesine(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); + return; + } + wr=0; + while(wr<samples) { + i=write(dsp, wave+wr, samples-wr); + if(i>=0) + wr+=i; + } + close(dsp); +} +#endif diff --git a/src/xpdev/xpbeep.h b/src/xpdev/xpbeep.h new file mode 100644 index 0000000000000000000000000000000000000000..8a47f85908c4d730d349de9537ef66f897a680d3 --- /dev/null +++ b/src/xpdev/xpbeep.h @@ -0,0 +1,25 @@ +#ifndef _XPBEEP_H_ +#define _XPBEEP_H_ + +#if defined(_WIN32) + #define BEEP(freq,dur) SineBeep((double)(freq),(DWORD)(dur)) +#elif defined(__OS2__) + #define BEEP(freq,dur) DosBeep(freq,dur) +#elif defined(__unix__) || defined(__APPLE__) + #define BEEP(freq,dur) SineBeep((double)(freq),(DWORD)(dur)) +#else + #error "Unsupported Target: Need some macros and/or function prototypes here." +#endif + +#ifdef __cplusplus +extern "C" { +#endif +void SineBeep(double freq, DWORD duration); +#ifdef __unix__ +void unix_beep(int freq, int dur); +#endif +#ifdef __cplusplus +} +#endif + +#endif