Instance->BufferCount = 100;
}
-
- /* Now start the stream */
- DeviceInfo.u.State = KSSTATE_RUN;
- SyncOverlappedDeviceIoControl(KernelHandle,
- IOCTL_SETDEVICE_STATE,
- (LPVOID) &DeviceInfo,
- sizeof(WDMAUD_DEVICE_INFO),
- (LPVOID) &DeviceInfo,
- sizeof(WDMAUD_DEVICE_INFO),
- NULL);
+ if (DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ /* Now start the stream */
+ DeviceInfo.u.State = KSSTATE_RUN;
+ SyncOverlappedDeviceIoControl(KernelHandle,
+ IOCTL_SETDEVICE_STATE,
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ NULL);
+ }
return MMSYSERR_NOERROR;
}
else if (DeviceType == WAVE_IN_DEVICE_TYPE)
{
Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
- if (Ret)
- WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
+ //if (Ret)
+ // WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
}
return MMSYSERR_NOERROR;
}
+MMRESULT
+SetWdmWaveState(
+ IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
+ IN BOOL bStart)
+{
+ MMRESULT Result;
+ PSOUND_DEVICE SoundDevice;
+ WDMAUD_DEVICE_INFO DeviceInfo;
+ MMDEVICE_TYPE DeviceType;
+ HANDLE Handle;
+
+ Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
+
+ if ( ! MMSUCCESS(Result) )
+ {
+ return TranslateInternalMmResult(Result);
+ }
+
+ Result = GetSoundDeviceType(SoundDevice, &DeviceType);
+ SND_ASSERT( Result == MMSYSERR_NOERROR );
+
+ Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
+ SND_ASSERT( Result == MMSYSERR_NOERROR );
+
+ ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+ DeviceInfo.hDevice = Handle;
+ DeviceInfo.DeviceType = DeviceType;
+
+ if (bStart)
+ DeviceInfo.u.State = KSSTATE_RUN;
+ else
+ DeviceInfo.u.State = KSSTATE_PAUSE;
+ Result = SyncOverlappedDeviceIoControl(KernelHandle,
+ IOCTL_SETDEVICE_STATE,
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ NULL);
+
+ return Result;
+}
+
MMRESULT
GetWdmPosition(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
}
+ if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ FuncTable.SetState = SetWdmWaveState;
+ }
+
FuncTable.Open = OpenWdmSoundDevice;
FuncTable.Close = CloseWdmSoundDevice;
#ifndef USERMODE_MIXER
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
+ if (uDeviceID == WAVE_MAPPER)
+ {
+ FIXME("Support WAVE_MAPPER\n");
+ uDeviceID = 0;
+ }
+
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEOUT, TRUE)) == NULL)
return MMSYSERR_BADDEVICEID;
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
+ if (uDeviceID == WAVE_MAPPER)
+ {
+ FIXME("Support WAVE_MAPPER\n");
+ uDeviceID = 0;
+ }
+
+
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEIN, TRUE)) == NULL)
return MMSYSERR_BADDEVICEID;
<file>mci.c</file>
<file>mmio.c</file>
<file>playsound.c</file>
+ <file>registry.c</file>
<file>time.c</file>
<file>winmm.c</file>
- <file>registry.c</file>
<file>winmm_res.rc</file>
</module>
</group>
// Wdmaud already probes buffers, therefore no need to probe it again
// probe the stream irp
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM)
- Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0);
- else
- Status = KsProbeStreamIrp(Irp, KSSTREAM_READ| KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0);
+ Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, 0);
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM)
+ Status = KsProbeStreamIrp(Irp, KSSTREAM_READ | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, 0);
+ else
+ PC_ASSERT(0);
// check for success
if (!NT_SUCCESS(Status))
PIO_STACK_LOCATION IoStack;
ULONG Length;
PMDL Mdl;
+ BOOLEAN Read = TRUE;
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->MajorFunction == IRP_MJ_WRITE)
{
/* probe the write stream irp */
+ Read = FALSE;
Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
}
else
/* get next stack location */
IoStack = IoGetNextIrpStackLocation(Irp);
+ if (Read)
+ {
+ IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_READ_STREAM;
+ }
+ else
+ {
+ IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM;
+ }
+
/* attach file object */
IoStack->FileObject = FileObject;
IoStack->Parameters.Write.Length = Length;
IoStack->MajorFunction = IRP_MJ_WRITE;
/* mark irp as pending */
- IoMarkIrpPending(Irp);
+// IoMarkIrpPending(Irp);
/* call the driver */
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
- ULONG Length;
/* Get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
- Length = IoStack->Parameters.Write.Length;
-
/* The dispatch context is stored in the FsContext member */
Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
/* store file object of next device object */
IoStack->FileObject = FileObject;
IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
- IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM; //FIXME
- IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
- ASSERT(Irp->AssociatedIrp.SystemBuffer);
+ //ASSERT(Irp->AssociatedIrp.SystemBuffer);
/* now call the driver */
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN MMTIME* Time);
+
+typedef MMRESULT(*MMSETSTATE_FUNC)(
+ IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
+ IN BOOL bStart);
+
+
typedef struct _MMFUNCTION_TABLE
{
union
WAVE_COMMIT_FUNC CommitWaveBuffer;
MMGETPOS_FUNC GetPos;
+ MMSETSTATE_FUNC SetState;
// Redundant
//MMWAVEHEADER_FUNC PrepareWaveHeader;
IN MMTIME* Time,
IN DWORD Size);
+MMRESULT
+MmeSetState(
+ IN DWORD PrivateHandle,
+ IN BOOL bStart);
+
#define MmePrepareWaveHeader(private_handle, header) \
PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
case MXDM_INIT :
{
+ Result = MMSYSERR_NOERROR;
break;
}
#include <sndtypes.h>
#include <mmebuddy.h>
+
+/*
+ Sets the device into running or stopped state
+*/
+
+MMRESULT
+MmeSetState(
+ IN DWORD PrivateHandle,
+ IN BOOL bStart)
+{
+ MMRESULT Result;
+ PMMFUNCTION_TABLE FunctionTable;
+ PSOUND_DEVICE SoundDevice;
+ PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
+
+ VALIDATE_MMSYS_PARAMETER( PrivateHandle );
+ SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
+
+ VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
+
+ Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
+ if ( ! MMSUCCESS(Result) )
+ return TranslateInternalMmResult(Result);
+
+ /* Get the function table, and validate it */
+ Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
+ if ( ! MMSUCCESS(Result) )
+ return TranslateInternalMmResult(Result);
+
+ SND_ASSERT( FunctionTable->SetState );
+ if ( FunctionTable->SetState == NULL )
+ {
+ /* FIXME */
+ return MMSYSERR_NOTSUPPORTED;
+ }
+ /* Try change state */
+ Result = FunctionTable->SetState(SoundDeviceInstance, bStart);
+
+ return Result;
+}
+
/*
Call the client application when something interesting happens (MME API
defines "interesting things" as device open, close, and buffer
PWAVEHDR WaveHdr;
PWAVEHDR_EXTENSION HdrExtension;
MMRESULT Result;
+ DWORD Bytes;
WaveHdr = (PWAVEHDR) SoundOverlapped->Header;
SND_ASSERT( WaveHdr );
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
SND_ASSERT( MMSUCCESS(Result) );
- HdrExtension->BytesCompleted += dwNumberOfBytesTransferred;
- SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
+ do
+ {
- /* We have an available buffer now */
- -- SoundDeviceInstance->OutstandingBuffers;
+ /* We have an available buffer now */
+ -- SoundDeviceInstance->OutstandingBuffers;
- /* Did we finish a WAVEHDR and aren't looping? */
- if ( HdrExtension->BytesCompleted == WaveHdr->dwBufferLength &&
- SoundOverlapped->PerformCompletion )
- {
- CompleteWaveHeader(SoundDeviceInstance, WaveHdr);
- }
+ /* Did we finish a WAVEHDR and aren't looping? */
+ if ( HdrExtension->BytesCompleted + dwNumberOfBytesTransferred >= WaveHdr->dwBufferLength &&
+ SoundOverlapped->PerformCompletion )
+ {
+ /* Wave buffer fully completed */
+ Bytes = WaveHdr->dwBufferLength - HdrExtension->BytesCompleted;
+
+ HdrExtension->BytesCompleted += Bytes;
+ dwNumberOfBytesTransferred -= Bytes;
+
+ CompleteWaveHeader(SoundDeviceInstance, WaveHdr);
+ SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
+ }
+ else
+ {
+ SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
+ /* Partially completed */
+ HdrExtension->BytesCompleted += dwNumberOfBytesTransferred;
+ break;
+ }
+
+ /* Move to next wave header */
+ WaveHdr = WaveHdr->lpNext;
+
+ if (!WaveHdr)
+ {
+ /* No following WaveHdr */
+ SND_ASSERT(dwNumberOfBytesTransferred == 0);
+ break;
+ }
+
+ HdrExtension = (PWAVEHDR_EXTENSION) WaveHdr->reserved;
+ SND_ASSERT( HdrExtension );
+
+
+ }while(dwNumberOfBytesTransferred);
DoWaveStreaming(SoundDeviceInstance);
break;
}
+ case WIDM_START :
+ {
+ Result = MmeSetState(PrivateHandle, TRUE);
+ break;
+ }
+
+ case WIDM_STOP :
+ {
+ Result = MmeSetState(PrivateHandle, FALSE);
+ break;
+ }
+
case WIDM_GETDEVCAPS :
{