From c0c670aab4d1cb87f7f49031ec8728d6f1701fe3 Mon Sep 17 00:00:00 2001 From: Thierry Bultel Date: Wed, 13 Feb 2019 11:44:02 +0100 Subject: alsa-api-pcm: added an 'optional' parameter This adds a boolean 'optional' parameter for both playback and capture devices. When the device is not detected, the stream(s) that use is are not created, without leading to the exit of the softmixer. Change-Id: I3effbd61bfe1d1d4a7cde573354b9db791f759cc Signed-off-by: Thierry Bultel --- plugins/alsa/alsa-api-pcm.c | 20 +++++++++++++++++--- plugins/alsa/alsa-api-streams.c | 21 +++++++++++++++++++-- plugins/alsa/alsa-softmixer.h | 5 +++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/plugins/alsa/alsa-api-pcm.c b/plugins/alsa/alsa-api-pcm.c index 26ea9dd..c91b054 100644 --- a/plugins/alsa/alsa-api-pcm.c +++ b/plugins/alsa/alsa-api-pcm.c @@ -392,6 +392,9 @@ PUBLIC void ApiPcmParamsShow(SoftMixerT * mixer, const char *msg, const AlsaPcmH PUBLIC AlsaPcmHwInfoT * ApiPcmSetParams(SoftMixerT *mixer, const char *uid, json_object * paramsJ) { const char *format = NULL, *access = NULL; + + AFB_API_NOTICE(mixer->api, "%s for %s: params are %s", __func__, uid, json_object_get_string(paramsJ)); + AlsaPcmHwInfoT *params = calloc(1, sizeof (AlsaPcmHwInfoT)); if (params == NULL) { SOFTMIXER_NOMEM(mixer->api); @@ -502,7 +505,9 @@ PUBLIC void ApiPcmDelete(SoftMixerT * mixer, AlsaSndPcmT * pcm) { pcmChannelsDestroy(mixer, pcm); - snd_ctl_close(card->ctl); + if (card->ctl) + snd_ctl_close(card->ctl); + free(card); free ((char*)pcm->mute.name); free ((char*)pcm->volume.name); @@ -554,7 +559,7 @@ PUBLIC AlsaSndPcmT * ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm } CDS_INIT_LIST_HEAD(&pcm->sndcard->registryList); - error = wrap_json_unpack(argsJ, "{ss,s?s,s?s,s?s,s?i,s?i,s?o,s?o,s?o,s?o !}" + error = wrap_json_unpack(argsJ, "{ss,s?s,s?s,s?s,s?i,s?i,s?o,s?o,s?o,s?o,s?b !}" , "uid", &pcm->uid , "pcmplug_params", &pcm->sndcard->cid.pcmplug_params , "path", &pcm->sndcard->cid.devpath @@ -565,9 +570,10 @@ PUBLIC AlsaSndPcmT * ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm , "source", &sourceJ , "params", ¶msJ , "quirks", &quirksJ + , "optional", &pcm->optional ); if (error) { - AFB_API_ERROR(mixer->api, "%s: hal=%s missing 'uid|path|cardid|device|sink|source|params|quirks' error=%s args=%s", + AFB_API_ERROR(mixer->api, "%s: hal=%s missing 'uid|path|cardid|device|sink|source|params|quirks|optional' error=%s args=%s", __func__, uid, wrap_json_get_error_string(error), json_object_get_string(argsJ)); goto fail_pcm_sndcard; } @@ -577,9 +583,17 @@ PUBLIC AlsaSndPcmT * ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm else pcm->isPcmPlug = false; + pcm->sndcard->optional = pcm->optional; + // try to open sound card control interface pcm->sndcard->ctl = AlsaByPathOpenCtl(mixer, pcm->uid, pcm->sndcard); if (!pcm->sndcard->ctl) { + if (pcm->optional) { + + AFB_API_INFO(mixer->api, "%s: hal=%s Fail to open OPTIONAL sndcard uid=%s devpath=%s cardid=%s", + __func__, uid, pcm->uid, pcm->sndcard->cid.devpath, pcm->sndcard->cid.cardid); + goto done; + } AFB_API_ERROR(mixer->api, "%s: hal=%s Fail to open sndcard uid=%s devpath=%s cardid=%s", __func__, uid, pcm->uid, pcm->sndcard->cid.devpath, pcm->sndcard->cid.cardid); diff --git a/plugins/alsa/alsa-api-streams.c b/plugins/alsa/alsa-api-streams.c index 43485b4..92e00c0 100644 --- a/plugins/alsa/alsa-api-streams.c +++ b/plugins/alsa/alsa-api-streams.c @@ -284,6 +284,14 @@ STATIC int CreateOneStream(SoftMixerT *mixer, const char * uid, AlsaStreamAudioT } } + stream->optional = captureCard->optional; + + if (!captureCard->ctl && captureCard->optional) { + stream->noHwDetected = true; + AFB_API_INFO(mixer->api,"%s: no detected capture device", __func__); + goto done; + } + // check PCM is valid and get its full name AlsaPcmCtlT *capturePcm = AlsaByPathOpenPcmCtl(mixer, captureDev, SND_PCM_STREAM_CAPTURE); if (!capturePcm) { @@ -532,7 +540,7 @@ STATIC int CreateOneStream(SoftMixerT *mixer, const char * uid, AlsaStreamAudioT AFB_API_NOTICE(mixer->api, "%s: mixer=%s stream=%s CREATED", __func__, mixer->uid, stream->uid); - +done: return 0; OnErrorExit: @@ -668,6 +676,9 @@ static void streamDestroy(SoftMixerT * mixer, void * arg) { int error = 0; AFB_API_DEBUG(mixer->api, "%s... %s", __func__, stream->uid); + if (stream->noHwDetected) + goto freemem; + error = afb_api_del_verb(mixer->api, stream->uid, (void**)stream->verbApiHandle); if (error) { AFB_API_DEBUG(mixer->api, "%s: failed to remove verb %s", __func__, stream->uid); @@ -675,6 +686,7 @@ static void streamDestroy(SoftMixerT * mixer, void * arg) { AlsaPcmCopyStop(mixer, stream->copy); +freemem: if (stream->softvolConfig) { AFB_API_DEBUG(mixer->api, "%s... %s delete softvol config", __func__, stream->uid); snd_config_delete(stream->softvolConfig); @@ -744,6 +756,8 @@ PUBLIC int ApiStreamAttach(SoftMixerT *mixer, afb_req_t request, const char * ui afb_req_fail_f(request, "bad-stream", "mixer=%s invalid stream= %s", mixer->uid, json_object_get_string(argsJ)); goto fail; } + if (newStream->noHwDetected) + AlsaMixerTransactionObjectDelete(mixer->transaction, newStream, true); break; @@ -766,7 +780,10 @@ PUBLIC int ApiStreamAttach(SoftMixerT *mixer, afb_req_t request, const char * ui "%s: mixer=%s invalid stream= %s", __func__, mixer->uid, json_object_get_string(streamJ)); goto fail; - } + } + if (newStream->noHwDetected) + AlsaMixerTransactionObjectDelete(mixer->transaction, newStream, true); + } break; default: diff --git a/plugins/alsa/alsa-softmixer.h b/plugins/alsa/alsa-softmixer.h index f33ea62..376635a 100644 --- a/plugins/alsa/alsa-softmixer.h +++ b/plugins/alsa/alsa-softmixer.h @@ -211,6 +211,7 @@ typedef struct AlsaSndCtlT_ { long nbRegistry; struct cds_list_head registryList; struct SubscribeHandleT_ * eventSubscribeHandle; + bool optional; } AlsaSndCtlT; @@ -244,6 +245,7 @@ typedef struct { bool isPcmPlug; void * apiVerbHandle; unsigned int quirks; + bool optional; } AlsaSndPcmT; typedef struct { @@ -283,9 +285,12 @@ typedef struct AlsaStreamAudioT_ { AlsaPcmCopyHandleT *copy; struct cds_list_head list; /* link to the global list*/ AlsaPcmCtlT * softvol; + snd_config_t * softvolConfig; snd_config_t * rateConfig; void * verbApiHandle; + bool optional; + bool noHwDetected; } AlsaStreamAudioT; typedef struct SoftMixerT_{ -- cgit 1.2.3-korg