- Timestamp:
- Feb 22, 2010, 2:44:21 PM (16 years ago)
- Location:
- trunk/src/winmm
- Files:
-
- 2 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/winmm/WINMM.DEF
r5433 r21358 202 202 ; winmmf_ThunkData32 = _winmmf_ThunkData32@?? @184 203 203 ; winmmsl_ThunkData32 = _winmmsl_ThunkData32@?? @185 204 ; ODIN-specific 205 ODIN_IsFlashAudioEnabled = _ODIN_IsFlashAudioEnabled@0 @186 206 ODIN_EnableFlashAudio = _ODIN_EnableFlashAudio@4 @187 207 -
trunk/src/winmm/WINMMDBG.DEF
r8470 r21358 202 202 ; winmmf_ThunkData32 = _Dbgwinmmf_ThunkData32@?? @184 203 203 ; winmmsl_ThunkData32 = _Dbgwinmmsl_ThunkData32@?? @185 204 ; ODIN-specific 205 ODIN_IsFlashAudioEnabled = _DbgODIN_IsFlashAudioEnabled@0 @186 206 ODIN_EnableFlashAudio = _DbgODIN_EnableFlashAudio@4 @187 207 -
trunk/src/winmm/dbglocal.cpp
r6375 r21358 43 43 "waveoutdaud", 44 44 "waveoutbase", 45 "waveinoutbase" 45 "waveinoutbase", 46 "waveoutflash" 46 47 }; 47 48 //****************************************************************************** -
trunk/src/winmm/dbglocal.h
r6375 r21358 43 43 #define DBG_waveoutbase 21 44 44 #define DBG_waveinoutbase 22 45 #define DBG_MAXFILES 23 45 #define DBG_waveoutflash 23 46 #define DBG_MAXFILES 24 46 47 47 48 extern USHORT DbgEnabledWINMM[DBG_MAXFILES]; -
trunk/src/winmm/dbgwrap.cpp
r9671 r21358 206 206 DEBUGWRAP12(waveOutUnprepareHeader) 207 207 DEBUGWRAP12(waveOutWrite) 208 DEBUGWRAP0(ODIN_IsFlashAudioEnabled) 209 DEBUGWRAP4(ODIN_EnableFlashAudio) 208 210 209 211 #undef DBG_LOCALLOG -
trunk/src/winmm/initwinmm.cpp
r10576 r21358 126 126 // try to load the MDM library, not MMPM directly!!! 127 127 if (DosLoadModule(szError, sizeof(szError), 128 "MDM .DLL", &MMPMLibraryHandle) != NO_ERROR)128 "MDM", &MMPMLibraryHandle) != NO_ERROR) 129 129 { 130 130 // this system has no MMPM :-( -
trunk/src/winmm/wavein.cpp
r10173 r21358 14 14 */ 15 15 16 17 /**************************************************************************** 18 * Includes * 19 ****************************************************************************/ 16 /******************************************************************************/ 17 // Includes 18 /******************************************************************************/ 20 19 21 20 #include <os2win.h> … … 34 33 #include "dbglocal.h" 35 34 36 37 35 /******************************************************************************/ 38 36 /******************************************************************************/ … … 47 45 return(WAVERR_BADFORMAT); 48 46 49 if(fdwOpen & WAVE_FORMAT_QUERY) 50 { 47 if(fdwOpen & WAVE_FORMAT_QUERY) { 51 48 if(DartWaveIn::queryFormat(pwfx->wFormatTag, pwfx->nChannels, pwfx->nSamplesPerSec, 52 49 pwfx->wBitsPerSample) == TRUE) 53 {54 50 return(MMSYSERR_NOERROR); 55 } 56 elsereturn(WAVERR_BADFORMAT);51 52 return(WAVERR_BADFORMAT); 57 53 } 58 54 … … 62 58 *phwi = (HWAVEOUT)new DartWaveIn(pwfx, fdwOpen, dwCallback, dwInstance); 63 59 64 if(*phwi == NULL) {60 if(*phwi == NULL) 65 61 return(MMSYSERR_NODRIVER); 66 } 67 68 rc = ((DartWaveIn *)*phwi)->getError(); 62 63 rc = ((DartWaveIn *)*phwi)->open(); 69 64 if(rc != MMSYSERR_NOERROR) { 70 65 delete (DartWaveIn *)*phwi; -
trunk/src/winmm/waveindart.cpp
r10185 r21358 10 10 * Project Odin Software License can be found in LICENSE.TXT 11 11 * 12 *13 12 */ 14 13 15 16 /**************************************************************************** 17 * Includes * 18 ****************************************************************************/ 19 20 14 /******************************************************************************/ 15 // Includes 16 /******************************************************************************/ 21 17 22 18 #define INCL_BASE … … 41 37 #endif 42 38 43 #ifndef max44 #define max(a, b) ((a > b) ? a : b)45 #endif46 47 39 LONG APIENTRY WaveInHandler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags); 48 40 41 /******************************************************************************/ 42 /******************************************************************************/ 43 49 44 static BOOL fwaveInFixedBuffers = FALSE; 50 45 51 //****************************************************************************** 46 /******************************************************************************/ 47 /******************************************************************************/ 52 48 // ODIN_waveInSetFixedBuffers 53 49 // 54 50 // Tell WINMM to use DART buffers of the same size as the first buffer delivered 55 51 // by waveInAddBuffer 56 // 57 //****************************************************************************** 52 58 53 void WIN32API ODIN_waveInSetFixedBuffers() 59 54 { … … 65 60 : WaveInOut(pwfx, fdwOpen, nCallback, dwInstance) 66 61 { 67 MCI_GENERIC_PARMS GenericParms; 68 MCI_AMP_OPEN_PARMS AmpOpenParms; 69 APIRET rc; 70 71 fOverrun = FALSE; 62 DeviceId = 0; 63 ulBufSize = DART_BUFSIZE_REC; 72 64 fMixerSetup = FALSE; 65 fOverrun = FALSE; 66 mixHandle = 0; 67 pmixReadProc = NULL; 68 MixBuffer = NULL; 69 BufferParms = NULL; 70 71 dprintf(("DartWaveIn: samplerate %d, numChan %d bps %d (%d), format %x", 72 SampleRate, nChannels, BitsPerSample, pwfx->nBlockAlign, pwfx->wFormatTag)); 73 } 74 75 /******************************************************************************/ 76 /******************************************************************************/ 77 MMRESULT DartWaveIn::open() 78 { 79 MCI_AMP_OPEN_PARMS AmpOpenParms; 80 MCI_GENERIC_PARMS GenericParms = {0}; 81 MCI_MIXSETUP_PARMS MixSetupParms; 82 APIRET rc; 73 83 74 84 MixBuffer = (MCI_MIX_BUFFER *)malloc(PREFILLBUF_DART_REC*sizeof(MCI_MIX_BUFFER)); 75 MixSetupParms = (MCI_MIXSETUP_PARMS *)malloc(sizeof(MCI_MIXSETUP_PARMS));76 85 BufferParms = (MCI_BUFFER_PARMS *)malloc(sizeof(MCI_BUFFER_PARMS)); 77 if(!MixBuffer || ! MixSetupParms || !BufferParms) {86 if(!MixBuffer || !BufferParms) { 78 87 dprintf(("ERROR: malloc failed!!")); 79 ulError = MMSYSERR_NOMEM; 80 return; 81 } 82 83 ulBufSize = DART_BUFSIZE_REC; 84 85 dprintf(("waveInOpen: samplerate %d, numChan %d bps %d (%d), format %x", SampleRate, nChannels, BitsPerSample, pwfx->nBlockAlign, pwfx->wFormatTag)); 88 return MMSYSERR_NOMEM; 89 } 90 86 91 // Setup the open structure, pass the playlist and tell MCI_OPEN to use it 87 memset(&AmpOpenParms, 0,sizeof(AmpOpenParms));88 89 AmpOpenParms. usDeviceID = ( USHORT ) 0;90 AmpOpenParms.pszDeviceType = ( PSZ ) MCI_DEVTYPE_AUDIO_AMPMIX; 91 92 rc = mymciSendCommand(0, MCI_OPEN,MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,92 memset(&AmpOpenParms, 0, sizeof(AmpOpenParms)); 93 AmpOpenParms.usDeviceID = 0; 94 AmpOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX; 95 96 rc = mymciSendCommand(0, MCI_OPEN, 97 MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE, 93 98 (PVOID) &AmpOpenParms, 0); 94 DeviceId = AmpOpenParms.usDeviceID;95 99 if(rc) { 96 100 dprintf(("MCI_OPEN failed\n")); 97 101 mciError(rc); 98 ulError = MMSYSERR_NODRIVER; 99 } 100 if(rc == 0) { 101 //Grab exclusive rights to device instance (NOT entire device) 102 GenericParms.hwndCallback = 0; //Not needed, so set to 0 103 rc = mymciSendCommand(DeviceId, MCI_ACQUIREDEVICE, MCI_EXCLUSIVE_INSTANCE, 104 (PVOID)&GenericParms, 0); 105 if(rc) { 106 dprintf(("MCI_ACQUIREDEVICE failed\n")); 107 mciError(rc); 108 ulError = MMSYSERR_NOTENABLED; 109 } 110 } 111 112 if(!ulError) 113 callback(WIM_OPEN, 0, 0); 102 return MMSYSERR_NODRIVER; 103 } 104 105 DeviceId = AmpOpenParms.usDeviceID; 106 107 //Grab exclusive rights to device instance (NOT entire device) 108 rc = mymciSendCommand(DeviceId, MCI_ACQUIREDEVICE, 109 MCI_EXCLUSIVE_INSTANCE, 110 (PVOID)&GenericParms, 0); 111 if(rc) { 112 dprintf(("MCI_ACQUIREDEVICE failed\n")); 113 mciError(rc); 114 return MMSYSERR_NOTENABLED; 115 } 116 117 dprintf(("device acquired\n")); 118 dprintf(("bps %d, sps %d chan %d\n", BitsPerSample, SampleRate, nChannels)); 119 120 // Set the MixSetupParms data structure 121 memset(&MixSetupParms, 0, sizeof(MCI_MIXSETUP_PARMS)); 122 MixSetupParms.ulBitsPerSample = BitsPerSample; 123 MixSetupParms.ulSamplesPerSec = SampleRate; 124 MixSetupParms.ulFormatTag = MCI_WAVE_FORMAT_PCM; 125 MixSetupParms.ulChannels = nChannels; 126 MixSetupParms.ulFormatMode = MCI_RECORD; 127 MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; 128 MixSetupParms.pmixEvent = WaveInHandler; 129 130 rc = mymciSendCommand(DeviceId, MCI_MIXSETUP, 131 MCI_WAIT | MCI_MIXSETUP_INIT, 132 (PVOID)&MixSetupParms, 0); 133 if ( rc != MCIERR_SUCCESS ) { 134 mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, 135 MCI_WAIT, 136 (PVOID)&GenericParms, 0); 137 mciError(rc); 138 return MMSYSERR_NOTSUPPORTED; 139 } 140 141 // Save the mixer handle & the ptr to the read proc. 142 mixHandle = MixSetupParms.ulMixHandle; 143 pmixReadProc = MixSetupParms.pmixRead; 144 145 146 callback(WIM_OPEN, 0, 0); 147 148 return MMSYSERR_NOERROR; 114 149 } 115 150 /******************************************************************************/ … … 117 152 DartWaveIn::~DartWaveIn() 118 153 { 119 MCI_GENERIC_PARMS GenericParms ;154 MCI_GENERIC_PARMS GenericParms = {0}; 120 155 121 156 State = STATE_STOPPED; 122 157 123 if (!ulError)158 if (DeviceId) 124 159 { 125 // Generic parameters126 GenericParms.hwndCallback = 0; //hwndFrame127 128 160 // Stop recording. 129 mymciSendCommand(DeviceId, MCI_STOP,MCI_WAIT, (PVOID)&GenericParms,0); 130 131 mymciSendCommand(DeviceId, 132 MCI_BUFFER, 133 MCI_WAIT | MCI_DEALLOCATE_MEMORY, 134 (PVOID)&BufferParms, 135 0); 136 137 // Generic parameters 138 GenericParms.hwndCallback = 0; //hwndFrame 161 mymciSendCommand(DeviceId, MCI_STOP, 162 MCI_WAIT, (PVOID)&GenericParms, 0); 163 164 if (fMixerSetup) 165 mymciSendCommand(DeviceId, MCI_BUFFER, 166 MCI_WAIT | MCI_DEALLOCATE_MEMORY, 167 (PVOID)&BufferParms, 0); 139 168 140 169 // Close the device 141 mymciSendCommand(DeviceId, MCI_CLOSE, MCI_WAIT, (PVOID)&GenericParms, 0);142 }143 if(!ulError)144 { 170 mymciSendCommand(DeviceId, MCI_CLOSE, 171 MCI_WAIT, 172 (PVOID)&GenericParms, 0); 173 145 174 callback(WIM_CLOSE, 0, 0); 146 175 } … … 148 177 if(MixBuffer) 149 178 free(MixBuffer); 150 if(MixSetupParms)151 free(MixSetupParms);152 179 if(BufferParms) 153 180 free(BufferParms); … … 180 207 if(fMixerSetup == FALSE) 181 208 { 182 dprintf(("device acquired\n"));183 /* Set the MixSetupParms data structure to match the loaded file.184 * This is a global that is used to setup the mixer.185 */186 memset(MixSetupParms, 0, sizeof( MCI_MIXSETUP_PARMS ) );187 188 MixSetupParms->ulBitsPerSample = BitsPerSample;189 MixSetupParms->ulSamplesPerSec = SampleRate;190 MixSetupParms->ulFormatTag = MCI_WAVE_FORMAT_PCM;191 MixSetupParms->ulChannels = nChannels;192 193 dprintf(("bps %d, sps %d chan %d\n", BitsPerSample, SampleRate, nChannels));194 195 /* Setup the mixer for recording of wave data196 */197 MixSetupParms->ulFormatMode = MCI_RECORD;198 MixSetupParms->ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;199 MixSetupParms->pmixEvent = WaveInHandler;200 201 rc = mymciSendCommand(DeviceId, MCI_MIXSETUP, MCI_WAIT | MCI_MIXSETUP_INIT,202 (PVOID)MixSetupParms, 0);203 204 if ( rc != MCIERR_SUCCESS ) {205 mciError(rc);206 mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, MCI_WAIT,207 (PVOID)&GenericParms, 0);208 return(MMSYSERR_NOTSUPPORTED);209 }210 211 209 /* 212 210 * Set up the BufferParms data structure and allocate … … 227 225 { 228 226 dprintf(("mix setup %d, %d\n", pwh->dwBufferLength, pwh->dwBufferLength)); 229 230 227 ulBufSize = pwh->dwBufferLength/2; 231 228 } … … 237 234 else ulBufSize = minbufsize; 238 235 239 MixSetupParms->ulBufferSize = ulBufSize;240 241 236 BufferParms->ulNumBuffers = PREFILLBUF_DART_REC; 242 BufferParms->ulBufferSize = MixSetupParms->ulBufferSize;237 BufferParms->ulBufferSize = ulBufSize; 243 238 BufferParms->pBufList = MixBuffer; 244 239 … … 247 242 } 248 243 249 rc = mymciSendCommand(DeviceId, 250 MCI_BUFFER, 251 MCI_WAIT | MCI_ALLOCATE_MEMORY, 252 (PVOID)BufferParms, 253 0); 244 rc = mymciSendCommand(DeviceId, MCI_BUFFER, 245 MCI_WAIT | MCI_ALLOCATE_MEMORY, 246 (PVOID)BufferParms, 0); 254 247 255 248 if(ULONG_LOWD(rc) != MCIERR_SUCCESS) { 256 249 mciError(rc); 257 mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, MCI_WAIT, 258 (PVOID)&GenericParms, 0); 259 return(MMSYSERR_NOTSUPPORTED); 250 mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, 251 MCI_WAIT, 252 (PVOID)&GenericParms, 0); 253 return MMSYSERR_NOTSUPPORTED; 260 254 } 261 255 … … 263 257 //(until we really support the mixer extensions anyway) 264 258 /* Set the connector to 'microphone' */ 265 memset( &ConnectorParms, '\0', sizeof( MCI_CONNECTOR_PARMS ));259 memset(&ConnectorParms, 0, sizeof(MCI_CONNECTOR_PARMS)); 266 260 ConnectorParms.ulConnectorType = MCI_MICROPHONE_CONNECTOR; 267 rc = mymciSendCommand(DeviceId, MCI_CONNECTOR, MCI_WAIT |268 MCI_ ENABLE_CONNECTOR | MCI_CONNECTOR_TYPE,269 ( PVOID )&ConnectorParms, 0 );261 rc = mymciSendCommand(DeviceId, MCI_CONNECTOR, 262 MCI_WAIT | MCI_ENABLE_CONNECTOR | MCI_CONNECTOR_TYPE, 263 (PVOID)&ConnectorParms, 0 ); 270 264 271 265 /* Allow the user to hear what is being recorded 272 266 * by turning the monitor on 273 267 */ 274 memset( &AmpSetParms, '\0', sizeof( MCI_AMP_SET_PARMS ) );268 memset(&AmpSetParms, 0, sizeof( MCI_AMP_SET_PARMS ) ); 275 269 AmpSetParms.ulItem = MCI_AMP_SET_MONITOR; 276 rc = mymciSendCommand(DeviceId, 277 MCI_SET, 278 MCI_WAIT | MCI_SET_ON | MCI_SET_ITEM, 279 ( PVOID ) &AmpSetParms, 280 0 ); 270 rc = mymciSendCommand(DeviceId, MCI_SET, 271 MCI_WAIT | MCI_SET_ON | MCI_SET_ITEM, 272 (PVOID)&AmpSetParms, 0); 281 273 282 274 wmutex.enter(); … … 284 276 } 285 277 286 for(i=0; i<PREFILLBUF_DART_REC;i++) {278 for(i=0; i< PREFILLBUF_DART_REC; i++) { 287 279 memset(MixBuffer[i].pBuffer, 0, MixBuffer[i].ulBufferLength); 288 280 } 289 281 dprintf(("Dart opened, bufsize = %d\n", MixBuffer[0].ulBufferLength)); 290 282 291 dprintf(("MixSetupParms = %X\n", MixSetupParms));292 283 State = STATE_RECORDING; 293 284 fOverrun = FALSE; … … 298 289 // Start recording. 299 290 USHORT selTIB = RestoreOS2FS(); // save current FS selector 300 MixSetupParms->pmixRead(MixSetupParms->ulMixHandle, &MixBuffer[0], PREFILLBUF_DART_REC);291 pmixReadProc(mixHandle, &MixBuffer[0], PREFILLBUF_DART_REC); 301 292 SetFS(selTIB); // switch back to the saved FS selector 302 293 … … 506 497 /******************************************************************************/ 507 498 /******************************************************************************/ 508 void DartWaveIn::mciError(ULONG ulError)499 void DartWaveIn::mciError(ULONG rc) 509 500 { 510 501 #ifdef DEBUG 511 502 char szError[256] = ""; 512 503 513 mymciGetErrorString( ulError, szError, sizeof(szError));504 mymciGetErrorString(rc, szError, sizeof(szError)); 514 505 dprintf(("WINMM: DartWaveIn: %s\n", szError)); 515 506 #endif … … 586 577 // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector! 587 578 USHORT selTIB = RestoreOS2FS(); // save current FS selector 588 MixSetupParms->pmixRead(MixSetupParms->ulMixHandle, pBuffer, 1);579 pmixReadProc(mixHandle, pBuffer, 1); 589 580 SetFS(selTIB); // switch back to the saved FS selector 590 581 } -
trunk/src/winmm/waveindart.h
r5358 r21358 6 6 * Project Odin Software License can be found in LICENSE.TXT 7 7 */ 8 8 9 #ifndef __DWAVEIN_H__ 9 10 #define __DWAVEIN_H__ … … 27 28 #endif 28 29 30 // this should be defined in some #included .h file, but it isn't 31 typedef LONG (APIENTRY MIXERPROC)(ULONG ulHandle, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags); 32 29 33 class DartWaveIn : public WaveInOut 30 34 { 31 35 public: 32 DartWaveIn(LPWAVEFORMATEX pwfx, DWORD fdwOpen, ULONG nCallback, ULONG dwInstance); 33 virtual ~DartWaveIn(); 36 DartWaveIn(LPWAVEFORMATEX pwfx, DWORD fdwOpen, 37 ULONG nCallback, ULONG dwInstance); 38 virtual ~DartWaveIn(); 34 39 35 MMRESULT addBuffer(LPWAVEHDR pwh, UINT cbwh);36 MMRESULT start();37 MMRESULT stop();38 int getState() { return State; };39 MMRESULTreset();40 ULONGgetPosition();40 MMRESULT open(); 41 MMRESULT addBuffer(LPWAVEHDR pwh, UINT cbwh); 42 MMRESULT start(); 43 MMRESULT stop(); 44 MMRESULT reset(); 45 ULONG getPosition(); 41 46 42 43 static int getNumDevices(); 44 45 static BOOL queryFormat(ULONG formatTag, ULONG nChannels, 46 ULONG nSamplesPerSec, ULONG sampleSize); 47 static int getNumDevices(); 48 static BOOL queryFormat(ULONG formatTag, ULONG nChannels, 49 ULONG nSamplesPerSec, ULONG sampleSize); 47 50 48 51 protected: 49 static void mciError(ULONG ulError); 50 void handler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags); 52 static void mciError(ULONG rc); 53 void handler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, 54 ULONG ulFlags); 51 55 52 56 private: 53 USHORT DeviceId; 54 ULONG ulBufferCount; /* Current file buffer */ 55 ULONG ulBufSize; 56 57 MCI_MIX_BUFFER *MixBuffer; /* Device buffers */ 58 MCI_MIXSETUP_PARMS *MixSetupParms; /* Mixer parameters */ 59 MCI_BUFFER_PARMS *BufferParms; /* Device buffer parms */ 60 61 62 BOOL fMixerSetup; 63 BOOL fOverrun; 57 USHORT DeviceId; 58 ULONG ulBufSize; 59 BOOL fMixerSetup; 60 BOOL fOverrun; 61 ULONG mixHandle; 62 MIXERPROC * pmixReadProc; 63 MCI_MIX_BUFFER * MixBuffer; 64 MCI_BUFFER_PARMS * BufferParms; 64 65 65 66 #ifndef _OS2WIN_H 66 friend LONG APIENTRY WaveInHandler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags); 67 friend LONG APIENTRY WaveInHandler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, 68 ULONG ulFlags); 67 69 #endif 68 70 }; -
trunk/src/winmm/waveinoutbase.cpp
r10269 r21358 12 12 */ 13 13 14 15 /**************************************************************************** 16 * Includes * 17 ****************************************************************************/ 18 19 14 /******************************************************************************/ 15 // Includes 16 /******************************************************************************/ 20 17 21 18 #define INCL_BASE … … 35 32 #include "dbglocal.h" 36 33 37 VMutex wavemutex; 34 /******************************************************************************/ 35 /******************************************************************************/ 36 37 VMutex wavemutex; 38 WaveInOut * WaveInOut::head = NULL; 38 39 39 40 /******************************************************************************/ … … 41 42 WaveInOut::WaveInOut(LPWAVEFORMATEX pwfx, ULONG fdwOpen, ULONG nCallback, ULONG dwInstance) 42 43 { 43 next = NULL;44 wavehdr = NULL;45 curhdr = NULL;46 ulError = 0;47 State = STATE_STOPPED;48 queuedbuffers = 0;49 50 BitsPerSample = pwfx->wBitsPerSample;51 SampleRate = pwfx->nSamplesPerSec;52 this->nChannels = pwfx->nChannels;44 SampleRate = pwfx->nSamplesPerSec; 45 BitsPerSample = pwfx->wBitsPerSample; 46 nChannels = pwfx->nChannels; 47 OpenFlags = fdwOpen; 48 Callback = nCallback; 49 Instance = dwInstance; 50 State = STATE_STOPPED; 51 queuedbuffers = 0; 52 wavehdr = NULL; 53 next = NULL; 53 54 54 55 dprintf(("WaveInOutOpen: samplerate %d, numChan %d bps %d (%d), format %x", SampleRate, nChannels, BitsPerSample, pwfx->nBlockAlign, pwfx->wFormatTag)); 55 56 State = STATE_STOPPED;57 56 58 57 wavemutex.enter(); … … 70 69 } 71 70 wavemutex.leave(); 72 73 this->fdwOpen = fdwOpen;74 dwCallback = nCallback;75 this->dwInstance = dwInstance;76 71 } 77 72 /******************************************************************************/ … … 101 96 { 102 97 dprintf(("WINMM:WaveInOut::callback type %x, callback 0x%x (HDRVR h=%08xh, UINT uMessage=%08xh, DWORD dwUser=%08xh, DWORD dw1=%08xh, DWORD dw2=%08xh)", 103 fdwOpen, dwCallback, this, uMessage, dwInstance, dw1, dw2));98 OpenFlags, Callback, this, uMessage, Instance, dw1, dw2)); 104 99 105 switch( fdwOpen& CALLBACK_TYPEMASK) {100 switch(OpenFlags & CALLBACK_TYPEMASK) { 106 101 case CALLBACK_WINDOW: 107 PostMessageA((HWND) dwCallback, uMessage, (WPARAM)this, dw1);102 PostMessageA((HWND)Callback, uMessage, (WPARAM)this, dw1); 108 103 break; 109 104 110 105 case CALLBACK_TASK: // == CALLBACK_THREAD 111 PostThreadMessageA( dwCallback, uMessage, (WPARAM)this, dw1);106 PostThreadMessageA(Callback, uMessage, (WPARAM)this, dw1); 112 107 break; 113 108 … … 116 111 USHORT selTIB = GetFS(); // save current FS selector 117 112 USHORT selCallback; 118 LPDRVCALLBACK mthdCallback = (LPDRVCALLBACK) dwCallback;113 LPDRVCALLBACK mthdCallback = (LPDRVCALLBACK)Callback; 119 114 120 115 if(selTIB == SELECTOR_OS2_FS) { … … 130 125 //@@@PH 1999/12/28 Shockwave Flash seem to make assumptions on a 131 126 // specific stack layout. Do we have the correct calling convention here? 132 mthdCallback((HDRVR)this, uMessage, dwInstance, dw1, dw2);127 mthdCallback((HDRVR)this, uMessage, Instance, dw1, dw2); 133 128 SetFS(selTIB); // switch back to the saved FS selector 134 129 } … … 140 135 141 136 case CALLBACK_EVENT: 142 SetEvent((HANDLE) dwCallback);137 SetEvent((HANDLE)Callback); 143 138 break; 144 139 … … 147 142 148 143 default: 149 dprintf(("WARNING: Unknown callback type %x %x", fdwOpen, dwCallback));144 dprintf(("WARNING: Unknown callback type %x %x", OpenFlags, Callback)); 150 145 break; 151 146 } //switch … … 187 182 /******************************************************************************/ 188 183 /******************************************************************************/ 189 WaveInOut *WaveInOut::head = NULL;190 184 -
trunk/src/winmm/waveinoutbase.h
r9671 r21358 8 8 * Project Odin Software License can be found in LICENSE.TXT 9 9 */ 10 10 11 #ifndef __WAVEINOUTBASE_H__ 11 12 #define __WAVEINOUTBASE_H__ … … 25 26 { 26 27 public: 27 WaveInOut(LPWAVEFORMATEX pwfx, DWORD fdwOpen, ULONG nCallback, ULONG dwInstance); 28 virtual ~WaveInOut(); 28 WaveInOut(LPWAVEFORMATEX pwfx, DWORD fdwOpen, 29 ULONG nCallback, ULONG dwInstance); 30 virtual ~WaveInOut(); 29 31 30 int getState() { return State; }; 31 MMRESULT getError() { return ulError; }; 32 ULONG getSampleRate() { return SampleRate; }; 33 ULONG getBitsPerSample() { return BitsPerSample; }; 34 ULONG getnumChannels() { return nChannels; }; 35 ULONG getAvgBytesPerSecond() { return (BitsPerSample/8) * nChannels * SampleRate; }; 32 int getState() { return State; }; 33 ULONG getSampleRate() { return SampleRate; }; 34 ULONG getBitsPerSample() { return BitsPerSample; }; 35 ULONG getnumChannels() { return nChannels; }; 36 ULONG getAvgBytesPerSecond() { return (BitsPerSample/8) * nChannels * SampleRate; }; 36 37 37 static BOOLfind(WaveInOut *wave);38 static voidshutdown();38 static BOOL find(WaveInOut *wave); 39 static void shutdown(); 39 40 40 41 protected: 42 void callback(UINT uMessage, DWORD dw1, DWORD dw2); 41 43 42 ULONG ulError, State; 43 44 int SampleRate; 45 int BitsPerSample; 46 int nChannels; 47 48 int queuedbuffers; 49 50 // callback interface 51 void callback(UINT uMessage, DWORD dw1, DWORD dw2); 52 53 DWORD fdwOpen; 54 DWORD dwCallback; 55 DWORD dwInstance; 56 57 WAVEHDR *wavehdr, 58 *curhdr; 59 60 VMutex wmutex; 44 int SampleRate; 45 int BitsPerSample; 46 int nChannels; 47 DWORD OpenFlags; 48 DWORD Callback; 49 DWORD Instance; 50 ULONG State; 51 int queuedbuffers; 52 WAVEHDR * wavehdr; 53 VMutex wmutex; 61 54 62 55 private: 63 // Linked list management 64 WaveInOut *next; // Next wave class 65 static WaveInOut *head; // List of wave classes 56 static WaveInOut * head; // List of wave classes 57 WaveInOut * next; // Next wave class 66 58 }; 67 59 -
trunk/src/winmm/waveout.cpp
r10173 r21358 1 1 /* $Id: waveout.cpp,v 1.27 2003-07-16 15:47:24 sandervl Exp $ */ 2 //#undef DEBUG 2 3 3 /* 4 4 * Wave out MM apis … … 13 13 */ 14 14 15 16 /**************************************************************************** 17 * Includes * 18 ****************************************************************************/ 15 /******************************************************************************/ 16 // Includes 17 /******************************************************************************/ 19 18 20 19 #include <os2win.h> … … 29 28 #include "waveoutdart.h" 30 29 #include "waveoutdaud.h" 30 #include "waveoutflash.h" 31 31 #include "misc.h" 32 32 #include "winmm.h" … … 36 36 #include "dbglocal.h" 37 37 38 39 38 /******************************************************************************/ 40 39 /******************************************************************************/ … … 42 41 DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen) 43 42 { 44 MMRESULT rc; 45 46 if(fMMPMAvailable == FALSE) return MMSYSERR_NODRIVER; 47 48 if(pwfx == NULL) 43 MMRESULT rc; 44 45 if (fMMPMAvailable == FALSE) 46 return MMSYSERR_NODRIVER; 47 48 if (pwfx == NULL) 49 49 return(WAVERR_BADFORMAT); 50 50 51 if (fdwOpen & WAVE_FORMAT_QUERY)52 {53 if(DartWaveOut::queryFormat(pwfx->wFormatTag, pwfx->nChannels,pwfx->nSamplesPerSec,54 55 return(MMSYSERR_NOERROR);56 } 57 else return(WAVERR_BADFORMAT);58 } 59 60 if (phwo == NULL)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 61 return(MMSYSERR_INVALPARAM); 62 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) { 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) 69 72 return(MMSYSERR_NODRIVER); 70 } 71 72 rc = ((WaveOut *)*phwo)->getError(); 73 if(rc != MMSYSERR_NOERROR) { 73 74 rc = ((WaveOut *)*phwo)->open(); 75 if (rc != MMSYSERR_NOERROR) 74 76 delete (WaveOut *)*phwo; 75 return(rc); 76 } 77 return(MMSYSERR_NOERROR); 77 78 return rc; 78 79 } 79 80 /******************************************************************************/ -
trunk/src/winmm/waveoutbase.cpp
r7196 r21358 14 14 */ 15 15 16 17 /**************************************************************************** 18 * Includes * 19 ****************************************************************************/ 20 21 16 /******************************************************************************/ 17 // Includes 18 /******************************************************************************/ 22 19 23 20 #define INCL_BASE … … 38 35 #include "dbglocal.h" 39 36 40 #ifndef min 41 #define min(a, b) ((a > b) ? b : a) 42 #endif 37 /******************************************************************************/ 38 /******************************************************************************/ 43 39 44 #ifndef max 45 #define max(a, b) ((a > b) ? a : b) 46 #endif 40 ULONG WaveOut::defvolume = 0xFFFFFFFF; 47 41 48 //TODO: mulaw, alaw & adpcm49 42 /******************************************************************************/ 50 43 /******************************************************************************/ … … 52 45 : WaveInOut(pwfx, fdwOpen, nCallback, dwInstance) 53 46 { 54 bytesPlayed = bytesCopied = bytesReturned = 0;55 56 47 volume = defvolume; 57 48 … … 67 58 int WaveOut::getNumDevices() 68 59 { 69 MCI_GENERIC_PARMS GenericParms;70 MCI_AMP_OPEN_PARMS AmpOpenParms;71 APIRET rc;60 MCI_AMP_OPEN_PARMS AmpOpenParms; 61 MCI_GENERIC_PARMS GenericParms = {0}; 62 APIRET rc; 72 63 73 // Setup the open structure, pass the playlist and tell MCI_OPEN to use it 74 memset(&AmpOpenParms,0,sizeof(AmpOpenParms)); 64 // Try to open the device to see if it's there 65 memset(&AmpOpenParms, 0, sizeof(AmpOpenParms)); 66 AmpOpenParms.usDeviceID = 0; 67 AmpOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX; 75 68 76 AmpOpenParms.usDeviceID = ( USHORT ) 0; 77 AmpOpenParms.pszDeviceType = ( PSZ ) MCI_DEVTYPE_AUDIO_AMPMIX; 69 rc = mymciSendCommand(0, MCI_OPEN, 70 MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE, 71 (PVOID) &AmpOpenParms, 0); 78 72 79 rc = mymciSendCommand(0, MCI_OPEN, 80 MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE, 81 (PVOID) &AmpOpenParms, 82 0); 73 if (LOUSHORT(rc) != MCIERR_SUCCESS) 74 return 0; 83 75 84 if(rc) { 85 return 0; //no devices present 86 } 76 // Close the device 77 mymciSendCommand(AmpOpenParms.usDeviceID, MCI_CLOSE, 78 MCI_WAIT, 79 (PVOID)&GenericParms, 0); 87 80 88 // Generic parameters 89 GenericParms.hwndCallback = 0; //hwndFrame 90 91 // Close the device 92 mymciSendCommand(AmpOpenParms.usDeviceID, MCI_CLOSE, MCI_WAIT, (PVOID)&GenericParms, 0); 93 94 return 1; 81 return 1; 95 82 } 96 83 /******************************************************************************/ 97 //Called if waveOutSetVolume is called by the application with waveout handle NULL 98 //Sets the default volume of each waveout stream (until it's volume is changed 99 //with an appropriate waveOutSetVolume call) 84 /******************************************************************************/ 85 BOOL WaveOut::queryFormat(ULONG formatTag, ULONG nChannels, 86 ULONG nSamplesPerSec, ULONG wBitsPerSample) 87 { 88 APIRET rc; 89 BOOL winrc = TRUE; 90 MCI_OPEN_PARMS OpenParms; 91 MCI_WAVE_GETDEVCAPS_PARMS DevCapsParms; 92 MCI_GENERIC_PARMS GenericParms = {0}; 93 #ifdef DEBUG 94 char szError[64] = ""; 95 #endif 96 97 dprintf(("WINMM: WaveOut::queryFormat %x srate=%d, nchan=%d, bps=%d", formatTag, nSamplesPerSec, nChannels, wBitsPerSample)); 98 99 // Open the device. 100 memset(&OpenParms, 0, sizeof(OpenParms)); 101 OpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_WAVEFORM_AUDIO; 102 103 rc = mymciSendCommand(0, MCI_OPEN, 104 MCI_WAIT | MCI_OPEN_TYPE_ID, 105 (PVOID)&OpenParms, 0); 106 if (LOUSHORT(rc) != MCIERR_SUCCESS) { 107 #ifdef DEBUG 108 mymciGetErrorString(rc, szError, sizeof(szError)); 109 dprintf(("WINMM: WaveOut::queryFormat: %s\n", szError)); 110 #endif 111 return FALSE; 112 } 113 114 // See if the device can handle the specified format. 115 memset(&DevCapsParms, 0, sizeof(MCI_WAVE_GETDEVCAPS_PARMS)); 116 DevCapsParms.ulBitsPerSample = wBitsPerSample; 117 DevCapsParms.ulFormatTag = DATATYPE_WAVEFORM; 118 DevCapsParms.ulSamplesPerSec = nSamplesPerSec; 119 DevCapsParms.ulChannels = nChannels; 120 DevCapsParms.ulFormatMode = MCI_PLAY; 121 DevCapsParms.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT; 122 123 rc = mymciSendCommand(OpenParms.usDeviceID, MCI_GETDEVCAPS, 124 MCI_WAIT | MCI_GETDEVCAPS_EXTENDED | MCI_GETDEVCAPS_ITEM, 125 (PVOID)&DevCapsParms, 0); 126 if (LOUSHORT(rc) != MCIERR_SUCCESS) { 127 #ifdef DEBUG 128 mymciGetErrorString(rc, szError, sizeof(szError)); 129 dprintf(("WINMM: WaveOut::queryFormat: %s\n", szError)); 130 #endif 131 winrc = FALSE; 132 } 133 134 // Close the device 135 rc = mymciSendCommand(OpenParms.usDeviceID, MCI_CLOSE, 136 MCI_WAIT, (PVOID)&GenericParms, 0); 137 if (LOUSHORT(rc) != MCIERR_SUCCESS) { 138 #ifdef DEBUG 139 mymciGetErrorString(rc, szError, sizeof(szError)); 140 dprintf(("WINMM: WaveOut::queryFormat: %s\n", szError)); 141 #endif 142 winrc = FALSE; 143 } 144 145 return winrc; 146 } 147 /******************************************************************************/ 148 // Called if waveOutSetVolume is called by the application with waveout handle NULL 149 // Sets the default volume of each waveout stream (until it's volume is changed 150 // with an appropriate waveOutSetVolume call) 100 151 /******************************************************************************/ 101 152 void WaveOut::setDefaultVolume(ULONG volume) … … 112 163 /******************************************************************************/ 113 164 /******************************************************************************/ 114 ULONG WaveOut::defvolume = 0xFFFFFFFF;115 165 -
trunk/src/winmm/waveoutbase.h
r8568 r21358 8 8 * Project Odin Software License can be found in LICENSE.TXT 9 9 */ 10 10 11 #ifndef __DWAVEOUTBASE_H__ 11 12 #define __DWAVEOUTBASE_H__ 12 13 13 14 #include "waveinoutbase.h" 14 15 15 #ifdef OS2_ONLY 16 16 #include "winmmtype.h" … … 21 21 { 22 22 public: 23 24 23 WaveOut(LPWAVEFORMATEX pwfx, DWORD fdwOpen, ULONG nCallback, ULONG dwInstance); 24 virtual ~WaveOut(); 25 25 26 virtual MMRESULT write(LPWAVEHDR pwh, UINT cbwh) = 0;27 virtual MMRESULT pause() = 0;28 virtual MMRESULT stop() = 0;29 virtual MMRESULT resume() = 0;30 virtual MMRESULT reset() = 0;31 virtual ULONG getPosition() = 0;32 virtual MMRESULT setVolume(ULONG ulVol) = 0;33 ULONG getVolume() { return volume; };26 virtual MMRESULT open() = 0; 27 virtual MMRESULT write(LPWAVEHDR pwh, UINT cbwh) = 0; 28 virtual MMRESULT pause() = 0; 29 virtual MMRESULT stop() = 0; 30 virtual MMRESULT resume() = 0; 31 virtual MMRESULT reset() = 0; 32 virtual ULONG getPosition() = 0; 33 virtual MMRESULT setVolume(ULONG ulVol) = 0; 34 34 35 static int getNumDevices(); 36 37 static void setDefaultVolume(ULONG volume); 38 static DWORD getDefaultVolume(); 35 static int getNumDevices(); 36 static BOOL queryFormat(ULONG formatTag, ULONG nChannels, 37 ULONG nSamplesPerSec, ULONG sampleSize); 38 static void setDefaultVolume(ULONG volume); 39 static DWORD getDefaultVolume(); 40 ULONG getVolume() { return volume; }; 39 41 40 42 protected: 41 42 ULONG bytesPlayed, bytesCopied, bytesReturned; 43 ULONG volume; // Volume state 44 45 static ULONG defvolume; //default volume for streams (if waveOutSetVolume called with NULL stream) 46 47 private: 48 43 ULONG volume; 44 static ULONG defvolume; // default volume for streams 45 // (if waveOutSetVolume called with NULL stream) 49 46 }; 50 47 -
trunk/src/winmm/waveoutdart.cpp
r10525 r21358 15 15 */ 16 16 17 18 /**************************************************************************** 19 * Includes * 20 ****************************************************************************/ 21 22 17 /******************************************************************************/ 18 // Includes 19 /******************************************************************************/ 23 20 24 21 #define INCL_BASE … … 41 38 #include "dbglocal.h" 42 39 40 /******************************************************************************/ 41 43 42 #ifndef min 44 43 #define min(a, b) ((a > b) ? b : a) … … 51 50 LONG APIENTRY WaveOutHandler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags); 52 51 53 static BOOL fFixedWaveBufferSize = FALSE; 52 #define DART_BUFCNT 64 53 #define DART_BUFSIZE 4096 54 55 /******************************************************************************/ 54 56 55 57 //#define DEBUG_DUMP_PCM … … 67 69 #endif 68 70 69 //****************************************************************************** 71 /******************************************************************************/ 72 73 static BOOL fFixedWaveBufferSize = FALSE; 74 75 /******************************************************************************/ 70 76 // ODIN_waveOutSetFixedBuffers 71 77 // … … 76 82 // purpose solution. 77 83 // 78 //****************************************************************************** 84 /******************************************************************************/ 85 79 86 void WIN32API ODIN_waveOutSetFixedBuffers() 80 87 { 81 88 fFixedWaveBufferSize = TRUE; 82 89 } 83 /******************************************************************************/ 84 /******************************************************************************/ 90 91 /******************************************************************************/ 92 /******************************************************************************/ 93 85 94 DartWaveOut::DartWaveOut(LPWAVEFORMATEX pwfx, ULONG fdwOpen, ULONG nCallback, ULONG dwInstance) 86 95 : WaveOut(pwfx, fdwOpen, nCallback, dwInstance) 87 96 { 88 MCI_GENERIC_PARMS GenericParms; 97 DeviceId = 0; 98 fMixerSetup = FALSE; 99 fUnderrun = FALSE; 100 curFillBuf = 0; 101 curPlayBuf = 0; 102 curFillPos = 0; 103 curPlayPos = 0; 104 ulBufSize = DART_BUFSIZE; 105 ulBufCount = DART_BUFCNT; 106 bytesPlayed = 0; 107 bytesCopied = 0; 108 bytesReturned = 0; 109 ulUnderrunBase = 0; 110 mixHandle = 0; 111 curhdr = NULL; 112 pmixWriteProc = 0; 113 MixBuffer = 0; 114 BufferParms = 0; 115 } 116 117 /******************************************************************************/ 118 /******************************************************************************/ 119 120 DartWaveOut::~DartWaveOut() 121 { 122 MCI_GENERIC_PARMS GenericParms = {0}; 123 124 State = STATE_STOPPED; 125 126 #ifdef DEBUG_DUMP_PCM 127 if (pcmfile) fclose(pcmfile); 128 #endif 129 130 if (DeviceId) { 131 // Stop the playback. 132 mymciSendCommand(DeviceId, MCI_STOP, 133 MCI_WAIT, 134 (PVOID)&GenericParms,0); 135 136 if (fMixerSetup) 137 mymciSendCommand(DeviceId, MCI_BUFFER, 138 MCI_WAIT | MCI_DEALLOCATE_MEMORY, 139 (PVOID)&BufferParms, 0); 140 141 // Close the device 142 mymciSendCommand(DeviceId, MCI_CLOSE, 143 MCI_WAIT, 144 (PVOID)&GenericParms, 0); 145 146 callback(WOM_CLOSE, 0, 0); 147 } 148 149 if (MixBuffer) 150 free(MixBuffer); 151 if (BufferParms) 152 free(BufferParms); 153 } 154 155 /******************************************************************************/ 156 /******************************************************************************/ 157 158 MMRESULT DartWaveOut::open() 159 { 89 160 MCI_AMP_OPEN_PARMS AmpOpenParms; 161 MCI_GENERIC_PARMS GenericParms = {0}; 162 MCI_MIXSETUP_PARMS MixSetupParms; 90 163 APIRET rc; 91 164 92 curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0; 93 fMixerSetup = FALSE; 94 fUnderrun = FALSE; 95 ulUnderrunBase= 0; 96 97 ulBufSize = DART_BUFSIZE; 98 99 MixBuffer = (MCI_MIX_BUFFER *)malloc(PREFILLBUF_DART*sizeof(MCI_MIX_BUFFER)); 100 MixSetupParms = (MCI_MIXSETUP_PARMS *)malloc(sizeof(MCI_MIXSETUP_PARMS)); 165 MixBuffer = (MCI_MIX_BUFFER *)malloc(ulBufCount*sizeof(MCI_MIX_BUFFER)); 101 166 BufferParms = (MCI_BUFFER_PARMS *)malloc(sizeof(MCI_BUFFER_PARMS)); 102 if (!MixBuffer || !MixSetupParms|| !BufferParms) {167 if (!MixBuffer || !BufferParms) { 103 168 dprintf(("ERROR: malloc failed!!")); 104 ulError = MMSYSERR_NOMEM; 105 return; 106 } 107 108 // Setup the open structure, pass the playlist and tell MCI_OPEN to use it 109 memset(&AmpOpenParms,0,sizeof(AmpOpenParms)); 110 111 AmpOpenParms.usDeviceID = ( USHORT ) 0; 112 AmpOpenParms.pszDeviceType = ( PSZ ) MCI_DEVTYPE_AUDIO_AMPMIX; 113 114 rc = mymciSendCommand(0, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE, 115 (PVOID) &AmpOpenParms, 0); 116 117 DeviceId = AmpOpenParms.usDeviceID; 118 if(rc) { 169 return MMSYSERR_NOMEM; 170 } 171 172 // Setup the open structure, then open the device 173 memset(&AmpOpenParms, 0, sizeof(AmpOpenParms)); 174 AmpOpenParms.usDeviceID = 0; 175 AmpOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX; 176 177 rc = mymciSendCommand(0, MCI_OPEN, 178 MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE, 179 (PVOID)&AmpOpenParms, 0); 180 if (LOUSHORT(rc) != MCIERR_SUCCESS) { 119 181 dprintf(("MCI_OPEN failed\n")); 120 182 mciError(rc); 121 ulError = MMSYSERR_NODRIVER; 122 } 123 if(rc == 0) { 124 //Grab exclusive rights to device instance (NOT entire device) 125 GenericParms.hwndCallback = 0; //Not needed, so set to 0 126 rc = mymciSendCommand(DeviceId, MCI_ACQUIREDEVICE, MCI_EXCLUSIVE_INSTANCE, 127 (PVOID)&GenericParms, 0); 128 if(rc) { 129 dprintf(("MCI_ACQUIREDEVICE failed\n")); 130 mciError(rc); 131 ulError = MMSYSERR_NOTENABLED; 183 return MMSYSERR_NODRIVER; 184 } 185 DeviceId = AmpOpenParms.usDeviceID; 186 187 // Grab exclusive rights to device instance (NOT entire device) 188 rc = mymciSendCommand(DeviceId, MCI_ACQUIREDEVICE, 189 MCI_EXCLUSIVE_INSTANCE, 190 (PVOID)&GenericParms, 0); 191 if (LOUSHORT(rc) != MCIERR_SUCCESS) { 192 dprintf(("MCI_ACQUIREDEVICE failed\n")); 193 mciError(rc); 194 return MMSYSERR_NOTENABLED; 195 } 196 dprintf(("device acquired\n")); 197 dprintf(("bps %d, sps %d chan %d\n", BitsPerSample, SampleRate, nChannels)); 198 199 // Setup the mixer for playback of wave data 200 memset(&MixSetupParms, 0, sizeof(MixSetupParms)); 201 MixSetupParms.ulBitsPerSample = BitsPerSample; 202 MixSetupParms.ulSamplesPerSec = SampleRate; 203 MixSetupParms.ulFormatTag = MCI_WAVE_FORMAT_PCM; 204 MixSetupParms.ulChannels = nChannels; 205 MixSetupParms.ulFormatMode = MCI_PLAY; 206 MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; 207 MixSetupParms.pmixEvent = WaveOutHandler; 208 209 rc = mymciSendCommand(DeviceId, MCI_MIXSETUP, 210 MCI_WAIT | MCI_MIXSETUP_INIT, 211 (PVOID)&MixSetupParms, 0); 212 213 if (LOUSHORT(rc) != MCIERR_SUCCESS) { 214 mciError(rc); 215 mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, 216 MCI_WAIT, 217 (PVOID)&GenericParms, 0); 218 return MMSYSERR_NOTSUPPORTED; 219 } 220 221 // Save the mixer handle & the ptr to the write proc. 222 mixHandle = MixSetupParms.ulMixHandle; 223 pmixWriteProc = MixSetupParms.pmixWrite; 224 225 #ifdef DEBUG_DUMP_PCM 226 REC_STRUCT recinfo; 227 228 pcmfile = fopen("dartpcm.dat", "wb"); 229 recinfo.bits = BitsPerSample; 230 recinfo.rate = SampleRate; 231 recinfo.format = MCI_WAVE_FORMAT_PCM; 232 recinfo.numchan = nChannels; 233 fwrite(&recinfo, sizeof(recinfo), 1, pcmfile); 234 #endif 235 236 setVolume(volume); 237 callback(WOM_OPEN, 0, 0); 238 239 return MMSYSERR_NOERROR; 240 } 241 242 /******************************************************************************/ 243 /******************************************************************************/ 244 245 MMRESULT DartWaveOut::write(LPWAVEHDR pwh, UINT cbwh) 246 { 247 APIRET rc; 248 249 queuedbuffers++; 250 pwh->lpNext = NULL; 251 pwh->reserved = 0; 252 253 // Set up the BufferParms data structure and allocate 254 // device buffers from the Amp-Mixer 255 if (fMixerSetup == FALSE) 256 { 257 ulBufSize = pwh->dwBufferLength; 258 if (!ulBufSize || ulBufSize > 0x10000) 259 return MMSYSERR_INVALPARAM; 260 261 rc = initBuffers(); 262 if (rc != MMSYSERR_NOERROR) 263 return rc; 264 265 curhdr = pwh; 266 fMixerSetup = TRUE; 267 } 268 269 wmutex.enter(); 270 271 if (wavehdr) { 272 WAVEHDR *chdr = wavehdr; 273 while (chdr->lpNext) { 274 #ifdef DEBUG 275 if (chdr == pwh) dprintf(("adding already present buffer!!!!!")); 276 #endif 277 chdr = chdr->lpNext; 132 278 } 133 } 134 setVolume(volume); 135 136 if(!ulError) 137 callback(WOM_OPEN, 0, 0); 138 } 139 /******************************************************************************/ 140 /******************************************************************************/ 141 DartWaveOut::~DartWaveOut() 142 { 143 MCI_GENERIC_PARMS GenericParms; 144 145 State = STATE_STOPPED; 146 147 #ifdef DEBUG_DUMP_PCM 148 if(pcmfile) fclose(pcmfile); 149 #endif 150 151 if(!ulError) { 152 // Generic parameters 153 GenericParms.hwndCallback = 0; //hwndFrame 154 155 // Stop the playback. 156 mymciSendCommand(DeviceId, MCI_STOP,MCI_WAIT, (PVOID)&GenericParms,0); 157 158 mymciSendCommand(DeviceId, MCI_BUFFER, 159 MCI_WAIT | MCI_DEALLOCATE_MEMORY, 160 (PVOID)&BufferParms, 0); 161 162 // Generic parameters 163 GenericParms.hwndCallback = 0; //hwndFrame 164 165 // Close the device 166 mymciSendCommand(DeviceId, MCI_CLOSE, MCI_WAIT, (PVOID)&GenericParms, 0); 167 } 168 169 if(!ulError) 279 chdr->lpNext = pwh; 280 } 281 else wavehdr = pwh; 282 283 //don't start playback if paused 284 if (!fUnderrun && State != STATE_STOPPED) { 285 //write new data to the DART buffers (if there's any room left) 286 if (State == STATE_PLAYING) 287 writeBuffer(); //must be called before (re)starting playback 288 wmutex.leave(); 289 return MMSYSERR_NOERROR; 290 } 291 292 writeBuffer(); //must be called before (re)starting playback 293 State = STATE_PLAYING; 294 fUnderrun = FALSE; 295 wmutex.leave(); 296 297 //write buffers to DART; starts playback 298 dprintf(("WINMM: transfer all buffers to DART")); 299 300 USHORT selTIB = RestoreOS2FS(); // save current FS selector 301 pmixWriteProc(mixHandle, MixBuffer, ulBufCount); 302 SetFS(selTIB); // switch back to the saved FS selector 303 304 dprintf(("Dart playing\n")); 305 306 return MMSYSERR_NOERROR; 307 } 308 309 /******************************************************************************/ 310 /******************************************************************************/ 311 312 MMRESULT DartWaveOut::initBuffers() 313 { 314 APIRET rc; 315 MCI_GENERIC_PARMS GenericParms = {0}; 316 int orgbufsize = ulBufSize; // on entry, ulBufSize == pwh->dwBufferLength 317 318 #if 1 319 //by default we need to select a small enough buffer 320 //to be able to signal buffer completion in time 321 if (fFixedWaveBufferSize == FALSE) 170 322 { 171 callback(WOM_CLOSE, 0, 0); 172 } 173 174 if(MixBuffer) 175 free(MixBuffer); 176 if(MixSetupParms) 177 free(MixSetupParms); 178 if(BufferParms) 179 free(BufferParms); 180 } 181 /******************************************************************************/ 182 /******************************************************************************/ 183 MMRESULT DartWaveOut::write(LPWAVEHDR pwh, UINT cbwh) 184 { 185 MCI_GENERIC_PARMS GenericParms = {0}; 186 APIRET rc; 187 int i, buflength; 188 189 queuedbuffers++; 190 if(fMixerSetup == FALSE) 191 { 192 dprintf(("device acquired\n")); 193 /* Set the MixSetupParms data structure to match the loaded file. 194 * This is a global that is used to setup the mixer. 195 */ 196 memset(MixSetupParms, 0, sizeof( MCI_MIXSETUP_PARMS ) ); 197 198 MixSetupParms->ulBitsPerSample = BitsPerSample; 199 MixSetupParms->ulSamplesPerSec = SampleRate; 200 MixSetupParms->ulFormatTag = MCI_WAVE_FORMAT_PCM; 201 MixSetupParms->ulChannels = nChannels; 202 203 dprintf(("bps %d, sps %d chan %d\n", BitsPerSample, SampleRate, nChannels)); 204 205 #ifdef DEBUG_DUMP_PCM 206 REC_STRUCT recinfo; 207 208 pcmfile = fopen("dartpcm.dat", "wb"); 209 recinfo.bits = BitsPerSample; 210 recinfo.rate = SampleRate; 211 recinfo.format = MCI_WAVE_FORMAT_PCM; 212 recinfo.numchan = nChannels; 213 fwrite(&recinfo, sizeof(recinfo), 1, pcmfile); 214 #endif 215 /* Setup the mixer for playback of wave data 216 */ 217 MixSetupParms->ulFormatMode = MCI_PLAY; 218 MixSetupParms->ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; 219 MixSetupParms->pmixEvent = WaveOutHandler; 220 221 rc = mymciSendCommand(DeviceId, 222 MCI_MIXSETUP, 223 MCI_WAIT | MCI_MIXSETUP_INIT, 224 (PVOID)MixSetupParms, 225 0); 226 227 if ( rc != MCIERR_SUCCESS ) { 228 mciError(rc); 229 mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, MCI_WAIT, 230 (PVOID)&GenericParms, 0); 231 return(MMSYSERR_NOTSUPPORTED); 323 int consumerate = getAvgBytesPerSecond(); 324 int minbufsize = consumerate/32; 325 326 ulBufSize /= 2; 327 if (ulBufSize > minbufsize) { 328 dprintf(("set buffer size to %d bytes (org size = %d)", minbufsize, orgbufsize)); 329 ulBufSize = minbufsize; 232 330 } 233 234 /* 235 * Set up the BufferParms data structure and allocate 236 * device buffers from the Amp-Mixer 237 */ 238 dprintf(("mix setup %d, %d\n", pwh->dwBufferLength, pwh->dwBufferLength)); 239 240 #if 1 241 if(fFixedWaveBufferSize == FALSE) 242 {//by default we need to select a small enough buffer to be able to 243 //signal buffer completion in time 244 int consumerate = getAvgBytesPerSecond(); 245 int minbufsize = consumerate/32; 246 247 ulBufSize = pwh->dwBufferLength/2; 248 if(ulBufSize > minbufsize) { 249 dprintf(("set buffer size to %d bytes (org size = %d)", minbufsize, pwh->dwBufferLength)); 250 ulBufSize = minbufsize; 251 } 252 } 253 else ulBufSize = pwh->dwBufferLength; 331 } 254 332 #else 255 if(pwh->dwBufferLength >= 512 && pwh->dwBufferLength <= 1024) 256 ulBufSize = pwh->dwBufferLength; 257 else ulBufSize = 1024; 258 #endif 259 MixSetupParms->ulBufferSize = ulBufSize; 260 261 BufferParms->ulNumBuffers = PREFILLBUF_DART; 262 BufferParms->ulBufferSize = MixSetupParms->ulBufferSize; 263 BufferParms->pBufList = MixBuffer; 264 265 for(i=0;i<PREFILLBUF_DART;i++) { 266 MixBuffer[i].ulUserParm = (ULONG)this; 267 } 268 269 rc = mymciSendCommand(DeviceId, 270 MCI_BUFFER, 271 MCI_WAIT | MCI_ALLOCATE_MEMORY, 272 (PVOID)BufferParms, 273 0); 274 275 if(ULONG_LOWD(rc) != MCIERR_SUCCESS) { 276 mciError(rc); 277 mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, MCI_WAIT, 278 (PVOID)&GenericParms, 0); 279 return(MMSYSERR_NOTSUPPORTED); 280 } 281 282 wmutex.enter(); 283 fMixerSetup = TRUE; 284 285 curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0; 286 bytesPlayed = bytesCopied = bytesReturned = 0; 287 288 for(i=0;i<PREFILLBUF_DART;i++) { 289 memset(MixBuffer[i].pBuffer, 0, MixBuffer[i].ulBufferLength); 290 } 291 dprintf(("Dart opened, bufsize = %d\n", MixBuffer[0].ulBufferLength)); 292 293 wavehdr = pwh; 294 curhdr = pwh; 295 pwh->lpNext = NULL; 296 pwh->reserved = 0; 297 298 if(State != STATE_STOPPED) {//don't start playback if paused 299 wmutex.leave(); 300 return(MMSYSERR_NOERROR); 301 } 302 303 writeBuffer(); //must be called before (re)starting playback 304 305 dprintf(("MixSetupParms = %X\n", MixSetupParms)); 306 State = STATE_PLAYING; 307 fUnderrun = FALSE; 308 wmutex.leave(); 309 310 //write buffers to DART; starts playback 311 dprintf(("WINMM: transfer all buffers to DART")); 312 USHORT selTIB = RestoreOS2FS(); // save current FS selector 313 314 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, 315 MixBuffer, 316 PREFILLBUF_DART); 317 SetFS(selTIB); // switch back to the saved FS selector 318 dprintf(("Dart playing\n")); 319 } 320 else 321 { 322 pwh->lpNext = NULL; 323 pwh->reserved = 0; 324 wmutex.enter(); 325 if(wavehdr) { 326 WAVEHDR *chdr = wavehdr; 327 while(chdr->lpNext) { 328 #ifdef DEBUG 329 if(chdr == pwh) dprintf(("adding already present buffer!!!!!")); 330 #endif 331 chdr = chdr->lpNext; 332 } 333 chdr->lpNext = pwh; 334 } 335 else wavehdr = pwh; 336 337 if(!fUnderrun && State != STATE_STOPPED) {//don't start playback if paused 338 //write new data to the DART buffers (if there's any room left) 339 if(State == STATE_PLAYING) { 340 writeBuffer(); //must be called before (re)starting playback 341 } 342 wmutex.leave(); 343 return(MMSYSERR_NOERROR); 344 } 345 writeBuffer(); //must be called before (re)starting playback 346 State = STATE_PLAYING; 347 fUnderrun = FALSE; 348 wmutex.leave(); 349 350 //write buffers to DART; starts playback 351 dprintf(("WINMM: transfer all buffers to DART")); 352 USHORT selTIB = RestoreOS2FS(); // save current FS selector 353 354 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, 355 MixBuffer, 356 PREFILLBUF_DART); 357 SetFS(selTIB); // switch back to the saved FS selector 358 359 dprintf(("Dart playing\n")); 360 } 361 return(MMSYSERR_NOERROR); 362 } 363 /******************************************************************************/ 364 /******************************************************************************/ 333 if (ulBufSize < 512 || ulBufSize > 1024) 334 ulBufSize = 1024; 335 #endif 336 337 dprintf(("buffer setup - WAVE size = %d, DART size = %d\n", 338 orgbufsize, ulBufSize)); 339 340 BufferParms->ulNumBuffers = ulBufCount; 341 BufferParms->ulBufferSize = ulBufSize; 342 BufferParms->pBufList = MixBuffer; 343 344 rc = mymciSendCommand(DeviceId, MCI_BUFFER, 345 MCI_WAIT | MCI_ALLOCATE_MEMORY, 346 (PVOID)BufferParms, 0); 347 348 if (LOUSHORT(rc) != MCIERR_SUCCESS) { 349 mciError(rc); 350 mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, 351 MCI_WAIT, 352 (PVOID)&GenericParms, 0); 353 return MMSYSERR_NOTSUPPORTED; 354 } 355 356 // DART may not have allocated all the buffers requested. 357 ulBufCount = BufferParms->ulNumBuffers; 358 359 for (int i = 0; i < ulBufCount; i++) { 360 MixBuffer[i].ulUserParm = (ULONG)this; 361 memset(MixBuffer[i].pBuffer, 0, MixBuffer[i].ulBufferLength); 362 } 363 dprintf(("Dart opened, bufsize = %d\n", MixBuffer[0].ulBufferLength)); 364 365 return MMSYSERR_NOERROR; 366 } 367 368 /******************************************************************************/ 369 /******************************************************************************/ 370 365 371 MMRESULT DartWaveOut::pause() 366 372 { 367 MCI_GENERIC_PARMS Params;373 MCI_GENERIC_PARMS GenericParms = {0}; 368 374 369 375 dprintf(("WINMM: DartWaveOut::pause")); 370 376 371 377 wmutex.enter(); 372 if (State != STATE_PLAYING) {378 if (State != STATE_PLAYING) { 373 379 State = STATE_PAUSED; 374 380 wmutex.leave(); 375 return (MMSYSERR_NOERROR);381 return MMSYSERR_NOERROR; 376 382 } 377 383 … … 379 385 wmutex.leave(); 380 386 381 memset(&Params, 0, sizeof(Params));382 383 387 // Pause playback. 384 mymciSendCommand(DeviceId, MCI_PAUSE, MCI_WAIT, (PVOID)&Params, 0); 385 386 return(MMSYSERR_NOERROR); 387 } 388 /******************************************************************************/ 389 /******************************************************************************/ 388 mymciSendCommand(DeviceId, MCI_PAUSE, 389 MCI_WAIT, 390 (PVOID)&GenericParms, 0); 391 392 return MMSYSERR_NOERROR; 393 } 394 395 /******************************************************************************/ 396 /******************************************************************************/ 397 390 398 MMRESULT DartWaveOut::resume() 391 399 { 392 MCI_GENERIC_PARMS Params;393 400 int i, curbuf; 394 401 … … 396 403 397 404 wmutex.enter(); 398 if (State != STATE_PAUSED) {405 if (State != STATE_PAUSED) { 399 406 wmutex.leave(); 400 return (MMSYSERR_NOERROR);407 return MMSYSERR_NOERROR; 401 408 } 402 409 State = STATE_PLAYING; … … 405 412 //Only write buffers to dart if mixer has been initialized; if not, then 406 413 //the first buffer write will do this for us. 407 if (fMixerSetup == TRUE)414 if (fMixerSetup == TRUE) 408 415 { 409 416 wmutex.enter(); 410 417 State = STATE_PLAYING; 411 418 fUnderrun = FALSE; 412 curbuf = curPlayBuf;419 curbuf = curPlayBuf; 413 420 writeBuffer(); //must be called before (re)starting playback 414 421 wmutex.leave(); 415 422 416 // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector!417 423 USHORT selTIB = GetFS(); // save current FS selector 418 419 for(i=0;i<PREFILLBUF_DART;i++) 424 for (i = 0; i < ulBufCount; i++) 420 425 { 421 426 dprintf(("restart: write buffer at %x size %d", MixBuffer[curbuf].pBuffer, MixBuffer[curbuf].ulBufferLength)); 422 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, &MixBuffer[curbuf], 1);423 if (++curbuf == PREFILLBUF_DART)427 pmixWriteProc(mixHandle, &MixBuffer[curbuf], 1); 428 if (++curbuf == ulBufCount) 424 429 curbuf = 0; 425 430 } 426 431 SetFS(selTIB); // switch back to the saved FS selector 427 432 } 428 return(MMSYSERR_NOERROR); 429 } 430 /******************************************************************************/ 431 /******************************************************************************/ 433 return MMSYSERR_NOERROR; 434 } 435 436 /******************************************************************************/ 437 /******************************************************************************/ 438 432 439 MMRESULT DartWaveOut::stop() 433 440 { 434 MCI_GENERIC_PARMS Params;441 MCI_GENERIC_PARMS GenericParms = {0}; 435 442 436 443 dprintf(("DartWaveOut::stop %s", (State == STATE_PLAYING) ? "playing" : "stopped")); 437 if(State != STATE_PLAYING) 438 return(MMSYSERR_HANDLEBUSY); 439 440 memset(&Params, 0, sizeof(Params)); 444 if (State != STATE_PLAYING) 445 return MMSYSERR_HANDLEBUSY; 441 446 442 447 // Stop the playback. 443 mymciSendCommand(DeviceId, MCI_STOP, MCI_WAIT, (PVOID)&Params, 0); 448 mymciSendCommand(DeviceId, MCI_STOP, 449 MCI_WAIT, 450 (PVOID)&GenericParms, 0); 444 451 445 452 State = STATE_STOPPED; … … 449 456 bytesPlayed = bytesCopied = bytesReturned = 0; 450 457 451 return(MMSYSERR_NOERROR); 452 } 453 /******************************************************************************/ 454 /******************************************************************************/ 458 return MMSYSERR_NOERROR; 459 } 460 461 /******************************************************************************/ 462 /******************************************************************************/ 463 455 464 MMRESULT DartWaveOut::reset() 456 465 { 457 MCI_GENERIC_PARMS Params;466 MCI_GENERIC_PARMS GenericParms = {0}; 458 467 LPWAVEHDR tmpwavehdr; 459 468 460 469 dprintf(("DartWaveOut::reset %s", (State == STATE_PLAYING) ? "playing" : "stopped")); 461 if(State != STATE_PLAYING) 462 return(MMSYSERR_HANDLEBUSY); 463 464 memset(&Params, 0, sizeof(Params)); 470 if (State != STATE_PLAYING) 471 return MMSYSERR_HANDLEBUSY; 465 472 466 473 wmutex.enter(); … … 469 476 470 477 // Stop the playback. 471 mymciSendCommand(DeviceId, MCI_STOP, MCI_WAIT, (PVOID)&Params, 0); 478 mymciSendCommand(DeviceId, MCI_STOP, 479 MCI_WAIT, 480 (PVOID)&GenericParms, 0); 472 481 473 482 wmutex.enter(); 474 while (wavehdr)483 while (wavehdr) 475 484 { 476 485 wavehdr->dwFlags |= WHDR_DONE; … … 494 503 495 504 wmutex.leave(); 496 return(MMSYSERR_NOERROR); 497 } 498 /******************************************************************************/ 499 /******************************************************************************/ 505 return MMSYSERR_NOERROR; 506 } 507 508 /******************************************************************************/ 509 /******************************************************************************/ 510 500 511 ULONG DartWaveOut::getPosition() 501 512 { 502 MCI_STATUS_PARMS mciStatus = {0};503 ULONG rc, nrbytes;504 505 if (State == STATE_STOPPED) {513 MCI_STATUS_PARMS StatusParms = {0}; 514 ULONG rc, nrbytes; 515 516 if (State == STATE_STOPPED) { 506 517 dprintf(("Not playing; return 0 position")); 507 518 return ulUnderrunBase; 508 519 } 509 520 510 mciStatus.ulItem = MCI_STATUS_POSITION; 511 rc = mymciSendCommand(DeviceId, MCI_STATUS, MCI_STATUS_ITEM|MCI_WAIT, (PVOID)&mciStatus, 0); 512 if((rc & 0xFFFF) == MCIERR_SUCCESS) { 513 nrbytes = (ULONG)(((double)mciStatus.ulReturn * (double)getAvgBytesPerSecond())/1000.0); 514 return ulUnderrunBase+nrbytes; 515 } 516 mciError(rc); 517 return 0xFFFFFFFF; 518 } 519 /******************************************************************************/ 520 /******************************************************************************/ 521 BOOL DartWaveOut::queryFormat(ULONG formatTag, ULONG nChannels, 522 ULONG nSamplesPerSec, ULONG wBitsPerSample) 523 { 524 MCI_WAVE_GETDEVCAPS_PARMS mciAudioCaps; 525 MCI_GENERIC_PARMS GenericParms; 526 MCI_OPEN_PARMS mciOpenParms; /* open parms for MCI_OPEN */ 527 int i, freqbits = 0; 528 ULONG rc, DeviceId; 529 BOOL winrc; 530 531 dprintf(("DartWaveOut::queryFormat %x srate=%d, nchan=%d, bps=%d", formatTag, nSamplesPerSec, nChannels, wBitsPerSample)); 532 533 memset(&mciOpenParms, /* Object to fill with zeros. */ 534 0, /* Value to place into the object. */ 535 sizeof( mciOpenParms ) ); /* How many zero's to use. */ 536 537 mciOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_WAVEFORM_AUDIO; 538 539 rc = mymciSendCommand( (USHORT) 0, 540 MCI_OPEN, 541 MCI_WAIT | MCI_OPEN_TYPE_ID, 542 (PVOID) &mciOpenParms, 543 0); 544 if((rc & 0xFFFF) != MCIERR_SUCCESS) { 521 StatusParms.ulItem = MCI_STATUS_POSITION; 522 rc = mymciSendCommand(DeviceId, MCI_STATUS, 523 MCI_STATUS_ITEM|MCI_WAIT, 524 (PVOID)&StatusParms, 0); 525 if (LOUSHORT(rc) != MCIERR_SUCCESS) { 545 526 mciError(rc); 546 return(FALSE); 547 } 548 DeviceId = mciOpenParms.usDeviceID; 549 550 memset( &mciAudioCaps , 0, sizeof(MCI_WAVE_GETDEVCAPS_PARMS)); 551 552 mciAudioCaps.ulBitsPerSample = wBitsPerSample; 553 mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM; 554 mciAudioCaps.ulSamplesPerSec = nSamplesPerSec; 555 mciAudioCaps.ulChannels = nChannels; 556 mciAudioCaps.ulFormatMode = MCI_PLAY; 557 mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT; 558 559 rc = mymciSendCommand(DeviceId, /* Device ID */ 560 MCI_GETDEVCAPS, 561 MCI_WAIT | MCI_GETDEVCAPS_EXTENDED | MCI_GETDEVCAPS_ITEM, 562 (PVOID) &mciAudioCaps, 563 0); 564 if((rc & 0xFFFF) != MCIERR_SUCCESS) { 527 return 0xFFFFFFFF; 528 } 529 530 nrbytes = (ULONG)(((double)StatusParms.ulReturn * (double)getAvgBytesPerSecond())/1000.0); 531 return (ulUnderrunBase + nrbytes); 532 } 533 534 /******************************************************************************/ 535 /******************************************************************************/ 536 537 MMRESULT DartWaveOut::setVolume(ULONG ulVol) 538 { 539 APIRET rc; 540 ULONG ulVolR = ((ulVol >> 16) * 100) / 0xFFFF; 541 ULONG ulVolL = ((ulVol & 0xffff) * 100) / 0xFFFF; 542 MCI_SET_PARMS SetParms = {0}; 543 544 dprintf(("DartWaveOut::setVolume %d %d", ulVolL, ulVolR)); 545 volume = ulVol; 546 547 // Some drivers can't set left & right volumes independently 548 #ifdef GOOD_AUDIO_CARD_DRIVER 549 SetParms.ulAudio = MCI_SET_AUDIO_LEFT; 550 SetParms.ulLevel = ulVolL; 551 552 rc = mymciSendCommand(DeviceId, MCI_SET, 553 MCI_WAIT | MCI_SET_AUDIO | MCI_SET_VOLUME, 554 &SetParms, 0); 555 if (LOUSHORT(rc) != MCIERR_SUCCESS) 565 556 mciError(rc); 566 winrc = FALSE; 567 } 568 else winrc = TRUE; 569 570 // Close the device 571 mymciSendCommand(DeviceId,MCI_CLOSE,MCI_WAIT,(PVOID)&GenericParms,0); 572 return(winrc); 573 } 574 /******************************************************************************/ 575 /******************************************************************************/ 576 void DartWaveOut::mciError(ULONG ulError) 557 558 SetParms.ulAudio = MCI_SET_AUDIO_RIGHT; 559 SetParms.ulLevel = ulVolR; 560 #else 561 SetParms.ulAudio = MCI_SET_AUDIO_ALL; 562 SetParms.ulLevel = (ulVolR + ulVolL) / 2; 563 #endif 564 565 rc = mymciSendCommand(DeviceId, MCI_SET, 566 MCI_WAIT | MCI_SET_AUDIO | MCI_SET_VOLUME, 567 &SetParms, 0); 568 if (LOUSHORT(rc) != MCIERR_SUCCESS) 569 mciError(rc); 570 571 return MMSYSERR_NOERROR; 572 } 573 574 /******************************************************************************/ 575 /******************************************************************************/ 576 577 void DartWaveOut::mciError(ULONG rc) 577 578 { 578 579 #ifdef DEBUG 579 580 char szError[256] = ""; 580 581 581 mymciGetErrorString( ulError, szError, sizeof(szError));582 mymciGetErrorString(rc, szError, sizeof(szError)); 582 583 dprintf(("WINMM: DartWaveOut: %s\n", szError)); 583 584 #endif 584 585 } 586 585 587 //****************************************************************************** 586 588 //****************************************************************************** 589 587 590 void DartWaveOut::handler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags) 588 591 { 589 ULONG buflength;590 WAVEHDR *whdr, *prevhdr = NULL;592 ULONG buflength; 593 WAVEHDR *whdr, *prevhdr = NULL; 591 594 592 595 dprintf2(("WINMM: handler %d; buffers left %d", curPlayBuf, queuedbuffers)); 593 if (ulFlags == MIX_STREAM_ERROR) {594 if (ulStatus == ERROR_DEVICE_UNDERRUN) {596 if (ulFlags == MIX_STREAM_ERROR) { 597 if (ulStatus == ERROR_DEVICE_UNDERRUN) { 595 598 dprintf(("WINMM: WaveOut handler UNDERRUN! state %s", (State == STATE_PLAYING) ? "playing" : "stopped")); 596 if (State == STATE_PLAYING) {599 if (State == STATE_PLAYING) { 597 600 fUnderrun = TRUE; 598 601 //save current position for when we continue later … … 605 608 return; 606 609 } 607 if (State != STATE_PLAYING) {610 if (State != STATE_PLAYING) 608 611 return; 609 }610 612 611 613 wmutex.enter(); … … 613 615 bytesPlayed += MixBuffer[curPlayBuf].ulBufferLength; 614 616 615 //update our buffer index 616 if(curPlayBuf == PREFILLBUF_DART-1) 617 curPlayBuf = 0; 618 else curPlayBuf++; 617 // update our buffer index 618 if (++curPlayBuf >= ulBufCount) 619 curPlayBuf = 0; 619 620 620 621 fUnderrun = FALSE; 621 622 622 623 whdr = wavehdr; 623 while(whdr) { 624 if(whdr->reserved == WHDR_DONE) 625 { 626 if(bytesPlayed < bytesReturned + whdr->dwBufferLength) { 627 dprintf2(("Buffer marked done, but not yet played completely (play %d/%d, cop %d, ret %d)", bytesPlayed, getPosition(), bytesCopied, bytesReturned)); 628 break; //not yet done 629 } 630 631 dprintf2(("WINMM: handler buf %X done (play %d/%d, cop %d, ret %d)", whdr, bytesPlayed, getPosition(), bytesCopied, bytesReturned)); 632 queuedbuffers--; 633 634 whdr->dwFlags &= ~WHDR_INQUEUE; 635 whdr->dwFlags |= WHDR_DONE; 636 whdr->reserved = 0; 637 638 if(prevhdr == NULL) 639 wavehdr = whdr->lpNext; 640 else prevhdr->lpNext = whdr->lpNext; 641 642 whdr->lpNext = NULL; 643 644 bytesReturned += whdr->dwBufferLength; 645 wmutex.leave(); 646 647 callback(WOM_DONE, (ULONG)whdr, 0); 648 649 wmutex.enter(); 624 while (whdr) { 625 if (whdr->reserved != WHDR_DONE) 626 break; 627 628 if (bytesPlayed < bytesReturned + whdr->dwBufferLength) { 629 dprintf2(("Buffer marked done, but not yet played completely (play %d/%d, cop %d, ret %d)", bytesPlayed, getPosition(), bytesCopied, bytesReturned)); 630 break; //not yet done 650 631 } 651 else break; 632 633 dprintf2(("WINMM: handler buf %X done (play %d/%d, cop %d, ret %d)", whdr, bytesPlayed, getPosition(), bytesCopied, bytesReturned)); 634 queuedbuffers--; 635 636 whdr->dwFlags &= ~WHDR_INQUEUE; 637 whdr->dwFlags |= WHDR_DONE; 638 whdr->reserved = 0; 639 640 if (prevhdr == NULL) 641 wavehdr = whdr->lpNext; 642 else prevhdr->lpNext = whdr->lpNext; 643 644 whdr->lpNext = NULL; 645 646 bytesReturned += whdr->dwBufferLength; 647 648 wmutex.leave(); 649 callback(WOM_DONE, (ULONG)whdr, 0); 650 wmutex.enter(); 652 651 653 652 prevhdr = whdr; … … 655 654 } 656 655 657 if (wavehdr == NULL) {658 // last buffer played -> no new ones -> return now656 if (wavehdr == NULL) { 657 // last buffer played -> no new ones -> return now 659 658 dprintf(("WINMM: WaveOut handler LAST BUFFER PLAYED! state %s (play %d (%d), cop %d, ret %d)", (State == STATE_PLAYING) ? "playing" : "stopped", bytesPlayed, getPosition(), bytesCopied, bytesReturned)); 660 if (getPosition() > bytesPlayed) {659 if (getPosition() > bytesPlayed) { 661 660 dprintf(("WINMM: WaveOut handler UNDERRUN! state %s", (State == STATE_PLAYING) ? "playing" : "stopped")); 662 661 //save current position for when we continue later … … 671 670 writeBuffer(); 672 671 673 sendbuffer:674 672 wmutex.leave(); 675 673 … … 677 675 dprintf2(("WINMM: handler transfer buffer %d", pBuffer - MixBuffer)); 678 676 USHORT selTIB = RestoreOS2FS(); // save current FS selector 679 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, pBuffer, 1);677 pmixWriteProc(mixHandle, pBuffer, 1); 680 678 SetFS(selTIB); // switch back to the saved FS selector 681 679 682 680 dprintf2(("WINMM: handler DONE")); 683 681 } 684 /******************************************************************************/ 685 /******************************************************************************/ 682 683 /******************************************************************************/ 684 /******************************************************************************/ 685 686 686 void DartWaveOut::writeBuffer() 687 687 { 688 688 ULONG buflength; 689 689 690 if (!fUnderrun && State == STATE_PLAYING && wavehdr == NULL && curFillBuf == curPlayBuf) {690 if (!fUnderrun && State == STATE_PLAYING && wavehdr == NULL && curFillBuf == curPlayBuf) { 691 691 dprintf2(("writeBuffer: no more room for more audio data")); 692 692 return; //no room left 693 693 } 694 694 695 if (curhdr == NULL)695 if (curhdr == NULL) 696 696 curhdr = wavehdr; 697 697 698 while (curhdr && (curhdr->reserved == WHDR_DONE)) {698 while (curhdr && (curhdr->reserved == WHDR_DONE)) { 699 699 curhdr = curhdr->lpNext; 700 700 } 701 701 702 if (curhdr == NULL) {702 if (curhdr == NULL) 703 703 return; //no unprocessed buffers left 704 } 705 706 if(State == STATE_PLAYING && curFillBuf == curPlayBuf) 704 705 if (State == STATE_PLAYING && curFillBuf == curPlayBuf) 707 706 { 708 707 dprintf(("curFillBuf == curPlayBuf; no more room (%d,%d)", curFillBuf, curPlayBuf)); … … 712 711 dprintf2(("WINMM: handler cur (%d,%d), fill (%d,%d)\n", curPlayBuf, curPlayPos, curFillBuf, curFillPos)); 713 712 714 while (curhdr) {713 while (curhdr) { 715 714 buflength = min((ULONG)MixBuffer[curFillBuf].ulBufferLength - curPlayPos, 716 715 (ULONG)curhdr->dwBufferLength - curFillPos); … … 727 726 bytesCopied += buflength; 728 727 729 if (curFillPos == curhdr->dwBufferLength) {728 if (curFillPos == curhdr->dwBufferLength) { 730 729 dprintf2(("Buffer %d done ptr %x size %d %x %x %x %x %x %x", curFillBuf, curhdr->lpData, curhdr->dwBufferLength, curhdr->dwBytesRecorded, curhdr->dwUser, curhdr->dwFlags, curhdr->dwLoops, curhdr->lpNext, curhdr->reserved)); 731 730 … … 733 732 curhdr->reserved = WHDR_DONE; 734 733 //search for next unprocessed buffer 735 while (curhdr && (curhdr->reserved == WHDR_DONE))734 while (curhdr && (curhdr->reserved == WHDR_DONE)) 736 735 curhdr = curhdr->lpNext; 737 736 } 738 if (curPlayPos == MixBuffer[curFillBuf].ulBufferLength) {737 if (curPlayPos == MixBuffer[curFillBuf].ulBufferLength) { 739 738 curPlayPos = 0; 740 739 741 if (++curFillBuf == PREFILLBUF_DART) {740 if (++curFillBuf >= ulBufCount) 742 741 curFillBuf = 0; 743 } 744 if (curFillBuf == curPlayBuf)742 743 if (curFillBuf == curPlayBuf) 745 744 break; //no more room left 746 745 } 747 746 } 748 747 } 749 /******************************************************************************/ 750 /******************************************************************************/ 748 749 /******************************************************************************/ 750 /******************************************************************************/ 751 751 752 LONG APIENTRY WaveOutHandler(ULONG ulStatus, 752 753 PMCI_MIX_BUFFER pBuffer, … … 759 760 760 761 ptib2 = (PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)); 761 if (ptib2 && HIBYTE(ptib2->tib2_ulpri) != PRTYC_TIMECRITICAL &&762 if (ptib2 && HIBYTE(ptib2->tib2_ulpri) != PRTYC_TIMECRITICAL && 762 763 LOBYTE(ptib2->tib2_ulpri) != PRTYD_MAXIMUM) 763 764 { … … 765 766 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0); 766 767 } 767 if (pBuffer && pBuffer->ulUserParm)768 if (pBuffer && pBuffer->ulUserParm) 768 769 { 769 770 dwave = (DartWaveOut *)pBuffer->ulUserParm; 770 771 dwave->handler(ulStatus, pBuffer, ulFlags); 771 772 } 772 return(TRUE); 773 } 774 775 /******************************************************************************/ 776 /******************************************************************************/ 777 MMRESULT DartWaveOut::setVolume(ULONG ulVol) 778 { 779 ULONG ulVolR = (((ulVol & 0xffff0000) >> 16 )*100)/0xFFFF; // Right Volume 780 ULONG ulVolL = ((ulVol& 0x0000ffff)*100)/0xFFFF; // Left Volume 781 MCI_SET_PARMS msp = {0}; 782 783 dprintf(("DartWaveOut::setVolume %d %d", ulVolL, ulVolR)); 784 volume = ulVol; 785 786 // PD: My card (ESS 1868 PnP) driver can't change only 787 // one channel Left or Right :-( 788 // 789 #ifdef GOOD_AUDIO_CARD_DRIVER 790 791 msp.ulAudio = MCI_SET_AUDIO_LEFT; 792 msp.ulLevel = ulVolL; 793 794 mymciSendCommand(DeviceId, MCI_SET, 795 MCI_WAIT | MCI_SET_AUDIO | MCI_SET_VOLUME, 796 &msp, 0); 797 798 msp.ulAudio = MCI_SET_AUDIO_RIGHT; 799 msp.ulLevel = ulVolR; 800 801 #else 802 msp.ulAudio = MCI_SET_AUDIO_ALL; 803 msp.ulLevel = max(ulVolR,ulVolL); 804 #endif 805 806 mymciSendCommand(DeviceId, MCI_SET, 807 MCI_WAIT | MCI_SET_AUDIO | MCI_SET_VOLUME, 808 &msp, 0); 809 return 0; 810 } 811 /******************************************************************************/ 812 /******************************************************************************/ 813 773 return TRUE; 774 } 775 776 /******************************************************************************/ 777 /******************************************************************************/ 778 -
trunk/src/winmm/waveoutdart.h
r21349 r21358 8 8 * Project Odin Software License can be found in LICENSE.TXT 9 9 */ 10 10 11 #ifndef __DWAVEOUT_H__ 11 12 #define __DWAVEOUT_H__ 12 13 13 14 #include "waveoutbase.h" 14 15 #define PREFILLBUF_DART 6416 #define DART_BUFSIZE 409617 15 18 16 #ifdef OS2_ONLY … … 29 27 #endif 30 28 29 // this should be defined in some #included .h file, but it isn't 30 typedef LONG (APIENTRY MIXERPROC)(ULONG ulHandle, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags); 31 31 32 class DartWaveOut : public WaveOut 32 33 { 33 34 public: 34 DartWaveOut(LPWAVEFORMATEX pwfx, DWORD fdwOpen, ULONG nCallback, ULONG dwInstance); 35 virtual ~DartWaveOut(); 35 DartWaveOut(LPWAVEFORMATEX pwfx, DWORD fdwOpen, 36 ULONG nCallback, ULONG dwInstance); 37 virtual ~DartWaveOut(); 36 38 37 virtual MMRESULT write(LPWAVEHDR pwh, UINT cbwh); 38 virtual MMRESULT pause(); 39 virtual MMRESULT stop(); 40 virtual MMRESULT resume(); 41 virtual MMRESULT setVolume(ULONG ulVol); 42 virtual MMRESULT reset(); 43 virtual ULONG getPosition(); 44 45 static BOOL queryFormat(ULONG formatTag, ULONG nChannels, 46 ULONG nSamplesPerSec, ULONG sampleSize); 39 virtual MMRESULT open(); 40 virtual MMRESULT write(LPWAVEHDR pwh, UINT cbwh); 41 virtual MMRESULT pause(); 42 virtual MMRESULT stop(); 43 virtual MMRESULT resume(); 44 virtual MMRESULT setVolume(ULONG ulVol); 45 virtual MMRESULT reset(); 46 virtual ULONG getPosition(); 47 47 48 48 protected: 49 static void mciError(ULONG ulError); 50 void Init(LPWAVEFORMATEX pwfx); 51 void handler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags); 49 MMRESULT initBuffers(); 50 void writeBuffer(); 51 static void mciError(ULONG rc); 52 void handler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags); 52 53 53 54 private: 54 void writeBuffer(); 55 USHORT DeviceId; 56 BOOL fMixerSetup; 57 BOOL fUnderrun; 58 int curFillBuf; 59 int curPlayBuf; 60 ULONG curFillPos; 61 ULONG curPlayPos; 62 ULONG ulBufSize; 63 ULONG ulBufCount; 64 ULONG bytesPlayed; 65 ULONG bytesCopied; 66 ULONG bytesReturned; 67 ULONG ulUnderrunBase; 68 ULONG mixHandle; 69 WAVEHDR * curhdr; 70 MIXERPROC * pmixWriteProc; 71 MCI_MIX_BUFFER * MixBuffer; 72 MCI_BUFFER_PARMS * BufferParms; 55 73 56 USHORT DeviceId; 57 ULONG ulBufferCount; /* Current file buffer */ 58 ULONG ulBufSize; 59 60 MCI_MIX_BUFFER *MixBuffer; /* Device buffers */ 61 MCI_MIXSETUP_PARMS *MixSetupParms; /* Mixer parameters */ 62 MCI_BUFFER_PARMS *BufferParms; /* Device buffer parms */ 63 64 int curPlayBuf, curFillBuf; 65 ULONG curFillPos, curPlayPos; //fillpos == pos in os2 mix buffer, bufpos == pos in win buffer 66 67 BOOL fMixerSetup; 68 BOOL fUnderrun; 69 ULONG ulUnderrunBase; 70 71 #ifndef _OS2WIN_H 72 friend LONG APIENTRY WaveOutHandler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags); 73 #endif 74 friend LONG APIENTRY WaveOutHandler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, 75 ULONG ulFlags); 74 76 }; 75 77 -
trunk/src/winmm/waveoutdaud.cpp
r9979 r21358 12 12 */ 13 13 14 15 /**************************************************************************** 16 * Includes * 17 ****************************************************************************/ 18 19 14 /******************************************************************************/ 15 // Includes 16 /******************************************************************************/ 20 17 21 18 #define INCL_BASE … … 57 54 : WaveOut(pwfx, fdwOpen, nCallback, dwInstance) 58 55 { 56 hSem = 0; 57 hDAudioDrv = 0; 58 hThread = 0; 59 dwThreadID = 0; 60 bytesReturned = 0; 61 fUnderrun = 0; 62 } 63 /******************************************************************************/ 64 /******************************************************************************/ 65 DAudioWaveOut::~DAudioWaveOut() 66 { 67 DAUDIO_CMD cmd; 68 69 if(hThread) 70 callback(WOM_CLOSE, 0, 0); 71 72 if(hDAudioDrv) { 73 cmd.Thread.hSemaphore = hSem; 74 sendIOCTL(DAUDIO_DEREGISTER_THREAD, &cmd); 75 sendIOCTL(DAUDIO_CLOSE, &cmd); 76 DosClose(hDAudioDrv); 77 hDAudioDrv = 0; 78 } 79 if(hSem) { 80 DosPostEventSem(hSem); 81 DosCloseEventSem(hSem); 82 } 83 } 84 /******************************************************************************/ 85 /******************************************************************************/ 86 MMRESULT DAudioWaveOut::open() 87 { 59 88 APIRET rc; 60 89 ULONG action; … … 64 93 ULONG ParmLength = 0, DataLength; 65 94 66 fUnderrun = FALSE; 67 hSem = 0; 68 69 dprintf(("DAudioWaveOut::DAudioWaveOut")); 95 dprintf(("DAudioWaveOut::open")); 70 96 71 97 rc = DosOpen(szPDDName, &hDAudioDrv, &action, 0, … … 75 101 if(rc) { 76 102 dprintf(("DosOpen failed with error %d\n", rc)); 77 ulError = MMSYSERR_NODRIVER; 78 goto fail; 103 return MMSYSERR_NODRIVER; 79 104 } 80 105 81 106 DataLength = sizeof(init); 82 107 83 init.lSRate = pwfx->nSamplesPerSec;84 init.lBitsPerSRate = pwfx->wBitsPerSample;85 init.sChannels = pwfx->nChannels;108 init.lSRate = SampleRate; 109 init.lBitsPerSRate = BitsPerSample; 110 init.sChannels = nChannels; 86 111 init.sMode = PCM; //todo!! 87 112 … … 90 115 if(rc) { 91 116 dprintf(("DosDevIOCtl failed with error %d\n", rc)); 92 ulError = MMSYSERR_NODRIVER; 93 goto fail; 117 return MMSYSERR_NODRIVER; 94 118 } 95 119 if(init.sReturnCode != 0) { 96 120 dprintf(("init.sReturnCode = %d\n", init.sReturnCode)); 97 ulError = MMSYSERR_NODRIVER; 98 goto fail; 121 return MMSYSERR_NODRIVER; 99 122 } 100 123 … … 102 125 if(rc) { 103 126 dprintf(("DosCreateEventSem failed with error %d\n", rc)); 104 ulError = MMSYSERR_NODRIVER; 105 goto fail; 127 return MMSYSERR_NODRIVER; 106 128 } 107 129 cmd.Thread.hSemaphore = hSem; … … 110 132 if(rc) { 111 133 dprintf(("DosDevIOCtl failed with error %d\n", rc)); 112 ulError = MMSYSERR_NODRIVER; 113 goto fail; 134 return MMSYSERR_NODRIVER; 114 135 } 115 136 116 137 hThread = CreateThread(NULL, 0x4000, (LPTHREAD_START_ROUTINE)DAudioThreadHandler, 117 138 (LPVOID)this, 0, &dwThreadID); 139 if (!hThread) { 140 dprintf(("CreateThread failed\n")); 141 return MMSYSERR_NODRIVER; 142 } 118 143 119 144 setVolume(volume); 120 121 if(!ulError) 122 callback(WOM_OPEN, 0, 0); 123 124 fail: 125 return; 126 } 127 /******************************************************************************/ 128 /******************************************************************************/ 129 DAudioWaveOut::~DAudioWaveOut() 130 { 131 DAUDIO_CMD cmd; 132 133 if(!ulError) 134 callback(WOM_CLOSE, 0, 0); 135 136 if(hDAudioDrv) { 137 cmd.Thread.hSemaphore = hSem; 138 sendIOCTL(DAUDIO_DEREGISTER_THREAD, &cmd); 139 sendIOCTL(DAUDIO_CLOSE, &cmd); 140 DosClose(hDAudioDrv); 141 hDAudioDrv = 0; 142 } 143 if(hSem) { 144 DosPostEventSem(hSem); 145 DosCloseEventSem(hSem); 146 } 145 callback(WOM_OPEN, 0, 0); 146 147 return(MMSYSERR_NOERROR); 147 148 } 148 149 /******************************************************************************/ … … 235 236 fUnderrun = FALSE; 236 237 237 bytes Played = bytesCopied = bytesReturned = 0;238 bytesReturned = 0; 238 239 239 240 return rc; … … 271 272 fUnderrun = FALSE; 272 273 273 bytes Played = bytesCopied = bytesReturned = 0;274 bytesReturned = 0; 274 275 queuedbuffers = 0; 275 276 … … 409 410 LPWAVEHDR whdr = wavehdr; 410 411 411 dprintf2(("WINMM: handler buf %X done (play %d /%d, cop %d, ret %d)", whdr, bytesPlayed, getPosition(), bytesCopied, bytesReturned));412 dprintf2(("WINMM: handler buf %X done (play %d, ret %d)", whdr, getPosition(), bytesReturned)); 412 413 413 414 if(State != STATE_PLAYING || whdr == NULL) -
trunk/src/winmm/waveoutdaud.h
r8568 r21358 8 8 * Project Odin Software License can be found in LICENSE.TXT 9 9 */ 10 10 11 #ifndef __DWAVEOUTEX_H__ 11 12 #define __DWAVEOUTEX_H__ … … 24 25 { 25 26 public: 26 DAudioWaveOut(LPWAVEFORMATEX pwfx, ULONG fdwOpen, ULONG nCallback, ULONG dwInstance); 27 virtual ~DAudioWaveOut(); 27 DAudioWaveOut(LPWAVEFORMATEX pwfx, ULONG fdwOpen, 28 ULONG nCallback, ULONG dwInstance); 29 virtual ~DAudioWaveOut(); 28 30 29 virtual MMRESULT write(LPWAVEHDR pwh, UINT cbwh); 30 virtual MMRESULT pause(); 31 virtual MMRESULT stop(); 32 virtual MMRESULT resume(); 33 virtual MMRESULT setVolume(ULONG ulVol); 34 virtual MMRESULT reset(); 35 virtual ULONG getPosition(); 31 virtual MMRESULT open(); 32 virtual MMRESULT write(LPWAVEHDR pwh, UINT cbwh); 33 virtual MMRESULT pause(); 34 virtual MMRESULT stop(); 35 virtual MMRESULT resume(); 36 virtual MMRESULT setVolume(ULONG ulVol); 37 virtual MMRESULT reset(); 38 virtual ULONG getPosition(); 36 39 37 static BOOL queryFormat(ULONG formatTag, ULONG nChannels, 38 ULONG nSamplesPerSec, ULONG sampleSize); 39 40 41 static BOOL isDirectAudioAvailable(); 40 static BOOL queryFormat(ULONG formatTag, ULONG nChannels, 41 ULONG nSamplesPerSec, ULONG sampleSize); 42 static BOOL isDirectAudioAvailable(); 42 43 43 44 protected: 44 45 45 46 private: 46 BOOLhandler();47 MMRESULTsendIOCTL(ULONG cmd, DAUDIO_CMD *pDataPacket);47 BOOL handler(); 48 MMRESULT sendIOCTL(ULONG cmd, DAUDIO_CMD *pDataPacket); 48 49 49 HEV hSem; 50 HEV hSem; 51 HFILE hDAudioDrv; 52 HANDLE hThread; 53 DWORD dwThreadID; 54 ULONG bytesReturned; 55 BOOL fUnderrun; 50 56 51 ULONG bytesPlayed, bytesReturned; 52 int queuedbuffers; 53 54 BOOL fUnderrun; 55 HANDLE hThread; 56 DWORD dwThreadID; 57 58 HFILE hDAudioDrv; 59 60 friend DWORD WIN32API DAudioThreadHandler(LPVOID pUserData); 57 friend DWORD WIN32API DAudioThreadHandler(LPVOID pUserData); 61 58 }; 62 59 -
trunk/src/winmm/winmm.mak
r21342 r21358 24 24 # 25 25 !include ../../makefile.inc 26 27 26 28 27 # … … 56 55 $(OBJDIR)\joyos2.obj \ 57 56 $(OBJDIR)\winmmrsrc.obj \ 57 $(OBJDIR)\waveoutflash.obj \ 58 58 !ifdef DEBUG 59 59 $(OBJDIR)\dbgwrap.obj \
Note:
See TracChangeset
for help on using the changeset viewer.