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

Last change on this file since 8470 was 8470, checked in by sandervl, 23 years ago

added debug wrappers (.def)

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