diff options
-rw-r--r-- | plugins/alsa/alsa-api-pcm.c | 20 | ||||
-rw-r--r-- | plugins/alsa/alsa-api-streams.c | 21 | ||||
-rw-r--r-- | 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 50246e1..0421119 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_ApiError(mixer->api, "%s: hal=%s missing 'uid|path|cardid|device|sink|source|params|quirks' error=%s args=%s", + AFB_ApiError(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_ApiError(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 7241f41..43c14da 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_ApiNotice(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_ApiDebug(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_ApiDebug(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_ApiDebug(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_ReqT request, const char * uid AFB_ReqFailF(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_ReqT request, const char * uid "%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 c73dd0e..d895cef 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_{ |