mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 16:10:29 +00:00
[AUDIO] Implement retreiving audio playback position (#6817)
Implement GetWavePosition API for both Legacy and MMixer modes. [WDMAUD.DRV] - Fix wrong I/O control code passed to DeviceIoControl for Legacy mode. Use IOCTL_GETPOS instead of IOCTL_OPEN_WDMAUD, to use the correct routine. - Implement WdmAudGetWavePosition for MMixer mode, as it was completely unimplemented there. Call an appropiate MMixer routine and return back resulting wave position. [WDMAUD] - Implement WdmAudGetPostion routine, which is used by Legacy mode, and call the same MMixer routine from it too. - Handle it in IOCTL_GETPOS I/O control request of dispatch routine. [MMIXER] - Implement MMixerGetWavePosition internal routine, which is called by both Legacy and MMixer modes, and does the actual work of retrieving playback position. - Call an apporpriate KSPROPERTY_AUDIO_POSITION property from it, and return in the output resulting KSAUDIO_POSITION.PlayOffset member, which contains the current playback position offset, to be returned to the caller. This fixes a failure retreiving the current audio playback position snd subsequent playing the audio data by several 3rd-party applications which are using this API (for example, some Gecko based browsers by @roytam1: Basilisk (Serpent) 52.9.0 IA-32 build, NewMoon 28.10.7 IA-32 build and KMeleon 76.5.3 Goanna engine). CORE-19542
This commit is contained in:
parent
9b563d32d2
commit
d1b8feb690
7 changed files with 97 additions and 2 deletions
|
@ -832,7 +832,7 @@ WdmAudGetWavePositionByLegacy(
|
|||
DeviceInfo.DeviceType = DeviceType;
|
||||
|
||||
Result = SyncOverlappedDeviceIoControl(KernelHandle,
|
||||
IOCTL_OPEN_WDMAUD,
|
||||
IOCTL_GETPOS,
|
||||
(LPVOID) &DeviceInfo,
|
||||
sizeof(WDMAUD_DEVICE_INFO),
|
||||
(LPVOID) &DeviceInfo,
|
||||
|
|
|
@ -776,7 +776,32 @@ WdmAudGetWavePositionByMMixer(
|
|||
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
|
||||
IN MMTIME* Time)
|
||||
{
|
||||
/* FIXME */
|
||||
PSOUND_DEVICE SoundDevice;
|
||||
MMDEVICE_TYPE DeviceType;
|
||||
MIXER_STATUS Status;
|
||||
MMRESULT Result;
|
||||
DWORD Position;
|
||||
|
||||
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
|
||||
if (!MMSUCCESS(Result))
|
||||
return TranslateInternalMmResult(Result);
|
||||
|
||||
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
|
||||
SND_ASSERT(Result == MMSYSERR_NOERROR);
|
||||
|
||||
if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
|
||||
{
|
||||
Status = MMixerGetWavePosition(&MixerContext, SoundDeviceInstance->Handle, &Position);
|
||||
if (Status == MM_STATUS_SUCCESS)
|
||||
{
|
||||
/* Store position */
|
||||
Time->wType = TIME_BYTES;
|
||||
Time->u.cb = Position;
|
||||
|
||||
/* Completed successfully */
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
}
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -366,6 +366,7 @@ WdmAudDeviceControl(
|
|||
case IOCTL_RESET_STREAM:
|
||||
return WdmAudResetStream(DeviceObject, Irp, DeviceInfo);
|
||||
case IOCTL_GETPOS:
|
||||
return WdmAudGetPosition(DeviceObject, Irp, DeviceInfo);
|
||||
case IOCTL_GETDEVID:
|
||||
case IOCTL_GETVOLUME:
|
||||
case IOCTL_SETVOLUME:
|
||||
|
|
|
@ -769,6 +769,28 @@ WdmAudMidiCapabilities(
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
WdmAudGetPosition(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PIRP Irp,
|
||||
_In_ PWDMAUD_DEVICE_INFO DeviceInfo)
|
||||
{
|
||||
MIXER_STATUS Status;
|
||||
ULONG Position;
|
||||
|
||||
/* Get position */
|
||||
Status = MMixerGetWavePosition(&MixerContext, DeviceInfo->hDevice, &Position);
|
||||
|
||||
if (Status == MM_STATUS_SUCCESS)
|
||||
{
|
||||
DeviceInfo->u.Position = (ULONGLONG)Position;
|
||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||
}
|
||||
else
|
||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
|
||||
}
|
||||
|
||||
|
||||
MIXER_STATUS
|
||||
CreatePinCallback(
|
||||
|
|
|
@ -198,6 +198,13 @@ WdmAudMidiCapabilities(
|
|||
IN PWDMAUD_CLIENT ClientInfo,
|
||||
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
WdmAudGetPosition(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PIRP Irp,
|
||||
_In_ PWDMAUD_DEVICE_INFO DeviceInfo);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
WdmAudFrameSize(
|
||||
|
|
|
@ -207,6 +207,12 @@ MMixerOpenWave(
|
|||
IN PVOID Context,
|
||||
OUT PHANDLE PinHandle);
|
||||
|
||||
MIXER_STATUS
|
||||
MMixerGetWavePosition(
|
||||
_In_ PMIXER_CONTEXT MixerContext,
|
||||
_In_ HANDLE PinHandle,
|
||||
_Out_ PDWORD Position);
|
||||
|
||||
MIXER_STATUS
|
||||
MMixerSetWaveStatus(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
|
|
|
@ -614,6 +614,40 @@ MMixerGetWaveOutCount(
|
|||
return MixerList->WaveOutListCount;
|
||||
}
|
||||
|
||||
MIXER_STATUS
|
||||
MMixerGetWavePosition(
|
||||
_In_ PMIXER_CONTEXT MixerContext,
|
||||
_In_ HANDLE PinHandle,
|
||||
_Out_ PDWORD Position)
|
||||
{
|
||||
KSAUDIO_POSITION AudioPosition;
|
||||
KSPROPERTY Property;
|
||||
MIXER_STATUS Status;
|
||||
ULONG Length;
|
||||
|
||||
/* Validate mixer context */
|
||||
Status = MMixerVerifyContext(MixerContext);
|
||||
|
||||
if (Status != MM_STATUS_SUCCESS)
|
||||
return Status;
|
||||
|
||||
Property.Id = KSPROPERTY_AUDIO_POSITION;
|
||||
Property.Set = KSPROPSETID_Audio;
|
||||
Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
|
||||
Status = MixerContext->Control(PinHandle, IOCTL_KS_PROPERTY,
|
||||
&Property, sizeof(Property),
|
||||
&AudioPosition, sizeof(AudioPosition),
|
||||
&Length);
|
||||
if (Status == MM_STATUS_SUCCESS)
|
||||
{
|
||||
/* store audio position */
|
||||
*Position = (DWORD)AudioPosition.PlayOffset;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
MIXER_STATUS
|
||||
MMixerSetWaveStatus(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
|
|
Loading…
Reference in a new issue