source: trunk/third/esound/audio_win32.c @ 20226

Revision 20226, 5.2 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20225, which included commits to RCS files with non-trunk default branches.
RevLine 
[20225]1
2#include <sys/types.h>
3#include <stdio.h>
4#include <fcntl.h>
5#include <stdlib.h>
6
7#include "mpg123.h"
8
9#include <windows.h>
10
11static CRITICAL_SECTION        cs;
12
13static HWAVEOUT dev    = NULL;
14static int nBlocks             = 0;
15static int MAX_BLOCKS  = 6;
16
17static _inline void wait(void)
18{
19   while(nBlocks)
20       Sleep(77);
21}
22
23static void CALLBACK wave_callback(HWAVE hWave, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
24{
25   WAVEHDR *wh;
26   HGLOBAL hg;
27
28   if(uMsg == WOM_DONE)
29   {
30       EnterCriticalSection( &cs );
31
32       wh = (WAVEHDR *)dwParam1;
33
34       waveOutUnprepareHeader(dev, wh, sizeof (WAVEHDR));
35
36       //Deallocate the buffer memory
37       hg = GlobalHandle(wh->lpData);
38       GlobalUnlock(hg);
39       GlobalFree(hg);
40
41       //Deallocate the header memory
42       hg = GlobalHandle(wh);
43       GlobalUnlock(hg);
44       GlobalFree(hg);
45
46       // decrease the number of USED blocks
47       nBlocks--;
48
49       LeaveCriticalSection( &cs );
50   }
51}
52
53int audio_open(struct audio_info_struct *ai)
54{
55   MMRESULT res;
56   WAVEFORMATEX outFormatex;
57
58   if(ai->rate == -1)
59       return(0);
60
61   if(!waveOutGetNumDevs())
62   {
63       MessageBox(NULL, "No audio devices present!", "Error...", MB_OK);
64       return -1;
65   }
66
67   outFormatex.wFormatTag      = WAVE_FORMAT_PCM;
68   outFormatex.wBitsPerSample  = 16;
69   outFormatex.nChannels       = 2;
70   outFormatex.nSamplesPerSec  = ai->rate;
71   outFormatex.nAvgBytesPerSec = outFormatex.nSamplesPerSec * outFormatex.nChannels * outFormatex.wBitsPerSample/8;
72   outFormatex.nBlockAlign     = outFormatex.nChannels * outFormatex.wBitsPerSample/8;
73
74   res = waveOutOpen(&dev, (UINT)ai->device, &outFormatex, (DWORD)wave_callback, 0, CALLBACK_FUNCTION);
75
76   if(res != MMSYSERR_NOERROR)
77   {
78       switch(res)
79       {
80           case MMSYSERR_ALLOCATED:
81               MessageBox(NULL, "Device Is Already Open", "Error...", MB_OK);
82               break;
83           case MMSYSERR_BADDEVICEID:
84               MessageBox(NULL, "The Specified Device Is out of range", "Error...", MB_OK);
85               break;
86           case MMSYSERR_NODRIVER:
87               MessageBox(NULL, "There is no audio driver in this system.", "Error...", MB_OK);
88               break;
89           case MMSYSERR_NOMEM:
90              MessageBox(NULL, "Unable to allocate sound memory.", "Error...", MB_OK);
91               break;
92           case WAVERR_BADFORMAT:
93               MessageBox(NULL, "This audio format is not supported.", "Error...", MB_OK);
94               break;
95           case WAVERR_SYNC:
96               MessageBox(NULL, "The device is synchronous.", "Error...", MB_OK);
97               break;
98           default:
99               MessageBox(NULL, "Unknown Media Error", "Error...", MB_OK);
100               break;
101       }
102       return -1;
103   }
104
105   waveOutReset(dev);
106   InitializeCriticalSection(&cs);
107
108   return 0;
109}
110
111int audio_reset_parameters(struct audio_info_struct *ai)
112{
113  return 0;
114}
115
116int audio_rate_best_match(struct audio_info_struct *ai)
117{
118  return 0;
119}
120
121int audio_set_rate(struct audio_info_struct *ai)
122{
123  return 0;
124}
125
126int audio_set_channels(struct audio_info_struct *ai)
127{
128  return 0;
129}
130
131int audio_set_format(struct audio_info_struct *ai)
132{
133  return 0;
134}
135
136int audio_get_formats(struct audio_info_struct *ai)
137{
138  return AUDIO_FORMAT_SIGNED_16;
139}
140
141int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
142{
143   HGLOBAL hg, hg2;
144   LPWAVEHDR wh;
145   MMRESULT res;
146   void *b;
147
148   ///////////////////////////////////////////////////////
149   //  Wait for a few FREE blocks...
150   ///////////////////////////////////////////////////////
151   while(nBlocks > MAX_BLOCKS)
152       Sleep(77);
153
154   ////////////////////////////////////////////////////////
155   // FIRST allocate some memory for a copy of the buffer!
156   ////////////////////////////////////////////////////////
157   hg2 = GlobalAlloc(GMEM_MOVEABLE, len);
158   if(!hg2)
159   {
160       MessageBox(NULL, "GlobalAlloc failed!", "Error...",  MB_OK);
161       return(-1);
162   }
163   b = GlobalLock(hg2);
164
165
166   //////////////////////////////////////////////////////////
167   // Here we can call any modification output functions we want....
168   ///////////////////////////////////////////////////////////
169   CopyMemory(b, buf, len);
170
171   ///////////////////////////////////////////////////////////
172   // now make a header and WRITE IT!
173   ///////////////////////////////////////////////////////////
174   hg = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (WAVEHDR));
175   if(!hg)
176   {
177       return -1;
178   }
179   wh = GlobalLock(hg);
180   wh->dwBufferLength = len;
181   wh->lpData = b;
182
183
184   EnterCriticalSection( &cs );
185
186   res = waveOutPrepareHeader(dev, wh, sizeof (WAVEHDR));
187   if(res)
188   {
189       GlobalUnlock(hg);
190       GlobalFree(hg);
191       LeaveCriticalSection( &cs );
192       return -1;
193   }
194
195   res = waveOutWrite(dev, wh, sizeof (WAVEHDR));
196   if(res)
197   {
198       GlobalUnlock(hg);
199       GlobalFree(hg);
200       LeaveCriticalSection( &cs );
201       return (-1);
202   }
203
204   nBlocks++;
205
206   LeaveCriticalSection( &cs );
207
208   return(len);
209}
210
211int audio_close(struct audio_info_struct *ai)
212{
213   if(dev)
214   {
215       wait();
216
217       waveOutReset(dev);      //reset the device
218       waveOutClose(dev);      //close the device
219       dev=NULL;
220   }
221
222   DeleteCriticalSection(&cs);
223
224   nBlocks = 0;
225   return(0);
226}
Note: See TracBrowser for help on using the repository browser.