Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/sanear.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Marsev <alex.marsev@gmail.com>2015-09-18 15:13:54 +0300
committerAlex Marsev <alex.marsev@gmail.com>2015-09-18 18:42:42 +0300
commit9f059101522f45e4061832b07d5b19abf7a6aad3 (patch)
treede4e38d08efe0443b6f6ef1292ca790f2999583f
parentcc453ddef1b864d0cf977db7c088ae13d28cdae2 (diff)
Try more channel configurations
-rw-r--r--src/AudioDeviceManager.cpp98
-rw-r--r--src/Utils.h6
2 files changed, 80 insertions, 24 deletions
diff --git a/src/AudioDeviceManager.cpp b/src/AudioDeviceManager.cpp
index 1e7320e..1936e77 100644
--- a/src/AudioDeviceManager.cpp
+++ b/src/AudioDeviceManager.cpp
@@ -35,6 +35,18 @@ namespace SaneAudioRenderer
return ret;
}
+ template <typename T>
+ void AppendPcmFormatPack(T& data, uint32_t rate, uint32_t channelCount, DWORD channelMask)
+ {
+ data.insert(data.cend(), {
+ BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 32, 32, rate, channelCount, channelMask),
+ BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 32, 32, rate, channelCount, channelMask),
+ BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 24, 24, rate, channelCount, channelMask),
+ BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 32, 24, rate, channelCount, channelMask),
+ BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 16, 16, rate, channelCount, channelMask),
+ });
+ }
+
UINT32 GetDevicePropertyUint(IPropertyStore* pStore, REFPROPERTYKEY key)
{
assert(pStore);
@@ -63,6 +75,12 @@ namespace SaneAudioRenderer
return ret;
}
+ DWORD ShiftBackSide(DWORD mask)
+ {
+ return mask ^ (SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT |
+ SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT);
+ }
+
void CreateAudioClient(IMMDeviceEnumerator* pEnumerator, AudioDeviceBackend& backend)
{
assert(pEnumerator);
@@ -186,6 +204,13 @@ namespace SaneAudioRenderer
backend->bitstream = (DspFormatFromWaveFormat(*format) == DspFormat::Unknown);
+ const auto inputRate = format->nSamplesPerSec;
+ const auto inputChannels = format->nChannels;
+ const auto inputMask = DspMatrix::GetChannelMask(*format);
+ const auto mixRate = mixFormat->nSamplesPerSec;
+ const auto mixChannels = mixFormat->nChannels;
+ const auto mixMask = DspMatrix::GetChannelMask(*mixFormat);
+
if (backend->bitstream)
{
// Exclusive bitstreaming.
@@ -198,27 +223,30 @@ namespace SaneAudioRenderer
else if (backend->exclusive)
{
// Exclusive.
- auto inputRate = format->nSamplesPerSec;
- auto mixRate = mixFormat->nSamplesPerSec;
- auto mixChannels = mixFormat->nChannels;
- auto mixMask = DspMatrix::GetChannelMask(*mixFormat);
-
- auto priorities = make_array(
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 32, 32, inputRate, mixChannels, mixMask),
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 32, 32, inputRate, mixChannels, mixMask),
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 24, 24, inputRate, mixChannels, mixMask),
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 32, 24, inputRate, mixChannels, mixMask),
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 16, 16, inputRate, mixChannels, mixMask),
-
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 32, 32, mixRate, mixChannels, mixMask),
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 32, 32, mixRate, mixChannels, mixMask),
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 24, 24, mixRate, mixChannels, mixMask),
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 32, 24, mixRate, mixChannels, mixMask),
- BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_PCM, 16, 16, mixRate, mixChannels, mixMask),
+ std::vector<WAVEFORMATEXTENSIBLE> priorities;
+
+ if (backend->endpointFormFactor == DigitalAudioDisplayDevice)
+ {
+ AppendPcmFormatPack(priorities, inputRate, inputChannels, inputMask);
+ AppendPcmFormatPack(priorities, mixRate, inputChannels, inputMask);
+
+ // Shift between 5.1 with side channels and 5.1 with back channels.
+ if (inputMask == KSAUDIO_SPEAKER_5POINT1 ||
+ inputMask == ShiftBackSide(KSAUDIO_SPEAKER_5POINT1))
+ {
+ auto altMask = ShiftBackSide(inputMask);
+ AppendPcmFormatPack(priorities, inputRate, inputChannels, altMask);
+ AppendPcmFormatPack(priorities, mixRate, inputChannels, altMask);
+ }
+ }
+ AppendPcmFormatPack(priorities, inputRate, mixChannels, mixMask);
+ AppendPcmFormatPack(priorities, mixRate, mixChannels, mixMask);
+
+ priorities.insert(priorities.cend(), {
WAVEFORMATEXTENSIBLE{BuildWaveFormat(WAVE_FORMAT_PCM, 16, inputRate, mixChannels)},
WAVEFORMATEXTENSIBLE{BuildWaveFormat(WAVE_FORMAT_PCM, 16, mixRate, mixChannels)}
- );
+ });
for (const auto& f : priorities)
{
@@ -237,6 +265,40 @@ namespace SaneAudioRenderer
// Shared.
backend->dspFormat = DspFormat::Float;
backend->waveFormat = mixFormat;
+
+ std::vector<WAVEFORMATEXTENSIBLE> priorities = {
+ BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 32, 32,
+ mixRate, inputChannels, inputMask),
+ };
+
+ // Shift between 5.1 with side channels and 5.1 with back channels.
+ if (inputMask == KSAUDIO_SPEAKER_5POINT1 ||
+ inputMask == ShiftBackSide(KSAUDIO_SPEAKER_5POINT1))
+ {
+ priorities.push_back(BuildWaveFormatExt(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 32, 32,
+ mixRate, inputChannels, ShiftBackSide(inputMask)));
+ }
+
+ for (const auto& f : priorities)
+ {
+ assert(DspFormatFromWaveFormat(f.Format) != DspFormat::Unknown);
+
+ WAVEFORMATEX* pClosest;
+ if (SUCCEEDED(backend->audioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,
+ &f.Format, &pClosest)))
+ {
+ if (pClosest)
+ {
+ CoTaskMemFree(pClosest);
+ }
+ else
+ {
+ backend->dspFormat = DspFormatFromWaveFormat(f.Format);
+ backend->waveFormat = CopyWaveFormat(f.Format);
+ break;
+ }
+ }
+ }
}
ThrowIfFailed(backend->audioClient->Initialize(
diff --git a/src/Utils.h b/src/Utils.h
index bc2af92..cb6cd6b 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -74,12 +74,6 @@ namespace SaneAudioRenderer
const UINT m_period;
};
- template <typename... T>
- inline std::array<typename std::common_type<T...>::type, sizeof...(T)> make_array(T&&... values)
- {
- return {std::forward<T>(values)...};
- }
-
inline std::wstring GetHexString(uint32_t number)
{
std::array<wchar_t, 11> temp;