2
audio_win32.c: audio output for Windows 32bit
4
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
5
see COPYING and AUTHORS files in distribution or http://mpg123.de
6
initially written (as it seems) by Tony Million
19
static CRITICAL_SECTION cs;
21
static HWAVEOUT dev = NULL;
22
static int nBlocks = 0;
23
static int MAX_BLOCKS = 6;
25
static _inline void wait(void)
31
static void CALLBACK wave_callback(HWAVE hWave, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
38
EnterCriticalSection( &cs );
40
wh = (WAVEHDR *)dwParam1;
42
waveOutUnprepareHeader(dev, wh, sizeof (WAVEHDR));
44
//Deallocate the buffer memory
45
hg = GlobalHandle(wh->lpData);
49
//Deallocate the header memory
50
hg = GlobalHandle(wh);
54
// decrease the number of USED blocks
57
LeaveCriticalSection( &cs );
61
int audio_open(struct audio_info_struct *ai)
64
WAVEFORMATEX outFormatex;
69
if(!waveOutGetNumDevs())
71
MessageBox(NULL, "No audio devices present!", "Error...", MB_OK);
75
outFormatex.wFormatTag = WAVE_FORMAT_PCM;
76
outFormatex.wBitsPerSample = 16;
77
outFormatex.nChannels = 2;
78
outFormatex.nSamplesPerSec = ai->rate;
79
outFormatex.nAvgBytesPerSec = outFormatex.nSamplesPerSec * outFormatex.nChannels * outFormatex.wBitsPerSample/8;
80
outFormatex.nBlockAlign = outFormatex.nChannels * outFormatex.wBitsPerSample/8;
82
res = waveOutOpen(&dev, (UINT)ai->device, &outFormatex, (DWORD)wave_callback, 0, CALLBACK_FUNCTION);
84
if(res != MMSYSERR_NOERROR)
88
case MMSYSERR_ALLOCATED:
89
MessageBox(NULL, "Device Is Already Open", "Error...", MB_OK);
91
case MMSYSERR_BADDEVICEID:
92
MessageBox(NULL, "The Specified Device Is out of range", "Error...", MB_OK);
94
case MMSYSERR_NODRIVER:
95
MessageBox(NULL, "There is no audio driver in this system.", "Error...", MB_OK);
98
MessageBox(NULL, "Unable to allocate sound memory.", "Error...", MB_OK);
100
case WAVERR_BADFORMAT:
101
MessageBox(NULL, "This audio format is not supported.", "Error...", MB_OK);
104
MessageBox(NULL, "The device is synchronous.", "Error...", MB_OK);
107
MessageBox(NULL, "Unknown Media Error", "Error...", MB_OK);
114
InitializeCriticalSection(&cs);
119
int audio_get_formats(struct audio_info_struct *ai)
121
return AUDIO_FORMAT_SIGNED_16;
124
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
131
///////////////////////////////////////////////////////
132
// Wait for a few FREE blocks...
133
///////////////////////////////////////////////////////
134
while(nBlocks > MAX_BLOCKS)
137
////////////////////////////////////////////////////////
138
// FIRST allocate some memory for a copy of the buffer!
139
////////////////////////////////////////////////////////
140
hg2 = GlobalAlloc(GMEM_MOVEABLE, len);
143
MessageBox(NULL, "GlobalAlloc failed!", "Error...", MB_OK);
149
//////////////////////////////////////////////////////////
150
// Here we can call any modification output functions we want....
151
///////////////////////////////////////////////////////////
152
CopyMemory(b, buf, len);
154
///////////////////////////////////////////////////////////
155
// now make a header and WRITE IT!
156
///////////////////////////////////////////////////////////
157
hg = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (WAVEHDR));
163
wh->dwBufferLength = len;
167
EnterCriticalSection( &cs );
169
res = waveOutPrepareHeader(dev, wh, sizeof (WAVEHDR));
174
LeaveCriticalSection( &cs );
178
res = waveOutWrite(dev, wh, sizeof (WAVEHDR));
183
LeaveCriticalSection( &cs );
189
LeaveCriticalSection( &cs );
194
int audio_close(struct audio_info_struct *ai)
200
waveOutReset(dev); //reset the device
201
waveOutClose(dev); //close the device
205
DeleteCriticalSection(&cs);
211
void audio_queueflush(struct audio_info_struct *ai)