From faff4c8348c7bc959b7c1160969e76cbfd244596 Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Fri, 21 Jan 2005 23:34:48 +0000
Subject: [PATCH] Introduced xptone() which allows run-time selection of the
 wave shape. This function *only* deals with the dsp/wave output device.
 Eliminated unused 'k' variable from makewave(). It might be cool to allow the
 application (e.g. syncterm or sbbs) to select the wave shape to use for
 different textures.

---
 src/xpdev/xpbeep.c | 169 ++++++++++++++++++++++++---------------------
 src/xpdev/xpbeep.h |  14 +++-
 2 files changed, 104 insertions(+), 79 deletions(-)

diff --git a/src/xpdev/xpbeep.c b/src/xpdev/xpbeep.c
index 57068070e0..bda3bf50ed 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 10c2724dbe..ce3d14a49e 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
-- 
GitLab