Skip to content
Snippets Groups Projects
Commit faff4c83 authored by rswindell's avatar rswindell
Browse files

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.
parent 28bf6e08
Branches
Tags
No related merge requests found
/* 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
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment