Changeset 512
- Timestamp:
- Jul 11, 2010, 5:47:24 PM (15 years ago)
- Location:
- OCO/branches/DAZ
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
OCO/branches/DAZ/drv16/wavestrm.cpp
r486 r512 1 1 /* SCCSID = %W% %E% */ 2 2 /**************************************************************************** 3 * 4 * Copyright (c) IBM Corporation 1994 - 1997. 5 * 6 * The following IBM OS/2 source code is provided to you solely for the 3 * * 4 * Copyright (c) IBM Corporation 1994 - 1997. * 5 * * 6 * The following IBM OS/2 source code is provided to you solely for the * 7 7 * the purpose of assisting you in your development of OS/2 device drivers. * 8 * You may use this code in accordance with the IBM License Agreement 9 * provided in the IBM Device Driver Source Kit for OS/2. 10 * 8 * You may use this code in accordance with the IBM License Agreement * 9 * provided in the IBM Device Driver Source Kit for OS/2. * 10 * * 11 11 ****************************************************************************/ 12 12 /**@internal %W% … … 14 14 * @version %I% 15 15 * @context Unless otherwise noted, all interfaces are Ring-0, 16-bit, 16 * 16 * <stack context>. 17 17 * @history 18 18 * 19 19 */ 20 20 #define INCL_NOPMAPI 21 #define INCL_DOSERRORS 21 #define INCL_DOSERRORS // for ERROR_INVALID_FUNCTION 22 22 #include <os2.h> 23 23 #include <os2me.h> 24 #include <audio.h> 24 #include <audio.h> // for #define MIDI 25 25 #include <string.h> 26 26 #include <include.h> … … 44 44 45 45 //****************************************************************************** 46 // 47 // 48 // 49 // 46 // _vRealignBuffer 47 // called just after a wave stream pause on a playback. 48 // Gets the end position of the stream when paused and a pointer to a 49 // STREAMBUFFER. Basicly this function looks at the streambuffer and if 50 50 // there is any unplayed data in it it adjusts the bufpos counter. 51 51 // the donepos counter is ALWAYS set to zero. It will return 0 if all 52 52 // the data has been played and 1 if there is still some data left. 53 53 //****************************************************************************** 54 USHORT 54 USHORT WAVESTREAM::_vRealignBuffer(ULONG ulEndPos, PSTREAMBUFFER pBuffer) 55 55 { 56 56 if (ulEndPos >= pBuffer->ulDonepos) { /* all of the data has been consumed */ … … 115 115 } 116 116 117 // if there are buffer eon the done queue, pop them off the head and117 // if there are buffers on the done queue, pop them off the head and 118 118 // push them on the head of qhTempHead. This will reorder them so 119 119 // that the more recently used ones will be in the front of the queue. … … 122 122 // be returned) so put it on the Tail of the done queue. 123 123 // If the rc is 1 then put it on the head of the InProcess queue. 124 125 124 while (qhDone.IsElements()) { 126 125 pTempHead->PushOnHead(qhDone.PopHead()); … … 130 129 { 131 130 usRC = _vRealignBuffer(ulEndPos, (PSTREAMBUFFER)pTempHead->Head()); 132 if (usRC) 131 if (usRC) { 133 132 qhInProcess.PushOnHead(pTempHead->PopHead()); 134 else 135 qhDone.PushOnTail(pTempHead->PopHead()); 133 } else { 134 qhDone.PushOnHead(pTempHead->PopHead()); 135 } 136 136 } 137 137 while (qhDone.IsElements()) { … … 142 142 break; 143 143 } /* endswitch */ 144 delete pTempHead; // free the memory 145 } 146 147 void WAVESTREAM::_vUnderrunStop(PCHAR pchStr) 148 { 149 if (ulStreamState == STREAM_STOPPED) return; 150 rprintf(("%s: Buffer Underrun-stop", pchStr)); 151 pahw->SetVolume(StreamId, getMixerStreamId(), 0); 152 pahw->Stop(StreamId); 153 ulStreamState = STREAM_STOPPED; 154 fUnderrun = TRUE; 155 _ulBytesProcessed = 0; 156 _ulBytesWritten = 0; 157 } 158 159 ULONG WAVESTREAM::_vUnderrunStart(void) 160 { 161 if (ulStreamState == STREAM_STREAMING) return 0; 162 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head(); 163 if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE) { 164 rprintf(("WS::Write: ConfigDev failed")); 165 return ERROR_INSUFF_BUFFER; 166 } 167 // prepare wave device for playback/recording 168 if(pahw->Prepare(StreamId) == FALSE) { 169 rprintf(("WS::Write: Prepare failed")); 170 return ERROR_START_STREAM; 171 } 172 173 _ulBytesProcessed = 0; 174 _ulBytesWritten = 0; 175 ulStreamState = STREAM_STREAMING; 176 fUnderrun = FALSE; 177 if (ulStreamType == STREAM_WAVE_PLAY) pahw->SetVolume(StreamId, getMixerStreamId(), volume); 178 return 0; 144 179 } 145 180 … … 154 189 #pragma on (unreferenced) 155 190 { 156 191 ULONG ulSpace, ulBytesWritten; 157 192 ULONG ulDAZ; 158 159 //dgprintf(("WS:AddBuffers First=%d, SampleSize=%lx", fFirst, _configinfo.ulSampleSize)); 160 161 ulBytesWritten = 0; 162 if (ulStreamType & STREAM_WRITE) 163 { 164 // get the space available in the hardware buffer 165 // only call GetSpace once because the amount of free space in 166 // the hardware buffer is a moving target and calling it more than once 167 // could keep us in this loop writing 4 or 8 bytes at a time. 168 // In extream cases we will stay stuck in this loop long enough to casue a trap rjj 169 if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE) 170 { 171 dgprintf(("WAVESTREAM::AddBuffers GetSpace failed")); 172 return; 173 } 174 ulSpace &= (~(_configinfo.ulSampleSize - 1)); 193 ULONG ulStatus; 194 195 //dprintf(("WS:AddBuffers First=%d, SampleSize=%lx", fFirst, _configinfo.ulSampleSize)); 196 197 ulBytesWritten = 0; 198 if (ulStreamType & STREAM_WRITE) 199 { 200 // get the space available in the hardware buffer 201 // only call GetSpace once because the amount of free space in 202 // the hardware buffer is a moving target and calling it more than once 203 // could keep us in this loop writing 4 or 8 bytes at a time. 204 // In extream cases we will stay stuck in this loop long enough to casue a trap rjj 205 if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE) { 206 rprintf(("WAVESTREAM::AddBuffers GetSpace failed")); 207 return; 208 } 209 ulSpace &= (~(_configinfo.ulSampleSize - 1)); 210 #if 1 211 if (ulSpace == 0) { 212 OSS16_WaveGetStatus(StreamId, &ulStatus); 213 rprintf(("WAVESTREAM::AddBuffers ulSpace=0, u32status=%lx", ulStatus)); 214 215 _vUnderrunStop("WS:AB"); 216 _vUnderrunStart(); 217 218 if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE) { 219 rprintf(("WS::AB GetSpace failed")); 220 return; 221 } 222 ulSpace &= (~(_configinfo.ulSampleSize - 1)); 223 } 224 #endif 175 225 ulDAZ = 0; 176 177 226 while (ulSpace && qhInProcess.IsElements()) 227 { 178 228 if (ulDAZ++ > 20) { 179 dgprintf(("WAVESTREAM::AddBuffers DAZ break")); // Temporary hack to prevent lockups when uniaud32 stops (underrun) 229 rprintf(("WAVESTREAM::AddBuffers DAZ break")); // Temporary hack to prevent lockups when uniaud32 stops (underrun) 230 int3(); /* should never happen */ 180 231 break; 181 232 } 182 // First time is in task time. For I7 need to give time for interrupt time 183 if (fFirst == TRUE) //PS+++ 184 { 233 #if 0 234 //DAZ move the ProcBlock to the start stream code, if really needed 235 // First time is in task time. For I7 need to give time for interrupt time 236 if (fFirst == TRUE) //PS+++ 237 { 185 238 //cli(); 186 187 239 DevHelp_ProcBlock (0x5541, 20, 0); // ok since the first call is at task time 240 ulBytesWritten = AddBuffer(ulSpace); 188 241 return; 189 242 } 190 ulBytesWritten = AddBuffer(ulSpace); 191 if (ulBytesWritten == (ULONG)-1) break; 192 ulSpace -= ulBytesWritten; 193 ulSpace &= ( ~(_configinfo.ulSampleSize - 1)); 194 } 195 196 } 197 } 198 199 //****************************************************************************** 200 // write one buffer to the audio buffer 1 201 // the caller of this function MUST make sure it ok to write the audio buffer.. 202 // _AudioBufWrite will not check if there is room in the audio buffer of if 203 // there are buffers on pHead... BEWARE 243 #endif 244 ulBytesWritten = AddBuffer(ulSpace); 245 if (ulBytesWritten == (ULONG)-1) { 246 OSS16_WaveGetStatus(StreamId, &ulStatus); 247 rprintf(("WAVESTREAM::AddBuffers AddBuffer returns -1 u32Status=%lx", ulStatus)); 248 break; 249 } 250 ulSpace -= ulBytesWritten; 251 ulSpace &= ( ~(_configinfo.ulSampleSize - 1)); 252 } 253 // if (ulSpace) { 254 // dprintf(("WAVESTREAM::AddBuffers done. ulSpace=%lx", ulSpace)); 255 // } 256 } 257 } 258 259 //****************************************************************************** 260 // write one buffer to the audio buffer in uniaud32 204 261 //****************************************************************************** 205 262 ULONG WAVESTREAM::AddBuffer(ULONG ulSpace) 206 263 { 207 208 209 264 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head(); 265 ULONG pDataBuf; 266 ULONG ulBuffLeft; 210 267 ULONG ulBytesWritten; 211 //DAZ ULONG ulStartPos; 212 213 /* make sure we have a buffer to copy from */ 214 if (!pTemp) 215 { 216 return (ULONG)-1; 217 } 268 269 /* make sure we have a buffer to copy from */ 270 if (!pTemp) return (ULONG)-1; 218 271 219 272 /* make sure there is space in the output buffer */ 220 if (!ulSpace) 221 { 222 return (ULONG)-1; 223 } 273 if (!ulSpace) return (ULONG)-1; 224 274 225 275 /* 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 /* DAZ */ 233 #if 0 234 // get the starting position. Call WaveGetHwPtr. if we get a bad rc then we bail out. 235 if(pahw->GetHwPtr(StreamId, &_configinfo, &ulStartPos) == FALSE) 236 { 237 dgprintf(("WAVESTREAM::AddBuffer Err in GetHwPtr")); 238 DebugInt3(); 239 return (ULONG)-1; 240 } 241 #endif 242 243 // get the buffer pointer and amount of data remaining 244 pDataBuf = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; /* points to the beginning of data in src buffer */ 245 ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos; /* amount of src data left to transfer */ 246 //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)); 247 ulBuffLeft = min(ulBuffLeft, ulSpace); /* the smaller of src data left or dst space available */ 248 249 if (pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesWritten) == FALSE) 250 { 276 if (!pTemp->ulBuffsz) { 277 qhDone.PushOnTail(qhInProcess.PopHead()); 278 return 0; 279 } 280 if (pTemp->ulBuffsz < (_configinfo.ulBytesPerIRQ*2)) { 281 rprintf(("WS::AB: BufferMode=1")); 282 usBufferMode = 1; 283 } 284 285 // get the buffer pointer and amount of data remaining 286 pDataBuf = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; /* points to the beginning of data in src buffer */ 287 ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos; /* amount of src data left to transfer */ 288 //dprintf(("WS::AddBuffer buf=%lx remain=%lx, space=%lx bp=%lx dp=%lx size=%lx", pTemp->pBuffptr, ulBuffLeft, ulSpace, pTemp->ulBuffpos, pTemp->ulDonepos, pTemp->ulBuffsz)); 289 ulBuffLeft = min(ulBuffLeft, ulSpace); /* the smaller of src data left or dst space available */ 290 291 if (!ulBuffLeft) { 292 qhDone.PushOnTail(qhInProcess.PopHead()); 293 return 0; 294 } 295 296 if (pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesWritten) == FALSE) { 251 297 // This could mean that the hardware has underrun TODO: implement underrun logic 252 dgprintf(("WS::AddBuffer: pahw->Transfer failed")); 253 return (ULONG)-1; 254 } 255 if (ulBytesWritten == 0) 256 { 298 rprintf(("WS::AddBuffer: pahw->Transfer failed")); 299 return (ULONG)-1; 300 } 301 if (ulBytesWritten == 0) { 257 302 // This could mean that the hardware has underrun TODO: implement underrun logic 258 dgprintf(("WS::AddBuffer: 0 of %lx bytes written by transfer", ulBuffLeft));259 return (ULONG)-1; /* DAZ check into returning zero, returning 0 may cause lockup */260 261 //d gprintf(("WS::AddBuffer added %lx from %lx BuffPos=%lx sz=%lx bw=%lx dp=%lx", ulBytesWritten, pTemp->pBuffptr, pTemp->ulBuffpos, pTemp->ulBuffsz, _ulBytesWritten, pTemp->ulDonepos));303 rprintf(("WS::AddBuffer: 0 of %lx bytes written by transfer", ulBuffLeft)); 304 return (ULONG)-1; 305 } 306 //dprintf(("WS::AddBuffer added %lx from %lx BuffPos=%lx sz=%lx bw=%lx dp=%lx", ulBytesWritten, pTemp->pBuffptr, pTemp->ulBuffpos, pTemp->ulBuffsz, _ulBytesWritten, pTemp->ulDonepos)); 262 307 263 308 _ulBytesWritten += ulBytesWritten; /* update the running counter */ 264 265 266 267 268 269 270 //d gprintf(("WS::AddBuffer done with buffer %lx dp=%lx", pTemp->pBuffptr, pTemp->ulDonepos));271 272 273 309 pTemp->ulBuffpos += ulBytesWritten; /* update the buffer pos counter */ 310 pTemp->ulDonepos = _ulBytesWritten; /* update the done Position for returning the buffer */ 311 312 // check to see if the whole buffer has been copied and needs to be put on the done queue 313 if (pTemp->ulBuffpos >= (pTemp->ulBuffsz /* & 0xFFFFFFFC*/)) /* DAZ */ 314 { 315 //dprintf(("WS::AddBuffer done with buffer %lx dp=%lx", pTemp->pBuffptr, pTemp->ulDonepos)); 316 qhDone.PushOnTail(qhInProcess.PopHead()); 317 } 318 return ulBytesWritten; 274 319 } 275 320 //****************************************************************************** … … 279 324 BOOL WAVESTREAM::_vReadAudioBuf(void) 280 325 { 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 326 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head(); 327 ULONG pDataBuf; 328 ULONG ulBuffLeft, ulBytesRead; 329 330 if(!pTemp) return FALSE; 331 332 // get the buffer pointer and amount of data remaining 333 pDataBuf = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; 334 ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos; 335 336 // read wave data 337 if(pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesRead) == FALSE) 338 { 339 return FALSE; /* No more data */ 340 } 341 if(ulBytesRead == 0) { 342 return FALSE; /* No more data */ 343 } 299 344 if (ulBytesRead > ulBuffLeft) { 300 301 } 302 303 304 305 345 return FALSE; /* Internal error */ 346 } 347 348 // update the buffer pos counter 349 pTemp->ulBuffpos += ulBytesRead; 350 _ulBytesProcessed += ulBytesRead; 306 351 307 352 //dprintf(("_vReadAudioBuf %lx Requested=%lx Read=%lx Remain=%lx Processed=%lx", pDataBuf, ulBuffLeft, ulBytesRead, pTemp->ulBuffsz-pTemp->ulBuffpos, _ulBytesProcessed)); 308 353 309 310 311 312 313 314 354 if(pTemp->ulBuffpos == pTemp->ulBuffsz) { 355 qhDone.PushOnTail(qhInProcess.PopHead()); 356 ReturnBuffer(); 357 } 358 359 return TRUE; 315 360 } 316 361 //****************************************************************************** … … 327 372 ULONG ulDAZ; 328 373 329 //d dprintf(("WAVESTREAM::Process Start"));330 331 332 333 334 374 //dprintf(("WAVESTREAM::Process Start")); 375 376 // get the stream position. if we get a bad rc or the position is 0 377 // then we bail out. Hopefully this will be better next time. 378 // GetPostiion returns the adjusted hw pointer from the ALSA status ioctl 379 // This is really a running total of bytes consumed by the hardware. 335 380 // DAZ - Note that this is a 32 bit counter and will wrap at sometime. ALSA 336 381 // attempts to wrap this counter intelligently. I haven't determined what 337 382 // effect, if any, the wrapping of this counter will have playing a stream. 338 if(pahw->GetPosition(StreamId, &_configinfo, &ulBytes) == FALSE) 339 { 340 ddprintf(("Error No bytes processed")); 341 DebugInt3(); 342 return; 343 } 344 _ulBytesProcessed = ulBytes; 345 346 switch (ulStreamType & STREAM_WRITE) 347 { 348 case STREAM_WRITE: 349 if (qhInProcess.IsElements()) 350 { 351 AddBuffers(FALSE); 352 } 353 // Return any buffers that have been completely written to uniaud32 383 if(pahw->GetPosition(StreamId, &_configinfo, &ulBytes) == FALSE) 384 { 385 //dprintf(("Error No bytes processed")); 386 DebugInt3(); 387 return; 388 } 389 _ulBytesProcessed = ulBytes; 390 391 switch (ulStreamType & STREAM_WRITE) 392 { 393 case STREAM_WRITE: 394 if(!qhInProcess.IsElements() && !qhDone.IsElements()) { 395 _vUnderrunStop("WS:Process"); 396 break; 397 } 398 if (qhInProcess.IsElements()) AddBuffers(FALSE); 399 // Return any buffers that have been completely written to uniaud32 400 //dprintf(("WS::Process usBufferMode=%x", usBufferMode)); 354 401 while (qhDone.IsElements()) { 355 402 pTemp = (PSTREAMBUFFER)qhDone.Head(); /* get a pointer to the first completed buffer */ 356 403 // Hang on to the last buffer until the hardware is done writing the data 357 404 // We do this because MMPM uses the return of the last buffer to determine when we are 358 405 // done playing the stream 359 if ((qhDone.Head() == qhDone.Tail()) && !qhInProcess.IsElements() && (_ulBytesProcessed < pTemp->ulDonepos)) break; /* only one buffer left */ 406 if ((qhDone.Head() == qhDone.Tail()) && !qhInProcess.IsElements()) { /* only one buffer left */ 407 if (_ulBytesProcessed < pTemp->ulDonepos) break; 408 } else { /* not the last buffer */ 409 /* if the buffer is bigger than BytesPerIRQ and it's not finished yet, hang on to it */ 410 if (!usBufferMode && (_ulBytesProcessed < pTemp->ulDonepos)) break; 411 //if ((_ulBytesProcessed + _configinfo.ulBytesPerIRQ) < pTemp->ulDonepos) break; 412 } 360 413 ReturnBuffer(); 361 414 } 362 363 415 break; 416 case STREAM_READ: 364 417 ulDAZ = 0; 365 418 while(_vReadAudioBuf()) { 366 419 if (ulDAZ++ > 20) { /* temporary hack to prevent hangs when uniaud32 stops (overruns) */ 367 ddprintf(("WAVESTREAM::Process Read DAZ Break"));420 rprintf(("WAVESTREAM::Process Read DAZ Break")); 368 421 break; 369 422 } 370 423 } 371 372 373 374 375 376 377 //ddprintf(("WAVESTREAM::Process End"));424 break; 425 default: 426 break; 427 } /* endswitch */ 428 429 ProcessEvents(); 430 //dprintf(("WAVESTREAM::Process End")); 378 431 } 379 432 //****************************************************************************** … … 383 436 #pragma on (unreferenced) 384 437 { 385 PSTREAMBUFFER pStreamBuf = new STREAMBUFFER(uLength, pbuf); 386 387 return Write(pStreamBuf); 388 } 389 //****************************************************************************** 390 //****************************************************************************** 438 PSTREAMBUFFER pStreamBuf = new STREAMBUFFER(uLength, pbuf); 439 440 return Write(pStreamBuf); 441 } 442 //****************************************************************************** 443 //****************************************************************************** 444 #define SNDRV_PCM_STATE_XRUN 4 /* stream reached an xrun */ 391 445 ULONG WAVESTREAM::Write(PSTREAMBUFFER pStreamBuf) 392 446 { 393 qhInProcess.PushOnTail((PQUEUEELEMENT)pStreamBuf); 394 // dprintf2(("WAVESTREAM::Write: Push on tail %lx %ld", ((PSTREAMBUFFER)qhInProcess.Tail())->pBuffptr, ((PSTREAMBUFFER)qhInProcess.Tail())->ulBuffsz)); 395 return 0; 447 448 #if 1 449 ULONG ulStatus; 450 451 ulStatus = 0; 452 if (OSS16_WaveGetStatus(StreamId, &ulStatus) != OSSERR_SUCCESS) ulStatus = SNDRV_PCM_STATE_XRUN; 453 //dprintf(("WS::Write: status=%lx", ulStatus)); 454 if (ulStatus == SNDRV_PCM_STATE_XRUN) { 455 rprintf(("WS::Write: Xrun detect")); 456 _vUnderrunStop("WS:Write"); 457 fUnderrun = TRUE; 458 } 459 #else 460 if (!fUnderrun && !qhInProcess.IsElements()) { 461 rprintf(("WS::Write: Buffer Underrun detect")); 462 fUnderrun = TRUE; 463 } 464 #endif 465 qhInProcess.PushOnTail((PQUEUEELEMENT)pStreamBuf); 466 //dprintf(("WS::Write: sz=%lx IRQ=%lx", pStreamBuf->ulBuffsz, _configinfo.ulBytesPerIRQ)); 467 // if (pStreamBuf->ulBuffsz < (_configinfo.ulBytesPerIRQ*2)) { 468 // dprintf(("WS::Write: BufferMode=1")); 469 // usBufferMode = 1; 470 // } 471 if (fUnderrun) { 472 _vUnderrunStart(); 473 AddBuffers(FALSE); 474 } 475 return 0; 396 476 } 397 477 //****************************************************************************** … … 399 479 ULONG WAVESTREAM::Read(PSTREAMBUF pbuf, unsigned uLength) 400 480 { 401 402 403 481 qhInProcess.PushOnTail((PQUEUEELEMENT)new STREAMBUFFER(uLength, pbuf)); 482 //dprintf2(("WAVESTREAM::Read: Push on tail %lx %lx", pbuf, uLength)); 483 return 0; 404 484 } 405 485 //****************************************************************************** … … 419 499 ULONG WAVESTREAM::GetCurrentTime() 420 500 { 421 ULONG Seconds, MilliSeconds, Overflow, Processed; 422 423 //PS++ optimize code 424 Processed = _ulBytesProcessed; 425 if (ulStreamState == STREAM_STREAMING) // if the stream is active 426 { 427 if (ulStreamType & STREAM_WRITE) 428 { 429 if (pahw->GetPosition(StreamId, &_configinfo, &Processed) == FALSE) 430 { 431 //DebugInt3(); 432 Processed = _ulBytesProcessed; //last known position 433 } 434 } 435 } 436 437 // if we haven't processed anything then just return _ulTimeBase 438 if(Processed == 0) 439 return(_ulTimeBase); 440 441 Seconds = Processed / _configinfo.ulPCMConsumeRate; 442 Overflow = Processed - (Seconds * _configinfo.ulPCMConsumeRate); 443 MilliSeconds = (Overflow * 1000) / _configinfo.ulPCMConsumeRate; 444 MilliSeconds += (Seconds * 1000); 445 return (MilliSeconds + _ulTimeBase); 446 } 447 //****************************************************************************** 448 //****************************************************************************** 449 ULONG WAVESTREAM::GetCurrentPos(void) 450 { 451 ULONG Processed; 501 ULONG Seconds, MilliSeconds, Overflow, Processed; 452 502 453 503 //PS++ optimize code 454 504 Processed = _ulBytesProcessed; 455 if (ulStreamState == STREAM_STREAMING) // if the stream is active 505 if (ulStreamState == STREAM_STREAMING) // if the stream is active 506 { 507 if (ulStreamType & STREAM_WRITE) 508 { 509 if (pahw->GetPosition(StreamId, &_configinfo, &Processed) == FALSE) 510 { 511 //DebugInt3(); 512 Processed = _ulBytesProcessed; //last known position 513 } 514 } 515 } 516 517 // if we haven't processed anything then just return _ulTimeBase 518 if(Processed == 0) 519 return(_ulTimeBase); 520 521 Seconds = Processed / _configinfo.ulPCMConsumeRate; 522 Overflow = Processed - (Seconds * _configinfo.ulPCMConsumeRate); 523 MilliSeconds = (Overflow * 1000) / _configinfo.ulPCMConsumeRate; 524 MilliSeconds += (Seconds * 1000); 525 return (MilliSeconds + _ulTimeBase); 526 } 527 //****************************************************************************** 528 //****************************************************************************** 529 ULONG WAVESTREAM::GetCurrentPos(void) 530 { 531 ULONG Processed; 532 533 //PS++ optimize code 534 Processed = _ulBytesProcessed; 535 if (ulStreamState == STREAM_STREAMING) // if the stream is active 456 536 { 457 537 if (ulStreamType & STREAM_WRITE) … … 478 558 if(!pTemp) 479 559 { 480 560 pTemp = (PSTREAMBUFFER)qhInProcess.Head(); 481 561 } 482 562 if(pTemp) 483 563 { 484 564 writepos = pTemp->ulBuffpos; 485 565 } 486 566 sti(); … … 495 575 void WAVESTREAM::SetCurrentTime(ULONG time) 496 576 { 497 //d dprintf(("SetCurrentTime: %lx", time));498 577 //dprintf(("SetCurrentTime: %lx", time)); 578 _ulTimeBase = time; 499 579 } 500 580 //****************************************************************************** … … 502 582 ULONG WAVESTREAM::StartStream() 503 583 { 504 505 506 507 508 ddprintf(("StartStream: already playing!!"));509 510 511 512 513 514 515 516 ddprintf(("StartStream: ConfigDev failed!!"));517 584 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head(); 585 586 if(ulStreamState == STREAM_STREAMING) 587 { 588 //dprintf(("StartStream: already playing!!")); 589 return NO_ERROR; 590 } 591 592 // configure the wave device 593 // (NOTE: Must call this function; sample rate position is reset there) 594 if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE) 595 { 596 rprintf(("StartStream: ConfigDev failed!!")); 597 return ERROR_INSUFF_BUFFER; 518 598 //goto fail; 519 520 521 522 523 ddprintf(("StartStream: Prepare failed!!"));524 525 526 527 599 } 600 // prepare wave device for playback/recording 601 if(pahw->Prepare(StreamId) == FALSE) 602 { 603 rprintf(("StartStream: Prepare failed!!")); 604 goto fail; 605 } 606 607 _ulBytesProcessed = 0; 528 608 _ulBytesWritten = 0; 529 530 ulStreamState = STREAM_STREAMING; 531 //Adding the first buffer also starts playback 532 if (ulStreamType == STREAM_WAVE_PLAY) 533 { 534 pahw->SetVolume(StreamId, getMixerStreamId(), volume); //PS 609 fUnderrun = FALSE; 610 usBufferMode = 0; 611 612 ulStreamState = STREAM_STREAMING; 613 //Adding the first buffer also starts playback 614 if (ulStreamType == STREAM_WAVE_PLAY) 615 { 616 pahw->SetVolume(StreamId, getMixerStreamId(), volume); //PS 535 617 AddBuffers(TRUE); 536 //Must set volume after adding buffers (voices inside sblive driver might not 537 //be allocated otherwise (first start) ) 538 // dprintf(("SetVolume %lx",volume)); 539 // PS, removing to high 540 // pahw->SetVolume(StreamId, getMixerStreamId(), volume); 541 } 542 else 543 { 544 //dprintf(("Starting Rec Stream")); 545 ulSavedInputGain = pahw->QueryVolume(StreamId, getMixerStreamId()); 546 pahw->SetInputSrc(StreamId, getMixerStreamId(), inputsrc); 547 pahw->SetVolume(StreamId, getMixerStreamId(), inputgain); 618 } 619 else 620 { 621 //dprintf(("Starting Rec Stream")); 622 ulSavedInputGain = pahw->QueryVolume(StreamId, getMixerStreamId()); 623 pahw->SetInputSrc(StreamId, getMixerStreamId(), inputsrc); 624 pahw->SetVolume(StreamId, getMixerStreamId(), inputgain); 548 625 549 626 if(pahw->Start(StreamId) != TRUE) 550 627 { 551 dprintf(("pahw->Start failed!!"));552 553 554 555 628 rprintf(("pahw->Start failed!!")); 629 goto fail; 630 } 631 } 632 return NO_ERROR; 556 633 557 634 fail: 558 559 635 DebugInt3(); 636 return ERROR_START_STREAM; 560 637 } 561 638 //****************************************************************************** … … 563 640 ULONG WAVESTREAM::StopStream(PCONTROL_PARM pControl) 564 641 { 565 if(ulStreamState == STREAM_STOPPED) { 566 dprintf(("WAVESTREAM::StopStream %lx (already stopped)", StreamId)); 567 pControl->ulTime = GetCurrentTime(); 568 return NO_ERROR; 569 } 570 //silence wave stream before stopping it (removes clicks) 571 if(ulStreamType == STREAM_WAVE_PLAY) { 572 pahw->SetVolume(StreamId, getMixerStreamId(), 0); 573 } 574 else { 575 pahw->SetVolume(StreamId, getMixerStreamId(), ulSavedInputGain); 576 } 577 pahw->Stop(StreamId); 578 579 ulStreamState = STREAM_STOPPED; 580 //ddprintf(("WAVESTREAM::StopStream %lx", StreamId)); 581 582 ReturnBuffers(); 583 pControl->ulTime = GetCurrentTime(); 584 585 // We need to set _ulBytesProcessed to 0 here. if we do not 586 // and MMPM restarts the stream by sending a DDCMD_SETUP followed By 587 // DDCMD_ENABLE_EVENT the event time will get screwed up. rjj 588 _ulBytesProcessed = 0; 642 if(ulStreamState == STREAM_STOPPED) { 643 dprintf(("WAVESTREAM::StopStream %lx (already stopped)", StreamId)); 644 fUnderrun = FALSE; 645 pControl->ulTime = GetCurrentTime(); 646 return NO_ERROR; 647 } 648 //silence wave stream before stopping it (removes clicks) 649 if(ulStreamType == STREAM_WAVE_PLAY) { 650 pahw->SetVolume(StreamId, getMixerStreamId(), 0); 651 } 652 else { 653 pahw->SetVolume(StreamId, getMixerStreamId(), ulSavedInputGain); 654 } 655 pahw->Stop(StreamId); 656 657 ulStreamState = STREAM_STOPPED; 658 fUnderrun = FALSE; 659 //dprintf(("WAVESTREAM::StopStream %lx", StreamId)); 660 661 ReturnBuffers(); 662 pControl->ulTime = GetCurrentTime(); 663 664 // We need to set _ulBytesProcessed to 0 here. if we do not 665 // and MMPM restarts the stream by sending a DDCMD_SETUP followed By 666 // DDCMD_ENABLE_EVENT the event time will get screwed up. rjj 667 _ulBytesProcessed = 0; 589 668 _ulBytesWritten = 0; 590 669 return NO_ERROR; 591 670 } 592 671 //****************************************************************************** … … 594 673 ULONG WAVESTREAM::PauseStream(PCONTROL_PARM pControl) 595 674 { 596 ULONG ulEndPos, ulEndPos2; 597 598 if(ulStreamState == STREAM_PAUSED) { 599 dprintf(("WAVESTREAM::PauseStream %lx (already paused)", StreamId)); 600 pControl->ulTime = GetCurrentTime(); 601 return NO_ERROR; 602 } 603 604 pahw->GetPosition(StreamId, &_configinfo, &ulEndPos); 605 //silence wave stream before stopping it (removes clicks) 606 pahw->SetVolume(StreamId, getMixerStreamId(), 0); 607 pahw->Stop(StreamId); 608 675 ULONG ulEndPos; 676 677 if(ulStreamState == STREAM_PAUSED) { 678 dprintf(("WAVESTREAM::PauseStream %lx (already paused)", StreamId)); 679 fUnderrun = FALSE; 680 pControl->ulTime = GetCurrentTime(); 681 return NO_ERROR; 682 } 683 684 pahw->GetPosition(StreamId, &_configinfo, &ulEndPos); 685 //silence wave stream before stopping it (removes clicks) 686 pahw->SetVolume(StreamId, getMixerStreamId(), 0); 687 pahw->Stop(StreamId); 688 689 #if 0 609 690 /* DAZ test code begin */ 610 691 if (pahw->GetPosition(StreamId, &_configinfo, &ulEndPos2) == FALSE) ulEndPos2 = 0; 611 692 if (ulEndPos2 != ulEndPos) { 612 ddprintf(("WAVESTREAM::PauseStream %lx!=%lx", ulEndPos, ulEndPos2));693 dprintf(("WAVESTREAM::PauseStream %lx!=%lx", ulEndPos, ulEndPos2)); 613 694 if (ulEndPos2) ulEndPos = ulEndPos2; 614 695 } 615 696 /* DAZ test code end */ 616 617 ulStreamState = STREAM_PAUSED; 618 619 ddprintf(("WAVESTREAM::PauseStream %lx", StreamId)); 620 621 _ulBytesProcessed = ulEndPos; 622 623 _vRealignPausedBuffers(ulEndPos); 624 625 pControl->ulTime = GetCurrentTime(); 626 627 _ulBytesProcessed = 0; 697 #endif 698 699 ulStreamState = STREAM_PAUSED; 700 701 dprintf(("WAVESTREAM::PauseStream %lx", StreamId)); 702 703 _ulBytesProcessed = ulEndPos; 704 705 _vRealignPausedBuffers(ulEndPos); 706 707 pControl->ulTime = GetCurrentTime(); 708 709 _ulBytesProcessed = 0; 628 710 _ulBytesWritten = 0; 629 630 return NO_ERROR; 711 fUnderrun = FALSE; 712 713 return NO_ERROR; 631 714 } 632 715 //****************************************************************************** … … 635 718 { 636 719 #ifdef DEBUG 637 720 //dprintf(("WAVESTREAM::ResumeStream %lx", StreamId)); 638 721 #endif 639 722 return StartStream(); 640 723 } 641 724 //****************************************************************************** … … 643 726 BOOL WAVESTREAM::SetProperty(int type, ULONG value, ULONG reserved) 644 727 { 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 728 switch(type) { 729 case PROPERTY_VOLUME: 730 volume = value; 731 dprintf(("WAVESTREAM::SetProperty() Vol: %0lx",value)); 732 if(ulStreamState == STREAM_STREAMING && ulStreamType == STREAM_WAVE_PLAY) { 733 MixerSetWaveVolume(getMixerStreamId(), StreamId, volume); 734 } 735 break; 736 737 case PROPERTY_INPUTSRC: 738 inputsrc = value; 739 break; 740 741 case PROPERTY_INPUTGAIN: 742 inputgain = value; 743 break; 744 745 default: 746 return STREAM::SetProperty(type, value, reserved); 747 } 748 return TRUE; 666 749 } 667 750 //****************************************************************************** … … 669 752 ULONG WAVESTREAM::GetProperty(int type) 670 753 { 671 672 673 674 675 676 677 678 679 680 681 682 683 754 switch(type) { 755 case PROPERTY_FREQUENCY: 756 return _configinfo.ulSampleRate; 757 758 case PROPERTY_INPUTSRC: 759 return inputsrc; 760 761 case PROPERTY_INPUTGAIN: 762 return inputgain; 763 764 default: 765 return STREAM::GetProperty(type); 766 } 684 767 } 685 768 //****************************************************************************** … … 688 771 STREAM(streamtype, filesysnum, mixerStreamId) 689 772 { 690 // get the pointer to the hardware object 691 pahw = (WAVEAUDIO*)GetHardwareDevice(streamtype); 692 693 _fmemset(&_configinfo, 0, sizeof(_configinfo)); 694 _configinfo.ulSampleRate = pinit->lSRate; 695 _configinfo.ulBitsPerSample = pinit->lBitsPerSRate; 696 _configinfo.ulNumChannels = pinit->sChannels; 697 _configinfo.ulDataType = pinit->sMode; 698 _ulBytesWritten = 0; 699 _ulBytesProcessed = 0; 700 _ulTimeBase = 0; 701 ulSavedInputGain = 0; 702 703 _configinfo.pConversionBuffer = 0; 704 pahw->SetupConversion(&_configinfo, pinit->ulOperation, pinit->sMode, pinit->sChannels, pinit->lBitsPerSRate); 705 706 if(_configinfo.usConversion != CONVERT_NONE) 707 {//allocate conversion buffer 708 PVOID pSelOff; 709 LIN linAddr; 710 711 if(DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0) 712 { 713 dgprintf(("Error in DevHelp_VMAlloc Conversion Buffer")); 714 DebugInt3(); //should never happen!! 715 _configinfo.usConversion = CONVERT_NONE; 716 } 717 else _configinfo.pConversionBuffer = linAddr; 718 } 719 if(_configinfo.fSampleRateConversion == TRUE) 720 {//allocate buffer for sample rate conversion 721 PVOID pSelOff; 722 LIN linAddr; 723 724 if (DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0) 725 { 726 dgprintf(("Error in DevHelp_VMAlloc SR Conversion Buffer")); 727 DebugInt3(); //should never happen!! 728 } 729 else _configinfo.pSRateConvBuffer = linAddr; 730 } 731 732 pinit->ulFlags |= pahw->QueryDataFlags(pinit->ulOperation, pinit->sMode, pinit->lBitsPerSRate); 733 734 StreamId = 0; 735 736 if(pahw->Open(current_device, ulStreamType, ulSysFileNum, &StreamId) != TRUE) 737 { 738 dprintf(("pahw->Open failed!!")); 739 DebugInt3(); 740 } 773 // get the pointer to the hardware object 774 pahw = (WAVEAUDIO*)GetHardwareDevice(streamtype); 775 776 _fmemset(&_configinfo, 0, sizeof(_configinfo)); 777 _configinfo.ulSampleRate = pinit->lSRate; 778 _configinfo.ulBitsPerSample = pinit->lBitsPerSRate; 779 _configinfo.ulNumChannels = pinit->sChannels; 780 _configinfo.ulDataType = pinit->sMode; 781 _ulBytesWritten = 0; 782 _ulBytesProcessed = 0; 783 _ulTimeBase = 0; 784 ulSavedInputGain = 0; 785 fUnderrun = FALSE; 786 usBufferMode = 0; 787 788 _configinfo.pConversionBuffer = 0; 789 pahw->SetupConversion(&_configinfo, pinit->ulOperation, pinit->sMode, pinit->sChannels, pinit->lBitsPerSRate); 790 791 if(_configinfo.usConversion != CONVERT_NONE) 792 {//allocate conversion buffer 793 PVOID pSelOff; 794 LIN linAddr; 795 796 if(DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0) 797 { 798 rprintf(("Error in DevHelp_VMAlloc Conversion Buffer")); 799 DebugInt3(); //should never happen!! 800 _configinfo.usConversion = CONVERT_NONE; 801 } 802 else _configinfo.pConversionBuffer = linAddr; 803 } 804 if(_configinfo.fSampleRateConversion == TRUE) 805 {//allocate buffer for sample rate conversion 806 PVOID pSelOff; 807 LIN linAddr; 808 809 if (DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0) 810 { 811 rprintf(("Error in DevHelp_VMAlloc SR Conversion Buffer")); 812 DebugInt3(); //should never happen!! 813 } 814 else _configinfo.pSRateConvBuffer = linAddr; 815 } 816 817 pinit->ulFlags |= pahw->QueryDataFlags(pinit->ulOperation, pinit->sMode, pinit->lBitsPerSRate); 818 819 StreamId = 0; 820 821 if(pahw->Open(current_device, ulStreamType, ulSysFileNum, &StreamId) != TRUE) 822 { 823 rprintf(("pahw->Open failed!!")); 824 DebugInt3(); 825 } 741 826 742 827 //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)); … … 747 832 { 748 833 //dprintf(("WAVESTREAM stream %x dtor %lx", hstream, StreamId)); 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 } 767 //****************************************************************************** 768 //****************************************************************************** 769 834 if(_configinfo.pConversionBuffer) { 835 if(DevHelp_VMFree(_configinfo.pConversionBuffer) != 0) { 836 DebugInt3(); 837 } 838 } 839 if(_configinfo.pSRateConvBuffer) { 840 if(DevHelp_VMFree(_configinfo.pSRateConvBuffer) != 0) { 841 DebugInt3(); 842 } 843 } 844 if(pahw) { 845 if (ulStreamState == STREAM_STREAMING) 846 pahw->Stop(StreamId); 847 848 pahw->Close(StreamId); 849 StreamId = 0; 850 } 851 } 852 //****************************************************************************** 853 //****************************************************************************** 854 -
OCO/branches/DAZ/drv16/wavestrm.hpp
r483 r512 69 69 ULONG AddBuffer(ULONG space); // write one buffer to the audio buffer 70 70 BOOL _vReadAudioBuf(void); // read data from the audio buffer 71 void _vUnderrunStop(PCHAR pchStr); 72 ULONG _vUnderrunStart(void); 71 73 72 74 ULONG ulSavedInputGain; 75 BOOL fUnderrun; 76 USHORT usBufferMode; 73 77 74 78 WAVEAUDIO *pahw; // pointer to the hardware object for this stream -
OCO/branches/DAZ/install/control.scr
r486 r512 25 25 ssgroup=0 26 26 ssname="mmbase" 27 ssversion="1.9. 1-SVNr486"27 ssversion="1.9.3-SVNr511" 28 28 sstermdll="ITERM.DLL" 29 29 sstermdllentry="ITermEntry" … … 43 43 ssgroup=17 44 44 ssname="OS/2 Universal Audio: Wave" 45 ssversion="1.9. 1-SVNr486"45 ssversion="1.9.3-SVNr511" 46 46 sssize=680 47 47 ssdll="genin.dll" -
OCO/branches/DAZ/uniaud.inc
r486 r512 6 6 # Full UNIAUD build version 7 7 # BUILDVERSION must be 3 parts, and only numbers like 5.44.108 8 # It is best that 2 'nd number is always 2 digits, eg at least 109 BUILDVERSION = 1.9. 18 # It is best that 2nd number is always 2 digits, eg at least 10 9 BUILDVERSION = 1.9.3 10 10 11 11 # Fixpack version … … 13 13 # ex RC3 GA FIXPACK2 beta_47 14 14 # Comment out to avoid a fixpack line in bldlevel 15 FIXPACK = SVNr 48615 FIXPACK = SVNr511 16 16 17 17 # ALSA BUILD VERSION
Note:
See TracChangeset
for help on using the changeset viewer.