Index: /OCO/branches/DAZ/drv16/wavestrm.cpp
===================================================================
--- /OCO/branches/DAZ/drv16/wavestrm.cpp	(revision 511)
+++ /OCO/branches/DAZ/drv16/wavestrm.cpp	(revision 512)
@@ -1,12 +1,12 @@
 /* SCCSID = %W% %E% */
 /****************************************************************************
- *                                                                          *
- * Copyright (c) IBM Corporation 1994 - 1997.                               *
- *                                                                          *
- * The following IBM OS/2 source code is provided to you solely for the     *
+ *																			*
+ * Copyright (c) IBM Corporation 1994 - 1997.								*
+ *																			*
+ * The following IBM OS/2 source code is provided to you solely for the 	*
  * the purpose of assisting you in your development of OS/2 device drivers. *
- * You may use this code in accordance with the IBM License Agreement       *
- * provided in the IBM Device Driver Source Kit for OS/2.                   *
- *                                                                          *
+ * You may use this code in accordance with the IBM License Agreement		*
+ * provided in the IBM Device Driver Source Kit for OS/2.					*
+ *																			*
  ****************************************************************************/
 /**@internal %W%
@@ -14,13 +14,13 @@
  * @version %I%
  * @context Unless otherwise noted, all interfaces are Ring-0, 16-bit,
- *  <stack context>.
+ *	<stack context>.
  * @history
  *
  */
 #define INCL_NOPMAPI
-#define INCL_DOSERRORS            // for ERROR_INVALID_FUNCTION
+#define INCL_DOSERRORS			  // for ERROR_INVALID_FUNCTION
 #include <os2.h>
 #include <os2me.h>
-#include <audio.h>                // for #define MIDI
+#include <audio.h>				  // for #define MIDI
 #include <string.h>
 #include <include.h>
@@ -44,13 +44,13 @@
 
 //******************************************************************************
-//  _vRealignBuffer
-//  called just after a wave stream pause on a playback.
-//  Gets the end position of the stream when paused and a pointer to a
-//  STREAMBUFFER. Basicly this function looks at the streambuffer and if
+//	_vRealignBuffer
+//	called just after a wave stream pause on a playback.
+//	Gets the end position of the stream when paused and a pointer to a
+//	STREAMBUFFER. Basicly this function looks at the streambuffer and if
 // there is any unplayed data in it it adjusts the bufpos counter.
 // the donepos counter is ALWAYS set to zero. It will return 0 if all
 // the data has been played and 1 if there is still some data left.
 //******************************************************************************
-USHORT  WAVESTREAM::_vRealignBuffer(ULONG ulEndPos, PSTREAMBUFFER pBuffer)
+USHORT	WAVESTREAM::_vRealignBuffer(ULONG ulEndPos, PSTREAMBUFFER pBuffer)
 {
 	if (ulEndPos >= pBuffer->ulDonepos) { /* all of the data has been consumed */
@@ -115,5 +115,5 @@
 		}
 
-		// if there are buffere on the done queue, pop them off the head and
+		// if there are buffers on the done queue, pop them off the head and
 		// push them on the head of qhTempHead.  This will reorder them so
 		// that the more recently used ones will be in the front of the queue.
@@ -122,5 +122,4 @@
 		// be returned) so put it on the Tail of the done queue.
 		// If the rc is 1 then put it on the head of the InProcess queue.
-
 		while (qhDone.IsElements()) {
 			pTempHead->PushOnHead(qhDone.PopHead());
@@ -130,8 +129,9 @@
 		{
 			usRC = _vRealignBuffer(ulEndPos, (PSTREAMBUFFER)pTempHead->Head());
-			if (usRC)
+			if (usRC) {
 				qhInProcess.PushOnHead(pTempHead->PopHead());
-			else
-				qhDone.PushOnTail(pTempHead->PopHead());
+			} else {
+				qhDone.PushOnHead(pTempHead->PopHead());
+			}
 		}
 		while (qhDone.IsElements()) {
@@ -142,4 +142,39 @@
 		break;
 	} /* endswitch */
+	delete pTempHead; // free the memory
+}
+
+void WAVESTREAM::_vUnderrunStop(PCHAR pchStr)
+{
+	if (ulStreamState == STREAM_STOPPED) return;
+	rprintf(("%s: Buffer Underrun-stop", pchStr));
+	pahw->SetVolume(StreamId, getMixerStreamId(), 0);
+	pahw->Stop(StreamId);
+	ulStreamState = STREAM_STOPPED;
+	fUnderrun = TRUE;
+	_ulBytesProcessed = 0;
+	_ulBytesWritten = 0;
+}
+
+ULONG WAVESTREAM::_vUnderrunStart(void)
+{
+	if (ulStreamState == STREAM_STREAMING) return 0;
+	PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
+	if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE) {
+		rprintf(("WS::Write: ConfigDev failed"));
+		return ERROR_INSUFF_BUFFER;
+	}
+	// prepare wave device for playback/recording
+	if(pahw->Prepare(StreamId) == FALSE) {
+		rprintf(("WS::Write: Prepare failed"));
+		return ERROR_START_STREAM;
+	}
+
+	_ulBytesProcessed = 0;
+	_ulBytesWritten = 0;
+	ulStreamState = STREAM_STREAMING;
+	fUnderrun = FALSE;
+	if (ulStreamType == STREAM_WAVE_PLAY) pahw->SetVolume(StreamId, getMixerStreamId(), volume);
+	return 0;
 }
 
@@ -154,122 +189,132 @@
 #pragma on (unreferenced)
 {
-    ULONG ulSpace, ulBytesWritten;
+	ULONG ulSpace, ulBytesWritten;
 	ULONG ulDAZ;
-
-	//dgprintf(("WS:AddBuffers First=%d, SampleSize=%lx", fFirst, _configinfo.ulSampleSize));
-
-    ulBytesWritten = 0;
-    if (ulStreamType & STREAM_WRITE)
-    {
-        // get the space available in the hardware buffer
-        // only call GetSpace once because the amount of free space in
-        // the hardware buffer is a moving target and calling it more than once
-        // could keep us in this loop writing 4 or 8 bytes at a time.
-        // In extream cases we will stay stuck in this loop long enough to casue a trap rjj
-		if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE)
-        {
-			dgprintf(("WAVESTREAM::AddBuffers GetSpace failed"));
-            return;
-        }
-        ulSpace &= (~(_configinfo.ulSampleSize - 1));
+	ULONG ulStatus;
+
+	//dprintf(("WS:AddBuffers First=%d, SampleSize=%lx", fFirst, _configinfo.ulSampleSize));
+
+	ulBytesWritten = 0;
+	if (ulStreamType & STREAM_WRITE)
+	{
+		// get the space available in the hardware buffer
+		// only call GetSpace once because the amount of free space in
+		// the hardware buffer is a moving target and calling it more than once
+		// could keep us in this loop writing 4 or 8 bytes at a time.
+		// In extream cases we will stay stuck in this loop long enough to casue a trap rjj
+		if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE) {
+			rprintf(("WAVESTREAM::AddBuffers GetSpace failed"));
+			return;
+		}
+		ulSpace &= (~(_configinfo.ulSampleSize - 1));
+#if 1
+		if (ulSpace == 0) {
+			OSS16_WaveGetStatus(StreamId, &ulStatus);
+			rprintf(("WAVESTREAM::AddBuffers ulSpace=0, u32status=%lx", ulStatus));
+
+			_vUnderrunStop("WS:AB");
+			_vUnderrunStart();
+
+			if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE) {
+				rprintf(("WS::AB GetSpace failed"));
+				return;
+			}
+			ulSpace &= (~(_configinfo.ulSampleSize - 1));
+		}
+#endif
 		ulDAZ = 0;
-        while (ulSpace && qhInProcess.IsElements())
-        {
+		while (ulSpace && qhInProcess.IsElements())
+		{
 			if (ulDAZ++ > 20) {
-				dgprintf(("WAVESTREAM::AddBuffers DAZ break")); // Temporary hack to prevent lockups when uniaud32 stops (underrun)
+				rprintf(("WAVESTREAM::AddBuffers DAZ break")); // Temporary hack to prevent lockups when uniaud32 stops (underrun)
+				int3(); /* should never happen */
 				break;
 			}
-	        // First time is in task time. For I7 need to give time for interrupt time
-	        if (fFirst == TRUE)  //PS+++
-    	    {
+#if 0
+//DAZ move the ProcBlock to the start stream code, if really needed
+			// First time is in task time. For I7 need to give time for interrupt time
+			if (fFirst == TRUE)  //PS+++
+			{
 				//cli();
-	            DevHelp_ProcBlock (0x5541, 20, 0); // ok since the first call is at task time
-    	        ulBytesWritten = AddBuffer(ulSpace);
+				DevHelp_ProcBlock (0x5541, 20, 0); // ok since the first call is at task time
+				ulBytesWritten = AddBuffer(ulSpace);
 				return;
 			}
-            ulBytesWritten = AddBuffer(ulSpace);
-            if (ulBytesWritten == (ULONG)-1) break;
-            ulSpace -= ulBytesWritten;
-            ulSpace &= ( ~(_configinfo.ulSampleSize - 1));
-        }
-
-    }
-}
-
-//******************************************************************************
-// write one buffer to the audio buffer                                           1
-// the caller of this function MUST make sure it ok to write the audio buffer..
-// _AudioBufWrite will not check if there is room in the audio buffer of if
-// there are buffers on pHead... BEWARE
+#endif
+			ulBytesWritten = AddBuffer(ulSpace);
+			if (ulBytesWritten == (ULONG)-1) {
+				OSS16_WaveGetStatus(StreamId, &ulStatus);
+				rprintf(("WAVESTREAM::AddBuffers AddBuffer returns -1 u32Status=%lx", ulStatus));
+				break;
+			}
+			ulSpace -= ulBytesWritten;
+			ulSpace &= ( ~(_configinfo.ulSampleSize - 1));
+		}
+//		if (ulSpace) {
+//			dprintf(("WAVESTREAM::AddBuffers done. ulSpace=%lx", ulSpace));
+//		}
+	}
+}
+
+//******************************************************************************
+// write one buffer to the audio buffer in uniaud32
 //******************************************************************************
 ULONG WAVESTREAM::AddBuffer(ULONG ulSpace)
 {
-    PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
-    ULONG pDataBuf;
-    ULONG ulBuffLeft;
+	PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
+	ULONG pDataBuf;
+	ULONG ulBuffLeft;
 	ULONG ulBytesWritten;
-//DAZ	ULONG ulStartPos;
-
-    /* make sure we have a buffer to copy from */
-    if (!pTemp)
-    {
-        return (ULONG)-1;
-    }
+
+	/* make sure we have a buffer to copy from */
+	if (!pTemp) return (ULONG)-1;
 
 	/* make sure there is space in the output buffer */
-    if (!ulSpace)
-    {
-        return (ULONG)-1;
-    }
+	if (!ulSpace) return (ULONG)-1;
 
 	/* PS+++ if input buffer is ZERO do nothing and ask for give new buffer, See REMARK in mmpm2.inf */
-    if (!pTemp->ulBuffsz)
-    {
-        qhDone.PushOnTail(qhInProcess.PopHead());
-        return (ULONG)-1;
-    }
-
-/* DAZ */
-#if 0
-    // get the starting position. Call WaveGetHwPtr. if we get a bad rc then we bail out.
-    if(pahw->GetHwPtr(StreamId, &_configinfo, &ulStartPos) == FALSE)
-    {
-        dgprintf(("WAVESTREAM::AddBuffer Err in GetHwPtr"));
-        DebugInt3();
-        return (ULONG)-1;
-    }
-#endif
-
-    // get the buffer pointer and amount of data remaining
-    pDataBuf  = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; /* points to the beginning of data in src buffer */
-    ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos; /* amount of src data left to transfer */
-    //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));
-    ulBuffLeft = min(ulBuffLeft, ulSpace); /* the smaller of src data left or dst space available */
-
-    if (pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesWritten) == FALSE)
-    {
+	if (!pTemp->ulBuffsz) {
+		qhDone.PushOnTail(qhInProcess.PopHead());
+		return 0;
+	}
+	if (pTemp->ulBuffsz < (_configinfo.ulBytesPerIRQ*2)) {
+		rprintf(("WS::AB: BufferMode=1"));
+		usBufferMode = 1;
+	}
+
+	// get the buffer pointer and amount of data remaining
+	pDataBuf  = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; /* points to the beginning of data in src buffer */
+	ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos; /* amount of src data left to transfer */
+	//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));
+	ulBuffLeft = min(ulBuffLeft, ulSpace); /* the smaller of src data left or dst space available */
+
+	if (!ulBuffLeft) {
+		qhDone.PushOnTail(qhInProcess.PopHead());
+		return 0;
+	}
+
+	if (pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesWritten) == FALSE) {
 		// This could mean that the hardware has underrun TODO: implement underrun logic
-        dgprintf(("WS::AddBuffer: pahw->Transfer failed"));
-        return (ULONG)-1;
-    }
-    if (ulBytesWritten == 0)
-    {
+		rprintf(("WS::AddBuffer: pahw->Transfer failed"));
+		return (ULONG)-1;
+	}
+	if (ulBytesWritten == 0) {
 		// This could mean that the hardware has underrun TODO: implement underrun logic
-        dgprintf(("WS::AddBuffer: 0 of %lx bytes written by transfer", ulBuffLeft));
-		return (ULONG)-1; /* DAZ check into returning zero, returning 0 may cause lockup */
-    }
-	//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));
+		rprintf(("WS::AddBuffer: 0 of %lx bytes written by transfer", ulBuffLeft));
+		return (ULONG)-1;
+	}
+	//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));
 
 	_ulBytesWritten += ulBytesWritten; /* update the running counter */
-    pTemp->ulBuffpos += ulBytesWritten; /* update the buffer pos counter */
-    pTemp->ulDonepos = _ulBytesWritten; /* update the done Position for returning the buffer */
-
-    // check to see if the whole buffer has been copied and needs to be put on the done queue
-    if (pTemp->ulBuffpos >= (pTemp->ulBuffsz /* & 0xFFFFFFFC*/)) /* DAZ */
-    {
-		//dgprintf(("WS::AddBuffer done with buffer %lx dp=%lx", pTemp->pBuffptr, pTemp->ulDonepos));
-        qhDone.PushOnTail(qhInProcess.PopHead());
-    }
-    return ulBytesWritten;
+	pTemp->ulBuffpos += ulBytesWritten; /* update the buffer pos counter */
+	pTemp->ulDonepos = _ulBytesWritten; /* update the done Position for returning the buffer */
+
+	// check to see if the whole buffer has been copied and needs to be put on the done queue
+	if (pTemp->ulBuffpos >= (pTemp->ulBuffsz /* & 0xFFFFFFFC*/)) /* DAZ */
+	{
+		//dprintf(("WS::AddBuffer done with buffer %lx dp=%lx", pTemp->pBuffptr, pTemp->ulDonepos));
+		qhDone.PushOnTail(qhInProcess.PopHead());
+	}
+	return ulBytesWritten;
 }
 //******************************************************************************
@@ -279,38 +324,38 @@
 BOOL WAVESTREAM::_vReadAudioBuf(void)
 {
-    PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
-    ULONG pDataBuf;
-    ULONG ulBuffLeft, ulBytesRead;
-
-    if(!pTemp) return FALSE;
-
-    // get the buffer pointer and amount of data remaining
-    pDataBuf  = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos;
-    ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos;
-
-    // read wave data
-    if(pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesRead) == FALSE)
-    {
-       return FALSE; /* No more data */
-    }
-    if(ulBytesRead == 0) {
-       return FALSE; /* No more data */
-    }
+	PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
+	ULONG pDataBuf;
+	ULONG ulBuffLeft, ulBytesRead;
+
+	if(!pTemp) return FALSE;
+
+	// get the buffer pointer and amount of data remaining
+	pDataBuf  = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos;
+	ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos;
+
+	// read wave data
+	if(pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesRead) == FALSE)
+	{
+	   return FALSE; /* No more data */
+	}
+	if(ulBytesRead == 0) {
+	   return FALSE; /* No more data */
+	}
 	if (ulBytesRead > ulBuffLeft) {
-       return FALSE; /* Internal error */
-	}
-
-    // update the buffer pos counter
-    pTemp->ulBuffpos  += ulBytesRead;
-    _ulBytesProcessed += ulBytesRead;
+	   return FALSE; /* Internal error */
+	}
+
+	// update the buffer pos counter
+	pTemp->ulBuffpos  += ulBytesRead;
+	_ulBytesProcessed += ulBytesRead;
 
 	//dprintf(("_vReadAudioBuf %lx Requested=%lx Read=%lx Remain=%lx Processed=%lx", pDataBuf, ulBuffLeft, ulBytesRead, pTemp->ulBuffsz-pTemp->ulBuffpos, _ulBytesProcessed));
 
-    if(pTemp->ulBuffpos == pTemp->ulBuffsz) {
-      	qhDone.PushOnTail(qhInProcess.PopHead());
-	    ReturnBuffer();
-    }
-
-    return TRUE;
+	if(pTemp->ulBuffpos == pTemp->ulBuffsz) {
+	  	qhDone.PushOnTail(qhInProcess.PopHead());
+		ReturnBuffer();
+	}
+
+	return TRUE;
 }
 //******************************************************************************
@@ -327,53 +372,61 @@
 	ULONG ulDAZ;
 
-	//ddprintf(("WAVESTREAM::Process Start"));
-
-    // get the stream position. if we get a bad rc or the position is 0
-    // then we bail out. Hopefully this will be better next time.
-    // GetPostiion returns the adjusted hw pointer from the ALSA status ioctl
-    // This is really a running total of bytes consumed by the hardware.
+	//dprintf(("WAVESTREAM::Process Start"));
+
+	// get the stream position. if we get a bad rc or the position is 0
+	// then we bail out. Hopefully this will be better next time.
+	// GetPostiion returns the adjusted hw pointer from the ALSA status ioctl
+	// This is really a running total of bytes consumed by the hardware.
 	// DAZ - Note that this is a 32 bit counter and will wrap at sometime. ALSA
 	// attempts to wrap this counter intelligently. I haven't determined what
 	// effect, if any, the wrapping of this counter will have playing a stream.
-    if(pahw->GetPosition(StreamId, &_configinfo, &ulBytes) == FALSE)
-    {
-        ddprintf(("Error No bytes processed"));
-        DebugInt3();
-        return;
-    }
-    _ulBytesProcessed = ulBytes;
-
-    switch (ulStreamType & STREAM_WRITE)
-    {
-        case STREAM_WRITE:
-            if (qhInProcess.IsElements())
-            {
-				AddBuffers(FALSE);
-            }
-	        // Return any buffers that have been completely written to uniaud32
+	if(pahw->GetPosition(StreamId, &_configinfo, &ulBytes) == FALSE)
+	{
+		//dprintf(("Error No bytes processed"));
+		DebugInt3();
+		return;
+	}
+	_ulBytesProcessed = ulBytes;
+
+	switch (ulStreamType & STREAM_WRITE)
+	{
+		case STREAM_WRITE:
+			if(!qhInProcess.IsElements() && !qhDone.IsElements()) {
+				_vUnderrunStop("WS:Process");
+				break;
+			}
+			if (qhInProcess.IsElements()) AddBuffers(FALSE);
+			// Return any buffers that have been completely written to uniaud32
+			//dprintf(("WS::Process usBufferMode=%x", usBufferMode));
 			while (qhDone.IsElements()) {
-            	pTemp = (PSTREAMBUFFER)qhDone.Head(); /* get a pointer to the first completed buffer */
+				pTemp = (PSTREAMBUFFER)qhDone.Head(); /* get a pointer to the first completed buffer */
 				// Hang on to the last buffer until the hardware is done writing the data
 				// We do this because MMPM uses the return of the last buffer to determine when we are
 				// done playing the stream
-				if ((qhDone.Head() == qhDone.Tail()) && !qhInProcess.IsElements() && (_ulBytesProcessed < pTemp->ulDonepos)) break; /* only one buffer left */
+				if ((qhDone.Head() == qhDone.Tail()) && !qhInProcess.IsElements()) {  /* only one buffer left */
+					if (_ulBytesProcessed < pTemp->ulDonepos) break;
+				} else { /* not the last buffer */
+					/* if the buffer is bigger than BytesPerIRQ and it's not finished yet, hang on to it */
+					if (!usBufferMode && (_ulBytesProcessed < pTemp->ulDonepos)) break;
+					//if ((_ulBytesProcessed + _configinfo.ulBytesPerIRQ) < pTemp->ulDonepos) break;
+				}
 				ReturnBuffer();
 			}
-	        break;
-        case STREAM_READ:
+			break;
+		case STREAM_READ:
 			ulDAZ = 0;
-		    while(_vReadAudioBuf()) {
+			while(_vReadAudioBuf()) {
 				if (ulDAZ++ > 20) { /* temporary hack to prevent hangs when uniaud32 stops (overruns) */
-    				ddprintf(("WAVESTREAM::Process Read DAZ Break"));
+					rprintf(("WAVESTREAM::Process Read DAZ Break"));
 					break;
 				}
 			}
-		    break;
-        default:
-            break;
-    } /* endswitch */
-
-    ProcessEvents();
-    //ddprintf(("WAVESTREAM::Process End"));
+			break;
+		default:
+			break;
+	} /* endswitch */
+
+	ProcessEvents();
+	//dprintf(("WAVESTREAM::Process End"));
 }
 //******************************************************************************
@@ -383,15 +436,42 @@
 #pragma on (unreferenced)
 {
-    PSTREAMBUFFER pStreamBuf = new STREAMBUFFER(uLength, pbuf);
-
-    return Write(pStreamBuf);
-}
-//******************************************************************************
-//******************************************************************************
+	PSTREAMBUFFER pStreamBuf = new STREAMBUFFER(uLength, pbuf);
+
+	return Write(pStreamBuf);
+}
+//******************************************************************************
+//******************************************************************************
+#define	SNDRV_PCM_STATE_XRUN 4 /* stream reached an xrun */
 ULONG WAVESTREAM::Write(PSTREAMBUFFER pStreamBuf)
 {
-    qhInProcess.PushOnTail((PQUEUEELEMENT)pStreamBuf);
-    //    dprintf2(("WAVESTREAM::Write: Push on tail %lx %ld", ((PSTREAMBUFFER)qhInProcess.Tail())->pBuffptr, ((PSTREAMBUFFER)qhInProcess.Tail())->ulBuffsz));
-    return 0;
+
+#if 1
+	ULONG ulStatus;
+
+	ulStatus = 0;
+	if (OSS16_WaveGetStatus(StreamId, &ulStatus) != OSSERR_SUCCESS) ulStatus = SNDRV_PCM_STATE_XRUN;
+	//dprintf(("WS::Write: status=%lx", ulStatus));
+	if (ulStatus == SNDRV_PCM_STATE_XRUN) {
+		rprintf(("WS::Write: Xrun detect"));
+		_vUnderrunStop("WS:Write");
+		fUnderrun = TRUE;
+	}
+#else
+	if (!fUnderrun && !qhInProcess.IsElements()) {
+		rprintf(("WS::Write: Buffer Underrun detect"));
+		fUnderrun = TRUE;
+	}
+#endif
+	qhInProcess.PushOnTail((PQUEUEELEMENT)pStreamBuf);
+	//dprintf(("WS::Write: sz=%lx IRQ=%lx", pStreamBuf->ulBuffsz, _configinfo.ulBytesPerIRQ));
+//	  if (pStreamBuf->ulBuffsz < (_configinfo.ulBytesPerIRQ*2)) {
+//		dprintf(("WS::Write: BufferMode=1"));
+//		usBufferMode = 1;
+//	}
+	if (fUnderrun) {
+		_vUnderrunStart();
+		AddBuffers(FALSE);
+	}
+	return 0;
 }
 //******************************************************************************
@@ -399,7 +479,7 @@
 ULONG WAVESTREAM::Read(PSTREAMBUF pbuf, unsigned uLength)
 {
-    qhInProcess.PushOnTail((PQUEUEELEMENT)new STREAMBUFFER(uLength, pbuf));
-    //dprintf2(("WAVESTREAM::Read: Push on tail %lx %lx", pbuf, uLength));
-    return 0;
+	qhInProcess.PushOnTail((PQUEUEELEMENT)new STREAMBUFFER(uLength, pbuf));
+	//dprintf2(("WAVESTREAM::Read: Push on tail %lx %lx", pbuf, uLength));
+	return 0;
 }
 //******************************************************************************
@@ -419,39 +499,39 @@
 ULONG WAVESTREAM::GetCurrentTime()
 {
-    ULONG Seconds, MilliSeconds, Overflow, Processed;
-
-	//PS++ optimize code
-    Processed = _ulBytesProcessed;
-    if (ulStreamState == STREAM_STREAMING)  // if the stream is active
-    {
-       if (ulStreamType & STREAM_WRITE)
-       {
-           if (pahw->GetPosition(StreamId, &_configinfo, &Processed) == FALSE)
-           {
-				//DebugInt3();
-                Processed = _ulBytesProcessed; //last known position
-           }
-        }
-    }
-
-    // if we haven't processed anything then just return _ulTimeBase
-    if(Processed == 0)
-        return(_ulTimeBase);
-
-    Seconds  = Processed / _configinfo.ulPCMConsumeRate;
-    Overflow = Processed - (Seconds * _configinfo.ulPCMConsumeRate);
-    MilliSeconds = (Overflow * 1000) / _configinfo.ulPCMConsumeRate;
-    MilliSeconds += (Seconds * 1000);
-    return (MilliSeconds + _ulTimeBase);
-}
-//******************************************************************************
-//******************************************************************************
-ULONG WAVESTREAM::GetCurrentPos(void)
-{
-	ULONG Processed;
+	ULONG Seconds, MilliSeconds, Overflow, Processed;
 
 	//PS++ optimize code
 	Processed = _ulBytesProcessed;
-	if (ulStreamState == STREAM_STREAMING)  // if the stream is active
+	if (ulStreamState == STREAM_STREAMING)	// if the stream is active
+	{
+	   if (ulStreamType & STREAM_WRITE)
+	   {
+		   if (pahw->GetPosition(StreamId, &_configinfo, &Processed) == FALSE)
+		   {
+				//DebugInt3();
+				Processed = _ulBytesProcessed; //last known position
+		   }
+		}
+	}
+
+	// if we haven't processed anything then just return _ulTimeBase
+	if(Processed == 0)
+		return(_ulTimeBase);
+
+	Seconds  = Processed / _configinfo.ulPCMConsumeRate;
+	Overflow = Processed - (Seconds * _configinfo.ulPCMConsumeRate);
+	MilliSeconds = (Overflow * 1000) / _configinfo.ulPCMConsumeRate;
+	MilliSeconds += (Seconds * 1000);
+	return (MilliSeconds + _ulTimeBase);
+}
+//******************************************************************************
+//******************************************************************************
+ULONG WAVESTREAM::GetCurrentPos(void)
+{
+	ULONG Processed;
+
+	//PS++ optimize code
+	Processed = _ulBytesProcessed;
+	if (ulStreamState == STREAM_STREAMING)	// if the stream is active
 	{
 		if (ulStreamType & STREAM_WRITE)
@@ -478,9 +558,9 @@
    if(!pTemp)
    {
-       pTemp = (PSTREAMBUFFER)qhInProcess.Head();
+	   pTemp = (PSTREAMBUFFER)qhInProcess.Head();
    }
    if(pTemp)
    {
-       writepos = pTemp->ulBuffpos;
+	   writepos = pTemp->ulBuffpos;
    }
    sti();
@@ -495,6 +575,6 @@
 void  WAVESTREAM::SetCurrentTime(ULONG time)
 {
-	//ddprintf(("SetCurrentTime: %lx", time));
-    _ulTimeBase = time;
+	//dprintf(("SetCurrentTime: %lx", time));
+	_ulTimeBase = time;
 }
 //******************************************************************************
@@ -502,60 +582,57 @@
 ULONG WAVESTREAM::StartStream()
 {
-    PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
-
-    if(ulStreamState == STREAM_STREAMING)
-    {
-        ddprintf(("StartStream: already playing!!"));
-        return NO_ERROR;
-    }
-
-    // configure the wave device
-    // (NOTE: Must call this function; sample rate position is reset there)
-    if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE)
-    {
-        ddprintf(("StartStream: ConfigDev failed!!"));
-        return ERROR_INSUFF_BUFFER;
+	PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
+
+	if(ulStreamState == STREAM_STREAMING)
+	{
+		//dprintf(("StartStream: already playing!!"));
+		return NO_ERROR;
+	}
+
+	// configure the wave device
+	// (NOTE: Must call this function; sample rate position is reset there)
+	if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE)
+	{
+		rprintf(("StartStream: ConfigDev failed!!"));
+		return ERROR_INSUFF_BUFFER;
 		//goto fail;
-    }
-    // prepare wave device for playback/recording
-    if(pahw->Prepare(StreamId) == FALSE)
-    {
-        ddprintf(("StartStream: Prepare failed!!"));
-        goto fail;
-    }
-
-    _ulBytesProcessed = 0;
+	}
+	// prepare wave device for playback/recording
+	if(pahw->Prepare(StreamId) == FALSE)
+	{
+		rprintf(("StartStream: Prepare failed!!"));
+		goto fail;
+	}
+
+	_ulBytesProcessed = 0;
 	_ulBytesWritten = 0;
-
-    ulStreamState = STREAM_STREAMING;
-    //Adding the first buffer also starts playback
-    if (ulStreamType == STREAM_WAVE_PLAY)
-    {
-		pahw->SetVolume(StreamId, getMixerStreamId(), volume);    //PS
+	fUnderrun = FALSE;
+	usBufferMode = 0;
+
+	ulStreamState = STREAM_STREAMING;
+	//Adding the first buffer also starts playback
+	if (ulStreamType == STREAM_WAVE_PLAY)
+	{
+		pahw->SetVolume(StreamId, getMixerStreamId(), volume);	  //PS
 		AddBuffers(TRUE);
-        //Must set volume after adding buffers (voices inside sblive driver might not
-        //be allocated otherwise (first start) )
-//        dprintf(("SetVolume %lx",volume));
-// PS, removing to high
-//      pahw->SetVolume(StreamId, getMixerStreamId(), volume);
-    }
-    else
-    {
-        //dprintf(("Starting Rec Stream"));
-        ulSavedInputGain = pahw->QueryVolume(StreamId, getMixerStreamId());
-        pahw->SetInputSrc(StreamId, getMixerStreamId(), inputsrc);
-        pahw->SetVolume(StreamId, getMixerStreamId(), inputgain);
+	}
+	else
+	{
+		//dprintf(("Starting Rec Stream"));
+		ulSavedInputGain = pahw->QueryVolume(StreamId, getMixerStreamId());
+		pahw->SetInputSrc(StreamId, getMixerStreamId(), inputsrc);
+		pahw->SetVolume(StreamId, getMixerStreamId(), inputgain);
 
 		if(pahw->Start(StreamId) != TRUE)
 		{
-            dprintf(("pahw->Start failed!!"));
-            goto fail;
-        }
-    }
-    return NO_ERROR;
+			rprintf(("pahw->Start failed!!"));
+			goto fail;
+		}
+	}
+	return NO_ERROR;
 
 fail:
-    DebugInt3();
-    return ERROR_START_STREAM;
+	DebugInt3();
+	return ERROR_START_STREAM;
 }
 //******************************************************************************
@@ -563,30 +640,32 @@
 ULONG WAVESTREAM::StopStream(PCONTROL_PARM pControl)
 {
-    if(ulStreamState == STREAM_STOPPED) {
-       	dprintf(("WAVESTREAM::StopStream %lx (already stopped)", StreamId));
-   	    pControl->ulTime = GetCurrentTime();
-	    return NO_ERROR;
-    }
-    //silence wave stream before stopping it (removes clicks)
-    if(ulStreamType == STREAM_WAVE_PLAY) {
-        pahw->SetVolume(StreamId, getMixerStreamId(), 0);
-    }
-    else {
-        pahw->SetVolume(StreamId, getMixerStreamId(), ulSavedInputGain);
-    }
-    pahw->Stop(StreamId);
-
-    ulStreamState = STREAM_STOPPED;
-	//ddprintf(("WAVESTREAM::StopStream %lx", StreamId));
-
-    ReturnBuffers();
-    pControl->ulTime = GetCurrentTime();
-
-    // We need to set _ulBytesProcessed to 0 here. if we do not
-    // and MMPM restarts the stream by sending a DDCMD_SETUP followed By
-    // DDCMD_ENABLE_EVENT the event time will get screwed up. rjj
-    _ulBytesProcessed = 0;
+	if(ulStreamState == STREAM_STOPPED) {
+	   	dprintf(("WAVESTREAM::StopStream %lx (already stopped)", StreamId));
+		fUnderrun = FALSE;
+   		pControl->ulTime = GetCurrentTime();
+		return NO_ERROR;
+	}
+	//silence wave stream before stopping it (removes clicks)
+	if(ulStreamType == STREAM_WAVE_PLAY) {
+		pahw->SetVolume(StreamId, getMixerStreamId(), 0);
+	}
+	else {
+		pahw->SetVolume(StreamId, getMixerStreamId(), ulSavedInputGain);
+	}
+	pahw->Stop(StreamId);
+
+	ulStreamState = STREAM_STOPPED;
+	fUnderrun = FALSE;
+	//dprintf(("WAVESTREAM::StopStream %lx", StreamId));
+
+	ReturnBuffers();
+	pControl->ulTime = GetCurrentTime();
+
+	// We need to set _ulBytesProcessed to 0 here. if we do not
+	// and MMPM restarts the stream by sending a DDCMD_SETUP followed By
+	// DDCMD_ENABLE_EVENT the event time will get screwed up. rjj
+	_ulBytesProcessed = 0;
 	_ulBytesWritten = 0;
-    return NO_ERROR;
+	return NO_ERROR;
 }
 //******************************************************************************
@@ -594,39 +673,43 @@
 ULONG  WAVESTREAM::PauseStream(PCONTROL_PARM pControl)
 {
-    ULONG ulEndPos, ulEndPos2;
-
-    if(ulStreamState == STREAM_PAUSED) {
-       	dprintf(("WAVESTREAM::PauseStream %lx (already paused)", StreamId));
-   	    pControl->ulTime = GetCurrentTime();
-	    return NO_ERROR;
-    }
-
-    pahw->GetPosition(StreamId, &_configinfo, &ulEndPos);
-    //silence wave stream before stopping it (removes clicks)
-    pahw->SetVolume(StreamId, getMixerStreamId(), 0);
-    pahw->Stop(StreamId);
-
+	ULONG ulEndPos;
+
+	if(ulStreamState == STREAM_PAUSED) {
+	   	dprintf(("WAVESTREAM::PauseStream %lx (already paused)", StreamId));
+		fUnderrun = FALSE;
+   		pControl->ulTime = GetCurrentTime();
+		return NO_ERROR;
+	}
+
+	pahw->GetPosition(StreamId, &_configinfo, &ulEndPos);
+	//silence wave stream before stopping it (removes clicks)
+	pahw->SetVolume(StreamId, getMixerStreamId(), 0);
+	pahw->Stop(StreamId);
+
+#if 0
 	/* DAZ test code begin */
-    if (pahw->GetPosition(StreamId, &_configinfo, &ulEndPos2) == FALSE) ulEndPos2 = 0;
+	if (pahw->GetPosition(StreamId, &_configinfo, &ulEndPos2) == FALSE) ulEndPos2 = 0;
 	if (ulEndPos2 != ulEndPos) {
-	    ddprintf(("WAVESTREAM::PauseStream %lx!=%lx", ulEndPos, ulEndPos2));
+		dprintf(("WAVESTREAM::PauseStream %lx!=%lx", ulEndPos, ulEndPos2));
 		if (ulEndPos2) ulEndPos = ulEndPos2;
 	}
 	/* DAZ test code end */
-
-    ulStreamState = STREAM_PAUSED;
-
-    ddprintf(("WAVESTREAM::PauseStream %lx", StreamId));
-
-    _ulBytesProcessed = ulEndPos;
-
-    _vRealignPausedBuffers(ulEndPos);
-
-    pControl->ulTime = GetCurrentTime();
-
-    _ulBytesProcessed = 0;
+#endif
+
+	ulStreamState = STREAM_PAUSED;
+
+	dprintf(("WAVESTREAM::PauseStream %lx", StreamId));
+
+	_ulBytesProcessed = ulEndPos;
+
+	_vRealignPausedBuffers(ulEndPos);
+
+	pControl->ulTime = GetCurrentTime();
+
+	_ulBytesProcessed = 0;
 	_ulBytesWritten = 0;
-
-    return NO_ERROR;
+	fUnderrun = FALSE;
+
+	return NO_ERROR;
 }
 //******************************************************************************
@@ -635,7 +718,7 @@
 {
 #ifdef DEBUG
-    //dprintf(("WAVESTREAM::ResumeStream %lx", StreamId));
+	//dprintf(("WAVESTREAM::ResumeStream %lx", StreamId));
 #endif
-    return StartStream();
+	return StartStream();
 }
 //******************************************************************************
@@ -643,25 +726,25 @@
 BOOL WAVESTREAM::SetProperty(int type, ULONG value, ULONG reserved)
 {
-    switch(type) {
-    case PROPERTY_VOLUME:
-        volume = value;
-        dprintf(("WAVESTREAM::SetProperty() Vol: %0lx",value));
-        if(ulStreamState == STREAM_STREAMING && ulStreamType == STREAM_WAVE_PLAY) {
-            MixerSetWaveVolume(getMixerStreamId(), StreamId, volume);
-        }
-        break;
-
-    case PROPERTY_INPUTSRC:
-        inputsrc = value;
-        break;
-
-    case PROPERTY_INPUTGAIN:
-        inputgain = value;
-        break;
-
-    default:
-        return STREAM::SetProperty(type, value, reserved);
-    }
-    return TRUE;
+	switch(type) {
+	case PROPERTY_VOLUME:
+		volume = value;
+		dprintf(("WAVESTREAM::SetProperty() Vol: %0lx",value));
+		if(ulStreamState == STREAM_STREAMING && ulStreamType == STREAM_WAVE_PLAY) {
+			MixerSetWaveVolume(getMixerStreamId(), StreamId, volume);
+		}
+		break;
+
+	case PROPERTY_INPUTSRC:
+		inputsrc = value;
+		break;
+
+	case PROPERTY_INPUTGAIN:
+		inputgain = value;
+		break;
+
+	default:
+		return STREAM::SetProperty(type, value, reserved);
+	}
+	return TRUE;
 }
 //******************************************************************************
@@ -669,17 +752,17 @@
 ULONG WAVESTREAM::GetProperty(int type)
 {
-    switch(type) {
-    case PROPERTY_FREQUENCY:
-       return _configinfo.ulSampleRate;
-
-    case PROPERTY_INPUTSRC:
-       return inputsrc;
-
-    case PROPERTY_INPUTGAIN:
-       return inputgain;
-
-    default:
-       return STREAM::GetProperty(type);
-    }
+	switch(type) {
+	case PROPERTY_FREQUENCY:
+	   return _configinfo.ulSampleRate;
+
+	case PROPERTY_INPUTSRC:
+	   return inputsrc;
+
+	case PROPERTY_INPUTGAIN:
+	   return inputgain;
+
+	default:
+	   return STREAM::GetProperty(type);
+	}
 }
 //******************************************************************************
@@ -688,55 +771,57 @@
    STREAM(streamtype, filesysnum, mixerStreamId)
 {
-    // get the pointer to the hardware object
-    pahw = (WAVEAUDIO*)GetHardwareDevice(streamtype);
-
-    _fmemset(&_configinfo, 0, sizeof(_configinfo));
-    _configinfo.ulSampleRate    = pinit->lSRate;
-    _configinfo.ulBitsPerSample = pinit->lBitsPerSRate;
-    _configinfo.ulNumChannels   = pinit->sChannels;
-    _configinfo.ulDataType      = pinit->sMode;
-    _ulBytesWritten             = 0;
-    _ulBytesProcessed           = 0;
-    _ulTimeBase                 = 0;
-    ulSavedInputGain            = 0;
-
-    _configinfo.pConversionBuffer  = 0;
-    pahw->SetupConversion(&_configinfo, pinit->ulOperation, pinit->sMode, pinit->sChannels, pinit->lBitsPerSRate);
-
-    if(_configinfo.usConversion != CONVERT_NONE)
-    {//allocate conversion buffer
-        PVOID pSelOff;
-        LIN   linAddr;
-
-        if(DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0)
-        {
-             dgprintf(("Error in DevHelp_VMAlloc Conversion Buffer"));
-             DebugInt3(); //should never happen!!
-             _configinfo.usConversion = CONVERT_NONE;
-        }
-        else _configinfo.pConversionBuffer = linAddr;
-    }
-    if(_configinfo.fSampleRateConversion == TRUE)
-    {//allocate buffer for sample rate conversion
-        PVOID pSelOff;
-        LIN   linAddr;
-
-        if (DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0)
-        {
-            dgprintf(("Error in DevHelp_VMAlloc SR Conversion Buffer"));
-            DebugInt3(); //should never happen!!
-        }
-        else _configinfo.pSRateConvBuffer = linAddr;
-    }
-
-    pinit->ulFlags |= pahw->QueryDataFlags(pinit->ulOperation, pinit->sMode, pinit->lBitsPerSRate);
-
-    StreamId    = 0;
-
-    if(pahw->Open(current_device, ulStreamType, ulSysFileNum, &StreamId) != TRUE)
-    {
-        dprintf(("pahw->Open failed!!"));
-        DebugInt3();
-    }
+	// get the pointer to the hardware object
+	pahw = (WAVEAUDIO*)GetHardwareDevice(streamtype);
+
+	_fmemset(&_configinfo, 0, sizeof(_configinfo));
+	_configinfo.ulSampleRate	= pinit->lSRate;
+	_configinfo.ulBitsPerSample = pinit->lBitsPerSRate;
+	_configinfo.ulNumChannels	= pinit->sChannels;
+	_configinfo.ulDataType		= pinit->sMode;
+	_ulBytesWritten 			= 0;
+	_ulBytesProcessed			= 0;
+	_ulTimeBase 				= 0;
+	ulSavedInputGain			= 0;
+	fUnderrun = FALSE;
+	usBufferMode = 0;
+
+	_configinfo.pConversionBuffer  = 0;
+	pahw->SetupConversion(&_configinfo, pinit->ulOperation, pinit->sMode, pinit->sChannels, pinit->lBitsPerSRate);
+
+	if(_configinfo.usConversion != CONVERT_NONE)
+	{//allocate conversion buffer
+		PVOID pSelOff;
+		LIN   linAddr;
+
+		if(DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0)
+		{
+			 rprintf(("Error in DevHelp_VMAlloc Conversion Buffer"));
+			 DebugInt3(); //should never happen!!
+			 _configinfo.usConversion = CONVERT_NONE;
+		}
+		else _configinfo.pConversionBuffer = linAddr;
+	}
+	if(_configinfo.fSampleRateConversion == TRUE)
+	{//allocate buffer for sample rate conversion
+		PVOID pSelOff;
+		LIN   linAddr;
+
+		if (DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0)
+		{
+			rprintf(("Error in DevHelp_VMAlloc SR Conversion Buffer"));
+			DebugInt3(); //should never happen!!
+		}
+		else _configinfo.pSRateConvBuffer = linAddr;
+	}
+
+	pinit->ulFlags |= pahw->QueryDataFlags(pinit->ulOperation, pinit->sMode, pinit->lBitsPerSRate);
+
+	StreamId	= 0;
+
+	if(pahw->Open(current_device, ulStreamType, ulSysFileNum, &StreamId) != TRUE)
+	{
+		rprintf(("pahw->Open failed!!"));
+		DebugInt3();
+	}
 
 	//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,23 +832,23 @@
 {
 	//dprintf(("WAVESTREAM stream %x dtor %lx", hstream, StreamId));
-    if(_configinfo.pConversionBuffer) {
-        if(DevHelp_VMFree(_configinfo.pConversionBuffer) != 0) {
-            DebugInt3();
-        }
-    }
-    if(_configinfo.pSRateConvBuffer) {
-        if(DevHelp_VMFree(_configinfo.pSRateConvBuffer) != 0) {
-            DebugInt3();
-        }
-    }
-    if(pahw) {
-        if (ulStreamState == STREAM_STREAMING)
-           pahw->Stop(StreamId);
-
-    	pahw->Close(StreamId);
-        StreamId = 0;
-    }
-}
-//******************************************************************************
-//******************************************************************************
-
+	if(_configinfo.pConversionBuffer) {
+		if(DevHelp_VMFree(_configinfo.pConversionBuffer) != 0) {
+			DebugInt3();
+		}
+	}
+	if(_configinfo.pSRateConvBuffer) {
+		if(DevHelp_VMFree(_configinfo.pSRateConvBuffer) != 0) {
+			DebugInt3();
+		}
+	}
+	if(pahw) {
+		if (ulStreamState == STREAM_STREAMING)
+		   pahw->Stop(StreamId);
+
+		pahw->Close(StreamId);
+		StreamId = 0;
+	}
+}
+//******************************************************************************
+//******************************************************************************
+
Index: /OCO/branches/DAZ/drv16/wavestrm.hpp
===================================================================
--- /OCO/branches/DAZ/drv16/wavestrm.hpp	(revision 511)
+++ /OCO/branches/DAZ/drv16/wavestrm.hpp	(revision 512)
@@ -69,6 +69,10 @@
    ULONG   AddBuffer(ULONG space);             // write one buffer to the audio buffer
    BOOL    _vReadAudioBuf(void);    // read data from the audio buffer
+   void    _vUnderrunStop(PCHAR pchStr);
+   ULONG   _vUnderrunStart(void);
 
    ULONG   ulSavedInputGain;
+   BOOL    fUnderrun;
+   USHORT  usBufferMode;
 
    WAVEAUDIO *pahw;            // pointer to the hardware object for this stream
Index: /OCO/branches/DAZ/install/control.scr
===================================================================
--- /OCO/branches/DAZ/install/control.scr	(revision 511)
+++ /OCO/branches/DAZ/install/control.scr	(revision 512)
@@ -25,5 +25,5 @@
 ssgroup=0
 ssname="mmbase"
-ssversion="1.9.1-SVNr486"
+ssversion="1.9.3-SVNr511"
 sstermdll="ITERM.DLL"
 sstermdllentry="ITermEntry"
@@ -43,5 +43,5 @@
 ssgroup=17
 ssname="OS/2 Universal Audio: Wave"
-ssversion="1.9.1-SVNr486"
+ssversion="1.9.3-SVNr511"
 sssize=680
 ssdll="genin.dll"
Index: /OCO/branches/DAZ/uniaud.inc
===================================================================
--- /OCO/branches/DAZ/uniaud.inc	(revision 511)
+++ /OCO/branches/DAZ/uniaud.inc	(revision 512)
@@ -6,6 +6,6 @@
 # Full UNIAUD build version
 # BUILDVERSION must be 3 parts, and only numbers like 5.44.108
-# It is best that 2'nd number is always 2 digits, eg at least 10
-BUILDVERSION = 1.9.1
+# It is best that 2nd number is always 2 digits, eg at least 10
+BUILDVERSION = 1.9.3
 
 # Fixpack version
@@ -13,5 +13,5 @@
 # ex RC3  GA  FIXPACK2 beta_47
 # Comment out to avoid a fixpack line in bldlevel
-FIXPACK = SVNr486
+FIXPACK = SVNr511
 
 # ALSA BUILD VERSION
