From 396da1607aa1cf1b3ba509c2ec4ebccda2fe382d Mon Sep 17 00:00:00 2001 From: Thierry Bultel Date: Wed, 13 Feb 2019 14:37:01 +0100 Subject: core-pcm: fixed channels setting issues Recent tries on the minnow board have show that the setting of channels on a PCM must be done -after- the setting of the rate. When not doing that, there can be issues (really, complicated to find) around the boundaries values (open intervals) on the period bytes. Additionally, the number of channels can now be forced in the json file. Change-Id: I2c20853daadf9ccab06be6e04d1a185440f57780 Signed-off-by: Thierry Bultel --- plugins/alsa/alsa-api-pcm.c | 12 ++++++++---- plugins/alsa/alsa-core-pcm.c | 25 ++++++++++++++++--------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/plugins/alsa/alsa-api-pcm.c b/plugins/alsa/alsa-api-pcm.c index c91b054..834d2fb 100644 --- a/plugins/alsa/alsa-api-pcm.c +++ b/plugins/alsa/alsa-api-pcm.c @@ -384,8 +384,8 @@ PUBLIC void ApiPcmDelParams(SoftMixerT* mixer, AlsaPcmHwInfoT* params) { } PUBLIC void ApiPcmParamsShow(SoftMixerT * mixer, const char *msg, const AlsaPcmHwInfoT * params) { - AFB_API_INFO(mixer->api, "%s PARAMS: rate=%d, format=%d, formatString=%s", - msg, params->rate, params->format, params->formatString); + AFB_API_INFO(mixer->api, "%s PARAMS: rate=%d, format=%d, formatString=%s, channels %d", + msg, params->rate, params->format, params->formatString, params->channels); } @@ -408,10 +408,11 @@ PUBLIC AlsaPcmHwInfoT * ApiPcmSetParams(SoftMixerT *mixer, const char *uid, json if (paramsJ) { int error = - wrap_json_unpack(paramsJ, "{s?i,s?s,s?s !}", + wrap_json_unpack(paramsJ, "{s?i,s?s,s?s,s?i !}", "rate", ¶ms->rate, "format", &format, - "access", &access); + "access", &access, + "channels", ¶ms->channels); if (error) { AFB_API_ERROR(mixer->api, "%s: sndcard=%s invalid params=%s", __func__, uid, json_object_get_string(paramsJ)); @@ -419,6 +420,9 @@ PUBLIC AlsaPcmHwInfoT * ApiPcmSetParams(SoftMixerT *mixer, const char *uid, json } } + AFB_API_NOTICE(mixer->api, "%s:%s rate set to %d", __func__, uid, params->rate); + AFB_API_NOTICE(mixer->api, "%s:%s channels set to %d", __func__, uid, params->channels); + // default format if (!format) { params->format = SND_PCM_FORMAT_S16_LE; diff --git a/plugins/alsa/alsa-core-pcm.c b/plugins/alsa/alsa-core-pcm.c index e03c320..f058cb9 100644 --- a/plugins/alsa/alsa-core-pcm.c +++ b/plugins/alsa/alsa-core-pcm.c @@ -136,7 +136,22 @@ PUBLIC int AlsaPcmConf(SoftMixerT *mixer, AlsaPcmCtlT *pcm, int mode) { } } - if (opts->rate > 0 ) { + unsigned int * channels = &opts->channels; + + if (*channels) { + AFB_API_DEBUG(mixer->api, "%s: Attempt to set %d channels", __func__, *channels); + if ((error = snd_pcm_hw_params_set_channels(pcm->handle, pxmHwParams, *channels)) < 0) { + AFB_API_ERROR(mixer->api, + "%s (%s): mixer=%s Set_Channels=%d Fail error=%s", + __func__, card, mixer->uid, *channels, snd_strerror(error)); + + AlsaDumpPcmParams(mixer, pxmHwParams); + goto OnErrorExit; + }; + AFB_API_DEBUG(mixer->api, "%s: CHANNELS SET TO %d", __func__, *channels); + } + + if (opts->rate > 0 ) { AFB_API_DEBUG(mixer->api,"%s (%s): set rate to %d", __func__, card, opts->rate); unsigned int pcmRate = opts->rate; @@ -158,14 +173,6 @@ PUBLIC int AlsaPcmConf(SoftMixerT *mixer, AlsaPcmCtlT *pcm, int mode) { } } - if (opts->channels) { - if ((error = snd_pcm_hw_params_set_channels(pcm->handle, pxmHwParams, opts->channels)) < 0) { - AFB_API_ERROR(mixer->api, - "%s (%s): mixer=%s Set_Channels=%d Fail error=%s", - __func__, card, mixer->uid, opts->channels, snd_strerror(error)); - goto OnErrorExit; - }; - } /* The following code, that * 1) sets period time/size; buffer time/size hardware params -- cgit 1.2.3-korg