From: Johannes Anderwald Date: Mon, 26 Oct 2009 00:15:22 +0000 (+0000) Subject: [WDMAUD.DRV] X-Git-Tag: ReactOS-0.3.11~287 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=85cbe2887bfabab1adf5c74bb9a51db9d5b4d6c0 [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 --- diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c index 7050ca72463..27c38a5dac8 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.c +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c @@ -428,16 +428,18 @@ SetWdmWaveDeviceFormat( 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,13 +504,56 @@ WriteFileEx_Committer2( 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, @@ -682,6 +727,11 @@ PopulateWdmDeviceList( 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 diff --git a/reactos/dll/win32/winmm/winmm.c b/reactos/dll/win32/winmm/winmm.c index 07e22e61b7a..2a1c7059ffd 100644 --- a/reactos/dll/win32/winmm/winmm.c +++ b/reactos/dll/win32/winmm/winmm.c @@ -2150,6 +2150,12 @@ UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps, 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 @@ UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSi 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; diff --git a/reactos/dll/win32/winmm/winmm.rbuild b/reactos/dll/win32/winmm/winmm.rbuild index 1231b37ddcc..52688daf28b 100644 --- a/reactos/dll/win32/winmm/winmm.rbuild +++ b/reactos/dll/win32/winmm/winmm.rbuild @@ -21,9 +21,9 @@ mci.c mmio.c playsound.c + registry.c time.c winmm.c - registry.c winmm_res.rc diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp index 5b4c8b16d5b..f3b1d7b0e2f 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp @@ -133,9 +133,11 @@ CIrpQueue::AddMapping( // 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)) diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 241b3f4848f..73b4b7056a8 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -291,6 +291,7 @@ WdmAudReadWrite( PIO_STACK_LOCATION IoStack; ULONG Length; PMDL Mdl; + BOOLEAN Read = TRUE; /* get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -318,6 +319,7 @@ WdmAudReadWrite( if (IoStack->MajorFunction == IRP_MJ_WRITE) { /* probe the write stream irp */ + Read = FALSE; Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length); } else @@ -353,13 +355,22 @@ WdmAudReadWrite( /* 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); diff --git a/reactos/drivers/wdm/audio/sysaudio/pin.c b/reactos/drivers/wdm/audio/sysaudio/pin.c index ef1a4df6d6e..234f43c4a39 100644 --- a/reactos/drivers/wdm/audio/sysaudio/pin.c +++ b/reactos/drivers/wdm/audio/sysaudio/pin.c @@ -73,13 +73,10 @@ Pin_fnWrite( 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 @@ Pin_fnWrite( /* 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); diff --git a/reactos/include/reactos/libs/sound/mmebuddy.h b/reactos/include/reactos/libs/sound/mmebuddy.h index f8b2d8d57ae..b8158005abe 100644 --- a/reactos/include/reactos/libs/sound/mmebuddy.h +++ b/reactos/include/reactos/libs/sound/mmebuddy.h @@ -236,6 +236,12 @@ typedef MMRESULT(*MMGETPOS_FUNC)( 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 @@ typedef struct _MMFUNCTION_TABLE WAVE_COMMIT_FUNC CommitWaveBuffer; MMGETPOS_FUNC GetPos; + MMSETSTATE_FUNC SetState; // Redundant //MMWAVEHEADER_FUNC PrepareWaveHeader; @@ -407,6 +414,11 @@ MmeGetPosition( 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) diff --git a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c index 7e25ac9e678..88190cb1abb 100644 --- a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c @@ -182,6 +182,7 @@ mxdMessage( case MXDM_INIT : { + Result = MMSYSERR_NOERROR; break; } diff --git a/reactos/lib/drivers/sound/mmebuddy/mmewrap.c b/reactos/lib/drivers/sound/mmebuddy/mmewrap.c index a5a4a6d0fb6..f63e55a5ee2 100644 --- a/reactos/lib/drivers/sound/mmebuddy/mmewrap.c +++ b/reactos/lib/drivers/sound/mmebuddy/mmewrap.c @@ -15,6 +15,47 @@ #include #include + +/* + 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 diff --git a/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c b/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c index e611a0b8d73..f910bf96c96 100644 --- a/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c +++ b/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c @@ -170,6 +170,7 @@ CompleteIO( PWAVEHDR WaveHdr; PWAVEHDR_EXTENSION HdrExtension; MMRESULT Result; + DWORD Bytes; WaveHdr = (PWAVEHDR) SoundOverlapped->Header; SND_ASSERT( WaveHdr ); @@ -187,18 +188,48 @@ CompleteIO( 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); diff --git a/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c b/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c index 366ab3cabe2..de9e353fadc 100644 --- a/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/wave/widMessage.c @@ -45,6 +45,18 @@ widMessage( break; } + case WIDM_START : + { + Result = MmeSetState(PrivateHandle, TRUE); + break; + } + + case WIDM_STOP : + { + Result = MmeSetState(PrivateHandle, FALSE); + break; + } + case WIDM_GETDEVCAPS : {