More correct fix for dsp empty case.

diff --git a/dlls/winmm/wineoss/audio.c b/dlls/winmm/wineoss/audio.c
index 1ca2bac..133cb82 100644
--- a/dlls/winmm/wineoss/audio.c
+++ b/dlls/winmm/wineoss/audio.c
@@ -1297,13 +1297,32 @@
 static BOOL wodUpdatePlayedTotal(WINE_WAVEOUT* wwo, audio_buf_info* info)
 {
     audio_buf_info dspspace;
+    DWORD notplayed;
     if (!info) info = &dspspace;
 
     if (ioctl(wwo->ossdev->fd, SNDCTL_DSP_GETOSPACE, info) < 0) {
         ERR("ioctl(%s, SNDCTL_DSP_GETOSPACE) failed (%s)\n", wwo->ossdev->dev_name, strerror(errno));
         return FALSE;
     }
-    wwo->dwPlayedTotal = wwo->dwWrittenTotal - (wwo->dwBufferSize - info->bytes);
+
+    /* GETOSPACE is not always accurate when we're down to the last fragment or two;
+    **   we try to accomodate that here by assuming that the dsp is empty by looking
+    **   at the clock rather than the result of GETOSPACE */
+    notplayed = wwo->dwBufferSize - info->bytes;
+    if (notplayed > 0 && notplayed < (info->fragsize * 2))
+    {
+        if (wwo->dwProjectedFinishTime && GetTickCount() >= wwo->dwProjectedFinishTime)
+        {
+            TRACE("Adjusting for a presumed OSS bug and assuming all data has been played.\n");
+            wwo->dwPlayedTotal = wwo->dwWrittenTotal;
+            return TRUE;
+        }
+        else
+            /* Some OSS drivers will clean up nicely if given a POST, so give 'em the chance... */
+            ioctl(wwo->ossdev->fd, SNDCTL_DSP_POST, 0);
+    }
+
+    wwo->dwPlayedTotal = wwo->dwWrittenTotal - notplayed;
     return TRUE;
 }
 
@@ -1371,6 +1390,16 @@
 }
 
 /**************************************************************************
+ * 			     wodPlayer_TicksTillEmpty		[internal]
+ * Returns the number of ticks until we think the DSP should be empty
+ */
+static DWORD wodPlayer_TicksTillEmpty(const WINE_WAVEOUT *wwo)
+{
+    return ((wwo->dwWrittenTotal - wwo->dwPlayedTotal) * 1000)
+        / wwo->waveFormat.Format.nAvgBytesPerSec;
+}
+
+/**************************************************************************
  * 			     wodPlayer_DSPWait			[internal]
  * Returns the number of milliseconds to wait for the DSP buffer to write
  * one fragment.
@@ -1659,17 +1688,6 @@
     TRACE("fragments=%d/%d, fragsize=%d, bytes=%d\n",
 	  dspspace.fragments, dspspace.fragstotal, dspspace.fragsize, dspspace.bytes);
 
-    /* input queue empty and output buffer with less than one fragment to play
-     * actually some cards do not play the fragment before the last if this one is partially feed
-     * so we need to test for full the availability of 2 fragments ; the DSP_POST ioctl
-     * will let the card know to play out the rest of the fragments
-     */
-    if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + 2 * wwo->dwFragmentSize &&
-        !wwo->bNeedPost) {
-	TRACE("Run out of wavehdr's, requesting a POST...\n");
-        wwo->bNeedPost = TRUE;
-    }
-
     /* no more room... no need to try to feed */
     if (dspspace.fragments != 0) {
         /* Feed from partial wavehdr */
@@ -1724,6 +1742,11 @@
 	wodPlayer_ProcessMessages(wwo);
 	if (wwo->state == WINE_WS_PLAYING) {
 	    dwNextFeedTime = wodPlayer_FeedDSP(wwo);
+            if (dwNextFeedTime != INFINITE)
+                wwo->dwProjectedFinishTime = GetTickCount() + wodPlayer_TicksTillEmpty(wwo);
+            else
+                wwo->dwProjectedFinishTime = 0;
+
 	    dwNextNotifyTime = wodPlayer_NotifyCompletions(wwo, FALSE);
 	    if (dwNextFeedTime == INFINITE) {
 		/* FeedDSP ran out of data, but before flushing, */
diff --git a/dlls/winmm/wineoss/audio.h b/dlls/winmm/wineoss/audio.h
index ee6b266..817a428 100644
--- a/dlls/winmm/wineoss/audio.h
+++ b/dlls/winmm/wineoss/audio.h
@@ -131,6 +131,10 @@
     HANDLE			hThread;
     DWORD			dwThreadID;
     OSS_MSG_RING		msgRing;
+
+    /* make accomodation for the inacuraccy of OSS when reporting buffer size remaining by using the clock instead of GETOSPACE */
+    DWORD                       dwProjectedFinishTime;
+
 } WINE_WAVEOUT;
 
 typedef struct {