aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/backends')
-rw-r--r--Alc/backends/wasapi.cpp132
1 files changed, 94 insertions, 38 deletions
diff --git a/Alc/backends/wasapi.cpp b/Alc/backends/wasapi.cpp
index 84e85fe6..976af0d0 100644
--- a/Alc/backends/wasapi.cpp
+++ b/Alc/backends/wasapi.cpp
@@ -300,6 +300,96 @@ HRESULT probe_devices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, al::vecto
}
+bool MakeExtensible(WAVEFORMATEXTENSIBLE *out, const WAVEFORMATEX *in)
+{
+ *out = WAVEFORMATEXTENSIBLE{};
+ if(in->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+ {
+ *out = reinterpret_cast<const WAVEFORMATEXTENSIBLE&>(*in);
+ out->Format.cbSize = sizeof(*out) - sizeof(out->Format);
+ }
+ else if(in->wFormatTag == WAVE_FORMAT_PCM)
+ {
+ out->Format = *in;
+ if(out->Format.nChannels == 1)
+ out->dwChannelMask = MONO;
+ else if(out->Format.nChannels == 2)
+ out->dwChannelMask = STEREO;
+ else
+ ERR("Unhandled PCM channel count: %d\n", out->Format.nChannels);
+ out->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+ }
+ else if(in->wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
+ {
+ out->Format = *in;
+ if(out->Format.nChannels == 1)
+ out->dwChannelMask = MONO;
+ else if(out->Format.nChannels == 2)
+ out->dwChannelMask = STEREO;
+ else
+ ERR("Unhandled IEEE float channel count: %d\n", out->Format.nChannels);
+ out->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
+ }
+ else
+ {
+ ERR("Unhandled format tag: 0x%04x\n", in->wFormatTag);
+ return false;
+ }
+ return true;
+}
+
+void TraceFormat(const char *msg, const WAVEFORMATEX *format)
+{
+ constexpr size_t fmtex_extra_size{sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX)};
+ if(format->wFormatTag == WAVE_FORMAT_EXTENSIBLE && format->cbSize >= fmtex_extra_size)
+ {
+ class GuidPrinter {
+ char mMsg[64];
+
+ public:
+ GuidPrinter(const GUID &guid)
+ {
+ std::snprintf(mMsg, al::size(mMsg),
+ "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ DWORD{guid.Data1}, guid.Data2, guid.Data3,
+ guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
+ guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
+ }
+ const char *c_str() const { return mMsg; }
+ };
+
+ const WAVEFORMATEXTENSIBLE *fmtex{
+ CONTAINING_RECORD(format, const WAVEFORMATEXTENSIBLE, Format)};
+ TRACE("%s:\n"
+ " FormatTag = 0x%04x\n"
+ " Channels = %d\n"
+ " SamplesPerSec = %lu\n"
+ " AvgBytesPerSec = %lu\n"
+ " BlockAlign = %d\n"
+ " BitsPerSample = %d\n"
+ " Size = %d\n"
+ " Samples = %d\n"
+ " ChannelMask = 0x%lx\n"
+ " SubFormat = %s\n",
+ msg, fmtex->Format.wFormatTag, fmtex->Format.nChannels, fmtex->Format.nSamplesPerSec,
+ fmtex->Format.nAvgBytesPerSec, fmtex->Format.nBlockAlign, fmtex->Format.wBitsPerSample,
+ fmtex->Format.cbSize, fmtex->Samples.wReserved, fmtex->dwChannelMask,
+ GuidPrinter{fmtex->SubFormat}.c_str());
+ }
+ else
+ TRACE("%s:\n"
+ " FormatTag = 0x%04x\n"
+ " Channels = %d\n"
+ " SamplesPerSec = %lu\n"
+ " AvgBytesPerSec = %lu\n"
+ " BlockAlign = %d\n"
+ " BitsPerSample = %d\n"
+ " Size = %d\n",
+ msg, format->wFormatTag, format->nChannels, format->nSamplesPerSec,
+ format->nAvgBytesPerSec, format->nBlockAlign, format->wBitsPerSample, format->cbSize);
+}
+
+
enum class MsgType : unsigned int {
OpenDevice,
ResetDevice,
@@ -604,44 +694,6 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
}
-bool MakeExtensible(WAVEFORMATEXTENSIBLE *out, const WAVEFORMATEX *in)
-{
- *out = WAVEFORMATEXTENSIBLE{};
- if(in->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
- {
- *out = reinterpret_cast<const WAVEFORMATEXTENSIBLE&>(*in);
- out->Format.cbSize = sizeof(*out) - sizeof(out->Format);
- }
- else if(in->wFormatTag == WAVE_FORMAT_PCM)
- {
- out->Format = *in;
- if(out->Format.nChannels == 1)
- out->dwChannelMask = MONO;
- else if(out->Format.nChannels == 2)
- out->dwChannelMask = STEREO;
- else
- ERR("Unhandled PCM channel count: %d\n", out->Format.nChannels);
- out->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- }
- else if(in->wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
- {
- out->Format = *in;
- if(out->Format.nChannels == 1)
- out->dwChannelMask = MONO;
- else if(out->Format.nChannels == 2)
- out->dwChannelMask = STEREO;
- else
- ERR("Unhandled IEEE float channel count: %d\n", out->Format.nChannels);
- out->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
- }
- else
- {
- ERR("Unhandled format tag: 0x%04x\n", in->wFormatTag);
- return false;
- }
- return true;
-}
-
ALCenum WasapiPlayback::open(const ALCchar *name)
{
HRESULT hr{S_OK};
@@ -883,6 +935,7 @@ HRESULT WasapiPlayback::resetProxy()
OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec *
OutputType.Format.nBlockAlign;
+ TraceFormat("Requesting playback format", &OutputType.Format);
hr = mClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &OutputType.Format, &wfx);
if(FAILED(hr))
{
@@ -897,6 +950,7 @@ HRESULT WasapiPlayback::resetProxy()
if(wfx != nullptr)
{
+ TraceFormat("Got playback format", wfx);
if(!MakeExtensible(&OutputType, wfx))
{
CoTaskMemFree(wfx);
@@ -1414,6 +1468,7 @@ HRESULT WasapiCapture::resetProxy()
OutputType.Format.nBlockAlign;
OutputType.Format.cbSize = sizeof(OutputType) - sizeof(OutputType.Format);
+ TraceFormat("Requesting capture format", &OutputType.Format);
WAVEFORMATEX *wfx;
hr = mClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &OutputType.Format, &wfx);
if(FAILED(hr))
@@ -1427,6 +1482,7 @@ HRESULT WasapiCapture::resetProxy()
if(wfx != nullptr)
{
+ TraceFormat("Got capture format", wfx);
if(!(wfx->nChannels == OutputType.Format.nChannels ||
(wfx->nChannels == 1 && OutputType.Format.nChannels == 2) ||
(wfx->nChannels == 2 && OutputType.Format.nChannels == 1)))