Added 0.030 of PicoDrive and moved license files into root
[cyclone68000.git] / PicoDrive / Wave.cpp
diff --git a/PicoDrive/Wave.cpp b/PicoDrive/Wave.cpp
new file mode 100644 (file)
index 0000000..b5e5a46
--- /dev/null
@@ -0,0 +1,105 @@
+\r
+#include "stdafx.h"\r
+\r
+int WaveRate=0;\r
+int WaveLen=0; // Length of each buffer in samples\r
+short *WaveDest=NULL; // Destination to render sound\r
+\r
+static HWAVEOUT WaveOut=NULL;\r
+static short *WaveBuf=NULL; // Wave double-buffer\r
+static WAVEHDR WaveHeader[2]; // WAVEHDR for each buffer\r
+static int WavePlay=0; // Next buffer side to play\r
+\r
+int WaveInit()\r
+{\r
+  WAVEFORMATEX wfx;\r
+  WAVEHDR *pwh=NULL;\r
+\r
+  if (WaveOut) return 0; // Already initted\r
+\r
+  memset(&wfx,0,sizeof(wfx));\r
+  memset(&WaveHeader,0,sizeof(WaveHeader));\r
+\r
+  wfx.wFormatTag=WAVE_FORMAT_PCM;\r
+  wfx.nChannels=2; // stereo\r
+  wfx.nSamplesPerSec=WaveRate; // sample rate\r
+  wfx.wBitsPerSample=16;\r
+  // Calculate bytes per sample and per second\r
+  wfx.nBlockAlign=(unsigned short)( (wfx.wBitsPerSample>>3)*wfx.nChannels );\r
+  wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;\r
+\r
+  waveOutOpen(&WaveOut,WAVE_MAPPER,&wfx,0,NULL,CALLBACK_NULL);\r
+\r
+  // Allocate both buffers\r
+  WaveBuf=(short *)malloc(WaveLen<<3);\r
+  if (WaveBuf==NULL) return 1;\r
+  memset(WaveBuf,0,WaveLen<<3);\r
+\r
+  // Make WAVEHDRs for both buffers\r
+  pwh=WaveHeader+0;\r
+  pwh->lpData=(char *)WaveBuf;\r
+  pwh->dwBufferLength=WaveLen<<2;\r
+  pwh->dwLoops=1;\r
+\r
+  pwh=WaveHeader+1;\r
+  *pwh=WaveHeader[0]; pwh->lpData+=WaveLen<<2;\r
+\r
+  // Prepare the buffers\r
+  waveOutPrepareHeader(WaveOut,WaveHeader,  sizeof(WAVEHDR));\r
+  waveOutPrepareHeader(WaveOut,WaveHeader+1,sizeof(WAVEHDR));\r
+\r
+  // Queue both buffers:\r
+  WavePlay=0;\r
+  WaveHeader[0].dwFlags|=WHDR_DONE;\r
+  WaveHeader[1].dwFlags|=WHDR_DONE;\r
+  WaveUpdate();\r
+  return 0;\r
+}\r
+\r
+int WaveExit()\r
+{\r
+  WAVEHDR *pwh=NULL;\r
+  int i=0;\r
+\r
+  if (WaveOut) waveOutReset(WaveOut);\r
+\r
+  for (i=0;i<2;i++)\r
+  {\r
+    pwh=WaveHeader+i;\r
+    if (pwh->lpData) waveOutUnprepareHeader(WaveOut,pwh,sizeof(*pwh));\r
+  }\r
+  memset(WaveHeader,0,sizeof(WaveHeader));\r
+\r
+  free(WaveBuf); WaveBuf=NULL; WaveLen=0;\r
+\r
+  if (WaveOut) waveOutClose(WaveOut);  WaveOut=NULL;\r
+  return 0;\r
+}\r
+\r
+int WaveUpdate()\r
+{\r
+  WAVEHDR *pwh=NULL; int i=0;\r
+  int Last=-1;\r
+\r
+  for (i=0;i<2;i++)\r
+  {\r
+    pwh=WaveHeader+WavePlay;\r
+    if (pwh->lpData==NULL) return 1; // Not initted\r
+\r
+    if (pwh->dwFlags&WHDR_DONE)\r
+    {\r
+      // This buffer has finished - start it playing again\r
+      WaveDest=(short *)pwh->lpData;\r
+      SndRender();\r
+      WaveDest=NULL;\r
+      \r
+      waveOutWrite(WaveOut,pwh,sizeof(*pwh));\r
+      Last=WavePlay; // Remember the last buffer we played\r
+    }\r
+\r
+    WavePlay++; WavePlay&=1;\r
+  }\r
+\r
+  if (Last>=0) WavePlay=Last^1; // Next buffer to play is the other one\r
+  return 0;\r
+}\r