summaryrefslogtreecommitdiffstats
path: root/plugins/alsa
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/alsa')
-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_{