source: trunk/src/winmm/waveout.cpp

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

Merge branch gcc-kmk to trunk.

File size: 15.8 KB
RevLine 
[10173]1/* $Id: waveout.cpp,v 1.27 2003-07-16 15:47:24 sandervl Exp $ */
[21358]2
[4]3/*
4 * Wave out MM apis
5 *
[2935]6 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
[4]7 *
[2935]8 * waveOutGetPosition partly based on Wine code (dll\winmm\wineoss\audio.c)
9 * Copyright 1994 Martin Ayotte
[4]10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
[588]14
[21358]15/******************************************************************************/
16// Includes
17/******************************************************************************/
[588]18
[4]19#include <os2win.h>
20#include <mmsystem.h>
[588]21#include <odinwrap.h>
[4]22
23#include <string.h>
24#include <stdio.h>
25#include <string.h>
26#include <unicode.h>
27
[5358]28#include "waveoutdart.h"
[5366]29#include "waveoutdaud.h"
[21358]30#include "waveoutflash.h"
[4]31#include "misc.h"
32#include "winmm.h"
[21916]33#include "initterm.h"
[4]34
[2935]35#define DBG_LOCALLOG DBG_waveout
[2812]36#include "dbglocal.h"
37
[4]38/******************************************************************************/
39/******************************************************************************/
[10173]40MMRESULT WINAPI waveOutOpen(LPHWAVEOUT phwo, UINT uDeviceID, const LPWAVEFORMATEX pwfx,
[8470]41 DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen)
[4]42{
[21358]43 MMRESULT rc;
[4]44
[21358]45 if (fMMPMAvailable == FALSE)
46 return MMSYSERR_NODRIVER;
[7196]47
[21358]48 if (pwfx == NULL)
[4]49 return(WAVERR_BADFORMAT);
50
[21358]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);
[4]56 }
[21358]57 return (WAVERR_BADFORMAT);
[5366]58 }
[4]59
[21358]60 if (phwo == NULL)
[3328]61 return(MMSYSERR_INVALPARAM);
62
[21358]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);
[4]70
[21358]71 if(*phwo == NULL)
[4]72 return(MMSYSERR_NODRIVER);
73
[21358]74 rc = ((WaveOut *)*phwo)->open();
75 if (rc != MMSYSERR_NOERROR)
[5358]76 delete (WaveOut *)*phwo;
[21358]77
78 return rc;
[4]79}
80/******************************************************************************/
81/******************************************************************************/
[8470]82MMRESULT WINAPI waveOutWrite(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
[4]83{
[5366]84 WaveOut *dwave = (WaveOut *)hwo;
[4]85
[5366]86 if(WaveOut::find(dwave) == TRUE)
87 {
[9916]88 if(!(pwh->dwFlags & WHDR_PREPARED) || pwh->lpData == NULL) {
89 dprintf(("waveOutWrite: WAVERR_UNPREPARED!!"));
[2935]90 return WAVERR_UNPREPARED;
[9916]91 }
92 if(pwh->dwFlags & WHDR_INQUEUE) {
93 dprintf(("waveOutWrite: WAVERR_STILLPLAYING!!"));
[2935]94 return WAVERR_STILLPLAYING;
[9916]95 }
[2935]96 pwh->dwFlags |= WHDR_INQUEUE;
97 pwh->dwFlags &= ~WHDR_DONE;
[588]98
[5348]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));
[2935]100 return(dwave->write(pwh, cbwh));
[5366]101 }
102 else return(MMSYSERR_INVALHANDLE);
[4]103}
104/******************************************************************************/
105/******************************************************************************/
[8470]106MMRESULT WINAPI waveOutReset(HWAVEOUT hwaveout)
[4]107{
[5358]108 WaveOut *dwave = (WaveOut *)hwaveout;
[4]109
[5358]110 if(WaveOut::find(dwave) == TRUE)
[2935]111 return(dwave->reset());
112 else return(MMSYSERR_INVALHANDLE);
[4]113}
114/******************************************************************************/
115/******************************************************************************/
[8470]116MMRESULT WINAPI waveOutBreakLoop(HWAVEOUT hwaveout)
[4]117{
[5366]118 WaveOut *dwave = (WaveOut *)hwaveout;
[4]119
[5366]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);
[4]124}
125/******************************************************************************/
126/******************************************************************************/
[8470]127MMRESULT WINAPI waveOutClose(HWAVEOUT hwaveout)
[4]128{
[5366]129 WaveOut *dwave = (WaveOut *)hwaveout;
[4]130
[5366]131 if(WaveOut::find(dwave) == TRUE)
132 {
[2935]133 if(dwave->getState() == STATE_PLAYING)
134 return(WAVERR_STILLPLAYING);
[588]135
[2935]136 delete dwave;
137 return(MMSYSERR_NOERROR);
[5366]138 }
139 else return(MMSYSERR_INVALHANDLE);
[4]140}
141/******************************************************************************/
142/******************************************************************************/
[8470]143MMRESULT WINAPI waveOutPause(HWAVEOUT hwaveout)
[4]144{
[5366]145 WaveOut *dwave = (WaveOut *)hwaveout;
[4]146
[5366]147 if(WaveOut::find(dwave) == TRUE)
[2935]148 return(dwave->pause());
[5366]149 else return(MMSYSERR_INVALHANDLE);
[4]150}
151/******************************************************************************/
152/******************************************************************************/
[8470]153MMRESULT WINAPI waveOutRestart(HWAVEOUT hwaveout)
[4]154{
[5366]155 WaveOut *dwave = (WaveOut *)hwaveout;
[4]156
[5366]157 if(WaveOut::find(dwave) == TRUE)
[8568]158 return(dwave->resume());
[5366]159 else return(MMSYSERR_INVALHANDLE);
[4]160}
161/******************************************************************************/
162/******************************************************************************/
[8470]163MMRESULT WINAPI waveOutPrepareHeader(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
[4]164{
[5366]165 WaveOut *dwave = (WaveOut *)hwo;
[4]166
[5366]167 if(WaveOut::find(dwave) == TRUE)
168 {
[2935]169 if(pwh->dwFlags & WHDR_INQUEUE)
170 return WAVERR_STILLPLAYING;
[4]171
[2935]172 pwh->dwFlags |= WHDR_PREPARED;
173 pwh->dwFlags &= ~WHDR_DONE;
174 pwh->lpNext = NULL;
175 return(MMSYSERR_NOERROR);
[5366]176 }
177 else return(MMSYSERR_INVALHANDLE);
[4]178}
179/******************************************************************************/
180/******************************************************************************/
[8470]181MMRESULT WINAPI waveOutUnprepareHeader(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
[4]182{
[5366]183 WaveOut *dwave = (WaveOut *)hwo;
[4]184
[5366]185 if(WaveOut::find(dwave) == TRUE)
186 {
[2935]187 if(pwh->dwFlags & WHDR_INQUEUE)
188 return WAVERR_STILLPLAYING;
[4]189
[2935]190 pwh->dwFlags &= ~WHDR_PREPARED;
191 pwh->dwFlags |= WHDR_DONE;
192 return(MMSYSERR_NOERROR);
[5366]193 }
194 else return(MMSYSERR_INVALHANDLE);
[4]195}
196/******************************************************************************/
197/******************************************************************************/
[8470]198MMRESULT WINAPI waveOutGetPosition(HWAVEOUT hwo, LPMMTIME pmmt, UINT cbmmt)
[4]199{
[5358]200 WaveOut *dwave = (WaveOut *)hwo;
[2935]201
[5366]202 if(pmmt == NULL)
[2935]203 return MMSYSERR_INVALPARAM;
204
[5366]205 if(WaveOut::find(dwave) == TRUE)
206 {
207 ULONG position;
[2935]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:
[5272]215 pmmt->u.cb = position;
[5334]216 dprintf2(("WINMM:waveOutGetPosition: TIME_BYTES %d (%x)", position, GetCurrentTime()));
[5272]217 break;
[2935]218 case TIME_SAMPLES:
[5272]219 pmmt->u.sample = position * 8 / dwave->getBitsPerSample();
[5334]220 dprintf2(("WINMM:waveOutGetPosition: TIME_SAMPLES %d", pmmt->u.sample));
[5272]221 break;
[2935]222 case TIME_SMPTE:
223 {
[5272]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;
[5334]233 dprintf2(("WINMM:waveOutGetPosition: TIME_SAMPLES %d", position));
[5272]234 break;
235 }
[2935]236 default:
[5272]237 dprintf(("waveOutGetPosition: Format %d not supported ! use TIME_MS !\n", pmmt->wType));
238 pmmt->wType = TIME_MS;
[2935]239 case TIME_MS:
[5272]240 pmmt->u.ms = position / (dwave->getAvgBytesPerSecond() / 1000);
[5334]241 dprintf2(("WINMM:waveOutGetPosition: TIME_MS pos=%d ms=%d time=%d", position, pmmt->u.ms, GetCurrentTime()));
[5272]242 break;
[2935]243 }
244 return MMSYSERR_NOERROR;
[5366]245 }
246 else return(MMSYSERR_INVALHANDLE);
[4]247}
248/******************************************************************************/
249/******************************************************************************/
[8470]250MMRESULT WINAPI waveOutGetDevCapsA(UINT uDeviceID, LPWAVEOUTCAPSA pwoc, UINT cbwoc)
[4]251{
[7196]252 if(fMMPMAvailable == FALSE) return MMSYSERR_NODRIVER;
253
[5366]254 if(WaveOut::getNumDevices() == 0) {
[2935]255 memset(pwoc, 0, sizeof(*pwoc));
256 return MMSYSERR_NODRIVER;
[5366]257 }
[1538]258
[5366]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;
[4]270
[5366]271 pwoc->wChannels = 2; /* number of sources supported */
272 pwoc->wReserved1 = 0; /* packing */
273 pwoc->dwSupport = WAVECAPS_LRVOLUME | WAVECAPS_VOLUME;
[4]274
[5366]275 return MMSYSERR_NOERROR;
[4]276}
277/******************************************************************************/
278/******************************************************************************/
[8470]279MMRESULT WINAPI waveOutGetDevCapsW(UINT uDeviceID, LPWAVEOUTCAPSW pwoc, UINT cbwoc)
[4]280{
[7196]281 if(fMMPMAvailable == FALSE) return MMSYSERR_NODRIVER;
282
[5366]283 if(WaveOut::getNumDevices() == 0) {
[2935]284 memset(pwoc, 0, sizeof(*pwoc));
285 return MMSYSERR_NODRIVER;
[5366]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;
[4]298
[5366]299 pwoc->wChannels = 2; /* number of sources supported */
300 pwoc->wReserved1 = 0; /* packing */
301 pwoc->dwSupport = WAVECAPS_LRVOLUME | WAVECAPS_VOLUME;
[4]302
[5366]303 return MMSYSERR_NOERROR;
[4]304}
305/******************************************************************************/
306/******************************************************************************/
[8470]307UINT WINAPI waveOutGetNumDevs()
[4]308{
[7196]309 if(fMMPMAvailable == FALSE) return 0;
310
[5358]311 return WaveOut::getNumDevices();
[4]312}
313/******************************************************************************/
314/******************************************************************************/
[8470]315MMRESULT WINAPI waveOutGetErrorTextA(MMRESULT wError, LPSTR lpText, UINT cchText)
[4]316{
[21916]317 const char * theMsg = getWinmmMsg( wError );
[5366]318 if(theMsg) {
[2935]319 strncpy( lpText, theMsg, cchText );
[5366]320 }
321 else
322 {
[2935]323 char errMsg[100];
324 sprintf( errMsg, "Unknown error number %d", wError );
325 strncpy( lpText, errMsg, cchText );
[5366]326 }
327 return MMSYSERR_NOERROR;
[4]328}
[2935]329/******************************************************************************/
330/******************************************************************************/
[8470]331MMRESULT WINAPI waveOutGetErrorTextW(MMRESULT wError, LPWSTR lpText, UINT cchText)
[4]332{
[21916]333 const char * theMsg = getWinmmMsg( wError );
[5366]334 if(theMsg) {
[10173]335 AsciiToUnicodeN( theMsg, lpText, cchText );
[5366]336 }
337 else
338 {
[2935]339 char errMsg[100];
340 sprintf( errMsg, "Unknown error number %d", wError );
[10173]341 AsciiToUnicodeN( errMsg, lpText, cchText );
[5366]342 }
343 return MMSYSERR_NOERROR;
[4]344}
[2935]345/******************************************************************************/
346/******************************************************************************/
[8470]347MMRESULT WINAPI waveOutGetID(HWAVEOUT hwo, LPUINT puDeviceID)
[4]348{
[5366]349 WaveOut *dwave = (WaveOut *)hwo;
350 if(WaveOut::find(dwave) == TRUE)
351 {
[2935]352 *puDeviceID = 1;
353 return MMSYSERR_NOERROR;
[5366]354 }
355 else return(MMSYSERR_INVALHANDLE);
[4]356}
[2935]357/******************************************************************************/
358/******************************************************************************/
[8470]359MMRESULT WINAPI waveOutGetPitch(HWAVEOUT hwo, LPDWORD pdwPitch)
[4]360{
[8470]361 WaveOut *dwave = (WaveOut *)hwo;
362 if(WaveOut::find(dwave) == TRUE)
[2935]363 return MMSYSERR_NOTSUPPORTED;
[8470]364 else return(MMSYSERR_INVALHANDLE);
[4]365}
[2935]366/******************************************************************************/
367/******************************************************************************/
[8470]368MMRESULT WINAPI waveOutSetPitch(HWAVEOUT hwo, DWORD dwPitch)
[4]369{
[5366]370 WaveOut *dwave = (WaveOut *)hwo;
371 if(WaveOut::find(dwave) == TRUE)
372 return MMSYSERR_NOTSUPPORTED;
373 else return(MMSYSERR_INVALHANDLE);
[4]374}
[2935]375/******************************************************************************/
376/******************************************************************************/
[8470]377MMRESULT WINAPI waveOutGetVolume(HWAVEOUT hwo, LPDWORD pdwVolume)
[4]378{
[8470]379 WaveOut *dwave = (WaveOut *)hwo;
380 if(WaveOut::find(dwave) == TRUE)
381 {
[2935]382 if(pdwVolume!=NULL)
383 *pdwVolume=dwave->getVolume();
384 return MMSYSERR_NOERROR;
[8470]385 }
386 else return MMSYSERR_NOERROR;
[2812]387// return(MMSYSERR_INVALHANDLE);
[4]388}
[2935]389/******************************************************************************/
390/******************************************************************************/
[8470]391MMRESULT WINAPI waveOutSetVolume(HWAVEOUT hwo, DWORD dwVolume)
[4]392{
[8470]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;
[2812]402// return(MMSYSERR_INVALHANDLE);
[4]403}
[2935]404/******************************************************************************/
405/******************************************************************************/
[8470]406MMRESULT WINAPI waveOutGetPlaybackRate(HWAVEOUT hwo, LPDWORD pdwRate)
[4]407{
[8470]408 WaveOut *dwave = (WaveOut *)hwo;
409
410 dprintf(("waveOutGetPlaybackRate: NOT IMPLEMENTED!!"));
411 if(WaveOut::find(dwave) == TRUE)
412 {
[2935]413 return MMSYSERR_NOTSUPPORTED;
[8470]414 }
415 else return(MMSYSERR_INVALHANDLE);
[4]416}
[2935]417/******************************************************************************/
418/******************************************************************************/
[8470]419MMRESULT WINAPI waveOutSetPlaybackRate(HWAVEOUT hwo, DWORD dwRate)
[4]420{
[8470]421 WaveOut *dwave = (WaveOut *)hwo;
[10173]422
[8470]423 dprintf(("waveOutSetPlaybackRate: NOT IMPLEMENTED!!"));
424 if(WaveOut::find(dwave) == TRUE)
425 {
[2935]426 return MMSYSERR_NOTSUPPORTED;
[8470]427 }
428 else return(MMSYSERR_INVALHANDLE);
[4]429}
[2935]430/******************************************************************************/
431/******************************************************************************/
[8470]432MMRESULT WINAPI waveOutMessage(HWAVEOUT hwo, UINT uMsg, DWORD dw1, DWORD dw2)
[4]433{
[8470]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);
[4]443}
[2935]444/******************************************************************************/
445/******************************************************************************/
[4]446
[588]447
Note: See TracBrowser for help on using the repository browser.