[AUDIO] Implement support for WAVE_FORMAT_EXTENSIBLE audio format (#6686)

[MMIXER] Implement hadling WAVE_FORMAT_EXTENSIBLE audio format
Fix opening audio device error when trying to open it with WAVE_FORMAT_EXTENSIBLE format tag set in wFormatTag member of WAVEFORMATEX:
- Pass additional data size from WAVEFORMATEX.cbSize to pin data format.
- Append it to the whole size of pin data format (KSDATAFORMAT.FormatSize).
- Set additional fields in WAVEFORMATEXTENSIBLE structure (data format, BPS and channel mask) when WAVE_FORMAT_EXTENSIBLE is used. They are used by our inbuilt Intel AC97 miniport driver at least. It simply fails when these members are not set.
- Fix pin connect allocation size by appending an additional data size from WAVEFORMATEX.cbSize to KSPIN_CONNECT + KSDATAFORMAT + WAVEFORMATEX. This allows to proerly initialize additional extensible data and avoids kernel memory leakage when using extensible audio format.
- Remove format tag check which allowed WAVE_FORMAT_PCM to be opened correctly. So now all possible audio formats can be opened properly at least (although it does not mean they may work correctly).
This fixes the audio playback for all apps those are supporting extensible audio data and use it by default (e. g. AIMP 5.30, QMMP 0.12.17, all Chrome/Chromium-based browsers, GameDev Tycoon Demo game etc.).
CORE-10907, CORE-14783

* [KS] Allow passing additional extensible audio data when extensible audio format is used
- Append additional data size from WAVEFORMATEX.cbSize to pin connect size passed to KsCreatePin. If the tag is WAVE_FORMAT_PCM, then this member should always be zero. So in that case, no any additional data is passed to creation request, and the passed data size is correct for PCM too (KSDATAFORMAT + WAVEFORMATEX).
This fixes audio playback in several apps those are supporting extensibble audio and use it by default (e. g. AIMP 5.30, QMMP 0.12.17, all Chrome/Chromium based browsers, GameDev Tycoon Demo game etc.).
CORE-10907, CORE-14783.

* [WDMAUD.DRV] Pass the correct additional data size to I/O control request
Store a correct size of additional data in WAVEFORMATEX.cbSize when performing open of audio device, when WAVE_FORMAT_EXTENSIBLE audio format is used.
It allows to properly open audio device with Legacy APIs enabled too.
This fixes audio playback in several apps those are using extensible audio data (e. g. AIMP 5.30, QMMP 0.12.17, all Chrome/Chromium based browsers, GameDevTycoon Demo game etc.).
CORE-10907, CORE-14783
This commit is contained in:
Oleg Dubinskiy 2024-04-11 11:59:14 +02:00 committed by GitHub
parent d72d61fe47
commit 12b3272d9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 26 additions and 14 deletions

View file

@ -506,7 +506,7 @@ WdmAudSetWaveDeviceFormatByLegacy(
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
DeviceInfo.DeviceIndex = DeviceId;
DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); //WaveFormat->cbSize;
DeviceInfo.u.WaveFormatEx.cbSize = WaveFormat->cbSize;
DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
#ifdef USERMODE_MIXER
DeviceInfo.u.WaveFormatEx.nChannels = 2;
@ -546,7 +546,7 @@ WdmAudSetWaveDeviceFormatByLegacy(
}
/* store details */
Instance->WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
Instance->WaveFormatEx.cbSize = WaveFormat->cbSize;
Instance->WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels);
/* Store sound device handle instance handle */

View file

@ -43,7 +43,7 @@ KsCreatePin(
PKSDATAFORMAT_WAVEFORMATEX Format = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1);
if (Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) ||
Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX))
Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX) + Format->WaveFormatEx.cbSize)
{
ConnectSize += Format->DataFormat.FormatSize;
}

View file

@ -116,22 +116,40 @@ MMixerInitializeDataFormat(
IN PKSDATAFORMAT_WAVEFORMATEX DataFormat,
LPWAVEFORMATEX WaveFormatEx)
{
DataFormat->WaveFormatEx.wFormatTag = WaveFormatEx->wFormatTag;
DataFormat->WaveFormatEx.nChannels = WaveFormatEx->nChannels;
DataFormat->WaveFormatEx.nSamplesPerSec = WaveFormatEx->nSamplesPerSec;
DataFormat->WaveFormatEx.nBlockAlign = WaveFormatEx->nBlockAlign;
DataFormat->WaveFormatEx.nAvgBytesPerSec = WaveFormatEx->nAvgBytesPerSec;
DataFormat->WaveFormatEx.wBitsPerSample = WaveFormatEx->wBitsPerSample;
DataFormat->WaveFormatEx.cbSize = 0;
DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
DataFormat->WaveFormatEx.cbSize = WaveFormatEx->cbSize;
DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX) + WaveFormatEx->cbSize;
DataFormat->DataFormat.Flags = 0;
DataFormat->DataFormat.Reserved = 0;
DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
DataFormat->DataFormat.SampleSize = 4;
/* Write additional fields for Extensible audio format */
if (WaveFormatEx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
{
PWAVEFORMATEXTENSIBLE WaveFormatExt = (PWAVEFORMATEXTENSIBLE)&DataFormat->WaveFormatEx;
WaveFormatExt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
WaveFormatExt->Samples.wValidBitsPerSample = WaveFormatEx->wBitsPerSample;
if (WaveFormatEx->nChannels == 0)
WaveFormatExt->dwChannelMask = KSAUDIO_SPEAKER_DIRECTOUT;
else if (WaveFormatEx->nChannels == 1)
WaveFormatExt->dwChannelMask = KSAUDIO_SPEAKER_MONO;
else if (WaveFormatEx->nChannels == 2)
WaveFormatExt->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
else if (WaveFormatEx->nChannels == 4)
WaveFormatExt->dwChannelMask = KSAUDIO_SPEAKER_QUAD;
else if (WaveFormatEx->nChannels == 5)
WaveFormatExt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
else if (WaveFormatEx->nChannels == 7)
WaveFormatExt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1;
}
}
MIXER_STATUS
@ -232,7 +250,7 @@ MMixerOpenWavePin(
return MM_STATUS_INVALID_PARAMETER;
/* allocate pin connect */
PinConnect = MMixerAllocatePinConnect(MixerContext, sizeof(KSDATAFORMAT_WAVEFORMATEX));
PinConnect = MMixerAllocatePinConnect(MixerContext, sizeof(KSDATAFORMAT_WAVEFORMATEX) + WaveFormatEx->cbSize);
if (!PinConnect)
{
/* no memory */
@ -453,12 +471,6 @@ MMixerOpenWave(
/* grab mixer list */
MixerList = (PMIXER_LIST)MixerContext->MixerContext;
if (WaveFormat->wFormatTag != WAVE_FORMAT_PCM)
{
/* not implemented */
return MM_STATUS_NOT_IMPLEMENTED;
}
/* find destination wave */
Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, bWaveIn, &WaveInfo);
if (Status != MM_STATUS_SUCCESS)