Commit ad130c35 authored by David Reid's avatar David Reid

WinMM: Simplify format selection.

parent fa8b0904
...@@ -5607,11 +5607,6 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type ...@@ -5607,11 +5607,6 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type
(void)pContext; (void)pContext;
mal_uint32 heapSize; mal_uint32 heapSize;
mal_uint32 iBit;
WORD closestBitsPerSample = 0;
WORD closestChannels = 0;
DWORD closestSampleRate = 0;
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
mal_zero_object(&pDevice->winmm); mal_zero_object(&pDevice->winmm);
...@@ -5663,10 +5658,12 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type ...@@ -5663,10 +5658,12 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type
// Change the format based on the closest match of the supported standard formats. // Change the format based on the closest match of the supported standard formats.
DWORD dwFormats = 0; DWORD dwFormats = 0;
WORD wChannels = 0;
if (type == mal_device_type_playback) { if (type == mal_device_type_playback) {
WAVEOUTCAPSA caps; WAVEOUTCAPSA caps;
if (((MAL_PFN_waveOutGetDevCapsA)pContext->winmm.waveOutGetDevCapsA)(winMMDeviceID, &caps, sizeof(caps)) == MMSYSERR_NOERROR) { if (((MAL_PFN_waveOutGetDevCapsA)pContext->winmm.waveOutGetDevCapsA)(winMMDeviceID, &caps, sizeof(caps)) == MMSYSERR_NOERROR) {
dwFormats = caps.dwFormats; dwFormats = caps.dwFormats;
wChannels = caps.wChannels;
} else { } else {
errorMsg = "[WinMM] Failed to retrieve internal device caps.", errorCode = MAL_WINMM_FAILED_TO_GET_DEVICE_CAPS; errorMsg = "[WinMM] Failed to retrieve internal device caps.", errorCode = MAL_WINMM_FAILED_TO_GET_DEVICE_CAPS;
goto on_error; goto on_error;
...@@ -5675,6 +5672,7 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type ...@@ -5675,6 +5672,7 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type
WAVEINCAPSA caps; WAVEINCAPSA caps;
if (((MAL_PFN_waveInGetDevCapsA)pContext->winmm.waveInGetDevCapsA)(winMMDeviceID, &caps, sizeof(caps)) == MMSYSERR_NOERROR) { if (((MAL_PFN_waveInGetDevCapsA)pContext->winmm.waveInGetDevCapsA)(winMMDeviceID, &caps, sizeof(caps)) == MMSYSERR_NOERROR) {
dwFormats = caps.dwFormats; dwFormats = caps.dwFormats;
wChannels = caps.wChannels;
} else { } else {
errorMsg = "[WinMM] Failed to retrieve internal device caps.", errorCode = MAL_WINMM_FAILED_TO_GET_DEVICE_CAPS; errorMsg = "[WinMM] Failed to retrieve internal device caps.", errorCode = MAL_WINMM_FAILED_TO_GET_DEVICE_CAPS;
goto on_error; goto on_error;
...@@ -5686,187 +5684,68 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type ...@@ -5686,187 +5684,68 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type
goto on_error; goto on_error;
} }
for (iBit = 0; iBit < 32; ++iBit) { if (wChannels == 1) {
WORD formatBitsPerSample = 0; wf.nChannels = 1;
WORD formatChannels = 0; wf.wBitsPerSample = 16;
DWORD formatSampleRate = 0; if ((dwFormats & WAVE_FORMAT_48M16) != 0) {
wf.nSamplesPerSec = 48000;
DWORD format = (dwFormats & (1 << iBit)); } else if ((dwFormats & WAVE_FORMAT_44M16) != 0) {
if (format != 0) { wf.nSamplesPerSec = 44100;
switch (format) } else if ((dwFormats & WAVE_FORMAT_2M16) != 0) {
{ wf.nSamplesPerSec = 22050;
case WAVE_FORMAT_1M08: } else if ((dwFormats & WAVE_FORMAT_1M16) != 0) {
{ wf.nSamplesPerSec = 11025;
formatBitsPerSample = 8; } else if ((dwFormats & WAVE_FORMAT_96M16) != 0) {
formatChannels = 1; wf.nSamplesPerSec = 96000;
formatSampleRate = 110025; } else {
} break; wf.wBitsPerSample = 8;
case WAVE_FORMAT_1M16: if ((dwFormats & WAVE_FORMAT_48M08) != 0) {
{ wf.nSamplesPerSec = 48000;
formatBitsPerSample = 16; } else if ((dwFormats & WAVE_FORMAT_44M08) != 0) {
formatChannels = 1; wf.nSamplesPerSec = 44100;
formatSampleRate = 110025; } else if ((dwFormats & WAVE_FORMAT_2M08) != 0) {
} break; wf.nSamplesPerSec = 22050;
case WAVE_FORMAT_1S08: } else if ((dwFormats & WAVE_FORMAT_1M08) != 0) {
{ wf.nSamplesPerSec = 11025;
formatBitsPerSample = 8; } else if ((dwFormats & WAVE_FORMAT_96M08) != 0) {
formatChannels = 2; wf.nSamplesPerSec = 96000;
formatSampleRate = 110025;
} break;
case WAVE_FORMAT_1S16:
{
formatBitsPerSample = 16;
formatChannels = 2;
formatSampleRate = 110025;
} break;
case WAVE_FORMAT_2M08:
{
formatBitsPerSample = 8;
formatChannels = 1;
formatSampleRate = 22050;
} break;
case WAVE_FORMAT_2M16:
{
formatBitsPerSample = 16;
formatChannels = 1;
formatSampleRate = 22050;
} break;
case WAVE_FORMAT_2S08:
{
formatBitsPerSample = 8;
formatChannels = 2;
formatSampleRate = 22050;
} break;
case WAVE_FORMAT_2S16:
{
formatBitsPerSample = 16;
formatChannels = 2;
formatSampleRate = 22050;
} break;
case WAVE_FORMAT_44M08:
{
formatBitsPerSample = 8;
formatChannels = 1;
formatSampleRate = 44100;
} break;
case WAVE_FORMAT_44M16:
{
formatBitsPerSample = 16;
formatChannels = 1;
formatSampleRate = 44100;
} break;
case WAVE_FORMAT_44S08:
{
formatBitsPerSample = 8;
formatChannels = 2;
formatSampleRate = 44100;
} break;
case WAVE_FORMAT_44S16:
{
formatBitsPerSample = 16;
formatChannels = 2;
formatSampleRate = 44100;
} break;
case WAVE_FORMAT_48M08:
{
formatBitsPerSample = 8;
formatChannels = 1;
formatSampleRate = 48000;
} break;
case WAVE_FORMAT_48M16:
{
formatBitsPerSample = 16;
formatChannels = 1;
formatSampleRate = 48000;
} break;
case WAVE_FORMAT_48S08:
{
formatBitsPerSample = 8;
formatChannels = 2;
formatSampleRate = 48000;
} break;
case WAVE_FORMAT_48S16:
{
formatBitsPerSample = 16;
formatChannels = 2;
formatSampleRate = 48000;
} break;
case WAVE_FORMAT_96M08:
{
formatBitsPerSample = 8;
formatChannels = 1;
formatSampleRate = 96000;
} break;
case WAVE_FORMAT_96M16:
{
formatBitsPerSample = 16;
formatChannels = 1;
formatSampleRate = 96000;
} break;
case WAVE_FORMAT_96S08:
{
formatBitsPerSample = 8;
formatChannels = 2;
formatSampleRate = 96000;
} break;
case WAVE_FORMAT_96S16:
{
formatBitsPerSample = 16;
formatChannels = 2;
formatSampleRate = 96000;
} break;
default:
{
errorMsg = "[WinMM] The internal device does not support any of the standard formats.", errorCode = MAL_ERROR; // <-- Should never hit this.
goto on_error;
} break;
}
if (formatBitsPerSample == wf.wBitsPerSample && formatChannels == wf.nChannels && formatSampleRate == wf.nSamplesPerSec) {
break; // It's an exact match.
} else { } else {
// It's not an exact match. Compare it with the closest match. errorMsg = "[WinMM] Could not find appropriate format for internal device.", errorCode = MAL_FORMAT_NOT_SUPPORTED;
if (closestBitsPerSample == 0) { goto on_error;
// This is the first format, so nothing to compare against. }
closestBitsPerSample = formatBitsPerSample; }
closestChannels = formatChannels; } else {
closestSampleRate = formatSampleRate; wf.nChannels = 2;
} else { wf.wBitsPerSample = 16;
// Prefer the channel count be the same over the others. if ((dwFormats & WAVE_FORMAT_48S16) != 0) {
if (formatChannels != closestChannels) { wf.nSamplesPerSec = 48000;
// Channels aren't equal. Favour the one equal to our desired channel count. } else if ((dwFormats & WAVE_FORMAT_44S16) != 0) {
if (formatChannels == wf.nChannels) { wf.nSamplesPerSec = 44100;
closestBitsPerSample = formatBitsPerSample; } else if ((dwFormats & WAVE_FORMAT_2S16) != 0) {
closestChannels = formatChannels; wf.nSamplesPerSec = 22050;
closestSampleRate = formatSampleRate; } else if ((dwFormats & WAVE_FORMAT_1S16) != 0) {
} wf.nSamplesPerSec = 11025;
} else { } else if ((dwFormats & WAVE_FORMAT_96S16) != 0) {
// The channels are equal. Look at the format now. wf.nSamplesPerSec = 96000;
if (formatBitsPerSample != closestBitsPerSample) { } else {
if (formatBitsPerSample == wf.wBitsPerSample) { wf.wBitsPerSample = 8;
closestBitsPerSample = formatBitsPerSample; if ((dwFormats & WAVE_FORMAT_48S08) != 0) {
closestChannels = formatChannels; wf.nSamplesPerSec = 48000;
closestSampleRate = formatSampleRate; } else if ((dwFormats & WAVE_FORMAT_44S08) != 0) {
} wf.nSamplesPerSec = 44100;
} else { } else if ((dwFormats & WAVE_FORMAT_2S08) != 0) {
// Both the channels and formats are the same, so now just favour whichever's sample rate is closest to the requested rate. wf.nSamplesPerSec = 22050;
mal_uint32 closestRateDiff = (closestSampleRate > wf.nSamplesPerSec) ? (closestSampleRate - wf.nSamplesPerSec) : (wf.nSamplesPerSec - closestSampleRate); } else if ((dwFormats & WAVE_FORMAT_1S08) != 0) {
mal_uint32 formatRateDiff = (formatSampleRate > wf.nSamplesPerSec) ? (formatSampleRate - wf.nSamplesPerSec) : (wf.nSamplesPerSec - formatSampleRate); wf.nSamplesPerSec = 11025;
if (formatRateDiff < closestRateDiff) { } else if ((dwFormats & WAVE_FORMAT_96S08) != 0) {
closestBitsPerSample = formatBitsPerSample; wf.nSamplesPerSec = 96000;
closestChannels = formatChannels; } else {
closestSampleRate = formatSampleRate; errorMsg = "[WinMM] Could not find appropriate format for internal device.", errorCode = MAL_FORMAT_NOT_SUPPORTED;
} goto on_error;
}
}
}
} }
} }
} }
wf.wBitsPerSample = closestBitsPerSample;
wf.nChannels = closestChannels;
wf.nSamplesPerSec = closestSampleRate;
wf.nBlockAlign = (wf.nChannels * wf.wBitsPerSample) / 8; wf.nBlockAlign = (wf.nChannels * wf.wBitsPerSample) / 8;
wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec; wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment