- Timestamp:
- Mar 19, 2001, 8:28:39 PM (24 years ago)
- Location:
- trunk/src/winmm
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/winmm/dbglocal.cpp
r5272 r5334 1 /* $Id: dbglocal.cpp,v 1. 3 2001-02-27 21:13:59sandervl Exp $ */1 /* $Id: dbglocal.cpp,v 1.4 2001-03-19 19:28:37 sandervl Exp $ */ 2 2 3 3 /* … … 16 16 #include "dbglocal.h" 17 17 18 USHORT DbgEnabled[DBG_MAXFILES]; 18 USHORT DbgEnabled[DBG_MAXFILES] = {0}; 19 USHORT DbgEnabledLvl2[DBG_MAXFILES] = {0}; 20 19 21 char *DbgFileNames[DBG_MAXFILES] = 20 22 { … … 45 47 { 46 48 char *envvar = getenv(DBG_ENVNAME); 49 char *envvar2= getenv(DBG_ENVNAME_LVL2); 47 50 char *dbgvar; 48 51 int i; … … 69 72 DbgEnabled[i] = 0; 70 73 } 71 else 74 else 72 75 if(*(dbgvar-1) == '+') { 73 DbgEnabled[i] = 1; 74 } 76 DbgEnabled[i] = 1; 77 } 78 } 79 } 80 if(envvar2) { 81 dbgvar = strstr(envvar2, "dll"); 82 if(dbgvar) { 83 if(*(dbgvar-1) == '+') { 84 for(i=0;i<DBG_MAXFILES;i++) { 85 DbgEnabledLvl2[i] = 1; 86 } 87 } 88 } 89 for(i=0;i<DBG_MAXFILES;i++) { 90 dbgvar = strstr(envvar2, DbgFileNames[i]); 91 if(dbgvar) { 92 if(*(dbgvar-1) == '-') { 93 DbgEnabledLvl2[i] = 0; 94 } 95 else 96 if(*(dbgvar-1) == '+') { 97 DbgEnabledLvl2[i] = 1; 98 } 99 } 75 100 } 76 101 } -
trunk/src/winmm/dbglocal.h
r5272 r5334 1 /* $Id: dbglocal.h,v 1. 3 2001-02-27 21:13:59sandervl Exp $ */1 /* $Id: dbglocal.h,v 1.4 2001-03-19 19:28:38 sandervl Exp $ */ 2 2 3 3 /* … … 18 18 19 19 #define DBG_ENVNAME "dbg_winmm" 20 #define DBG_ENVNAME_LVL2 "dbg_winmm_lvl2" 20 21 21 22 #define DBG_os2timer 0 … … 42 43 43 44 extern USHORT DbgEnabled[DBG_MAXFILES]; 45 extern USHORT DbgEnabledLvl2[DBG_MAXFILES]; 44 46 45 47 #ifdef dprintf … … 48 50 49 51 #define dprintf(a) if(DbgEnabled[DBG_LOCALLOG] == 1) WriteLog a 52 53 #ifdef dprintf2 54 #undef dprintf2 55 #endif 56 57 #define dprintf2(a) if(DbgEnabledLvl2[DBG_LOCALLOG] == 1) WriteLog a 50 58 51 59 #else -
trunk/src/winmm/dwavein.cpp
r5272 r5334 1 /* $Id: dwavein.cpp,v 1. 1 2001-02-27 21:13:59sandervl Exp $ */1 /* $Id: dwavein.cpp,v 1.2 2001-03-19 19:28:38 sandervl Exp $ */ 2 2 3 3 /* … … 54 54 /******************************************************************************/ 55 55 /******************************************************************************/ 56 DartWaveIn::DartWaveIn(LPWAVEFORMATEX pwfx, ULONG nCallback, ULONG dwInstance , USHORT usSel)56 DartWaveIn::DartWaveIn(LPWAVEFORMATEX pwfx, ULONG nCallback, ULONG dwInstance) 57 57 { 58 58 Init(pwfx); 59 59 60 60 mthdCallback = (LPDRVCALLBACK)nCallback; // callback function 61 selCallback = usSel; // callback win32 tib selector62 61 this->dwInstance = dwInstance; 63 62 fOverrun = FALSE; … … 82 81 { 83 82 USHORT selTIB = GetFS(); // save current FS selector 83 USHORT selCallback; 84 84 85 85 dprintf(("WINMM:DartWaveIn::callback(HDRVR h=%08xh, UINT uMessage=%08xh, DWORD dwUser=%08xh, DWORD dw1=%08xh, DWORD dw2=%08xh)\n", 86 86 h, uMessage, dwUser, dw1, dw2)); 87 87 88 if (selCallback != 0) 89 SetFS(selCallback); // switch to callback win32 tib selector (stored in waveInOpen) 90 else 91 dprintf(("WINMM:DartWaveIn::callback - selCallback is invalid")); 92 93 //@@@PH 1999/12/28 Shockwave Flashes seem to make assumptions on a 94 // specific stack layout. Do we have the correct calling convention here? 95 mthdCallback(h,uMessage,dwUser,dw1,dw2); 96 SetFS(selTIB); // switch back to the saved FS selector 88 selCallback = GetProcessTIBSel(); 89 90 //TODO: may not be very safe. perhaps we should allocate a new TIB for the DART thread or let another thread do the actual callback 91 if(selCallback) 92 { 93 SetFS(selCallback); // switch to callback win32 tib selector (stored in waveOutOpen) 94 95 //@@@PH 1999/12/28 Shockwave Flashes seem to make assumptions on a 96 // specific stack layout. Do we have the correct calling convention here? 97 mthdCallback(h,uMessage,dwUser,dw1,dw2); 98 SetFS(selTIB); // switch back to the saved FS selector 99 } 100 else { 101 dprintf(("WARNING: no valid selector of main thread available (process exiting); skipping waveout notify")); 102 } 103 dprintf(("WINMM:DartWaveOut::callback returned")); 97 104 } 98 105 /******************************************************************************/ … … 109 116 mthdCallback = NULL; 110 117 hwndCallback = 0; 111 selCallback = 0;112 118 dwInstance = 0; 113 119 ulError = 0; 114 selCallback = 0;115 120 State = STATE_STOPPED; 116 121 … … 450 455 { 451 456 MCI_GENERIC_PARMS Params; 452 453 dprintf(("DartWaveIn::reset %s", (State == STATE_RECORDING) ? "recording" : "stopped")); 454 if(State != STATE_RECORDING) 457 LPWAVEHDR tmpwavehdr; 458 459 dprintf(("DartWaveIn::reset %s", (State == STATE_RECORDING) ? "recording" : "stopped")); 460 if(State != STATE_RECORDING) 455 461 return(MMSYSERR_HANDLEBUSY); 456 462 457 memset(&Params, 0, sizeof(Params));458 459 // Stop recording460 mciSendCommand(DeviceId, MCI_STOP, MCI_WAIT, (PVOID)&Params, 0);461 462 dprintf(("Nr of threads blocked on mutex = %d\n", wmutex->getNrBlocked()));463 464 wmutex->enter(VMUTEX_WAIT_FOREVER);465 while(wavehdr)466 {463 memset(&Params, 0, sizeof(Params)); 464 465 // Stop recording 466 mciSendCommand(DeviceId, MCI_STOP, MCI_WAIT, (PVOID)&Params, 0); 467 468 dprintf(("Nr of threads blocked on mutex = %d\n", wmutex->getNrBlocked())); 469 470 wmutex->enter(VMUTEX_WAIT_FOREVER); 471 while(wavehdr) 472 { 467 473 wavehdr->dwFlags |= WHDR_DONE; 468 474 wavehdr->dwFlags &= ~WHDR_INQUEUE; 469 wavehdr = wavehdr->lpNext; 470 wavehdr->lpNext = NULL; 475 tmpwavehdr = wavehdr; 476 wavehdr = wavehdr->lpNext; 477 tmpwavehdr->lpNext = NULL; 471 478 472 479 wmutex->leave(); 473 480 if(mthdCallback) { 474 callback((ULONG)this, WIM_DATA, dwInstance, (ULONG) wavehdr, 0);481 callback((ULONG)this, WIM_DATA, dwInstance, (ULONG)tmpwavehdr, 0); 475 482 } 476 483 else 477 484 if(hwndCallback) { 478 485 dprintf(("Callback (msg) for buffer %x", wavehdr)); 479 PostMessageA(hwndCallback, WIM_DATA, (WPARAM)this, (ULONG) wavehdr);486 PostMessageA(hwndCallback, WIM_DATA, (WPARAM)this, (ULONG)tmpwavehdr); 480 487 } 481 488 wmutex->enter(VMUTEX_WAIT_FOREVER); 482 }483 wavehdr = NULL;484 State = STATE_STOPPED;485 fOverrun = FALSE;486 487 wmutex->leave();488 return(MMSYSERR_NOERROR);489 } 490 wavehdr = NULL; 491 State = STATE_STOPPED; 492 fOverrun = FALSE; 493 494 wmutex->leave(); 495 return(MMSYSERR_NOERROR); 489 496 } 490 497 /******************************************************************************/ … … 495 502 496 503 wmutex->enter(VMUTEX_WAIT_FOREVER); 497 pwh->lpNext = NULL;504 pwh->lpNext = NULL; 498 505 pwh->dwBytesRecorded = 0; 499 506 if(wavehdr) { … … 585 592 { 586 593 #ifdef DEBUG 587 char szError[256] = "";588 589 mciGetErrorString(ulError, szError, sizeof(szError));590 dprintf(("WINMM: DartWaveIn: %s\n", szError));594 char szError[256] = ""; 595 596 mciGetErrorString(ulError, szError, sizeof(szError)); 597 dprintf(("WINMM: DartWaveIn: %s\n", szError)); 591 598 #endif 592 599 } … … 595 602 BOOL DartWaveIn::find(DartWaveIn *dwave) 596 603 { 597 DartWaveIn *curwave = wavein; 598 599 while(curwave) { 600 if(dwave == curwave) { 601 return(TRUE); 602 } 603 curwave = curwave->next; 604 } 605 606 #ifdef DEBUG 607 // WriteLog("WINMM:DartWaveIn not found!\n"); 608 #endif 609 return(FALSE); 604 DartWaveIn *curwave = wavein; 605 606 while(curwave) { 607 if(dwave == curwave) { 608 return(TRUE); 609 } 610 curwave = curwave->next; 611 } 612 613 dprintf2(("WINMM:DartWaveIn not found!")); 614 return(FALSE); 610 615 } 611 616 /******************************************************************************/ … … 619 624 WAVEHDR *whdr, *prevhdr = NULL; 620 625 621 #ifdef DEBUG1 622 dprintf(("WINMM: DartWaveIn handler %x\n", pBuffer)); 623 #endif 626 dprintf2(("WINMM: DartWaveIn handler %x\n", pBuffer)); 624 627 if(ulFlags == MIX_STREAM_ERROR) { 625 628 if(ulStatus == ERROR_DEVICE_OVERRUN) { … … 627 630 if(State == STATE_RECORDING) { 628 631 fOverrun = TRUE; 629 stop(); //out of buffers, so pauseplayback632 stop(); //out of buffers, so stop playback 630 633 } 631 634 return; … … 644 647 return; 645 648 } 646 647 #ifdef DEBUG1648 dprintf(("WINMM: DartWaveIn handler cur (%d,%d), fill (%d,%d)\n", curPlayBuf, curPlayPos, curFillBuf, curFillPos));649 #endif650 649 651 650 buflength = pBuffer->ulBufferLength; … … 663 662 buflength -= bytestocopy; 664 663 665 if(wavehdr->dwBytesRecorded == wavehdr->dwBufferLength) { 666 #ifdef DEBUG1 667 dprintf(("WINMM: DartWaveIn handler buf %X done\n", whdr)); 668 #endif 664 if(wavehdr->dwBytesRecorded == wavehdr->dwBufferLength) 665 { 666 dprintf2(("WINMM: DartWaveIn handler buf %X done\n", whdr)); 669 667 whdr->dwFlags |= WHDR_DONE; 670 668 whdr->dwFlags &= ~WHDR_INQUEUE; … … 675 673 676 674 if(mthdCallback) { 677 callback((ULONG)this, WIM_DATA, dwInstance, (ULONG)whdr, 0);675 callback((ULONG)this, WIM_DATA, dwInstance, (ULONG)whdr, whdr->dwBytesRecorded); 678 676 } 679 677 else 680 678 if(hwndCallback) { 681 682 683 679 dprintf(("Callback (msg) for buffer %x", whdr)); 680 PostMessageA(hwndCallback, WIM_DATA, (WPARAM)this, (ULONG)whdr); 681 } 684 682 wmutex->enter(VMUTEX_WAIT_FOREVER); 685 683 } … … 701 699 ULONG ulFlags) 702 700 { 703 // PTIB ptib;704 // PPIB ppib;705 // DosGetInfoBlocks(&ptib, &ppib);706 // dprintf(("WaveInHandler: thread %d prio %X", ptib->tib_ptib2->tib2_ultid, ptib->tib_ptib2->tib2_ulpri));707 708 701 DartWaveIn *dwave; 709 702 -
trunk/src/winmm/dwavein.h
r5272 r5334 1 /* $Id: dwavein.h,v 1. 1 2001-02-27 21:13:59sandervl Exp $ */1 /* $Id: dwavein.h,v 1.2 2001-03-19 19:28:38 sandervl Exp $ */ 2 2 3 3 /* … … 31 31 { 32 32 public: 33 DartWaveIn(LPWAVEFORMATEX pwfx, ULONG nCallback, ULONG dwInstance , USHORT usSel);33 DartWaveIn(LPWAVEFORMATEX pwfx, ULONG nCallback, ULONG dwInstance); 34 34 DartWaveIn(LPWAVEFORMATEX pwfx, HWND hwndCallback); 35 35 DartWaveIn(LPWAVEFORMATEX pwfx); … … 77 77 // callback interface 78 78 LPDRVCALLBACK mthdCallback; // pointer to win32 routine for the callback 79 USHORT selCallback; // the win32 tib selector for the callback (saved at waveOutOpen)80 79 void callback(HDRVR h, UINT uMessage, DWORD dwUser, DWORD dw1, DWORD dw2); 81 80 HWND hwndCallback; -
trunk/src/winmm/dwaveout.cpp
r5272 r5334 1 /* $Id: dwaveout.cpp,v 1.3 1 2001-02-27 21:13:59sandervl Exp $ */1 /* $Id: dwaveout.cpp,v 1.32 2001-03-19 19:28:38 sandervl Exp $ */ 2 2 3 3 /* … … 56 56 /******************************************************************************/ 57 57 /******************************************************************************/ 58 DartWaveOut::DartWaveOut(LPWAVEFORMATEX pwfx, ULONG nCallback, ULONG dwInstance , USHORT usSel)58 DartWaveOut::DartWaveOut(LPWAVEFORMATEX pwfx, ULONG nCallback, ULONG dwInstance) 59 59 { 60 60 Init(pwfx); 61 61 62 mthdCallback = (LPDRVCALLBACK)nCallback; // callback function 63 selCallback = usSel; // callback win32 tib selector 62 mthdCallback = (LPDRVCALLBACK)nCallback; // callback function 64 63 this->dwInstance = dwInstance; 65 64 fUnderrun = FALSE; 66 65 67 66 if(!ulError) 68 callback((ULONG)this, WOM_OPEN, dwInstance, 0, 0);67 callback((ULONG)this, WOM_OPEN, dwInstance, 0, 0); 69 68 } 70 69 /******************************************************************************/ … … 77 76 78 77 if(!ulError) 79 PostMessageA(hwndCallback, WOM_OPEN, 0, 0);78 PostMessageA(hwndCallback, WOM_OPEN, 0, 0); 80 79 } 81 80 /******************************************************************************/ … … 83 82 void DartWaveOut::callback(HDRVR h, UINT uMessage, DWORD dwUser, DWORD dw1, DWORD dw2) 84 83 { 85 USHORT selTIB = GetFS(); // save current FS selector 86 87 dprintf(("WINMM:DartWaveOut::callback(HDRVR h=%08xh, UINT uMessage=%08xh, DWORD dwUser=%08xh, DWORD dw1=%08xh, DWORD dw2=%08xh)\n", 84 USHORT selTIB = GetFS(); // save current FS selector 85 USHORT selCallback; 86 87 dprintf(("WINMM:DartWaveOut::callback(HDRVR h=%08xh, UINT uMessage=%08xh, DWORD dwUser=%08xh, DWORD dw1=%08xh, DWORD dw2=%08xh)\n", 88 88 h, 89 89 uMessage, … … 92 92 dw2)); 93 93 94 if (selCallback != 0) 95 SetFS(selCallback); // switch to callback win32 tib selector (stored in waveOutOpen) 96 else 97 dprintf(("WINMM:DartWaveOut::callback - selCallback is invalid")); 98 99 //@@@PH 1999/12/28 Shockwave Flashes seem to make assumptions on a 100 // specific stack layout. Do we have the correct calling convention here? 101 mthdCallback(h,uMessage,dwUser,dw1,dw2); 102 SetFS(selTIB); // switch back to the saved FS selector 94 selCallback = GetProcessTIBSel(); 95 96 //TODO: may not be very safe. perhaps we should allocate a new TIB for the DART thread or let another thread do the actual callback 97 if(selCallback) 98 { 99 SetFS(selCallback); // switch to callback win32 tib selector (stored in waveOutOpen) 100 101 //@@@PH 1999/12/28 Shockwave Flashes seem to make assumptions on a 102 // specific stack layout. Do we have the correct calling convention here? 103 mthdCallback(h,uMessage,dwUser,dw1,dw2); 104 SetFS(selTIB); // switch back to the saved FS selector 105 } 106 else { 107 dprintf(("WARNING: no valid selector of main thread available (process exiting); skipping waveout notify")); 108 } 109 dprintf(("WINMM:DartWaveOut::callback returned")); 103 110 } 104 111 /******************************************************************************/ 105 112 /******************************************************************************/ 106 113 void DartWaveOut::Init(LPWAVEFORMATEX pwfx) 114 { 115 MCI_GENERIC_PARMS GenericParms; 116 MCI_AMP_OPEN_PARMS AmpOpenParms; 117 APIRET rc; 118 119 curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0; 120 readPos = writePos = 0; 121 122 fMixerSetup = FALSE; 123 next = NULL; 124 wavehdr = NULL; 125 curhdr = NULL; 126 mthdCallback = NULL; 127 hwndCallback = 0; 128 dwInstance = 0; 129 ulError = 0; 130 volume = defvolume; 131 State = STATE_STOPPED; 132 133 MixBuffer = (MCI_MIX_BUFFER *)malloc(PREFILLBUF_DART*sizeof(MCI_MIX_BUFFER)); 134 MixSetupParms = (MCI_MIXSETUP_PARMS *)malloc(sizeof(MCI_MIXSETUP_PARMS)); 135 BufferParms = (MCI_BUFFER_PARMS *)malloc(sizeof(MCI_BUFFER_PARMS)); 136 137 BitsPerSample = pwfx->wBitsPerSample; 138 SampleRate = pwfx->nSamplesPerSec; 139 this->nChannels = pwfx->nChannels; 140 ulBufSize = DART_BUFSIZE; 141 142 dprintf(("waveOutOpen: samplerate %d, numChan %d bps %d (%d), format %x", SampleRate, nChannels, BitsPerSample, pwfx->nBlockAlign, pwfx->wFormatTag)); 143 // Setup the open structure, pass the playlist and tell MCI_OPEN to use it 144 memset(&AmpOpenParms,0,sizeof(AmpOpenParms)); 145 146 AmpOpenParms.usDeviceID = ( USHORT ) 0; 147 AmpOpenParms.pszDeviceType = ( PSZ ) MCI_DEVTYPE_AUDIO_AMPMIX; 148 149 rc = mciSendCommand(0, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE, 150 (PVOID) &AmpOpenParms, 0); 151 152 DeviceId = AmpOpenParms.usDeviceID; 153 if(rc) { 154 dprintf(("MCI_OPEN failed\n")); 155 mciError(rc); 156 ulError = MMSYSERR_NODRIVER; 157 } 158 if(rc == 0) { 159 //Grab exclusive rights to device instance (NOT entire device) 160 GenericParms.hwndCallback = 0; //Not needed, so set to 0 161 rc = mciSendCommand(DeviceId, MCI_ACQUIREDEVICE, MCI_EXCLUSIVE_INSTANCE, 162 (PVOID)&GenericParms, 0); 163 if(rc) { 164 dprintf(("MCI_ACQUIREDEVICE failed\n")); 165 mciError(rc); 166 ulError = MMSYSERR_NOTENABLED; 167 } 168 } 169 State = STATE_STOPPED; 170 171 setVolume(volume); 172 173 wmutex = new VMutex(); 174 if(wmutex == NULL) { 175 DebugInt3(); 176 ulError = MMSYSERR_NOTSUPPORTED; 177 } 178 if(wmutex) 179 wmutex->enter(VMUTEX_WAIT_FOREVER); 180 181 if(waveout == NULL) { 182 waveout = this; 183 } 184 else { 185 DartWaveOut *dwave = waveout; 186 187 while(dwave->next) { 188 dwave = dwave->next; 189 } 190 dwave->next = this; 191 } 192 193 if(wmutex) 194 wmutex->leave(); 195 } 196 /******************************************************************************/ 197 /******************************************************************************/ 198 DartWaveOut::~DartWaveOut() 199 { 200 MCI_GENERIC_PARMS GenericParms; 201 202 if(!ulError) { 203 // Generic parameters 204 GenericParms.hwndCallback = 0; //hwndFrame 205 206 // Stop the playback. 207 mciSendCommand(DeviceId, MCI_STOP,MCI_WAIT, (PVOID)&GenericParms,0); 208 209 mciSendCommand(DeviceId, MCI_BUFFER, 210 MCI_WAIT | MCI_DEALLOCATE_MEMORY, 211 (PVOID)&BufferParms, 0); 212 213 // Generic parameters 214 GenericParms.hwndCallback = 0; //hwndFrame 215 216 // Close the device 217 mciSendCommand(DeviceId, MCI_CLOSE, MCI_WAIT, (PVOID)&GenericParms, 0); 218 } 219 220 if(wmutex) 221 wmutex->enter(VMUTEX_WAIT_FOREVER); 222 223 State = STATE_STOPPED; 224 225 if(waveout == this) { 226 waveout = this->next; 227 } 228 else { 229 DartWaveOut *dwave = waveout; 230 231 while(dwave->next != this) { 232 dwave = dwave->next; 233 } 234 dwave->next = this->next; 235 } 236 if(wmutex) 237 wmutex->leave(); 238 239 if(!ulError) { 240 if(mthdCallback) { 241 callback((ULONG)this, WOM_CLOSE, dwInstance, 0, 0); 242 } 243 else 244 if(hwndCallback) 245 PostMessageA(hwndCallback, WOM_CLOSE, 0, 0); 246 } 247 248 if(wmutex) 249 delete wmutex; 250 251 if(MixBuffer) 252 free(MixBuffer); 253 if(MixSetupParms) 254 free(MixSetupParms); 255 if(BufferParms) 256 free(BufferParms); 257 } 258 /******************************************************************************/ 259 /******************************************************************************/ 260 MMRESULT DartWaveOut::getError() 261 { 262 return(ulError); 263 } 264 /******************************************************************************/ 265 /******************************************************************************/ 266 int DartWaveOut::getNumDevices() 107 267 { 108 268 MCI_GENERIC_PARMS GenericParms; … … 110 270 APIRET rc; 111 271 112 curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0;113 114 fMixerSetup = FALSE;115 next = NULL;116 wavehdr = NULL;117 curhdr = NULL;118 mthdCallback = NULL;119 hwndCallback = 0;120 selCallback = 0;121 dwInstance = 0;122 ulError = 0;123 selCallback = 0;124 volume = defvolume;125 State = STATE_STOPPED;126 127 MixBuffer = (MCI_MIX_BUFFER *)malloc(PREFILLBUF_DART*sizeof(MCI_MIX_BUFFER));128 MixSetupParms = (MCI_MIXSETUP_PARMS *)malloc(sizeof(MCI_MIXSETUP_PARMS));129 BufferParms = (MCI_BUFFER_PARMS *)malloc(sizeof(MCI_BUFFER_PARMS));130 131 BitsPerSample = pwfx->wBitsPerSample;132 SampleRate = pwfx->nSamplesPerSec;133 this->nChannels = pwfx->nChannels;134 ulBufSize = DART_BUFSIZE;135 136 dprintf(("waveOutOpen: samplerate %d, numChan %d bps %d (%d), format %x", SampleRate, nChannels, BitsPerSample, pwfx->nBlockAlign, pwfx->wFormatTag));137 272 // Setup the open structure, pass the playlist and tell MCI_OPEN to use it 138 273 memset(&AmpOpenParms,0,sizeof(AmpOpenParms)); … … 145 280 (PVOID) &AmpOpenParms, 146 281 0); 147 DeviceId = AmpOpenParms.usDeviceID;148 if(rc) {149 dprintf(("MCI_OPEN failed\n"));150 mciError(rc);151 ulError = MMSYSERR_NODRIVER;152 }153 if(rc == 0) {154 //Grab exclusive rights to device instance (NOT entire device)155 GenericParms.hwndCallback = 0; //Not needed, so set to 0156 rc = mciSendCommand(DeviceId, MCI_ACQUIREDEVICE, MCI_EXCLUSIVE_INSTANCE,157 (PVOID)&GenericParms, 0);158 if(rc) {159 dprintf(("MCI_ACQUIREDEVICE failed\n"));160 mciError(rc);161 ulError = MMSYSERR_NOTENABLED;162 }163 }164 State = STATE_STOPPED;165 166 setVolume(volume);167 168 wmutex = new VMutex();169 if(wmutex == NULL) {170 DebugInt3();171 ulError = MMSYSERR_NOTSUPPORTED;172 }173 if(wmutex)174 wmutex->enter(VMUTEX_WAIT_FOREVER);175 176 if(waveout == NULL) {177 waveout = this;178 }179 else {180 DartWaveOut *dwave = waveout;181 182 while(dwave->next) {183 dwave = dwave->next;184 }185 dwave->next = this;186 }187 188 if(wmutex)189 wmutex->leave();190 }191 /******************************************************************************/192 /******************************************************************************/193 DartWaveOut::~DartWaveOut()194 {195 MCI_GENERIC_PARMS GenericParms;196 197 if(!ulError) {198 // Generic parameters199 GenericParms.hwndCallback = 0; //hwndFrame200 201 // Stop the playback.202 mciSendCommand(DeviceId, MCI_STOP,MCI_WAIT, (PVOID)&GenericParms,0);203 204 mciSendCommand(DeviceId,205 MCI_BUFFER,206 MCI_WAIT | MCI_DEALLOCATE_MEMORY,207 (PVOID)&BufferParms,208 0);209 210 // Generic parameters211 GenericParms.hwndCallback = 0; //hwndFrame212 213 // Close the device214 mciSendCommand(DeviceId, MCI_CLOSE, MCI_WAIT, (PVOID)&GenericParms, 0);215 }216 217 if(wmutex)218 wmutex->enter(VMUTEX_WAIT_FOREVER);219 220 State = STATE_STOPPED;221 222 if(waveout == this) {223 waveout = this->next;224 }225 else {226 DartWaveOut *dwave = waveout;227 228 while(dwave->next != this) {229 dwave = dwave->next;230 }231 dwave->next = this->next;232 }233 if(wmutex)234 wmutex->leave();235 236 if(!ulError) {237 if(mthdCallback) {238 callback((ULONG)this, WOM_CLOSE, dwInstance, 0, 0);239 }240 else241 if(hwndCallback)242 PostMessageA(hwndCallback, WOM_CLOSE, 0, 0);243 }244 245 if(wmutex)246 delete wmutex;247 248 if(MixBuffer)249 free(MixBuffer);250 if(MixSetupParms)251 free(MixSetupParms);252 if(BufferParms)253 free(BufferParms);254 }255 /******************************************************************************/256 /******************************************************************************/257 MMRESULT DartWaveOut::getError()258 {259 return(ulError);260 }261 /******************************************************************************/262 /******************************************************************************/263 int DartWaveOut::getNumDevices()264 {265 MCI_GENERIC_PARMS GenericParms;266 MCI_AMP_OPEN_PARMS AmpOpenParms;267 APIRET rc;268 269 // Setup the open structure, pass the playlist and tell MCI_OPEN to use it270 memset(&AmpOpenParms,0,sizeof(AmpOpenParms));271 272 AmpOpenParms.usDeviceID = ( USHORT ) 0;273 AmpOpenParms.pszDeviceType = ( PSZ ) MCI_DEVTYPE_AUDIO_AMPMIX;274 275 rc = mciSendCommand(0, MCI_OPEN,276 MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,277 (PVOID) &AmpOpenParms,278 0);279 282 280 283 if(rc) { … … 294 297 MMRESULT DartWaveOut::write(LPWAVEHDR pwh, UINT cbwh) 295 298 { 296 MCI_GENERIC_PARMS GenericParms = {0};297 APIRET rc;298 int i, buflength;299 300 if(fMixerSetup == FALSE)301 {299 MCI_GENERIC_PARMS GenericParms = {0}; 300 APIRET rc; 301 int i, buflength; 302 303 if(fMixerSetup == FALSE) 304 { 302 305 dprintf(("device acquired\n")); 303 306 /* Set the MixSetupParms data structure to match the loaded file. … … 339 342 340 343 #if 1 341 342 344 int consumerate = getAvgBytesPerSecond(); 345 int minbufsize = consumerate/32; 343 346 344 347 ulBufSize = pwh->dwBufferLength/2; 345 if(ulBufSize <minbufsize) {346 347 348 348 if(ulBufSize > minbufsize) { 349 dprintf(("set buffer size to %d bytes (org size = %d)", minbufsize, pwh->dwBufferLength)); 350 ulBufSize = minbufsize; 351 } 349 352 #else 350 353 if(pwh->dwBufferLength >= 512 && pwh->dwBufferLength <= 1024) … … 380 383 381 384 curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0; 385 readPos = writePos = 0; 382 386 383 387 for(i=0;i<PREFILLBUF_DART;i++) { … … 389 393 curhdr = pwh; 390 394 pwh->lpNext = NULL; 395 pwh->reserved = 0; 391 396 392 397 if(State != STATE_STOPPED) {//don't start playback if paused 393 wmutex->leave(); 394 return(MMSYSERR_NOERROR); 395 } 396 397 while(TRUE) { 398 buflength = min((ULONG)MixBuffer[curFillBuf].ulBufferLength - curPlayPos, 399 (ULONG)wavehdr->dwBufferLength - curFillPos); 400 dprintf(("Copying %d data; curPlayPos = %d curFillPos = %d\n", buflength, curPlayPos, curFillPos)); 401 402 memcpy((char *)MixBuffer[curFillBuf].pBuffer + curPlayPos, 403 wavehdr->lpData + curFillPos, 404 buflength); 405 406 curPlayPos += buflength; 407 curFillPos += buflength; 408 if(curFillPos == wavehdr->dwBufferLength) { 409 dprintf(("Processed first win32 buffer\n")); 410 curFillPos = 0; 411 wavehdr->dwFlags |= WHDR_DONE; 412 curhdr = NULL; 413 } 414 if(curPlayPos == MixBuffer[curPlayBuf].ulBufferLength) { 415 if(++curPlayBuf == PREFILLBUF_DART) { 416 curPlayBuf = 0; 417 break; 418 } 419 curPlayPos = 0; 420 } 421 if(curFillPos == 0) 422 break; 423 } 398 wmutex->leave(); 399 return(MMSYSERR_NOERROR); 400 } 401 402 writeBuffer(); //must be called before (re)starting playback 403 424 404 dprintf(("MixSetupParms = %X\n", MixSetupParms)); 425 405 State = STATE_PLAYING; … … 428 408 429 409 //write buffers to DART; starts playback 430 { 431 // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector! 432 USHORT selTIB = GetFS(); // save current FS selector 433 434 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, 435 MixBuffer, 436 PREFILLBUF_DART); 437 SetFS(selTIB); // switch back to the saved FS selector 438 } 410 // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector! 411 USHORT selTIB = GetFS(); // save current FS selector 412 413 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, 414 MixBuffer, 415 PREFILLBUF_DART); 416 SetFS(selTIB); // switch back to the saved FS selector 417 439 418 dprintf(("Dart playing\n")); 440 } 441 else 442 { 419 } 420 else 421 { 422 pwh->lpNext = NULL; 423 pwh->reserved = 0; 443 424 wmutex->enter(VMUTEX_WAIT_FOREVER); 444 pwh->lpNext = NULL;445 425 if(wavehdr) { 446 426 WAVEHDR *chdr = wavehdr; … … 450 430 chdr->lpNext = pwh; 451 431 } 452 else wavehdr = pwh; 432 else wavehdr = pwh; 433 434 writeBuffer(); //must be called before (re)starting playback 435 453 436 wmutex->leave(); 454 if(State == STATE_STOPPED || fUnderrun) {//continue playback437 if(State == STATE_STOPPED) {//continue playback 455 438 restart(); 456 439 } 457 } 458 459 return(MMSYSERR_NOERROR); 440 } 441 return(MMSYSERR_NOERROR); 460 442 } 461 443 /******************************************************************************/ … … 465 447 MCI_GENERIC_PARMS Params; 466 448 467 wmutex->enter(VMUTEX_WAIT_FOREVER);468 if(State != STATE_PLAYING) {469 470 449 wmutex->enter(VMUTEX_WAIT_FOREVER); 450 if(State != STATE_PLAYING) { 451 State = STATE_PAUSED; 452 wmutex->leave(); 471 453 return(MMSYSERR_NOERROR); 472 } 473 474 State = STATE_PAUSED; 475 wmutex->leave(); 476 477 memset(&Params, 0, sizeof(Params)); 478 479 // Stop the playback. 480 mciSendCommand(DeviceId, MCI_PAUSE, MCI_WAIT, (PVOID)&Params, 0); 481 482 return(MMSYSERR_NOERROR); 454 } 455 456 State = STATE_PAUSED; 457 wmutex->leave(); 458 459 memset(&Params, 0, sizeof(Params)); 460 461 // Stop the playback. 462 mciSendCommand(DeviceId, MCI_PAUSE, MCI_WAIT, (PVOID)&Params, 0); 463 464 return(MMSYSERR_NOERROR); 465 } 466 /******************************************************************************/ 467 /******************************************************************************/ 468 MMRESULT DartWaveOut::stop() 469 { 470 MCI_GENERIC_PARMS Params; 471 472 dprintf(("DartWaveOut::stop %s", (State == STATE_PLAYING) ? "playing" : "stopped")); 473 if(State != STATE_PLAYING) 474 return(MMSYSERR_HANDLEBUSY); 475 476 memset(&Params, 0, sizeof(Params)); 477 478 // Stop the playback. 479 mciSendCommand(DeviceId, MCI_STOP, MCI_WAIT, (PVOID)&Params, 0); 480 481 State = STATE_STOPPED; 482 fUnderrun = FALSE; 483 484 curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0; 485 readPos = writePos = 0; 486 487 return(MMSYSERR_NOERROR); 483 488 } 484 489 /******************************************************************************/ … … 487 492 { 488 493 MCI_GENERIC_PARMS Params; 489 490 dprintf(("DartWaveOut::reset %s", (State == STATE_PLAYING) ? "playing" : "stopped")); 491 if(State != STATE_PLAYING) 494 LPWAVEHDR tmpwavehdr; 495 496 dprintf(("DartWaveOut::reset %s", (State == STATE_PLAYING) ? "playing" : "stopped")); 497 if(State != STATE_PLAYING) 492 498 return(MMSYSERR_HANDLEBUSY); 493 499 494 memset(&Params, 0, sizeof(Params)); 495 496 // Stop the playback. 497 mciSendCommand(DeviceId, MCI_STOP, MCI_WAIT, (PVOID)&Params, 0); 498 499 dprintf(("Nr of threads blocked on mutex = %d\n", wmutex->getNrBlocked())); 500 501 wmutex->enter(VMUTEX_WAIT_FOREVER); 502 while(wavehdr) { 503 wavehdr->dwFlags |= WHDR_DONE; 504 wavehdr->dwFlags &= ~WHDR_INQUEUE; 505 wavehdr = wavehdr->lpNext; 506 wavehdr->lpNext = NULL; 507 wmutex->leave(); 508 if(mthdCallback) { 509 callback((ULONG)this, WOM_DONE, dwInstance, (ULONG)wavehdr, 0); 510 } 511 else 500 memset(&Params, 0, sizeof(Params)); 501 502 // Stop the playback. 503 mciSendCommand(DeviceId, MCI_STOP, MCI_WAIT, (PVOID)&Params, 0); 504 505 dprintf(("Nr of threads blocked on mutex = %d\n", wmutex->getNrBlocked())); 506 507 wmutex->enter(VMUTEX_WAIT_FOREVER); 508 while(wavehdr) 509 { 510 wavehdr->dwFlags |= WHDR_DONE; 511 wavehdr->dwFlags &= ~WHDR_INQUEUE; 512 tmpwavehdr = wavehdr; 513 wavehdr = wavehdr->lpNext; 514 tmpwavehdr->lpNext = NULL; 515 wmutex->leave(); 516 517 if(mthdCallback) { 518 callback((ULONG)this, WOM_DONE, dwInstance, (ULONG)tmpwavehdr, 0); 519 } 520 else 512 521 if(hwndCallback) { 513 dprintf(("Callback (msg) for buffer %x", wavehdr)); 514 PostMessageA(hwndCallback, WOM_DONE, (WPARAM)this, (ULONG)wavehdr); 515 } 516 wmutex->enter(VMUTEX_WAIT_FOREVER); 517 } 518 wavehdr = NULL; 519 State = STATE_STOPPED; 520 fUnderrun = FALSE; 521 522 wmutex->leave(); 523 return(MMSYSERR_NOERROR); 522 dprintf(("Callback (msg) for buffer %x", tmpwavehdr)); 523 PostMessageA(hwndCallback, WOM_DONE, (WPARAM)this, (ULONG)tmpwavehdr); 524 } 525 wmutex->enter(VMUTEX_WAIT_FOREVER); 526 } 527 wavehdr = NULL; 528 State = STATE_STOPPED; 529 fUnderrun = FALSE; 530 531 curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0; 532 readPos = writePos = 0; 533 534 wmutex->leave(); 535 return(MMSYSERR_NOERROR); 524 536 } 525 537 /******************************************************************************/ … … 529 541 int i, curbuf; 530 542 531 dprintf(("DartWaveOut::restart")); 532 if(State == STATE_PLAYING) 543 dprintf(("DartWaveOut::restart")); 544 if(State == STATE_PLAYING) 545 return(MMSYSERR_NOERROR); 546 547 //Only write buffers to dart if mixer has been initialized; if not, then 548 //the first buffer write will do this for us. 549 if(fMixerSetup == TRUE) 550 { 551 wmutex->enter(VMUTEX_WAIT_FOREVER); 552 State = STATE_PLAYING; 553 fUnderrun = FALSE; 554 wmutex->leave(); 555 curbuf = curPlayBuf; 556 557 // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector! 558 USHORT selTIB = GetFS(); // save current FS selector 559 560 for(i=0;i<PREFILLBUF_DART;i++) 561 { 562 dprintf(("restart: write buffer at %x size %d", MixBuffer[curbuf].pBuffer, MixBuffer[curbuf].ulBufferLength)); 563 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, &MixBuffer[curbuf], 1); 564 if(++curbuf == PREFILLBUF_DART) 565 curbuf = 0; 566 } 567 SetFS(selTIB); // switch back to the saved FS selector 568 } 533 569 return(MMSYSERR_NOERROR); 534 535 //Only write buffers to dart if mixer has been initialized; if not, then536 //the first buffer write will do this for us.537 if(fMixerSetup == TRUE)538 {539 wmutex->enter(VMUTEX_WAIT_FOREVER);540 State = STATE_PLAYING;541 fUnderrun = FALSE;542 wmutex->leave();543 curbuf = curPlayBuf;544 545 // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector!546 USHORT selTIB = GetFS(); // save current FS selector547 548 for(i=0;i<PREFILLBUF_DART;i++)549 {550 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, &MixBuffer[curbuf], 1);551 if(++curbuf == PREFILLBUF_DART)552 curbuf = 0;553 }554 555 SetFS(selTIB); // switch back to the saved FS selector556 }557 return(MMSYSERR_NOERROR);558 570 } 559 571 /******************************************************************************/ … … 585 597 BOOL winrc; 586 598 587 dprintf(("DartWaveOut::queryFormat %x srate=%d, nchan=%d, bps=%d", formatTag, nSamplesPerSec, nChannels, wBitsPerSample));588 589 memset(&mciOpenParms, /* Object to fill with zeros. */590 0, /* Value to place into the object. */591 sizeof( mciOpenParms ) ); /* How many zero's to use. */592 593 mciOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_WAVEFORM_AUDIO;594 595 rc = mciSendCommand( (USHORT) 0,596 MCI_OPEN,597 MCI_WAIT | MCI_OPEN_TYPE_ID,598 (PVOID) &mciOpenParms,599 0);600 if((rc & 0xFFFF) != MCIERR_SUCCESS) {599 dprintf(("DartWaveOut::queryFormat %x srate=%d, nchan=%d, bps=%d", formatTag, nSamplesPerSec, nChannels, wBitsPerSample)); 600 601 memset(&mciOpenParms, /* Object to fill with zeros. */ 602 0, /* Value to place into the object. */ 603 sizeof( mciOpenParms ) ); /* How many zero's to use. */ 604 605 mciOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_WAVEFORM_AUDIO; 606 607 rc = mciSendCommand( (USHORT) 0, 608 MCI_OPEN, 609 MCI_WAIT | MCI_OPEN_TYPE_ID, 610 (PVOID) &mciOpenParms, 611 0); 612 if((rc & 0xFFFF) != MCIERR_SUCCESS) { 601 613 mciError(rc); 602 614 return(FALSE); 603 }604 DeviceId = mciOpenParms.usDeviceID;605 606 memset( &mciAudioCaps , 0, sizeof(MCI_WAVE_GETDEVCAPS_PARMS));607 608 mciAudioCaps.ulBitsPerSample = wBitsPerSample;609 mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;610 mciAudioCaps.ulSamplesPerSec = nSamplesPerSec;611 mciAudioCaps.ulChannels = nChannels;612 mciAudioCaps.ulFormatMode = MCI_PLAY;613 mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;614 615 rc = mciSendCommand(DeviceId, /* Device ID */616 MCI_GETDEVCAPS,617 MCI_WAIT | MCI_GETDEVCAPS_EXTENDED | MCI_GETDEVCAPS_ITEM,618 (PVOID) &mciAudioCaps,619 0);620 if((rc & 0xFFFF) != MCIERR_SUCCESS) {615 } 616 DeviceId = mciOpenParms.usDeviceID; 617 618 memset( &mciAudioCaps , 0, sizeof(MCI_WAVE_GETDEVCAPS_PARMS)); 619 620 mciAudioCaps.ulBitsPerSample = wBitsPerSample; 621 mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM; 622 mciAudioCaps.ulSamplesPerSec = nSamplesPerSec; 623 mciAudioCaps.ulChannels = nChannels; 624 mciAudioCaps.ulFormatMode = MCI_PLAY; 625 mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT; 626 627 rc = mciSendCommand(DeviceId, /* Device ID */ 628 MCI_GETDEVCAPS, 629 MCI_WAIT | MCI_GETDEVCAPS_EXTENDED | MCI_GETDEVCAPS_ITEM, 630 (PVOID) &mciAudioCaps, 631 0); 632 if((rc & 0xFFFF) != MCIERR_SUCCESS) { 621 633 mciError(rc); 622 634 winrc = FALSE; 623 }624 else winrc = TRUE;625 626 // Close the device627 mciSendCommand(DeviceId,MCI_CLOSE,MCI_WAIT,(PVOID)&GenericParms,0);628 return(winrc);635 } 636 else winrc = TRUE; 637 638 // Close the device 639 mciSendCommand(DeviceId,MCI_CLOSE,MCI_WAIT,(PVOID)&GenericParms,0); 640 return(winrc); 629 641 } 630 642 /******************************************************************************/ … … 633 645 { 634 646 #ifdef DEBUG 635 char szError[256] = "";636 637 mciGetErrorString(ulError, szError, sizeof(szError));638 dprintf(("WINMM: DartWaveOut: %s\n", szError));647 char szError[256] = ""; 648 649 mciGetErrorString(ulError, szError, sizeof(szError)); 650 dprintf(("WINMM: DartWaveOut: %s\n", szError)); 639 651 #endif 640 652 } … … 645 657 DartWaveOut *curwave = waveout; 646 658 647 while(curwave) { 648 if(dwave == curwave) { 649 return(TRUE); 650 } 651 curwave = curwave->next; 652 } 653 654 #ifdef DEBUG 655 // WriteLog("WINMM:DartWaveOut not found!\n"); 656 #endif 657 return(FALSE); 659 while(curwave) { 660 if(dwave == curwave) { 661 return(TRUE); 662 } 663 curwave = curwave->next; 664 } 665 666 dprintf2(("WINMM:DartWaveOut not found!\n")); 667 return(FALSE); 658 668 } 659 669 /******************************************************************************/ … … 664 674 WAVEHDR *whdr, *prevhdr = NULL; 665 675 666 #ifdef DEBUG1 667 dprintf(("WINMM: handler %d\n", curPlayBuf)); 668 #endif 669 if(ulFlags == MIX_STREAM_ERROR) { 670 if(ulStatus == ERROR_DEVICE_UNDERRUN) { 671 dprintf(("WINMM: WaveOut handler UNDERRUN!\n")); 672 if(State == STATE_PLAYING) { 673 fUnderrun = TRUE; 674 pause(); //out of buffers, so pause playback 675 } 676 dprintf2(("WINMM: handler %d\n", curPlayBuf)); 677 if(ulFlags == MIX_STREAM_ERROR) { 678 if(ulStatus == ERROR_DEVICE_UNDERRUN) { 679 dprintf(("WINMM: WaveOut handler UNDERRUN! state %s", (State == STATE_PLAYING) ? "playing" : "stopped")); 680 if(State == STATE_PLAYING) { 681 fUnderrun = TRUE; 682 stop(); //out of buffers, so stop playback 683 } 684 return; 685 } 686 dprintf(("WINMM: WaveOut handler, Unknown error %X\n", ulStatus)); 676 687 return; 677 688 } 678 dprintf(("WINMM: WaveOut handler, Unknown error %X\n", ulStatus)); 679 return; 680 } 681 wmutex->enter(VMUTEX_WAIT_FOREVER); 682 683 whdr = wavehdr; 684 if(whdr == NULL) { 689 if(State != STATE_PLAYING) { 690 return; 691 } 692 693 wmutex->enter(VMUTEX_WAIT_FOREVER); 694 695 readPos += MixBuffer[curPlayBuf].ulBufferLength; 696 697 if(curPlayBuf == PREFILLBUF_DART-1) 698 curPlayBuf = 0; 699 else curPlayBuf++; 700 701 whdr = wavehdr; 702 if(whdr == NULL) { 703 //last buffer played -> no new ones -> silence buffer & continue 704 dprintf(("WINMM: WaveOut handler LAST BUFFER PLAYED! state %s", (State == STATE_PLAYING) ? "playing" : "stopped")); 705 if(State == STATE_PLAYING) { 706 fUnderrun = TRUE; 707 //// memset(MixBuffer[curPlayBuf].pBuffer, 0, MixBuffer[curPlayBuf].ulBufferLength); 708 goto sendbuffer; 709 } 685 710 wmutex->leave(); 686 //last buffer played -> no new ones -> underrun; pause playback687 dprintf(("WINMM: WaveOut handler UNDERRUN!\n"));688 if(State == STATE_PLAYING) {689 fUnderrun = TRUE;690 pause(); //out of buffers, so pause playback691 }692 711 return; 693 } 694 while(whdr) { 695 if(whdr->dwFlags & WHDR_DONE) { 696 #ifdef DEBUG1 697 dprintf(("WINMM: handler buf %X done\n", whdr)); 698 #endif 699 whdr->dwFlags &= ~WHDR_INQUEUE; 700 701 if(prevhdr == NULL) 702 wavehdr = whdr->lpNext; 703 else prevhdr->lpNext = whdr->lpNext; 704 705 whdr->lpNext = NULL; 706 wmutex->leave(); 707 708 if(mthdCallback) { 709 callback((ULONG)this, WOM_DONE, dwInstance, (ULONG)whdr, 0); 710 } 711 else 712 if(hwndCallback) { 713 dprintf(("Callback (msg) for buffer %x", whdr)); 714 PostMessageA(hwndCallback, WOM_DONE, (WPARAM)this, (ULONG)whdr); 715 } 716 717 wmutex->enter(VMUTEX_WAIT_FOREVER); 718 } 719 prevhdr = whdr; 720 whdr = whdr->lpNext; 721 } 722 723 if(curhdr == NULL) 724 curhdr = wavehdr; 725 726 #ifdef DEBUG1 727 dprintf(("WINMM: handler cur (%d,%d), fill (%d,%d)\n", curPlayBuf, curPlayPos, curFillBuf, curFillPos)); 728 #endif 729 730 while(curhdr) { 731 buflength = min((ULONG)MixBuffer[curFillBuf].ulBufferLength - curPlayPos, 732 (ULONG)curhdr->dwBufferLength - curFillPos); 733 memcpy((char *)MixBuffer[curFillBuf].pBuffer + curPlayPos, 734 curhdr->lpData + curFillPos, 735 buflength); 736 curPlayPos += buflength; 737 curFillPos += buflength; 738 #ifdef DEBUG1 739 dprintf(("WINMM: copied %d bytes, cufFillPos = %d, dwBufferLength = %d\n", buflength, curFillPos, curhdr->dwBufferLength)); 740 #endif 741 if(curFillPos == curhdr->dwBufferLength) { 742 #ifdef DEBUG1 743 dprintf(("Buffer %d done\n", curFillBuf)); 744 #endif 745 curFillPos = 0; 746 curhdr->dwFlags |= WHDR_DONE; 747 //search for next unprocessed buffer 748 while(curhdr && curhdr->dwFlags & WHDR_DONE) 749 curhdr = curhdr->lpNext; 750 } 751 if(curPlayPos == MixBuffer[curFillBuf].ulBufferLength) { 752 curPlayPos = 0; 753 if(++curFillBuf == PREFILLBUF_DART) { 754 curFillBuf = 0; 755 } 756 if(curFillBuf == curPlayBuf) 757 break; //no more room left 758 } 759 } 760 761 if(curPlayBuf == PREFILLBUF_DART-1) 762 curPlayBuf = 0; 763 else curPlayBuf++; 764 765 wmutex->leave(); 766 767 //Transfer buffer to DART 768 // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector! 769 USHORT selTIB = GetFS(); // save current FS selector 770 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, &MixBuffer[curPlayBuf], 1); 771 SetFS(selTIB); // switch back to the saved FS selector 712 } 713 fUnderrun = FALSE; 714 while(whdr) { 715 if(whdr->reserved == WHDR_DONE) 716 { 717 if(readPos < writePos + whdr->dwBufferLength) { 718 dprintf2(("Buffer marked done, but not yet played completely (%d,%d)", readPos, writePos)); 719 break; //not yet done 720 } 721 722 dprintf2(("WINMM: handler buf %X done (read %d, write %d)", whdr, readPos, writePos)); 723 whdr->dwFlags &= ~WHDR_INQUEUE; 724 whdr->dwFlags |= WHDR_DONE; 725 726 if(prevhdr == NULL) 727 wavehdr = whdr->lpNext; 728 else prevhdr->lpNext = whdr->lpNext; 729 730 whdr->lpNext = NULL; 731 732 writePos += whdr->dwBufferLength; 733 wmutex->leave(); 734 735 if(mthdCallback) { 736 callback((ULONG)this, WOM_DONE, dwInstance, (ULONG)whdr, 0); 737 } 738 else 739 if(hwndCallback) { 740 dprintf(("Callback (msg) for buffer %x", whdr)); 741 PostMessageA(hwndCallback, WOM_DONE, (WPARAM)this, (ULONG)whdr); 742 } 743 744 wmutex->enter(VMUTEX_WAIT_FOREVER); 745 } 746 else break; 747 748 prevhdr = whdr; 749 whdr = whdr->lpNext; 750 } 751 752 writeBuffer(); 753 754 sendbuffer: 755 wmutex->leave(); 756 757 //Transfer buffer to DART 758 // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector! 759 USHORT selTIB = GetFS(); // save current FS selector 760 MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, &MixBuffer[curPlayBuf], 1); 761 SetFS(selTIB); // switch back to the saved FS selector 762 } 763 /******************************************************************************/ 764 /******************************************************************************/ 765 void DartWaveOut::writeBuffer() 766 { 767 ULONG buflength; 768 769 if(!fUnderrun && State == STATE_PLAYING && curFillBuf == curPlayBuf) { 770 dprintf2(("writeBuffer: no more room for more audio data")); 771 return; //no room left 772 } 773 774 if(curhdr == NULL) 775 curhdr = wavehdr; 776 777 while(curhdr && (curhdr->reserved == WHDR_DONE)) { 778 curhdr = curhdr->lpNext; 779 } 780 781 if(curhdr == NULL) { 782 return; //no unprocessed buffers left 783 } 784 785 dprintf2(("WINMM: handler cur (%d,%d), fill (%d,%d)\n", curPlayBuf, curPlayPos, curFillBuf, curFillPos)); 786 787 while(curhdr) { 788 buflength = min((ULONG)MixBuffer[curFillBuf].ulBufferLength - curPlayPos, 789 (ULONG)curhdr->dwBufferLength - curFillPos); 790 dprintf2(("WINMM: copied %d bytes, cufFillPos = %d, dwBufferLength = %d\n", buflength, curFillPos, curhdr->dwBufferLength)); 791 792 memcpy((char *)MixBuffer[curFillBuf].pBuffer + curPlayPos, 793 curhdr->lpData + curFillPos, buflength); 794 curPlayPos += buflength; 795 curFillPos += buflength; 796 797 798 if(curFillPos == curhdr->dwBufferLength) { 799 dprintf2(("Buffer %d done (%x)", curFillBuf, curhdr)); 800 curFillPos = 0; 801 curhdr->reserved = WHDR_DONE; 802 //search for next unprocessed buffer 803 while(curhdr && (curhdr->reserved == WHDR_DONE)) 804 curhdr = curhdr->lpNext; 805 } 806 if(curPlayPos == MixBuffer[curFillBuf].ulBufferLength) { 807 curPlayPos = 0; 808 if(++curFillBuf == PREFILLBUF_DART) { 809 curFillBuf = 0; 810 } 811 if(curFillBuf == curPlayBuf) 812 break; //no more room left 813 } 814 } 772 815 } 773 816 /******************************************************************************/ … … 777 820 ULONG ulFlags) 778 821 { 779 // PTIB ptib; 780 // PPIB ppib; 781 // DosGetInfoBlocks(&ptib, &ppib); 782 // dprintf(("WaveOutHandler: thread %d prio %X", ptib->tib_ptib2->tib2_ultid, ptib->tib_ptib2->tib2_ulpri)); 783 784 DartWaveOut *dwave; 785 786 if(pBuffer && pBuffer->ulUserParm) 787 { 788 dwave = (DartWaveOut *)pBuffer->ulUserParm; 789 dwave->handler(ulStatus, pBuffer, ulFlags); 790 } 791 return(TRUE); 822 PTIB2 ptib2; 823 DartWaveOut *dwave; 824 825 ptib2 = (PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)); 826 if(ptib2 && HIBYTE(ptib2->tib2_ulpri) != PRTYC_TIMECRITICAL) { 827 dprintf(("Setting priority of DART thread to PRTYC_TIMECRITICAL")); 828 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); 829 } 830 if(pBuffer && pBuffer->ulUserParm) 831 { 832 dwave = (DartWaveOut *)pBuffer->ulUserParm; 833 dwave->handler(ulStatus, pBuffer, ulFlags); 834 } 835 return(TRUE); 792 836 } 793 837 -
trunk/src/winmm/dwaveout.h
r3852 r5334 1 /* $Id: dwaveout.h,v 1.1 0 2000-07-18 18:34:43sandervl Exp $ */1 /* $Id: dwaveout.h,v 1.11 2001-03-19 19:28:38 sandervl Exp $ */ 2 2 3 3 /* … … 32 32 { 33 33 public: 34 DartWaveOut(LPWAVEFORMATEX pwfx, ULONG nCallback, ULONG dwInstance , USHORT usSel);34 DartWaveOut(LPWAVEFORMATEX pwfx, ULONG nCallback, ULONG dwInstance); 35 35 DartWaveOut(LPWAVEFORMATEX pwfx, HWND hwndCallback); 36 36 DartWaveOut(LPWAVEFORMATEX pwfx); … … 40 40 MMRESULT write(LPWAVEHDR pwh, UINT cbwh); 41 41 MMRESULT pause(); 42 MMRESULT stop(); 42 43 MMRESULT restart(); 43 44 MMRESULT setVolume(ULONG ulVol); … … 66 67 67 68 private: 69 void writeBuffer(); 70 68 71 USHORT DeviceId; 69 72 ULONG ulBufferCount; /* Current file buffer */ … … 77 80 MCI_BUFFER_PARMS *BufferParms; /* Device buffer parms */ 78 81 79 int SampleRate; 80 int BitsPerSample; 81 int nChannels; 82 int curPlayBuf, curFillBuf; 83 int curFillPos, curPlayPos; //fillpos == pos in os2 mix buffer, bufpos == pos in win buffer 82 int SampleRate; 83 int BitsPerSample; 84 int nChannels; 85 int curPlayBuf, curFillBuf; 86 ULONG curFillPos, curPlayPos; //fillpos == pos in os2 mix buffer, bufpos == pos in win buffer 87 ULONG readPos, writePos; 84 88 85 89 // callback interface 86 90 LPDRVCALLBACK mthdCallback; // pointer to win32 routine for the callback 87 USHORT selCallback; // the win32 tib selector for the callback (saved at waveOutOpen)88 91 void callback(HDRVR h, UINT uMessage, DWORD dwUser, DWORD dw1, DWORD dw2); 89 92 HWND hwndCallback; -
trunk/src/winmm/wavein.cpp
r5273 r5334 1 /* $Id: wavein.cpp,v 1. 7 2001-02-27 21:17:01sandervl Exp $ */1 /* $Id: wavein.cpp,v 1.8 2001-03-19 19:28:38 sandervl Exp $ */ 2 2 3 3 /* … … 68 68 if(fdwOpen == CALLBACK_FUNCTION) 69 69 { 70 //@@@PH 1999/12/28 save valid FS: to win32 TIB 71 *phwi = (HWAVEOUT)new DartWaveIn(pwfx, dwCallback, dwInstance, GetFS()); 70 *phwi = (HWAVEOUT)new DartWaveIn(pwfx, dwCallback, dwInstance); 72 71 } 73 72 else *phwi = (HWAVEOUT)new DartWaveIn(pwfx); -
trunk/src/winmm/waveout.cpp
r5272 r5334 1 /* $Id: waveout.cpp,v 1.1 7 2001-02-27 21:14:00sandervl Exp $ */1 /* $Id: waveout.cpp,v 1.18 2001-03-19 19:28:39 sandervl Exp $ */ 2 2 //#undef DEBUG 3 3 /* … … 73 73 if(fdwOpen == CALLBACK_FUNCTION) 74 74 { 75 //@@@PH 1999/12/28 save valid FS: to win32 TIB 76 *phwo = (HWAVEOUT)new DartWaveOut(pwfx, dwCallback, dwInstance, GetFS()); 75 *phwo = (HWAVEOUT)new DartWaveOut(pwfx, dwCallback, dwInstance); 77 76 } 78 77 else *phwo = (HWAVEOUT)new DartWaveOut(pwfx); … … 240 239 case TIME_BYTES: 241 240 pmmt->u.cb = position; 241 dprintf2(("WINMM:waveOutGetPosition: TIME_BYTES %d (%x)", position, GetCurrentTime())); 242 242 break; 243 243 case TIME_SAMPLES: 244 244 pmmt->u.sample = position * 8 / dwave->getBitsPerSample(); 245 dprintf2(("WINMM:waveOutGetPosition: TIME_SAMPLES %d", pmmt->u.sample)); 245 246 break; 246 247 case TIME_SMPTE: … … 255 256 pmmt->u.smpte.frame = timeval; 256 257 pmmt->u.smpte.fps = 30; 258 dprintf2(("WINMM:waveOutGetPosition: TIME_SAMPLES %d", position)); 257 259 break; 258 260 } … … 262 264 case TIME_MS: 263 265 pmmt->u.ms = position / (dwave->getAvgBytesPerSecond() / 1000); 264 dprintf (("WINMM:waveOutGetPosition: TIME_MS pos=%d ms=%d time=%d", position, pmmt->u.ms, GetCurrentTime()));266 dprintf2(("WINMM:waveOutGetPosition: TIME_MS pos=%d ms=%d time=%d", position, pmmt->u.ms, GetCurrentTime())); 265 267 break; 266 268 }
Note:
See TracChangeset
for help on using the changeset viewer.