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