waveThread is not longer stub it is alive and do not have all case implement Modified: trunk/reactos/lib/mmdrv/wave.c _____
Modified: trunk/reactos/lib/mmdrv/wave.c --- trunk/reactos/lib/mmdrv/wave.c 2005-11-21 19:19:13 UTC (rev 19419) +++ trunk/reactos/lib/mmdrv/wave.c 2005-11-21 20:41:34 UTC (rev 19420) @@ -18,8 +18,16 @@
#include <debug.h>
#define WHDR_COMPLETE 0x80000000 +#define MAX_BUFFER_SIZE 8192 +#define MAX_WAVE_BYTES 5*MAX_BUFFER_SIZE + PWAVEALLOC WaveLists;
+static MMRESULT waveReadWrite(PWAVEALLOC pClient); +void wavePartialOvl(DWORD dwErrorCode, DWORD BytesTransferred, LPOVERLAPPED pOverlapped); +void waveOvl(DWORD dwErrorCode, DWORD BytesTransferred, LPOVERLAPPED pOverlapped); +void waveLoopOvl(DWORD dwErrorCode, DWORD BytesTransferred, LPOVERLAPPED pOverlapped); +void waveBreakOvl(DWORD dwErrorCode, DWORD BytesTransferred, LPOVERLAPPED pOverlapped);
/* ============================ * INTERNAL @@ -145,7 +153,7 @@ } }
- //waveStart; + waveReadWrite(pClient);
if (Terminate) return 1; SetEvent(pClient->AuxEvent2); @@ -174,7 +182,7 @@ } }
- //waveStart; + waveReadWrite(pClient); } }
@@ -183,10 +191,215 @@ }
+static MMRESULT waveReadWrite(PWAVEALLOC pClient) +{ + DWORD dwSize; + BOOL Result;
+ + while (pClient->NextBuffer) + { + PWAVEHDR pHdr;
+ pHdr = pClient->NextBuffer; + + //FIXME + //assert(!(pHdr->dwFlags & (WHDR_DONE | WHDR_COMPLETE))); + //assert(pClient->DeviceQueue != NULL); +
+ dwSize = pHdr->dwBufferLength - pClient->BufferPosition; + if (dwSize > MAX_BUFFER_SIZE) + dwSize = MAX_BUFFER_SIZE; +
+ if (dwSize + pClient->BytesOutstanding <= MAX_WAVE_BYTES) + { + PWAVEOVL pWaveOvl; + + if (pClient->BufferPosition == 0) + { + if (pClient->NextBuffer && (pClient->NextBuffer->dwFlags & WHDR_BEGINLOOP) && + pClient->NextBuffer != pClient->LoopHead) + { + pClient->LoopCount = pClient->NextBuffer->dwLoops; + pClient->LoopHead = pClient->NextBuffer; + if (pClient->LoopCount > 0) + pClient->LoopCount--; + } + + if (pClient->LoopCount == 0) + pClient->LoopHead = NULL; + } + + pWaveOvl = (PWAVEOVL)HeapAlloc(Heap, HEAP_ZERO_MEMORY, sizeof(*pWaveOvl)); + + if (pWaveOvl == NULL) + return MMSYSERR_NOMEM; + + pWaveOvl->WaveHdr = pHdr; + + if (pClient->DeviceType == WaveOutDevice) + { + Result = WriteFileEx(pClient->hDev, + (PBYTE)pHdr->lpData + pClient->BufferPosition, + dwSize, + (LPOVERLAPPED)pWaveOvl, + (LPOVERLAPPED_COMPLETION_ROUTINE) + (pHdr->dwBufferLength != + pClient->BufferPosition + dwSize ? wavePartialOvl : NULL != pClient->LoopHead ? + waveLoopOvl : waveOvl)); + } + else if (pClient->DeviceType == WaveInDevice) + { + Result = ReadFileEx(pClient->hDev, (PBYTE)pHdr->lpData + pClient->BufferPosition, + dwSize, (LPOVERLAPPED)pWaveOvl, + (LPOVERLAPPED_COMPLETION_ROUTINE) + (pHdr->dwBufferLength != + pClient->BufferPosition + dwSize ? wavePartialOvl : NULL != pClient->LoopHead ? + waveLoopOvl : waveOvl)); + } + + + if (!Result && GetLastError() != ERROR_IO_PENDING) + { + HeapFree(Heap, 0, (LPSTR)pWaveOvl); + + if (pClient->BytesOutstanding == 0) + { + PWAVEHDR pHdr; + for (pHdr = pClient->DeviceQueue; pHdr != NULL; pHdr = pHdr->lpNext) + { + pHdr->dwFlags |= WHDR_COMPLETE; + } + + pClient->NextBuffer = NULL; + pClient->BufferPosition = 0; + + } + return TranslateStatus(); + + } + else + { + pClient->BufferPosition += dwSize; + pClient->BytesOutstanding += dwSize; + if (pClient->BufferPosition == pHdr->dwBufferLength) + { + + if (!pClient->LoopHead || !(pHdr->dwFlags & WHDR_ENDLOOP)) + pClient->NextBuffer = pHdr->lpNext; + else + { + if (pClient->LoopCount != 0) + { + pClient->NextBuffer = pClient->LoopHead; + pClient->LoopCount--; + } + else + { + pClient->DummyWaveOvl.WaveHdr = pClient->LoopHead; + + Result = WriteFileEx(pClient->hDev, (PVOID)pHdr->lpData, 0, + &pClient->DummyWaveOvl.Ovl, + (LPOVERLAPPED_COMPLETION_ROUTINE)waveBreakOvl); + + if (Result || GetLastError() == ERROR_IO_PENDING) + { + pClient->NextBuffer = pHdr->lpNext; + pClient->LoopHead = NULL; + + } + } + } + pClient->BufferPosition = 0; + } + } + + + } + else + break; + } + return MMSYSERR_NOERROR; +} + +void wavePartialOvl(DWORD dwErrorCode, DWORD BytesTransferred, LPOVERLAPPED pOverlapped) +{ + LPWAVEHDR pHdr; + PWAVEALLOC pClient; + + pHdr = ((PWAVEOVL)pOverlapped)->WaveHdr; + pClient = (PWAVEALLOC)pHdr->reserved; + + + /* FIXME + Assert(pHdr->dwFlags & WHDR_INQUEUE); + Assert(!(pHdr->dwFlags & WHDR_COMPLETE)); + */ + + pClient->BytesOutstanding -= MAX_BUFFER_SIZE; + + if (pClient->DeviceType == WaveInDevice) + pHdr->dwBytesRecorded += BytesTransferred; + HeapFree(Heap, 0, (LPSTR)pOverlapped); +} + +void waveBreakOvl(DWORD dwErrorCode, DWORD BytesTransferred, LPOVERLAPPED pOverlapped) +{ + ((PWAVEOVL)pOverlapped)->WaveHdr->dwFlags |= WHDR_COMPLETE; +} + +void waveLoopOvl(DWORD dwErrorCode, DWORD BytesTransferred, LPOVERLAPPED pOverlapped) +{ + DWORD dwFlags; + PWAVEHDR pHdr; + + pHdr = ((PWAVEOVL)pOverlapped)->WaveHdr; + dwFlags = pHdr->dwFlags; + waveOvl(dwErrorCode, BytesTransferred, pOverlapped); + pHdr->dwFlags = dwFlags; +} + +void waveOvl(DWORD dwErrorCode, DWORD BytesTransferred, LPOVERLAPPED pOverlapped) +{ + PWAVEHDR pHdr; + PWAVEALLOC pClient; + + pHdr = ((PWAVEOVL)pOverlapped)->WaveHdr; + pClient = (PWAVEALLOC)pHdr->reserved; + + /* FIXME + Assert(pHdr->dwFlags & WHDR_INQUEUE); + Assert(!(pHdr->dwFlags & WHDR_COMPLETE)); + */ + + pHdr->dwFlags |= WHDR_COMPLETE; + + if (pHdr->dwFlags & WHDR_BEGINLOOP) + { + PWAVEHDR pHdrSearch; + for (pHdrSearch = pClient->DeviceQueue ; pHdrSearch != pHdr ; pHdrSearch = pHdrSearch->lpNext) + { + //Assert(pHdrSearch != NULL); + pHdrSearch->dwFlags |= WHDR_COMPLETE; + } + } + + if (pHdr->dwBufferLength) + pClient->BytesOutstanding -= (pHdr->dwBufferLength - 1) % MAX_BUFFER_SIZE + 1; + + if (pClient->DeviceType == WaveInDevice) + pHdr->dwBytesRecorded += BytesTransferred; + + HeapFree(Heap, 0, (LPSTR)pOverlapped); + +} + + + + + static MMRESULT OpenWaveDevice(UINT DeviceType, DWORD id, DWORD dwUser,