~ubuntu-branches/ubuntu/lucid/mpg123/lucid

« back to all changes in this revision

Viewing changes to src/audio_win32.c

Tags: upstream-0.60
ImportĀ upstreamĀ versionĀ 0.60

Show diffs side-by-side

added added

removed removed

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