@@ -5820,6 +5849,24 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
}
// MMAP Mode
//
// Try using interleaved MMAP access. If this fails, fall back to standard readi/writei.
pDevice->alsa.isUsingMMap=MAL_FALSE;
if(!pConfig->alsa.noMMap&&pDevice->type!=mal_device_type_capture){// <-- Disabling MMAP mode for capture devices because I apparently do not have a device that supports it so I can test it... Contributions welcome.
returnmal_post_error(pDevice,"[ALSA] Failed to set access mode to neither SND_PCM_ACCESS_MMAP_INTERLEAVED nor SND_PCM_ACCESS_RW_INTERLEAVED. snd_pcm_hw_params_set_access() failed.",MAL_FORMAT_NOT_SUPPORTED);
}
}
// Most important properties first. The documentation for OSS (yes, I know this is ALSA!) recommends format, channels, then sample rate. I can't
// find any documentation for ALSA specifically, so I'm going to copy the recommendation for OSS.
...
...
@@ -5875,7 +5922,24 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
}
pDevice->internalChannels=channels;
// Sample Rate
// Sample Rate. It appears there's either a bug in ALSA, a bug in some drivers, or I'm doing something silly; but having resampling
// enabled causes problems with some device configurations when used in conjunction with MMAP access mode. To fix this problem we
// need to disable resampling.
//
// To reproduce this problem, open the "plug:dmix" device, and set the sample rate to 44100. Internally, it looks like dmix uses a
// sample rate of 48000. The hardware parameters will get set correctly with no errors, but it looks like the 44100 -> 48000 resampling
// doesn't work properly - but only with MMAP access mode. You will notice skipping/crackling in the audio, and it'll run at a slightly
// faster rate.
//
// mini_al has built-in support for sample rate conversion (albeit low quality at the moment), so disabling resampling should be fine
// for us. The only problem is that it won't be taking advantage of any kind of hardware-accelerated resampling and it won't be very
// good quality until I get a chance to improve the quality of mini_al's software sample rate conversion.
//
// I don't currently know if the dmix plugin is the only one with this error. Indeed, this is the only one I've been able to reproduce
// this error with. In the future, we may want to restrict the disabling of resampling to only known bad plugins.
@@ -5891,7 +5954,7 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
mal_device_uninit__alsa(pDevice);
returnmal_post_error(pDevice,"[ALSA] Failed to set buffer size for device. snd_pcm_hw_params_set_buffer_size() failed.",MAL_FORMAT_NOT_SUPPORTED);
}
pDevice->bufferSizeInFrames=actualBufferSize;
// Periods.
mal_uint32periods=pConfig->periods;
...
...
@@ -5900,37 +5963,19 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
mal_device_uninit__alsa(pDevice);
returnmal_post_error(pDevice,"[ALSA] Failed to set period count. snd_pcm_hw_params_set_periods_near() failed.",MAL_FORMAT_NOT_SUPPORTED);
}
pDevice->bufferSizeInFrames=actualBufferSize;
pDevice->periods=periods;
// MMAP Mode
//
// Try using interleaved MMAP access. If this fails, fall back to standard readi/writei.
pDevice->alsa.isUsingMMap=MAL_FALSE;
if(!pConfig->alsa.noMMap&&pDevice->type!=mal_device_type_capture){// <-- Disabling MMAP mode for capture devices because I apparently do not have a device that supports it so I can test it... Contributions welcome.
returnmal_post_error(pDevice,"[ALSA] Failed to set access mode to neither SND_PCM_ACCESS_MMAP_INTERLEAVED nor SND_PCM_ACCESS_RW_INTERLEAVED. snd_pcm_hw_params_set_access() failed.",MAL_FORMAT_NOT_SUPPORTED);
returnmal_post_error(pDevice,"[ALSA] Failed to set start threshold for playback device. snd_pcm_sw_params_set_start_threshold() failed.",MAL_ALSA_FAILED_TO_SET_SW_PARAMS);