Changeset 483 for OCO/trunk/drv16/wavestrm.cpp
- Timestamp:
- May 6, 2010, 3:08:34 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
OCO/trunk/drv16/wavestrm.cpp
r478 r483 40 40 #endif 41 41 42 extern "C" ULONG __cdecl __saveregs OSSIDC_EntryPoint(ULONG cmd, ULONG param1, ULONG param2); 43 42 44 43 45 //****************************************************************************** … … 50 52 // the data has been played and 1 if there is still some data left. 51 53 //****************************************************************************** 52 USHORT WAVESTREAM::_vRealignBuffer(ULONG endpos, PSTREAMBUFFER pbuffer) 53 { 54 ULONG streambuf_start, bufconsumed; 55 USHORT usRC; 56 57 streambuf_start = pbuffer->ulDonepos - pbuffer->ulBuffpos; 58 // if none of the data in this stream buffer has been consumed 59 if (endpos <= streambuf_start) { 60 pbuffer->ulDonepos = 0; 61 pbuffer->ulBuffpos = 0; 62 usRC = 1; 63 } 64 // else some or all of the data has been consumed 65 else { 66 bufconsumed = endpos - streambuf_start; 67 // some of the buffer has been consumed 68 if (bufconsumed <= pbuffer->ulBuffsz) { 69 pbuffer->ulDonepos = 0; 70 pbuffer->ulBuffpos = pbuffer->ulBuffsz - bufconsumed; 71 pbuffer->ulBuffpos &= 0xFFFFFFFC; //keep it on a dword boundary 72 usRC = 1; 73 } 74 // all of the buffer has been consumed 75 else { 76 pbuffer->ulDonepos = 0; 77 pbuffer->ulBuffpos = pbuffer->ulBuffsz; 78 usRC = 0; 79 } 80 } 81 return(usRC); 54 USHORT WAVESTREAM::_vRealignBuffer(ULONG ulEndPos, PSTREAMBUFFER pBuffer) 55 { 56 if (ulEndPos >= pBuffer->ulDonepos) { /* all of the data has been consumed */ 57 pBuffer->ulBuffpos = pBuffer->ulBuffsz; 58 pBuffer->ulDonepos = 0; 59 return(0); 60 } 61 62 if (ulEndPos >= (pBuffer->ulDonepos - pBuffer->ulBuffpos)) { /* some of the data has been consumed */ 63 pBuffer->ulBuffpos = pBuffer->ulDonepos - ulEndPos; 64 pBuffer->ulBuffpos &= 0xFFFFFFFC; //keep it on a dword boundary 65 pBuffer->ulDonepos = 0; 66 return(1); 67 } 68 /* none of the data in this buffer has been consumed */ 69 pBuffer->ulDonepos = 0; 70 pBuffer->ulBuffpos = 0; 71 return(1); 82 72 } 83 73 … … 99 89 // and put the STREAMBUFFER on the Head queue. 100 90 //****************************************************************************** 101 void WAVESTREAM::_vRealignPausedBuffers(ULONG endpos) 102 { 103 PQUEUEHEAD pTempHead = new QUEUEHEAD; 104 PSTREAMBUFFER ptempbuff; 105 USHORT usRC; 106 107 108 switch (ulStreamType & STREAM_WRITE) { 109 case STREAM_READ: 110 _vReadAudioBuf(); 111 break; 112 113 case STREAM_WRITE: 114 115 // if there is a buffer on the InProcess Queue 116 // only check the first one as any others are just waiting..... 117 if (qhInProcess.IsElements()) 118 { 119 // if any data has been written from this stream buffer 120 ptempbuff = (PSTREAMBUFFER)qhInProcess.Head(); 121 if (ptempbuff->ulDonepos) 122 { 123 _vRealignBuffer(endpos, ptempbuff); 124 } /* end if ulDonepos */ 125 } 126 127 // if there are bufferes on the done queue, pop them off the head and 128 // push them on the head of qhTempHead. This will reorder them so 129 // that the more recently used ones will be in the front of the queue. 130 // Pass them all to _vRealignBuffer. If the rc from _vRealignBuffer is 131 // 0 then there is no unprocessed data in the buffer (it is ready to 132 // be returned) so put it on the Tail of the done queue. 133 // If the rc is 1 then put it on the head of the InProcess queue. 134 135 while (qhDone.IsElements()) 136 { 137 pTempHead->PushOnHead(qhDone.PopHead()); 138 } /* endwhile */ 139 140 while (pTempHead->IsElements()) 141 { 142 usRC = _vRealignBuffer(endpos, (PSTREAMBUFFER)pTempHead->Head()); 143 if (usRC) 144 qhInProcess.PushOnHead(pTempHead->PopHead()); 145 else 146 qhDone.PushOnTail(pTempHead->PopHead()); 147 } /* endwhile */ 148 break; 149 default: 150 break; 151 } /* endswitch */ 152 delete pTempHead; // free the memory this ain't no Java here !! 91 void WAVESTREAM::_vRealignPausedBuffers(ULONG ulEndPos) 92 { 93 PQUEUEHEAD pTempHead = new QUEUEHEAD; 94 PSTREAMBUFFER pTmpBuf; 95 USHORT usRC; 96 97 98 switch (ulStreamType & STREAM_WRITE) { 99 case STREAM_READ: 100 _vReadAudioBuf(); 101 break; 102 103 case STREAM_WRITE: 104 105 // if there is a buffer on the InProcess Queue 106 // only check the first one as any others are just waiting..... 107 if (qhInProcess.IsElements()) 108 { 109 // if any data has been written from this stream buffer 110 pTmpBuf = (PSTREAMBUFFER)qhInProcess.Head(); 111 if (pTmpBuf->ulDonepos) 112 { 113 _vRealignBuffer(ulEndPos, pTmpBuf); 114 } 115 } 116 117 // if there are buffere on the done queue, pop them off the head and 118 // push them on the head of qhTempHead. This will reorder them so 119 // that the more recently used ones will be in the front of the queue. 120 // Pass them all to _vRealignBuffer. If the rc from _vRealignBuffer is 121 // 0 then there is no unprocessed data in the buffer (it is ready to 122 // be returned) so put it on the Tail of the done queue. 123 // If the rc is 1 then put it on the head of the InProcess queue. 124 125 while (qhDone.IsElements()) { 126 pTempHead->PushOnHead(qhDone.PopHead()); 127 } 128 129 while (pTempHead->IsElements()) 130 { 131 usRC = _vRealignBuffer(ulEndPos, (PSTREAMBUFFER)pTempHead->Head()); 132 if (usRC) 133 qhInProcess.PushOnHead(pTempHead->PopHead()); 134 else 135 qhDone.PushOnTail(pTempHead->PopHead()); 136 } 137 while (qhDone.IsElements()) { 138 ReturnBuffer(); 139 } 140 break; 141 default: 142 break; 143 } /* endswitch */ 153 144 } 154 145 … … 163 154 #pragma on (unreferenced) 164 155 { 165 ULONG space, byteswritten, curspace,i; 166 167 // dgprintf(("AddBuffers %d",fFirst == TRUE?1:2)); 168 169 byteswritten = 0; 170 if (ulStreamType & STREAM_WRITE) 156 ULONG ulSpace, ulBytesWritten; 157 ULONG ulDAZ; 158 159 //dgprintf(("WS:AddBuffers First=%d, SampleSize=%lx", fFirst, _configinfo.ulSampleSize)); 160 161 ulBytesWritten = 0; 162 if (ulStreamType & STREAM_WRITE) 171 163 { 172 164 // get the space available in the hardware buffer … … 175 167 // could keep us in this loop writing 4 or 8 bytes at a time. 176 168 // In extream cases we will stay stuck in this loop long enough to casue a trap rjj 177 if (pahw->GetSpace(StreamId, &_configinfo, &space) == FALSE)169 if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE) 178 170 { 179 // dgprintf(("WAVESTREAM::AddBuffers Error 1"));171 dgprintf(("WAVESTREAM::AddBuffers GetSpace failed")); 180 172 return; 181 173 } 182 space &= (~(_configinfo.ulSampleSize - 1)); 183 // curspace = min(space, _configinfo.ulBytesPerIRQ/_configinfo.ulSampleSize * 2); 184 curspace = space; 185 while (space && qhInProcess.IsElements()) 174 ulSpace &= (~(_configinfo.ulSampleSize - 1)); 175 ulDAZ = 0; 176 while (ulSpace && qhInProcess.IsElements()) 186 177 { 187 // Fisrt time going in task time 188 // for I7 need give time for interrupt time 189 if (fFirst == TRUE) //PS+++ 190 { 191 cli(); 192 // DevHelp_ProcBlock (space, 20, 0); 193 } 194 // dgprintf(("AddBuffers write %ld SSize:%ld %d",space, _configinfo.ulSampleSize, fFirst == TRUE?1:2)); 195 byteswritten = AddBuffer(space > curspace? curspace: space); 196 if (pahw->GetSpace(StreamId, &_configinfo, &curspace) == FALSE) 197 { 198 // dgprintf(("WAVESTREAM::AddBuffers Error 2")); 199 break; 200 } 201 if(byteswritten == (ULONG)-1) 202 break; 203 if (!curspace) 204 { 205 curspace = _configinfo.ulSampleSize; 206 } 207 space -= byteswritten; 208 space &= ( ~(_configinfo.ulSampleSize - 1)); 209 } 210 211 } 212 // dgprintf(("AddBuffers %d End",fFirst == TRUE?1:2)); 213 } 178 if (ulDAZ++ > 20) { 179 dgprintf(("WAVESTREAM::AddBuffers DAZ break")); // Temporary hack to prevent lockups when uniaud32 stops (underrun) 180 break; 181 } 182 // First time is in task time. For I7 need to give time for interrupt time 183 if (fFirst == TRUE) //PS+++ 184 { 185 //cli(); 186 DevHelp_ProcBlock (0x5541, 20, 0); // ok since the first call is at task time 187 ulBytesWritten = AddBuffer(ulSpace); 188 return; 189 } 190 ulBytesWritten = AddBuffer(ulSpace); 191 if (ulBytesWritten == (ULONG)-1) break; 192 ulSpace -= ulBytesWritten; 193 ulSpace &= ( ~(_configinfo.ulSampleSize - 1)); 194 } 195 196 } 197 } 198 214 199 //****************************************************************************** 215 200 // write one buffer to the audio buffer 1 … … 218 203 // there are buffers on pHead... BEWARE 219 204 //****************************************************************************** 220 ULONG WAVESTREAM::AddBuffer(ULONG space)205 ULONG WAVESTREAM::AddBuffer(ULONG ulSpace) 221 206 { 222 207 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head(); 223 ULONG pdataBuf; 224 ULONG Buff_left, byteswritten, start_pos; 225 226 // ddprintf(("AddBuffer")); 227 // make sure we have a buffer to copy from..... 228 if (!pTemp) 208 ULONG pDataBuf; 209 ULONG ulBuffLeft; 210 ULONG ulBytesWritten; 211 ULONG ulStartPos; 212 213 /* make sure we have a buffer to copy from */ 214 if (!pTemp) 229 215 { 230 216 return (ULONG)-1; 231 217 } 232 218 233 // get the starting position. Call WaveGetHwPtr. if we get a bad rc 234 // then we bail out. 235 if(pahw->GetHwPtr(StreamId, &_configinfo, &start_pos) == FALSE) 219 /* make sure there is space in the output buffer */ 220 if (!ulSpace) 221 { 222 return (ULONG)-1; 223 } 224 225 /* PS+++ if input buffer is ZERO do nothing and ask for give new buffer, See REMARK in mmpm2.inf */ 226 if (!pTemp->ulBuffsz) 227 { 228 qhDone.PushOnTail(qhInProcess.PopHead()); 229 return (ULONG)-1; 230 } 231 232 // get the starting position. Call WaveGetHwPtr. if we get a bad rc then we bail out. 233 if(pahw->GetHwPtr(StreamId, &_configinfo, &ulStartPos) == FALSE) 236 234 { 237 235 dgprintf(("WAVESTREAM::AddBuffer Err in GetHwPtr")); … … 240 238 } 241 239 242 if (!pTemp->ulBuffsz || !space) 243 { 244 dgprintf(("WAVESTREAM::AddBuffer 0, Bufsz:%ld Space:%ld",pTemp->ulBuffsz, space)); 245 //PS+++ if is ZERO do nothing and ask for give new buffer, See REMARK in mmpm2.inf 240 // get the buffer pointer and amount of data remaining 241 pDataBuf = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; /* points to the beginning of data in src buffer */ 242 ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos; /* amount of src data left to transfer */ 243 //dgprintf(("WS::AddBuffer buf=%lx remain=%lx, space=%lx bp=%lx dp=%lx size=%lx", pTemp->pBuffptr, ulBuffLeft, ulSpace, pTemp->ulBuffpos, pTemp->ulDonepos, pTemp->ulBuffsz)); 244 ulBuffLeft = min(ulBuffLeft, ulSpace); /* the smaller of src data left or dst space available */ 245 246 if (pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesWritten) == FALSE) 247 { 248 // This could mean that the hardware has underrun TODO: implement underrun logic 249 dgprintf(("WS::AddBuffer: pahw->Transfer failed")); 250 return (ULONG)-1; 251 } 252 if (ulBytesWritten == 0) 253 { 254 // This could mean that the hardware has underrun TODO: implement underrun logic 255 dgprintf(("WS::AddBuffer: 0 of %lx bytes written by transfer", ulBuffLeft)); 256 return (ULONG)-1; /* DAZ check into returning zero, returning 0 may cause lockup */ 257 } 258 //dgprintf(("WS::AddBuffer added %lx from %lx BuffPos=%lx sz=%lx bw=%lx dp=%lx", ulBytesWritten, pTemp->pBuffptr, pTemp->ulBuffpos, pTemp->ulBuffsz, _ulBytesWritten, pTemp->ulDonepos)); 259 260 _ulBytesWritten += ulBytesWritten; /* update the running counter */ 261 pTemp->ulBuffpos += ulBytesWritten; /* update the buffer pos counter */ 262 pTemp->ulDonepos = _ulBytesWritten; /* update the done Position for returning the buffer */ 263 264 // check to see if the whole buffer has been copied and needs to be put on the done queue 265 if (pTemp->ulBuffpos >= (pTemp->ulBuffsz /* & 0xFFFFFFFC*/)) /* DAZ */ 266 { 267 //dgprintf(("WS::AddBuffer done with buffer %lx dp=%lx", pTemp->pBuffptr, pTemp->ulDonepos)); 246 268 qhDone.PushOnTail(qhInProcess.PopHead()); 247 // DebugInt3(); 248 return -1; 249 } 250 // get the buffer pointer and amount of data remaining 251 pdataBuf = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; 252 Buff_left = pTemp->ulBuffsz - pTemp->ulBuffpos; 253 Buff_left = min(Buff_left, space); 254 255 if (pahw->Transfer(StreamId, &_configinfo, pdataBuf, Buff_left, &byteswritten) == FALSE) 256 { 257 dgprintf(("AddBuffer: pahw->Transfer failed!!")); 258 // DebugInt3(); 259 return (ULONG)-1; 260 } 261 if (byteswritten == 0) 262 { 263 dgprintf(("AddBuffer: No more room!!")); 264 // DebugInt3(); 265 //PS+++ return (ULONG)-1; //no more room 266 return 0; //PS+++ may be in next time? 267 } 268 // update the buffer pos counter 269 pTemp->ulBuffpos += byteswritten; 270 271 // update the done Position 272 pTemp->ulDonepos = start_pos + byteswritten; 273 274 // check to see if the buffer has been copied and needs to be put on the done queue 275 if (pTemp->ulBuffpos >= (pTemp->ulBuffsz & 0xFFFFFFFC)) 276 { 277 qhDone.PushOnTail(qhInProcess.PopHead()); 278 } 279 // dgprintf(("WV::AddBuffer sz %lx, bywr %lx dp %lx", Buff_left, byteswritten,pTemp->ulDonepos)); 280 return byteswritten; 269 } 270 return ulBytesWritten; 281 271 } 282 272 //****************************************************************************** … … 287 277 { 288 278 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head(); 289 ULONG pdataBuf; 290 ULONG Buff_left, bytesread; 291 292 if(!pTemp) 293 return FALSE; 279 ULONG pDataBuf; 280 ULONG ulBuffLeft, ulBytesRead; 281 282 if(!pTemp) return FALSE; 294 283 295 284 // get the buffer pointer and amount of data remaining 296 p dataBuf = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos;297 Buff_left = pTemp->ulBuffsz - pTemp->ulBuffpos;285 pDataBuf = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; 286 ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos; 298 287 299 288 // read wave data 300 if(pahw->Transfer(StreamId, &_configinfo, p dataBuf, Buff_left, &bytesread) == FALSE)301 { 302 dprintf(("_vReadAudioBuf: pahw->Transfer failed!!"));303 return FALSE;304 }305 if(bytesread == 0) {306 return FALSE; //no more data307 } 308 309 // dprintf4(("_vReadAudioBuf %lx size %ld, bytes read %ld", pdataBuf, Buff_left, bytesread)); 289 if(pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesRead) == FALSE) 290 { 291 return FALSE; /* No more data */ 292 } 293 if(ulBytesRead == 0) { 294 return FALSE; /* No more data */ 295 } 296 if (ulBytesRead > ulBuffLeft) { 297 return FALSE; /* Internal error */ 298 } 310 299 311 300 // update the buffer pos counter 312 pTemp->ulBuffpos += bytesread; 313 _ulBytesProcessed += bytesread; 301 pTemp->ulBuffpos += ulBytesRead; 302 _ulBytesProcessed += ulBytesRead; 303 304 //dprintf(("_vReadAudioBuf %lx Requested=%lx Read=%lx Remain=%lx Processed=%lx", pDataBuf, ulBuffLeft, ulBytesRead, pTemp->ulBuffsz-pTemp->ulBuffpos, _ulBytesProcessed)); 314 305 315 306 if(pTemp->ulBuffpos == pTemp->ulBuffsz) { 316 307 qhDone.PushOnTail(qhInProcess.PopHead()); 317 308 ReturnBuffer(); 318 dprintf(("_vReadAudioBuf return buffer %lx size %ld, bytes read %ld position %ld", (ULONG)pTemp->pBuffptr, pTemp->ulBuffsz, bytesread, _ulBytesProcessed));319 309 } 320 310 … … 328 318 // can be returned and finally process any events pending. 329 319 //****************************************************************************** 330 USHORT ProcNumber = 0;331 320 void DBGCALLCONV WAVESTREAM::Process(void) 332 321 { 333 PSTREAMBUFFER ptemp; 334 ULONG ulCurBytesProcessed = 0; 335 USHORT CurProcNumber = ProcNumber++; 336 ULONG space; 337 338 #ifdef DEBUG 339 // ddprintf(("WAVESTREAM::Process %d",CurProcNumber)); 340 #endif 322 PSTREAMBUFFER pTemp; 323 ULONG ulBytes; 324 ULONG ulDAZ; 325 326 //ddprintf(("WAVESTREAM::Process Start")); 341 327 342 328 // get the stream position. if we get a bad rc or the position is 0 … … 344 330 // GetPostiion returns the adjusted hw pointer from the ALSA status ioctl 345 331 // This is really a running total of bytes consumed by the hardware. 346 if(pahw->GetPosition(StreamId, &_configinfo, &ulCurBytesProcessed) == FALSE) 332 // DAZ - Note that this is a 32 bit counter and will wrap at sometime. ALSA 333 // attempts to wrap this counter intelligently. I haven't determined what 334 // effect, if any, the wrapping of this counter will have playing a stream. 335 if(pahw->GetPosition(StreamId, &_configinfo, &ulBytes) == FALSE) 347 336 { 348 337 ddprintf(("Error No bytes processed")); … … 350 339 return; 351 340 } 352 // ddprintf(("StPos: %lx", ulCurBytesProcessed)); 353 // save the bytes processed in the stream object 354 _ulBytesProcessed = ulCurBytesProcessed; 355 356 switch (ulStreamType & STREAM_WRITE) 357 { 358 359 // if there are buffers that have been completly written to the audio buffer 360 // check the first one on the done queue 361 // if it's data has been consumed by the hardware return it. 362 // 363 // Bug #18 Sometimes MMPM gives us really small buffers. If we 364 // wait for the buffer to be completly consumed and there is a tiny buffer 365 // on the queue after this one, the sound part could underrun before we get a 366 // chance to refill it. To fix this we will return the buffer if it will be 367 // consumed before the next call to WAVESTREAM:Process(). 368 // rjj Fix for Bug #18 28082008 341 _ulBytesProcessed = ulBytes; 342 343 switch (ulStreamType & STREAM_WRITE) 344 { 369 345 case STREAM_WRITE: 370 { 371 if (qhDone.IsElements()) 346 if (qhInProcess.IsElements()) 372 347 { 373 ptemp = (PSTREAMBUFFER)qhDone.Head(); 374 while ((_ulBytesProcessed + _configinfo.ulBytesPerIRQ) >= ptemp->ulDonepos) 375 { 376 ReturnBuffer(); 377 ptemp = (PSTREAMBUFFER)qhDone.Head(); 378 } 348 AddBuffers(FALSE); 379 349 } 380 if ((pahw->GetSpace(StreamId, &_configinfo, &space) != FALSE) 381 && qhInProcess.IsElements()) 382 { 383 AddBuffers(FALSE); 384 } 385 386 break; 387 388 } 350 // Return any buffers that have been completely written to uniaud32 351 while (qhDone.IsElements()) { 352 pTemp = (PSTREAMBUFFER)qhDone.Head(); /* get a pointer to the first completed buffer */ 353 // Hang on to the last buffer until the hardware is done writing the data 354 // We do this because MMPM uses the return of the last buffer to determine when we are 355 // done playing the stream 356 if ((qhDone.Head() == qhDone.Tail()) && !qhInProcess.IsElements() && (_ulBytesProcessed < pTemp->ulDonepos)) break; /* only one buffer left */ 357 ReturnBuffer(); 358 } 359 break; 389 360 case STREAM_READ: 390 while(_vReadAudioBuf()); 391 break; 361 ulDAZ = 0; 362 while(_vReadAudioBuf()) { 363 if (ulDAZ++ > 20) { /* temporary hack to prevent hangs when uniaud32 stops (overruns) */ 364 ddprintf(("WAVESTREAM::Process Read DAZ Break")); 365 break; 366 } 367 } 368 break; 392 369 default: 393 370 break; … … 395 372 396 373 ProcessEvents(); 397 // ddprintf(("WAVESTREAM::Process %d End",CurProcNumber));374 //ddprintf(("WAVESTREAM::Process End")); 398 375 } 399 376 //****************************************************************************** … … 404 381 { 405 382 PSTREAMBUFFER pStreamBuf = new STREAMBUFFER(uLength, pbuf); 406 383 407 384 return Write(pStreamBuf); 408 385 } … … 420 397 { 421 398 qhInProcess.PushOnTail((PQUEUEELEMENT)new STREAMBUFFER(uLength, pbuf)); 422 // dprintf2(("WAVESTREAM::Read: Push on tail %lx %d", pbuf, uLength));399 //dprintf2(("WAVESTREAM::Read: Push on tail %lx %lx", pbuf, uLength)); 423 400 return 0; 424 401 } … … 441 418 ULONG Seconds, MilliSeconds, Overflow, Processed; 442 419 443 //PS++ optimize code420 //PS++ optimize code 444 421 Processed = _ulBytesProcessed; 445 422 if (ulStreamState == STREAM_STREAMING) // if the stream is active … … 449 426 if (pahw->GetPosition(StreamId, &_configinfo, &Processed) == FALSE) 450 427 { 451 //DebugInt3();428 //DebugInt3(); 452 429 Processed = _ulBytesProcessed; //last known position 453 430 } … … 455 432 } 456 433 457 // if we haven't processed anything then just return 458 // _ulTimeBase 434 // if we haven't processed anything then just return _ulTimeBase 459 435 if(Processed == 0) 460 436 return(_ulTimeBase); … … 470 446 ULONG WAVESTREAM::GetCurrentPos(void) 471 447 { 472 ULONG Processed; 473 474 //PS++ optimize code 475 Processed = _ulBytesProcessed; 476 if (ulStreamState == STREAM_STREAMING) // if the stream is active 477 { 478 if (ulStreamType & STREAM_WRITE) 479 { 480 if (pahw->GetPosition(StreamId, &_configinfo, &Processed) == FALSE) 481 { 482 DebugInt3(); 483 Processed = _ulBytesProcessed; //last known position 484 } 448 ULONG Processed; 449 450 //PS++ optimize code 451 Processed = _ulBytesProcessed; 452 if (ulStreamState == STREAM_STREAMING) // if the stream is active 453 { 454 if (ulStreamType & STREAM_WRITE) 455 { 456 if (pahw->GetPosition(StreamId, &_configinfo, &Processed) == FALSE) 457 { 458 DebugInt3(); 459 Processed = _ulBytesProcessed; //last known position 460 } 461 } 485 462 } 486 } 487 488 return Processed; 463 return Processed; 489 464 } 490 465 //****************************************************************************** … … 498 473 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhDone.Tail(); 499 474 500 if(!pTemp) 475 if(!pTemp) 501 476 { 502 477 pTemp = (PSTREAMBUFFER)qhInProcess.Head(); 503 478 } 504 if(pTemp) 479 if(pTemp) 505 480 { 506 481 writepos = pTemp->ulBuffpos; … … 517 492 void WAVESTREAM::SetCurrentTime(ULONG time) 518 493 { 494 //ddprintf(("SetCurrentTime: %lx", time)); 519 495 _ulTimeBase = time; 520 496 } … … 525 501 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head(); 526 502 527 #ifdef DEBUG 528 // ddprintf(("WAVESTREAM::StartStream")); 529 #endif 530 531 if(ulStreamState == STREAM_STREAMING) 503 if(ulStreamState == STREAM_STREAMING) 532 504 { 533 505 ddprintf(("StartStream: already playing!!")); … … 537 509 // configure the wave device 538 510 // (NOTE: Must call this function; sample rate position is reset there) 539 if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE) 511 if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE) 540 512 { 541 513 ddprintf(("StartStream: ConfigDev failed!!")); 542 514 return ERROR_INSUFF_BUFFER; 543 //goto fail;515 //goto fail; 544 516 } 545 517 // prepare wave device for playback/recording 546 if(pahw->Prepare(StreamId) == FALSE) 518 if(pahw->Prepare(StreamId) == FALSE) 547 519 { 548 520 ddprintf(("StartStream: Prepare failed!!")); … … 551 523 552 524 _ulBytesProcessed = 0; 525 _ulBytesWritten = 0; 553 526 554 527 ulStreamState = STREAM_STREAMING; 555 528 //Adding the first buffer also starts playback 556 if (ulStreamType == STREAM_WAVE_PLAY) 557 { 558 559 529 if (ulStreamType == STREAM_WAVE_PLAY) 530 { 531 pahw->SetVolume(StreamId, getMixerStreamId(), volume); //PS 532 AddBuffers(TRUE); 560 533 //Must set volume after adding buffers (voices inside sblive driver might not 561 534 //be allocated otherwise (first start) ) 562 535 // dprintf(("SetVolume %lx",volume)); 563 536 // PS, removing to high 564 // pahw->SetVolume(StreamId, getMixerStreamId(), volume); 565 } 566 else 567 { 537 // pahw->SetVolume(StreamId, getMixerStreamId(), volume); 538 } 539 else 540 { 541 //dprintf(("Starting Rec Stream")); 568 542 ulSavedInputGain = pahw->QueryVolume(StreamId, getMixerStreamId()); 569 543 pahw->SetInputSrc(StreamId, getMixerStreamId(), inputsrc); 570 544 pahw->SetVolume(StreamId, getMixerStreamId(), inputgain); 571 545 572 if(pahw->Start(StreamId) != TRUE)573 546 if(pahw->Start(StreamId) != TRUE) 547 { 574 548 dprintf(("pahw->Start failed!!")); 575 549 goto fail; 576 550 } 577 551 } 578 // ddprintf(("WAVESTREAM::StartStream %lx End", StreamId));579 552 return NO_ERROR; 580 553 … … 602 575 603 576 ulStreamState = STREAM_STOPPED; 604 // ddprintf(("WAVESTREAM::StopStream %lx", StreamId)); 577 //ddprintf(("WAVESTREAM::StopStream %lx", StreamId)); 578 605 579 ReturnBuffers(); 606 580 pControl->ulTime = GetCurrentTime(); … … 610 584 // DDCMD_ENABLE_EVENT the event time will get screwed up. rjj 611 585 _ulBytesProcessed = 0; 586 _ulBytesWritten = 0; 612 587 return NO_ERROR; 613 588 } … … 616 591 ULONG WAVESTREAM::PauseStream(PCONTROL_PARM pControl) 617 592 { 618 ULONG endpos; 619 620 pahw->GetPosition(StreamId, &_configinfo, &endpos); 593 ULONG ulEndPos, ulEndPos2; 594 595 if(ulStreamState == STREAM_PAUSED) { 596 dprintf(("WAVESTREAM::PauseStream %lx (already paused)", StreamId)); 597 pControl->ulTime = GetCurrentTime(); 598 return NO_ERROR; 599 } 600 601 pahw->GetPosition(StreamId, &_configinfo, &ulEndPos); 621 602 //silence wave stream before stopping it (removes clicks) 622 603 pahw->SetVolume(StreamId, getMixerStreamId(), 0); 623 604 pahw->Stop(StreamId); 624 605 606 /* DAZ test code begin */ 607 if (pahw->GetPosition(StreamId, &_configinfo, &ulEndPos2) == FALSE) ulEndPos2 = 0; 608 if (ulEndPos2 != ulEndPos) { 609 ddprintf(("WAVESTREAM::PauseStream %lx!=%lx", ulEndPos, ulEndPos2)); 610 if (ulEndPos2) ulEndPos = ulEndPos2; 611 } 612 /* DAZ test code end */ 613 625 614 ulStreamState = STREAM_PAUSED; 626 615 627 616 ddprintf(("WAVESTREAM::PauseStream %lx", StreamId)); 628 617 629 _vRealignPausedBuffers(endpos); 630 631 _ulBytesProcessed = endpos; 618 _ulBytesProcessed = ulEndPos; 619 620 _vRealignPausedBuffers(ulEndPos); 621 632 622 pControl->ulTime = GetCurrentTime(); 623 633 624 _ulBytesProcessed = 0; 625 _ulBytesWritten = 0; 626 634 627 return NO_ERROR; 635 628 } … … 639 632 { 640 633 #ifdef DEBUG 641 dprintf(("WAVESTREAM::ResumeStream %lx", StreamId));634 //dprintf(("WAVESTREAM::ResumeStream %lx", StreamId)); 642 635 #endif 643 636 return StartStream(); … … 647 640 BOOL WAVESTREAM::SetProperty(int type, ULONG value, ULONG reserved) 648 641 { 649 #ifdef DEBUG650 // dprintf(("WAVESTREAM::SetProperty"));651 #endif652 653 642 switch(type) { 654 643 case PROPERTY_VOLUME: … … 677 666 ULONG WAVESTREAM::GetProperty(int type) 678 667 { 679 #ifdef DEBUG680 // dprintf(("WAVESTREAM::GetProperty"));681 #endif682 668 switch(type) { 683 669 case PROPERTY_FREQUENCY: … … 699 685 STREAM(streamtype, filesysnum, mixerStreamId) 700 686 { 701 #ifdef DEBUG702 dprintf(("WS::WS:S"));703 #endif704 687 // get the pointer to the hardware object 705 688 pahw = (WAVEAUDIO*)GetHardwareDevice(streamtype); … … 710 693 _configinfo.ulNumChannels = pinit->sChannels; 711 694 _configinfo.ulDataType = pinit->sMode; 695 _ulBytesWritten = 0; 712 696 _ulBytesProcessed = 0; 713 697 _ulTimeBase = 0; 714 //_ulUnderrunBase = 0;715 698 ulSavedInputGain = 0; 716 699 … … 746 729 pinit->ulFlags |= pahw->QueryDataFlags(pinit->ulOperation, pinit->sMode, pinit->lBitsPerSRate); 747 730 748 //fUnderrun = FALSE;749 731 StreamId = 0; 750 732 … … 755 737 } 756 738 757 //dprintf(("WAVESTREAM stream %lx ctor %lx: rate %d bps %d numchan %d type %x", hstream, StreamId, (USHORT)_configinfo.ulSampleRate, (USHORT)_configinfo.ulBitsPerSample, (USHORT)_configinfo.ulNumChannels, (USHORT)_configinfo.ulNumChannels, (USHORT)_configinfo.ulDataType));739 //dprintf(("WAVESTREAM stream %lx ctor %lx: rate %d bps %d numchan %d type %x", hstream, StreamId, (USHORT)_configinfo.ulSampleRate, (USHORT)_configinfo.ulBitsPerSample, (USHORT)_configinfo.ulNumChannels, (USHORT)_configinfo.ulNumChannels, (USHORT)_configinfo.ulDataType)); 758 740 } 759 741 //****************************************************************************** … … 761 743 WAVESTREAM::~WAVESTREAM() 762 744 { 763 //dprintf(("WAVESTREAM stream %x dtor %lx", hstream, StreamId));745 //dprintf(("WAVESTREAM stream %x dtor %lx", hstream, StreamId)); 764 746 if(_configinfo.pConversionBuffer) { 765 747 if(DevHelp_VMFree(_configinfo.pConversionBuffer) != 0) {
Note:
See TracChangeset
for help on using the changeset viewer.