Added 0.030 of PicoDrive and moved license files into root
[cyclone68000.git] / PicoDrive / Wave.cpp
1 \r
2 #include "stdafx.h"\r
3 \r
4 int WaveRate=0;\r
5 int WaveLen=0; // Length of each buffer in samples\r
6 short *WaveDest=NULL; // Destination to render sound\r
7 \r
8 static HWAVEOUT WaveOut=NULL;\r
9 static short *WaveBuf=NULL; // Wave double-buffer\r
10 static WAVEHDR WaveHeader[2]; // WAVEHDR for each buffer\r
11 static int WavePlay=0; // Next buffer side to play\r
12 \r
13 int WaveInit()\r
14 {\r
15   WAVEFORMATEX wfx;\r
16   WAVEHDR *pwh=NULL;\r
17 \r
18   if (WaveOut) return 0; // Already initted\r
19 \r
20   memset(&wfx,0,sizeof(wfx));\r
21   memset(&WaveHeader,0,sizeof(WaveHeader));\r
22 \r
23   wfx.wFormatTag=WAVE_FORMAT_PCM;\r
24   wfx.nChannels=2; // stereo\r
25   wfx.nSamplesPerSec=WaveRate; // sample rate\r
26   wfx.wBitsPerSample=16;\r
27   // Calculate bytes per sample and per second\r
28   wfx.nBlockAlign=(unsigned short)( (wfx.wBitsPerSample>>3)*wfx.nChannels );\r
29   wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;\r
30 \r
31   waveOutOpen(&WaveOut,WAVE_MAPPER,&wfx,0,NULL,CALLBACK_NULL);\r
32 \r
33   // Allocate both buffers\r
34   WaveBuf=(short *)malloc(WaveLen<<3);\r
35   if (WaveBuf==NULL) return 1;\r
36   memset(WaveBuf,0,WaveLen<<3);\r
37 \r
38   // Make WAVEHDRs for both buffers\r
39   pwh=WaveHeader+0;\r
40   pwh->lpData=(char *)WaveBuf;\r
41   pwh->dwBufferLength=WaveLen<<2;\r
42   pwh->dwLoops=1;\r
43 \r
44   pwh=WaveHeader+1;\r
45   *pwh=WaveHeader[0]; pwh->lpData+=WaveLen<<2;\r
46 \r
47   // Prepare the buffers\r
48   waveOutPrepareHeader(WaveOut,WaveHeader,  sizeof(WAVEHDR));\r
49   waveOutPrepareHeader(WaveOut,WaveHeader+1,sizeof(WAVEHDR));\r
50 \r
51   // Queue both buffers:\r
52   WavePlay=0;\r
53   WaveHeader[0].dwFlags|=WHDR_DONE;\r
54   WaveHeader[1].dwFlags|=WHDR_DONE;\r
55   WaveUpdate();\r
56   return 0;\r
57 }\r
58 \r
59 int WaveExit()\r
60 {\r
61   WAVEHDR *pwh=NULL;\r
62   int i=0;\r
63 \r
64   if (WaveOut) waveOutReset(WaveOut);\r
65 \r
66   for (i=0;i<2;i++)\r
67   {\r
68     pwh=WaveHeader+i;\r
69     if (pwh->lpData) waveOutUnprepareHeader(WaveOut,pwh,sizeof(*pwh));\r
70   }\r
71   memset(WaveHeader,0,sizeof(WaveHeader));\r
72 \r
73   free(WaveBuf); WaveBuf=NULL; WaveLen=0;\r
74 \r
75   if (WaveOut) waveOutClose(WaveOut);  WaveOut=NULL;\r
76   return 0;\r
77 }\r
78 \r
79 int WaveUpdate()\r
80 {\r
81   WAVEHDR *pwh=NULL; int i=0;\r
82   int Last=-1;\r
83 \r
84   for (i=0;i<2;i++)\r
85   {\r
86     pwh=WaveHeader+WavePlay;\r
87     if (pwh->lpData==NULL) return 1; // Not initted\r
88 \r
89     if (pwh->dwFlags&WHDR_DONE)\r
90     {\r
91       // This buffer has finished - start it playing again\r
92       WaveDest=(short *)pwh->lpData;\r
93       SndRender();\r
94       WaveDest=NULL;\r
95       \r
96       waveOutWrite(WaveOut,pwh,sizeof(*pwh));\r
97       Last=WavePlay; // Remember the last buffer we played\r
98     }\r
99 \r
100     WavePlay++; WavePlay&=1;\r
101   }\r
102 \r
103   if (Last>=0) WavePlay=Last^1; // Next buffer to play is the other one\r
104   return 0;\r
105 }\r