Home | Info | Community | Development | myReactOS | Contact Us
[static]
Definition at line 82 of file mcicda.c.
Referenced by MCICDA_Play().
{ WINE_MCICDAUDIO *wmcda = (WINE_MCICDAUDIO*)ptr; DWORD lastPos, curPos, endPos, br; void *cdData; DWORD lockLen, fragLen; DSBCAPS caps; RAW_READ_INFO rdInfo; HRESULT hr = DS_OK; memset(&caps, 0, sizeof(caps)); caps.dwSize = sizeof(caps); hr = IDirectSoundBuffer_GetCaps(wmcda->dsBuf, &caps); fragLen = caps.dwBufferBytes/CDDA_FRAG_COUNT; curPos = lastPos = 0; endPos = ~0u; while (SUCCEEDED(hr) && endPos != lastPos && WaitForSingleObject(wmcda->stopEvent, 0) != WAIT_OBJECT_0) { hr = IDirectSoundBuffer_GetCurrentPosition(wmcda->dsBuf, &curPos, NULL); if ((curPos-lastPos+caps.dwBufferBytes)%caps.dwBufferBytes < fragLen) { Sleep(1); continue; } EnterCriticalSection(&wmcda->cs); rdInfo.DiskOffset.QuadPart = wmcda->start<<11; rdInfo.SectorCount = min(fragLen/RAW_SECTOR_SIZE, wmcda->end-wmcda->start); rdInfo.TrackMode = CDDA; hr = IDirectSoundBuffer_Lock(wmcda->dsBuf, lastPos, fragLen, &cdData, &lockLen, NULL, NULL, 0); if (hr == DSERR_BUFFERLOST) { if(FAILED(IDirectSoundBuffer_Restore(wmcda->dsBuf)) || FAILED(IDirectSoundBuffer_Play(wmcda->dsBuf, 0, 0, DSBPLAY_LOOPING))) { LeaveCriticalSection(&wmcda->cs); break; } hr = IDirectSoundBuffer_Lock(wmcda->dsBuf, lastPos, fragLen, &cdData, &lockLen, NULL, NULL, 0); } if (SUCCEEDED(hr)) { if (rdInfo.SectorCount > 0) { if (!DeviceIoControl(wmcda->handle, IOCTL_CDROM_RAW_READ, &rdInfo, sizeof(rdInfo), cdData, lockLen, &br, NULL)) WARN("CD read failed at sector %d: 0x%x\n", wmcda->start, GetLastError()); } if (rdInfo.SectorCount*RAW_SECTOR_SIZE < lockLen) { if(endPos == ~0u) endPos = lastPos; memset((BYTE*)cdData + rdInfo.SectorCount*RAW_SECTOR_SIZE, 0, lockLen - rdInfo.SectorCount*RAW_SECTOR_SIZE); } hr = IDirectSoundBuffer_Unlock(wmcda->dsBuf, cdData, lockLen, NULL, 0); } lastPos += fragLen; lastPos %= caps.dwBufferBytes; wmcda->start += rdInfo.SectorCount; LeaveCriticalSection(&wmcda->cs); } IDirectSoundBuffer_Stop(wmcda->dsBuf); SetEvent(wmcda->stopEvent); /* A design bug in native: the independent CD player called by the * MCI has no means to signal end of playing, therefore the MCI * notification is left hanging. MCI_NOTIFY_SUPERSEDED will be * signaled by the next command that has MCI_NOTIFY set (or * MCI_NOTIFY_ABORTED for MCI_PLAY). */ return 0; }