source: trunk/src/winmm/waveout.cpp@ 21916

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 15.8 KB
Line 
1/* $Id: waveout.cpp,v 1.27 2003-07-16 15:47:24 sandervl Exp $ */
2
3/*
4 * Wave out MM apis
5 *
6 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * waveOutGetPosition partly based on Wine code (dll\winmm\wineoss\audio.c)
9 * Copyright 1994 Martin Ayotte
10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
14
15/******************************************************************************/
16// Includes
17/******************************************************************************/
18
19#include <os2win.h>
20#include <mmsystem.h>
21#include <odinwrap.h>
22
23#include <string.h>
24#include <stdio.h>
25#include <string.h>
26#include <unicode.h>
27
28#include "waveoutdart.h"
29#include "waveoutdaud.h"
30#include "waveoutflash.h"
31#include "misc.h"
32#include "winmm.h"
33#include "initterm.h"
34
35#define DBG_LOCALLOG DBG_waveout
36#include "dbglocal.h"
37
38/******************************************************************************/
39/******************************************************************************/
40MMRESULT WINAPI waveOutOpen(LPHWAVEOUT phwo, UINT uDeviceID, const LPWAVEFORMATEX pwfx,
41 DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen)
42{
43 MMRESULT rc;
44
45 if (fMMPMAvailable == FALSE)
46 return MMSYSERR_NODRIVER;
47
48 if (pwfx == NULL)
49 return(WAVERR_BADFORMAT);
50
51 if (fdwOpen & WAVE_FORMAT_QUERY) {
52 if (WaveOut::queryFormat(pwfx->wFormatTag, pwfx->nChannels,
53 pwfx->nSamplesPerSec,
54 pwfx->wBitsPerSample) == TRUE) {
55 return (MMSYSERR_NOERROR);
56 }
57 return (WAVERR_BADFORMAT);
58 }
59
60 if (phwo == NULL)
61 return(MMSYSERR_INVALPARAM);
62
63 if (ODIN_IsFlashAudioEnabled())
64 *phwo = (HWAVEOUT)new FlashWaveOut(pwfx, fdwOpen, dwCallback, dwInstance);
65 else
66 if (DAudioWaveOut::isDirectAudioAvailable())
67 *phwo = (HWAVEOUT)new DAudioWaveOut(pwfx, fdwOpen, dwCallback, dwInstance);
68 else
69 *phwo = (HWAVEOUT)new DartWaveOut(pwfx, fdwOpen, dwCallback, dwInstance);
70
71 if(*phwo == NULL)
72 return(MMSYSERR_NODRIVER);
73
74 rc = ((WaveOut *)*phwo)->open();
75 if (rc != MMSYSERR_NOERROR)
76 delete (WaveOut *)*phwo;
77
78 return rc;
79}
80/******************************************************************************/
81/******************************************************************************/
82MMRESULT WINAPI waveOutWrite(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
83{
84 WaveOut *dwave = (WaveOut *)hwo;
85
86 if(WaveOut::find(dwave) == TRUE)
87 {
88 if(!(pwh->dwFlags & WHDR_PREPARED) || pwh->lpData == NULL) {
89 dprintf(("waveOutWrite: WAVERR_UNPREPARED!!"));
90 return WAVERR_UNPREPARED;
91 }
92 if(pwh->dwFlags & WHDR_INQUEUE) {
93 dprintf(("waveOutWrite: WAVERR_STILLPLAYING!!"));
94 return WAVERR_STILLPLAYING;
95 }
96 pwh->dwFlags |= WHDR_INQUEUE;
97 pwh->dwFlags &= ~WHDR_DONE;
98
99 dprintf(("waveOutWrite ptr %x size %d %x %x %x %x %x %x", pwh->lpData, pwh->dwBufferLength, pwh->dwBytesRecorded, pwh->dwUser, pwh->dwFlags, pwh->dwLoops, pwh->lpNext, pwh->reserved));
100 return(dwave->write(pwh, cbwh));
101 }
102 else return(MMSYSERR_INVALHANDLE);
103}
104/******************************************************************************/
105/******************************************************************************/
106MMRESULT WINAPI waveOutReset(HWAVEOUT hwaveout)
107{
108 WaveOut *dwave = (WaveOut *)hwaveout;
109
110 if(WaveOut::find(dwave) == TRUE)
111 return(dwave->reset());
112 else return(MMSYSERR_INVALHANDLE);
113}
114/******************************************************************************/
115/******************************************************************************/
116MMRESULT WINAPI waveOutBreakLoop(HWAVEOUT hwaveout)
117{
118 WaveOut *dwave = (WaveOut *)hwaveout;
119
120 dprintf(("WINMM:waveOutBreakLoop (implemented as reset) %X\n", hwaveout));
121 if(WaveOut::find(dwave) == TRUE)
122 return(dwave->reset());
123 else return(MMSYSERR_INVALHANDLE);
124}
125/******************************************************************************/
126/******************************************************************************/
127MMRESULT WINAPI waveOutClose(HWAVEOUT hwaveout)
128{
129 WaveOut *dwave = (WaveOut *)hwaveout;
130
131 if(WaveOut::find(dwave) == TRUE)
132 {
133 if(dwave->getState() == STATE_PLAYING)
134 return(WAVERR_STILLPLAYING);
135
136 delete dwave;
137 return(MMSYSERR_NOERROR);
138 }
139 else return(MMSYSERR_INVALHANDLE);
140}
141/******************************************************************************/
142/******************************************************************************/
143MMRESULT WINAPI waveOutPause(HWAVEOUT hwaveout)
144{
145 WaveOut *dwave = (WaveOut *)hwaveout;
146
147 if(WaveOut::find(dwave) == TRUE)
148 return(dwave->pause());
149 else return(MMSYSERR_INVALHANDLE);
150}
151/******************************************************************************/
152/******************************************************************************/
153MMRESULT WINAPI waveOutRestart(HWAVEOUT hwaveout)
154{
155 WaveOut *dwave = (WaveOut *)hwaveout;
156
157 if(WaveOut::find(dwave) == TRUE)
158 return(dwave->resume());
159 else return(MMSYSERR_INVALHANDLE);
160}
161/******************************************************************************/
162/******************************************************************************/
163MMRESULT WINAPI waveOutPrepareHeader(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
164{
165 WaveOut *dwave = (WaveOut *)hwo;
166
167 if(WaveOut::find(dwave) == TRUE)
168 {
169 if(pwh->dwFlags & WHDR_INQUEUE)
170 return WAVERR_STILLPLAYING;
171
172 pwh->dwFlags |= WHDR_PREPARED;
173 pwh->dwFlags &= ~WHDR_DONE;
174 pwh->lpNext = NULL;
175 return(MMSYSERR_NOERROR);
176 }
177 else return(MMSYSERR_INVALHANDLE);
178}
179/******************************************************************************/
180/******************************************************************************/
181MMRESULT WINAPI waveOutUnprepareHeader(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
182{
183 WaveOut *dwave = (WaveOut *)hwo;
184
185 if(WaveOut::find(dwave) == TRUE)
186 {
187 if(pwh->dwFlags & WHDR_INQUEUE)
188 return WAVERR_STILLPLAYING;
189
190 pwh->dwFlags &= ~WHDR_PREPARED;
191 pwh->dwFlags |= WHDR_DONE;
192 return(MMSYSERR_NOERROR);
193 }
194 else return(MMSYSERR_INVALHANDLE);
195}
196/******************************************************************************/
197/******************************************************************************/
198MMRESULT WINAPI waveOutGetPosition(HWAVEOUT hwo, LPMMTIME pmmt, UINT cbmmt)
199{
200 WaveOut *dwave = (WaveOut *)hwo;
201
202 if(pmmt == NULL)
203 return MMSYSERR_INVALPARAM;
204
205 if(WaveOut::find(dwave) == TRUE)
206 {
207 ULONG position;
208
209 position = dwave->getPosition();
210 if(position == -1) {
211 return MMSYSERR_HANDLEBUSY; //todo correct error value
212 }
213 switch (pmmt->wType) {
214 case TIME_BYTES:
215 pmmt->u.cb = position;
216 dprintf2(("WINMM:waveOutGetPosition: TIME_BYTES %d (%x)", position, GetCurrentTime()));
217 break;
218 case TIME_SAMPLES:
219 pmmt->u.sample = position * 8 / dwave->getBitsPerSample();
220 dprintf2(("WINMM:waveOutGetPosition: TIME_SAMPLES %d", pmmt->u.sample));
221 break;
222 case TIME_SMPTE:
223 {
224 ULONG timeval = position / (dwave->getAvgBytesPerSecond() / 1000);
225 pmmt->u.smpte.hour = timeval / 108000;
226 timeval -= pmmt->u.smpte.hour * 108000;
227 pmmt->u.smpte.min = timeval / 1800;
228 timeval -= pmmt->u.smpte.min * 1800;
229 pmmt->u.smpte.sec = timeval / 30;
230 timeval -= pmmt->u.smpte.sec * 30;
231 pmmt->u.smpte.frame = timeval;
232 pmmt->u.smpte.fps = 30;
233 dprintf2(("WINMM:waveOutGetPosition: TIME_SAMPLES %d", position));
234 break;
235 }
236 default:
237 dprintf(("waveOutGetPosition: Format %d not supported ! use TIME_MS !\n", pmmt->wType));
238 pmmt->wType = TIME_MS;
239 case TIME_MS:
240 pmmt->u.ms = position / (dwave->getAvgBytesPerSecond() / 1000);
241 dprintf2(("WINMM:waveOutGetPosition: TIME_MS pos=%d ms=%d time=%d", position, pmmt->u.ms, GetCurrentTime()));
242 break;
243 }
244 return MMSYSERR_NOERROR;
245 }
246 else return(MMSYSERR_INVALHANDLE);
247}
248/******************************************************************************/
249/******************************************************************************/
250MMRESULT WINAPI waveOutGetDevCapsA(UINT uDeviceID, LPWAVEOUTCAPSA pwoc, UINT cbwoc)
251{
252 if(fMMPMAvailable == FALSE) return MMSYSERR_NODRIVER;
253
254 if(WaveOut::getNumDevices() == 0) {
255 memset(pwoc, 0, sizeof(*pwoc));
256 return MMSYSERR_NODRIVER;
257 }
258
259 // we have to fill in this thing
260 pwoc->wMid = 0; /* manufacturer ID */
261 pwoc->wPid = 0; /* product ID */
262 pwoc->vDriverVersion = 0x0001; /* version of the driver */
263 strcpy( pwoc->szPname, "OS/2 DART Wave Out" ); /* product name */
264 pwoc->dwFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_1S08 |
265 WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16 |
266 WAVE_FORMAT_2M08 | WAVE_FORMAT_2S08 |
267 WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 |
268 WAVE_FORMAT_4M08 | WAVE_FORMAT_4S08 |
269 WAVE_FORMAT_4M16 | WAVE_FORMAT_4S16;
270
271 pwoc->wChannels = 2; /* number of sources supported */
272 pwoc->wReserved1 = 0; /* packing */
273 pwoc->dwSupport = WAVECAPS_LRVOLUME | WAVECAPS_VOLUME;
274
275 return MMSYSERR_NOERROR;
276}
277/******************************************************************************/
278/******************************************************************************/
279MMRESULT WINAPI waveOutGetDevCapsW(UINT uDeviceID, LPWAVEOUTCAPSW pwoc, UINT cbwoc)
280{
281 if(fMMPMAvailable == FALSE) return MMSYSERR_NODRIVER;
282
283 if(WaveOut::getNumDevices() == 0) {
284 memset(pwoc, 0, sizeof(*pwoc));
285 return MMSYSERR_NODRIVER;
286 }
287 // we have to fill in this thing
288 pwoc->wMid = 0; /* manufacturer ID */
289 pwoc->wPid = 0; /* product ID */
290 pwoc->vDriverVersion = 0x0001; /* version of the driver */
291 lstrcpyW(pwoc->szPname, (LPCWSTR)L"OS/2 DART Wave Out"); /* product name */
292 pwoc->dwFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_1S08 |
293 WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16 |
294 WAVE_FORMAT_2M08 | WAVE_FORMAT_2S08 |
295 WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 |
296 WAVE_FORMAT_4M08 | WAVE_FORMAT_4S08 |
297 WAVE_FORMAT_4M16 | WAVE_FORMAT_4S16;
298
299 pwoc->wChannels = 2; /* number of sources supported */
300 pwoc->wReserved1 = 0; /* packing */
301 pwoc->dwSupport = WAVECAPS_LRVOLUME | WAVECAPS_VOLUME;
302
303 return MMSYSERR_NOERROR;
304}
305/******************************************************************************/
306/******************************************************************************/
307UINT WINAPI waveOutGetNumDevs()
308{
309 if(fMMPMAvailable == FALSE) return 0;
310
311 return WaveOut::getNumDevices();
312}
313/******************************************************************************/
314/******************************************************************************/
315MMRESULT WINAPI waveOutGetErrorTextA(MMRESULT wError, LPSTR lpText, UINT cchText)
316{
317 const char * theMsg = getWinmmMsg( wError );
318 if(theMsg) {
319 strncpy( lpText, theMsg, cchText );
320 }
321 else
322 {
323 char errMsg[100];
324 sprintf( errMsg, "Unknown error number %d", wError );
325 strncpy( lpText, errMsg, cchText );
326 }
327 return MMSYSERR_NOERROR;
328}
329/******************************************************************************/
330/******************************************************************************/
331MMRESULT WINAPI waveOutGetErrorTextW(MMRESULT wError, LPWSTR lpText, UINT cchText)
332{
333 const char * theMsg = getWinmmMsg( wError );
334 if(theMsg) {
335 AsciiToUnicodeN( theMsg, lpText, cchText );
336 }
337 else
338 {
339 char errMsg[100];
340 sprintf( errMsg, "Unknown error number %d", wError );
341 AsciiToUnicodeN( errMsg, lpText, cchText );
342 }
343 return MMSYSERR_NOERROR;
344}
345/******************************************************************************/
346/******************************************************************************/
347MMRESULT WINAPI waveOutGetID(HWAVEOUT hwo, LPUINT puDeviceID)
348{
349 WaveOut *dwave = (WaveOut *)hwo;
350 if(WaveOut::find(dwave) == TRUE)
351 {
352 *puDeviceID = 1;
353 return MMSYSERR_NOERROR;
354 }
355 else return(MMSYSERR_INVALHANDLE);
356}
357/******************************************************************************/
358/******************************************************************************/
359MMRESULT WINAPI waveOutGetPitch(HWAVEOUT hwo, LPDWORD pdwPitch)
360{
361 WaveOut *dwave = (WaveOut *)hwo;
362 if(WaveOut::find(dwave) == TRUE)
363 return MMSYSERR_NOTSUPPORTED;
364 else return(MMSYSERR_INVALHANDLE);
365}
366/******************************************************************************/
367/******************************************************************************/
368MMRESULT WINAPI waveOutSetPitch(HWAVEOUT hwo, DWORD dwPitch)
369{
370 WaveOut *dwave = (WaveOut *)hwo;
371 if(WaveOut::find(dwave) == TRUE)
372 return MMSYSERR_NOTSUPPORTED;
373 else return(MMSYSERR_INVALHANDLE);
374}
375/******************************************************************************/
376/******************************************************************************/
377MMRESULT WINAPI waveOutGetVolume(HWAVEOUT hwo, LPDWORD pdwVolume)
378{
379 WaveOut *dwave = (WaveOut *)hwo;
380 if(WaveOut::find(dwave) == TRUE)
381 {
382 if(pdwVolume!=NULL)
383 *pdwVolume=dwave->getVolume();
384 return MMSYSERR_NOERROR;
385 }
386 else return MMSYSERR_NOERROR;
387// return(MMSYSERR_INVALHANDLE);
388}
389/******************************************************************************/
390/******************************************************************************/
391MMRESULT WINAPI waveOutSetVolume(HWAVEOUT hwo, DWORD dwVolume)
392{
393 WaveOut *dwave = (WaveOut *)hwo;
394 if(WaveOut::find(dwave) == TRUE)
395 {
396 return(dwave->setVolume(dwVolume));
397 }
398 if(hwo == NULL) {
399 WaveOut::setDefaultVolume(dwVolume);
400 }
401 return MMSYSERR_NOERROR;
402// return(MMSYSERR_INVALHANDLE);
403}
404/******************************************************************************/
405/******************************************************************************/
406MMRESULT WINAPI waveOutGetPlaybackRate(HWAVEOUT hwo, LPDWORD pdwRate)
407{
408 WaveOut *dwave = (WaveOut *)hwo;
409
410 dprintf(("waveOutGetPlaybackRate: NOT IMPLEMENTED!!"));
411 if(WaveOut::find(dwave) == TRUE)
412 {
413 return MMSYSERR_NOTSUPPORTED;
414 }
415 else return(MMSYSERR_INVALHANDLE);
416}
417/******************************************************************************/
418/******************************************************************************/
419MMRESULT WINAPI waveOutSetPlaybackRate(HWAVEOUT hwo, DWORD dwRate)
420{
421 WaveOut *dwave = (WaveOut *)hwo;
422
423 dprintf(("waveOutSetPlaybackRate: NOT IMPLEMENTED!!"));
424 if(WaveOut::find(dwave) == TRUE)
425 {
426 return MMSYSERR_NOTSUPPORTED;
427 }
428 else return(MMSYSERR_INVALHANDLE);
429}
430/******************************************************************************/
431/******************************************************************************/
432MMRESULT WINAPI waveOutMessage(HWAVEOUT hwo, UINT uMsg, DWORD dw1, DWORD dw2)
433{
434 WaveOut *dwave = (WaveOut *)hwo;
435
436 dprintf(("waveOutMessage: NOT IMPLEMENTED!!"));
437 if(WaveOut::find(dwave) == TRUE)
438 {
439 return MMSYSERR_NOTSUPPORTED;
440 }
441 else
442 return(MMSYSERR_INVALHANDLE);
443}
444/******************************************************************************/
445/******************************************************************************/
446
447
Note: See TracBrowser for help on using the repository browser.