Skip to content

Commit

Permalink
[AUDIO] Implement support for WAVE_FORMAT_EXTENSIBLE audio format (#6686
Browse files Browse the repository at this point in the history
)


[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
  • Loading branch information
oleg-dubinskiy committed Apr 11, 2024
1 parent d72d61f commit 12b3272
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 14 deletions.
4 changes: 2 additions & 2 deletions dll/win32/wdmaud.drv/legacy.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion drivers/ksfilter/ks/connectivity.c
Expand Up @@ -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;
}
Expand Down
34 changes: 23 additions & 11 deletions sdk/lib/drivers/sound/mmixer/wave.c
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 12b3272

Please sign in to comment.