Author: janderwald Date: Mon Oct 26 01:15:22 2009 New Revision: 43765 URL: http://svn.reactos.org/svn/reactos?rev=43765&view=rev Log: [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
Modified: trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c trunk/reactos/dll/win32/winmm/winmm.c trunk/reactos/dll/win32/winmm/winmm.rbuild trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c trunk/reactos/drivers/wdm/audio/sysaudio/pin.c trunk/reactos/include/reactos/libs/sound/mmebuddy.h trunk/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c trunk/reactos/lib/drivers/sound/mmebuddy/mmewrap.c trunk/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c trunk/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c Modified: trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -428,16 +428,18 @@ 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; } @@ -502,11 +504,54 @@ else if (DeviceType == WAVE_IN_DEVICE_TYPE) { Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine); - if (Ret) - WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE); - } - - return MMSYSERR_NOERROR; + //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 @@ -680,6 +725,11 @@ else { FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat; + } + + if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE) + { + FuncTable.SetState = SetWdmWaveState; } FuncTable.Open = OpenWdmSoundDevice; Modified: trunk/reactos/dll/win32/winmm/winmm.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/winmm/winmm.c?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/dll/win32/winmm/winmm.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/winmm/winmm.c [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -2150,6 +2150,12 @@ 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; @@ -2543,6 +2549,13 @@ 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; Modified: trunk/reactos/dll/win32/winmm/winmm.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/winmm/winmm.rbuild?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/dll/win32/winmm/winmm.rbuild [iso-8859-1] (original) +++ trunk/reactos/dll/win32/winmm/winmm.rbuild [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -21,9 +21,9 @@ <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> Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -133,9 +133,11 @@ // 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)) Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -291,6 +291,7 @@ PIO_STACK_LOCATION IoStack; ULONG Length; PMDL Mdl; + BOOLEAN Read = TRUE; /* get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -318,6 +319,7 @@ if (IoStack->MajorFunction == IRP_MJ_WRITE) { /* probe the write stream irp */ + Read = FALSE; Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length); } else @@ -352,6 +354,15 @@ /* 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; @@ -359,7 +370,7 @@ IoStack->MajorFunction = IRP_MJ_WRITE; /* mark irp as pending */ - IoMarkIrpPending(Irp); +// IoMarkIrpPending(Irp); /* call the driver */ Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp); Modified: trunk/reactos/drivers/wdm/audio/sysaudio/pin.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/pin.c?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -73,12 +73,9 @@ 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; @@ -113,9 +110,7 @@ /* 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); Modified: trunk/reactos/include/reactos/libs/sound/mmebuddy.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/sound/mmebuddy.h?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -236,6 +236,12 @@ 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 @@ -258,6 +264,7 @@ WAVE_COMMIT_FUNC CommitWaveBuffer; MMGETPOS_FUNC GetPos; + MMSETSTATE_FUNC SetState; // Redundant //MMWAVEHEADER_FUNC PrepareWaveHeader; @@ -407,6 +414,11 @@ 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) Modified: trunk/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -182,6 +182,7 @@ case MXDM_INIT : { + Result = MMSYSERR_NOERROR; break; } Modified: trunk/reactos/lib/drivers/sound/mmebuddy/mmewrap.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmebuddy/mmewrap.c?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/lib/drivers/sound/mmebuddy/mmewrap.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/sound/mmebuddy/mmewrap.c [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -15,6 +15,47 @@ #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 Modified: trunk/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -170,6 +170,7 @@ PWAVEHDR WaveHdr; PWAVEHDR_EXTENSION HdrExtension; MMRESULT Result; + DWORD Bytes; WaveHdr = (PWAVEHDR) SoundOverlapped->Header; SND_ASSERT( WaveHdr ); @@ -187,18 +188,48 @@ 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); - - /* 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); - } + do + { + + /* We have an available buffer now */ + -- SoundDeviceInstance->OutstandingBuffers; + + /* 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); Modified: trunk/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c?rev=43765&r1=43764&r2=43765&view=diff ============================================================================== --- trunk/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c [iso-8859-1] Mon Oct 26 01:15:22 2009 @@ -42,6 +42,18 @@ case WIDM_GETNUMDEVS : { Result = GetSoundDeviceCount(WAVE_IN_DEVICE_TYPE); + break; + } + + case WIDM_START : + { + Result = MmeSetState(PrivateHandle, TRUE); + break; + } + + case WIDM_STOP : + { + Result = MmeSetState(PrivateHandle, FALSE); break; }