Commit af3fa1c4 authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Enable exact position calculation when hardware supports it.

parent cb86255d
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
/* an exact wodGetPosition is usually not worth the extra context switches, /* an exact wodGetPosition is usually not worth the extra context switches,
* as we're going to have near fragment accuracy anyway */ * as we're going to have near fragment accuracy anyway */
/* #define EXACT_WODPOSITION */ #define EXACT_WODPOSITION
#define EXACT_WIDPOSITION
#include "config.h" #include "config.h"
#include "wine/port.h" #include "wine/port.h"
...@@ -211,6 +212,7 @@ typedef struct { ...@@ -211,6 +212,7 @@ typedef struct {
PCMWAVEFORMAT format; PCMWAVEFORMAT format;
LPWAVEHDR lpQueuePtr; LPWAVEHDR lpQueuePtr;
DWORD dwTotalRecorded; DWORD dwTotalRecorded;
DWORD dwTotalRead;
/* synchronization stuff */ /* synchronization stuff */
HANDLE hThread; HANDLE hThread;
...@@ -1873,11 +1875,15 @@ static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize) ...@@ -1873,11 +1875,15 @@ static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
return MMSYSERR_BADDEVICEID; return MMSYSERR_BADDEVICEID;
} }
if (lpTime == NULL) return MMSYSERR_INVALPARAM; if (lpTime == NULL) {
WARN("invalid parameter: lpTime == NULL\n");
return MMSYSERR_INVALPARAM;
}
wwo = &WOutDev[wDevID]; wwo = &WOutDev[wDevID];
#ifdef EXACT_WODPOSITION #ifdef EXACT_WODPOSITION
OSS_AddRingMessage(&wwo->msgRing, WINE_WM_UPDATE, 0, TRUE); if (wwo->ossdev->out_caps.dwSupport & WAVECAPS_SAMPLEACCURATE)
OSS_AddRingMessage(&wwo->msgRing, WINE_WM_UPDATE, 0, TRUE);
#endif #endif
val = wwo->dwPlayedTotal; val = wwo->dwPlayedTotal;
...@@ -3068,6 +3074,7 @@ static DWORD CALLBACK widRecorder(LPVOID pmt) ...@@ -3068,6 +3074,7 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
wwi->state = WINE_WS_STOPPED; wwi->state = WINE_WS_STOPPED;
wwi->dwTotalRecorded = 0; wwi->dwTotalRecorded = 0;
wwi->dwTotalRead = 0;
wwi->lpQueuePtr = NULL; wwi->lpQueuePtr = NULL;
SetEvent(wwi->hStartUpEvent); SetEvent(wwi->hStartUpEvent);
...@@ -3117,7 +3124,8 @@ static DWORD CALLBACK widRecorder(LPVOID pmt) ...@@ -3117,7 +3124,8 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
{ {
/* update number of bytes recorded in current buffer and by this device */ /* update number of bytes recorded in current buffer and by this device */
lpWaveHdr->dwBytesRecorded += bytesRead; lpWaveHdr->dwBytesRecorded += bytesRead;
wwi->dwTotalRecorded += bytesRead; wwi->dwTotalRead += bytesRead;
wwi->dwTotalRecorded = wwi->dwTotalRead;
/* buffer is full. notify client */ /* buffer is full. notify client */
if (lpWaveHdr->dwBytesRecorded == lpWaveHdr->dwBufferLength) if (lpWaveHdr->dwBytesRecorded == lpWaveHdr->dwBufferLength)
...@@ -3155,7 +3163,8 @@ static DWORD CALLBACK widRecorder(LPVOID pmt) ...@@ -3155,7 +3163,8 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
/* update number of bytes recorded in current buffer and by this device */ /* update number of bytes recorded in current buffer and by this device */
lpWaveHdr->dwBytesRecorded += dwToCopy; lpWaveHdr->dwBytesRecorded += dwToCopy;
wwi->dwTotalRecorded += dwToCopy; wwi->dwTotalRead += dwToCopy;
wwi->dwTotalRecorded = wwi->dwTotalRead;
bytesRead -= dwToCopy; bytesRead -= dwToCopy;
pOffset += dwToCopy; pOffset += dwToCopy;
...@@ -3305,6 +3314,7 @@ static DWORD CALLBACK widRecorder(LPVOID pmt) ...@@ -3305,6 +3314,7 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
} }
wwi->state = WINE_WS_STOPPED; wwi->state = WINE_WS_STOPPED;
wwi->dwTotalRecorded = 0; wwi->dwTotalRecorded = 0;
wwi->dwTotalRead = 0;
/* read any headers in queue */ /* read any headers in queue */
widRecorder_ReadHeaders(wwi); widRecorder_ReadHeaders(wwi);
...@@ -3321,6 +3331,16 @@ static DWORD CALLBACK widRecorder(LPVOID pmt) ...@@ -3321,6 +3331,16 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
wwi->lpQueuePtr = NULL; wwi->lpQueuePtr = NULL;
SetEvent(ev); SetEvent(ev);
break; break;
case WINE_WM_UPDATE:
if (wwi->state == WINE_WS_PLAYING) {
audio_buf_info tmp_info;
if (ioctl(wwi->ossdev->fd, SNDCTL_DSP_GETISPACE, &tmp_info) < 0)
ERR("ioctl(%s, SNDCTL_DSP_GETISPACE) failed (%s)\n", wwi->ossdev->dev_name, strerror(errno));
else
wwi->dwTotalRecorded = wwi->dwTotalRead + tmp_info.bytes;
}
SetEvent(ev);
break;
case WINE_WM_CLOSING: case WINE_WM_CLOSING:
wwi->hThread = 0; wwi->hThread = 0;
wwi->state = WINE_WS_CLOSED; wwi->state = WINE_WS_CLOSED;
...@@ -3431,6 +3451,7 @@ static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags) ...@@ -3431,6 +3451,7 @@ static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
wwi->lpQueuePtr = NULL; wwi->lpQueuePtr = NULL;
} }
wwi->dwTotalRecorded = 0; wwi->dwTotalRecorded = 0;
wwi->dwTotalRead = 0;
wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
memcpy(&wwi->waveDesc, lpDesc, sizeof(WAVEOPENDESC)); memcpy(&wwi->waveDesc, lpDesc, sizeof(WAVEOPENDESC));
...@@ -3623,9 +3644,17 @@ static DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize) ...@@ -3623,9 +3644,17 @@ static DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
WARN("can't get pos !\n"); WARN("can't get pos !\n");
return MMSYSERR_INVALHANDLE; return MMSYSERR_INVALHANDLE;
} }
if (lpTime == NULL) return MMSYSERR_INVALPARAM;
if (lpTime == NULL) {
WARN("invalid parameter: lpTime == NULL\n");
return MMSYSERR_INVALPARAM;
}
wwi = &WInDev[wDevID]; wwi = &WInDev[wDevID];
#ifdef EXACT_WIDPOSITION
if (wwi->ossdev->in_caps_support & WAVECAPS_SAMPLEACCURATE)
OSS_AddRingMessage(&(wwi->msgRing), WINE_WM_UPDATE, 0, TRUE);
#endif
TRACE("wType=%04X !\n", lpTime->wType); TRACE("wType=%04X !\n", lpTime->wType);
TRACE("wBitsPerSample=%u\n", wwi->format.wBitsPerSample); TRACE("wBitsPerSample=%u\n", wwi->format.wBitsPerSample);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment