mirror of
https://github.com/reactos/reactos.git
synced 2024-06-27 08:21:31 +00:00
[WDMAUD.DRV]
- Set the audio pin to KSSTATE_RUN if it is wave-out pin - Implement support for manually starting / stopping a pin, which is used for recording [WINMM] - Add a hack for handling requests with WAVE_MAPPER [PORTCLS] - Pass correct flags to KsProbeStreamIrp when the irp has not already been probed (DirectKs) [WDMAUD] - Set correct irp dispatch code [SYSAUDIO] - Remove a hack [MMEBUDDY] - Return no error for MXDM_INIT message - Add support for completing multiple wave headers at once - Use new functions to implement WIDM_START / WIDM_STOP - ReactOS now "supports" wave in recording. Tested with Audacity / sndrec32 @ XP, WIP svn path=/trunk/; revision=43765
This commit is contained in:
parent
fe966a972d
commit
85cbe2887b
|
@ -428,16 +428,18 @@ SetWdmWaveDeviceFormat(
|
||||||
Instance->BufferCount = 100;
|
Instance->BufferCount = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DeviceType == WAVE_OUT_DEVICE_TYPE)
|
||||||
/* Now start the stream */
|
{
|
||||||
DeviceInfo.u.State = KSSTATE_RUN;
|
/* Now start the stream */
|
||||||
SyncOverlappedDeviceIoControl(KernelHandle,
|
DeviceInfo.u.State = KSSTATE_RUN;
|
||||||
IOCTL_SETDEVICE_STATE,
|
SyncOverlappedDeviceIoControl(KernelHandle,
|
||||||
(LPVOID) &DeviceInfo,
|
IOCTL_SETDEVICE_STATE,
|
||||||
sizeof(WDMAUD_DEVICE_INFO),
|
(LPVOID) &DeviceInfo,
|
||||||
(LPVOID) &DeviceInfo,
|
sizeof(WDMAUD_DEVICE_INFO),
|
||||||
sizeof(WDMAUD_DEVICE_INFO),
|
(LPVOID) &DeviceInfo,
|
||||||
NULL);
|
sizeof(WDMAUD_DEVICE_INFO),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return MMSYSERR_NOERROR;
|
return MMSYSERR_NOERROR;
|
||||||
}
|
}
|
||||||
|
@ -502,13 +504,56 @@ WriteFileEx_Committer2(
|
||||||
else if (DeviceType == WAVE_IN_DEVICE_TYPE)
|
else if (DeviceType == WAVE_IN_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
|
Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
|
||||||
if (Ret)
|
//if (Ret)
|
||||||
WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
|
// WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MMSYSERR_NOERROR;
|
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
|
MMRESULT
|
||||||
GetWdmPosition(
|
GetWdmPosition(
|
||||||
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
|
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
|
||||||
|
@ -682,6 +727,11 @@ PopulateWdmDeviceList(
|
||||||
FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
|
FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
FuncTable.SetState = SetWdmWaveState;
|
||||||
|
}
|
||||||
|
|
||||||
FuncTable.Open = OpenWdmSoundDevice;
|
FuncTable.Open = OpenWdmSoundDevice;
|
||||||
FuncTable.Close = CloseWdmSoundDevice;
|
FuncTable.Close = CloseWdmSoundDevice;
|
||||||
#ifndef USERMODE_MIXER
|
#ifndef USERMODE_MIXER
|
||||||
|
|
|
@ -2150,6 +2150,12 @@ UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps,
|
||||||
|
|
||||||
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
|
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)
|
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEOUT, TRUE)) == NULL)
|
||||||
return MMSYSERR_BADDEVICEID;
|
return MMSYSERR_BADDEVICEID;
|
||||||
|
|
||||||
|
@ -2543,6 +2549,13 @@ UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSi
|
||||||
|
|
||||||
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
|
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)
|
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEIN, TRUE)) == NULL)
|
||||||
return MMSYSERR_BADDEVICEID;
|
return MMSYSERR_BADDEVICEID;
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
<file>mci.c</file>
|
<file>mci.c</file>
|
||||||
<file>mmio.c</file>
|
<file>mmio.c</file>
|
||||||
<file>playsound.c</file>
|
<file>playsound.c</file>
|
||||||
|
<file>registry.c</file>
|
||||||
<file>time.c</file>
|
<file>time.c</file>
|
||||||
<file>winmm.c</file>
|
<file>winmm.c</file>
|
||||||
<file>registry.c</file>
|
|
||||||
<file>winmm_res.rc</file>
|
<file>winmm_res.rc</file>
|
||||||
</module>
|
</module>
|
||||||
</group>
|
</group>
|
||||||
|
|
|
@ -133,9 +133,11 @@ CIrpQueue::AddMapping(
|
||||||
// Wdmaud already probes buffers, therefore no need to probe it again
|
// Wdmaud already probes buffers, therefore no need to probe it again
|
||||||
// probe the stream irp
|
// probe the stream irp
|
||||||
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM)
|
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM)
|
||||||
Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0);
|
Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, 0);
|
||||||
else
|
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM)
|
||||||
Status = KsProbeStreamIrp(Irp, KSSTREAM_READ| KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0);
|
Status = KsProbeStreamIrp(Irp, KSSTREAM_READ | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, 0);
|
||||||
|
else
|
||||||
|
PC_ASSERT(0);
|
||||||
|
|
||||||
// check for success
|
// check for success
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
|
@ -291,6 +291,7 @@ WdmAudReadWrite(
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
|
BOOLEAN Read = TRUE;
|
||||||
|
|
||||||
/* get current irp stack location */
|
/* get current irp stack location */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
@ -318,6 +319,7 @@ WdmAudReadWrite(
|
||||||
if (IoStack->MajorFunction == IRP_MJ_WRITE)
|
if (IoStack->MajorFunction == IRP_MJ_WRITE)
|
||||||
{
|
{
|
||||||
/* probe the write stream irp */
|
/* probe the write stream irp */
|
||||||
|
Read = FALSE;
|
||||||
Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
|
Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -353,13 +355,22 @@ WdmAudReadWrite(
|
||||||
/* get next stack location */
|
/* get next stack location */
|
||||||
IoStack = IoGetNextIrpStackLocation(Irp);
|
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 */
|
/* attach file object */
|
||||||
IoStack->FileObject = FileObject;
|
IoStack->FileObject = FileObject;
|
||||||
IoStack->Parameters.Write.Length = Length;
|
IoStack->Parameters.Write.Length = Length;
|
||||||
IoStack->MajorFunction = IRP_MJ_WRITE;
|
IoStack->MajorFunction = IRP_MJ_WRITE;
|
||||||
|
|
||||||
/* mark irp as pending */
|
/* mark irp as pending */
|
||||||
IoMarkIrpPending(Irp);
|
// IoMarkIrpPending(Irp);
|
||||||
/* call the driver */
|
/* call the driver */
|
||||||
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
|
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
|
||||||
|
|
||||||
|
|
|
@ -73,13 +73,10 @@ Pin_fnWrite(
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG Length;
|
|
||||||
|
|
||||||
/* Get current stack location */
|
/* Get current stack location */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
Length = IoStack->Parameters.Write.Length;
|
|
||||||
|
|
||||||
/* The dispatch context is stored in the FsContext member */
|
/* The dispatch context is stored in the FsContext member */
|
||||||
Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
|
Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
|
||||||
|
|
||||||
|
@ -113,9 +110,7 @@ Pin_fnWrite(
|
||||||
/* store file object of next device object */
|
/* store file object of next device object */
|
||||||
IoStack->FileObject = FileObject;
|
IoStack->FileObject = FileObject;
|
||||||
IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
|
IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
|
||||||
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM; //FIXME
|
//ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||||
IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
|
|
||||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
|
||||||
|
|
||||||
/* now call the driver */
|
/* now call the driver */
|
||||||
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
|
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
|
||||||
|
|
|
@ -236,6 +236,12 @@ typedef MMRESULT(*MMGETPOS_FUNC)(
|
||||||
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
|
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
|
||||||
IN MMTIME* Time);
|
IN MMTIME* Time);
|
||||||
|
|
||||||
|
|
||||||
|
typedef MMRESULT(*MMSETSTATE_FUNC)(
|
||||||
|
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
|
||||||
|
IN BOOL bStart);
|
||||||
|
|
||||||
|
|
||||||
typedef struct _MMFUNCTION_TABLE
|
typedef struct _MMFUNCTION_TABLE
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
|
@ -258,6 +264,7 @@ typedef struct _MMFUNCTION_TABLE
|
||||||
WAVE_COMMIT_FUNC CommitWaveBuffer;
|
WAVE_COMMIT_FUNC CommitWaveBuffer;
|
||||||
|
|
||||||
MMGETPOS_FUNC GetPos;
|
MMGETPOS_FUNC GetPos;
|
||||||
|
MMSETSTATE_FUNC SetState;
|
||||||
|
|
||||||
// Redundant
|
// Redundant
|
||||||
//MMWAVEHEADER_FUNC PrepareWaveHeader;
|
//MMWAVEHEADER_FUNC PrepareWaveHeader;
|
||||||
|
@ -407,6 +414,11 @@ MmeGetPosition(
|
||||||
IN MMTIME* Time,
|
IN MMTIME* Time,
|
||||||
IN DWORD Size);
|
IN DWORD Size);
|
||||||
|
|
||||||
|
MMRESULT
|
||||||
|
MmeSetState(
|
||||||
|
IN DWORD PrivateHandle,
|
||||||
|
IN BOOL bStart);
|
||||||
|
|
||||||
|
|
||||||
#define MmePrepareWaveHeader(private_handle, header) \
|
#define MmePrepareWaveHeader(private_handle, header) \
|
||||||
PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
|
PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
|
||||||
|
|
|
@ -182,6 +182,7 @@ mxdMessage(
|
||||||
|
|
||||||
case MXDM_INIT :
|
case MXDM_INIT :
|
||||||
{
|
{
|
||||||
|
Result = MMSYSERR_NOERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,47 @@
|
||||||
#include <sndtypes.h>
|
#include <sndtypes.h>
|
||||||
#include <mmebuddy.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
|
Call the client application when something interesting happens (MME API
|
||||||
defines "interesting things" as device open, close, and buffer
|
defines "interesting things" as device open, close, and buffer
|
||||||
|
|
|
@ -170,6 +170,7 @@ CompleteIO(
|
||||||
PWAVEHDR WaveHdr;
|
PWAVEHDR WaveHdr;
|
||||||
PWAVEHDR_EXTENSION HdrExtension;
|
PWAVEHDR_EXTENSION HdrExtension;
|
||||||
MMRESULT Result;
|
MMRESULT Result;
|
||||||
|
DWORD Bytes;
|
||||||
|
|
||||||
WaveHdr = (PWAVEHDR) SoundOverlapped->Header;
|
WaveHdr = (PWAVEHDR) SoundOverlapped->Header;
|
||||||
SND_ASSERT( WaveHdr );
|
SND_ASSERT( WaveHdr );
|
||||||
|
@ -187,18 +188,48 @@ CompleteIO(
|
||||||
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
|
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
|
||||||
SND_ASSERT( MMSUCCESS(Result) );
|
SND_ASSERT( MMSUCCESS(Result) );
|
||||||
|
|
||||||
HdrExtension->BytesCompleted += dwNumberOfBytesTransferred;
|
do
|
||||||
SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
|
{
|
||||||
|
|
||||||
/* We have an available buffer now */
|
/* We have an available buffer now */
|
||||||
-- SoundDeviceInstance->OutstandingBuffers;
|
-- SoundDeviceInstance->OutstandingBuffers;
|
||||||
|
|
||||||
/* Did we finish a WAVEHDR and aren't looping? */
|
/* Did we finish a WAVEHDR and aren't looping? */
|
||||||
if ( HdrExtension->BytesCompleted == WaveHdr->dwBufferLength &&
|
if ( HdrExtension->BytesCompleted + dwNumberOfBytesTransferred >= WaveHdr->dwBufferLength &&
|
||||||
SoundOverlapped->PerformCompletion )
|
SoundOverlapped->PerformCompletion )
|
||||||
{
|
{
|
||||||
CompleteWaveHeader(SoundDeviceInstance, WaveHdr);
|
/* 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);
|
DoWaveStreaming(SoundDeviceInstance);
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,18 @@ widMessage(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WIDM_START :
|
||||||
|
{
|
||||||
|
Result = MmeSetState(PrivateHandle, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WIDM_STOP :
|
||||||
|
{
|
||||||
|
Result = MmeSetState(PrivateHandle, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WIDM_GETDEVCAPS :
|
case WIDM_GETDEVCAPS :
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue