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

Last change on this file since 2935 was 2935, checked in by sandervl, 25 years ago

Implemented waveOutGetPosition

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