summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Bultel <thierry.bultel@iot.bzh>2019-02-13 11:44:02 +0100
committerThierry Bultel <thierry.bultel@iot.bzh>2019-05-13 13:55:58 +0200
commiteb45566268d0bbb7df9e30f733a95d79275eb3a7 (patch)
tree38cc3fd2a9aafec9e0a0b1dffbefb447d59f9682
parent93bf6e6901744f4bee2b673361ae81a97d3dd340 (diff)
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 <thierry.bultel@iot.bzh>
-rw-r--r--plugins/alsa/alsa-api-pcm.c20
-rw-r--r--plugins/alsa/alsa-api-streams.c21
-rw-r--r--plugins/alsa/alsa-softmixer.h5
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", &paramsJ
, "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_{