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