From fe8135a9a769f9df7e7e0d0eeacdd8497661a8c4 Mon Sep 17 00:00:00 2001 From: fulup Date: Sun, 10 Jun 2018 00:49:02 +0200 Subject: Cleanup and added return of previous volume when setting new value --- plugins/alsa/alsa-api-loop.c | 12 +- plugins/alsa/alsa-api-mixer.c | 262 ++++++++++++++++++++++++++++++--------- plugins/alsa/alsa-api-pcm.c | 91 +++++++++----- plugins/alsa/alsa-api-ramp.c | 6 +- plugins/alsa/alsa-api-sink.c | 6 +- plugins/alsa/alsa-api-source.c | 6 +- plugins/alsa/alsa-api-streams.c | 102 ++++++++++----- plugins/alsa/alsa-api-zones.c | 6 +- plugins/alsa/alsa-core-pcm.c | 4 +- plugins/alsa/alsa-plug-rate.c | 2 +- plugins/alsa/alsa-plug-route.c | 2 +- plugins/alsa/alsa-plug-vol.c | 2 +- plugins/alsa/alsa-softmixer.h | 9 +- plugins/alsa/alsa-utils-bypath.c | 1 + 14 files changed, 364 insertions(+), 147 deletions(-) (limited to 'plugins') diff --git a/plugins/alsa/alsa-api-loop.c b/plugins/alsa/alsa-api-loop.c index 16fe9fc..6995e25 100644 --- a/plugins/alsa/alsa-api-loop.c +++ b/plugins/alsa/alsa-api-loop.c @@ -161,7 +161,7 @@ PUBLIC int ApiLoopAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, j } if (index == mixer->max.loops) { - AFB_ReqFailF(request, "too-small", "mixer=%s hal=%s max loop=%d argsJ= %s", mixer->uid, uid, mixer->max.loops, json_object_get_string(argsJ)); + AFB_IfReqFailF(mixer, request, "too-small", "mixer=%s hal=%s max loop=%d", mixer->uid, uid, mixer->max.loops); goto OnErrorExit; } @@ -171,15 +171,15 @@ PUBLIC int ApiLoopAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, j case json_type_object: mixer->loops[index] = AttachOneLoop(mixer, uid, argsJ); if (!mixer->loops[index]) { - AFB_ReqFailF(request, "invalid-syntax", "mixer=%s hal=%s invalid loop= %s", mixer->uid, uid, json_object_get_string(argsJ)); + AFB_IfReqFailF(mixer, request, "invalid-syntax", "mixer=%s hal=%s invalid loop= %s", mixer->uid, uid, json_object_get_string(argsJ)); goto OnErrorExit; } break; case json_type_array: count = json_object_array_length(argsJ); - if (count > (mixer->max.loops - count)) { - AFB_ReqFailF(request, "too-small", "mixer=%s hal=%s max loop=%d argsJ= %s", mixer->uid, uid, mixer->max.loops, json_object_get_string(argsJ)); + if (count > (mixer->max.loops - index)) { + AFB_IfReqFailF(mixer, request, "too-small", "mixer=%s hal=%s max loop=%d", mixer->uid, uid, mixer->max.loops); goto OnErrorExit; } @@ -188,13 +188,13 @@ PUBLIC int ApiLoopAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, j json_object *loopJ = json_object_array_get_idx(argsJ, idx); mixer->loops[index + idx] = AttachOneLoop(mixer, uid, loopJ); if (!mixer->loops[index + idx]) { - AFB_ReqFailF(request, "invalid-syntax", "mixer=%s hal=%s invalid loop= %s", mixer->uid, uid, json_object_get_string(loopJ)); + AFB_IfReqFailF(mixer, request, "invalid-syntax", "mixer=%s hal=%s invalid loop= %s", mixer->uid, uid, json_object_get_string(loopJ)); goto OnErrorExit; } } break; default: - AFB_ReqFailF(request, "invalid-syntax", "mixer=%s hal=%s loops invalid argsJ= %s", mixer->uid, uid, json_object_get_string(argsJ)); + AFB_IfReqFailF(mixer, request, "invalid-syntax", "mixer=%s hal=%s loops invalid argsJ= %s", mixer->uid, uid, json_object_get_string(argsJ)); goto OnErrorExit; } diff --git a/plugins/alsa/alsa-api-mixer.c b/plugins/alsa/alsa-api-mixer.c index 8616384..ca90649 100644 --- a/plugins/alsa/alsa-api-mixer.c +++ b/plugins/alsa/alsa-api-mixer.c @@ -62,7 +62,7 @@ static void MixerRemoveVerb(AFB_ReqT request) { // finally free mixer handle free(mixer); - AFB_ReqSucess(request, NULL, "Fulup: delete might not clean everything properly"); + AFB_ReqSuccess(request, NULL, "Fulup: delete might not clean everything properly"); return; @@ -70,21 +70,124 @@ OnErrorExit: AFB_ReqFail(request, "internal-error", "fail to delete mixer"); } -STATIC void MixerInfoAction(AFB_ReqT request, json_object *argsJ) { +STATIC json_object * MixerInfoStreams(SoftMixerT *mixer, json_object *streamsJ, int verbose) { + const char * key; + json_object *valueJ; + json_object *responseJ = json_object_new_array(); + AlsaStreamAudioT **streams = mixer->streams; + + switch (json_object_get_type(streamsJ)) { + + case json_type_null: + case json_type_boolean: + + for (int idx = 0; streams[idx]; idx++) { + json_object *alsaJ; + + if (!verbose) { + wrap_json_pack(&alsaJ, "{ss}", "alsa", streams[idx]->source); + json_object_array_add(responseJ, alsaJ); + } else { + + wrap_json_pack(&alsaJ, "{ss,si,si}" + , "cardid", streams[idx]->source + , "volume", streams[idx]->volume + , "mute", streams[idx]->mute + ); + wrap_json_pack(&valueJ, "{ss,ss,so}" + , "uid", streams[idx]->uid + , "verb", streams[idx]->verb + , "alsa", alsaJ + ); + json_object_array_add(responseJ, valueJ); + } + } + break; + + case json_type_string: + + key = json_object_get_string(streamsJ); + for (int idx = 0; streams[idx]; idx++) { + json_object *alsaJ; + + if (!strcasestr(streams[idx]->uid, key)) continue; + + if (!verbose) { + wrap_json_pack(&alsaJ, "{ss}", "alsa", streams[idx]->source); + json_object_array_add(responseJ, alsaJ); + } else { + + wrap_json_pack(&alsaJ, "{ss,si,si}" + , "cardid", streams[idx]->source + , "volume", streams[idx]->volume + , "mute", streams[idx]->mute + ); + wrap_json_pack(&valueJ, "{ss,ss,so}" + , "uid", streams[idx]->uid + , "verb", streams[idx]->verb + , "alsa", alsaJ + ); + json_object_array_add(responseJ, valueJ); + } + } + break; + + case json_type_array: + + for (int idx=0; idx < json_object_array_length(streamsJ); idx++) { + json_object *streamJ = json_object_array_get_idx(streamsJ, idx); + valueJ= MixerInfoStreams (mixer, streamJ, verbose); + json_object_array_add(responseJ, valueJ); + } + + default: + goto OnErrorExit; + } + return (responseJ); + +OnErrorExit: + return NULL; +} + +STATIC json_object * MixerInfoRamps(SoftMixerT *mixer, int verbose) { + + json_object *rampsJ = json_object_new_array(); + json_object *valueJ; + + AlsaVolRampT **ramps = mixer->ramps; + for (int idx = 0; ramps[idx]; idx++) { + if (!verbose) { + json_object_array_add(rampsJ, json_object_new_string(ramps[idx]->uid)); + } else { + wrap_json_pack(&valueJ, "{ss,si,si,si}" + , "uid", ramps[idx]->uid + , "delay", ramps[idx]->delay + , "step_down", ramps[idx]->stepDown + , "step_up", ramps[idx]->stepUp + ); + json_object_array_add(rampsJ, valueJ); + } + } + + return (rampsJ); +} + +STATIC void MixerInfoAction(AFB_ReqT request, json_object * argsJ) { SoftMixerT *mixer = (SoftMixerT*) afb_request_get_vcbdata(request); - int error, streams = 0, quiet = 0, ramps = 0, zones = 0, captures = 0, playbacks = 0; + int error, verbose = 0, ramps = 0, zones = 0, captures = 0, playbacks = 0; + json_object *streamsJ = NULL; if (json_object_get_type(argsJ) == json_type_null) { - streams = 1; + streamsJ = json_object_new_boolean(1); ramps = 1; zones = 0; captures = 0; playbacks = 0; } else { - error = wrap_json_unpack(argsJ, "{s?b,s?b,s?b,s?b,s?b,s?b !}" - , "quiet", &quiet - , "streams", &streams + error = wrap_json_unpack(argsJ, "{s?b,s?o,s?b,s?b,s?b,s?b !}" + , "verbose", &verbose + , "streams", &streamsJ , "ramps", &ramps , "captures", &captures , "playbacks", &playbacks @@ -97,48 +200,17 @@ STATIC void MixerInfoAction(AFB_ReqT request, json_object *argsJ) { } json_object *responseJ = json_object_new_object(); - if (streams) { - json_object *streamsJ = json_object_new_array(); - json_object *valueJ; - - AlsaStreamAudioT **streams = mixer->streams; - for (int idx = 0; streams[idx]; idx++) { - if (quiet) { - json_object_array_add(streamsJ, json_object_new_string(streams[idx]->uid)); - } else { - wrap_json_pack(&valueJ, "{ss,ss?,s{si,si}}" - , "uid", streams[idx]->uid - , "alsa", streams[idx]->source - , "numid" - , "volume", streams[idx]->volume - , "mute", streams[idx]->mute - ); - json_object_array_add(streamsJ, valueJ); - } - + if (streamsJ) { + json_object *resultJ = MixerInfoStreams(mixer, streamsJ, verbose); + if (!resultJ) { + AFB_ReqFailF(request, "invalid-object", "streams should be boolean or string argsJ=%s", json_object_get_string(streamsJ)); + goto OnErrorExit; } - json_object_object_add(responseJ, "streams", streamsJ); + json_object_object_add(responseJ, "streams", resultJ); } if (ramps) { - json_object *rampsJ = json_object_new_array(); - json_object *valueJ; - - AlsaVolRampT **ramps = mixer->ramps; - for (int idx = 0; ramps[idx]; idx++) { - if (quiet) { - json_object_array_add(rampsJ, json_object_new_string(ramps[idx]->uid)); - } else { - wrap_json_pack(&valueJ, "{ss,si,si,si}" - , "uid", ramps[idx]->uid - , "delay", ramps[idx]->delay - , "step_down", ramps[idx]->stepDown - , "step_up", ramps[idx]->stepUp - ); - json_object_array_add(rampsJ, valueJ); - } - - } + json_object *rampsJ = MixerInfoRamps (mixer, verbose); json_object_object_add(responseJ, "ramps", rampsJ); } @@ -147,7 +219,7 @@ STATIC void MixerInfoAction(AFB_ReqT request, json_object *argsJ) { AlsaSndZoneT **zones = mixer->zones; for (int idx = 0; zones[idx]; idx++) { - if (quiet) { + if (!verbose) { json_object_array_add(zonesJ, json_object_new_string(zones[idx]->uid)); } else { json_object *zoneJ = json_object_new_object(); @@ -198,7 +270,7 @@ STATIC void MixerInfoAction(AFB_ReqT request, json_object *argsJ) { goto OnErrorExit; } - AFB_ReqSucess(request, responseJ, NULL); + AFB_ReqSuccess(request, responseJ, NULL); return; OnErrorExit: @@ -206,19 +278,21 @@ OnErrorExit: } STATIC void MixerInfoVerb(AFB_ReqT request) { - json_object *argsJ = afb_request_json(request); - MixerInfoAction (request, argsJ); + json_object *argsJ = afb_request_json(request); + MixerInfoAction(request, argsJ); } STATIC void MixerAttachVerb(AFB_ReqT request) { SoftMixerT *mixer = (SoftMixerT*) afb_request_get_vcbdata(request); - const char *uid = NULL; + const char *uid = NULL, *prefix = NULL; json_object *playbackJ = NULL, *captureJ = NULL, *zonesJ = NULL, *streamsJ = NULL, *rampsJ = NULL, *loopsJ = NULL; json_object *argsJ = afb_request_json(request); + json_object *responseJ = json_object_new_object(); int error; - error = wrap_json_unpack(argsJ, "{ss,s?o,s?o,s?o,s?o,s?o,s?o !}" + error = wrap_json_unpack(argsJ, "{ss,s?s,s?o,s?o,s?o,s?o,s?o,s?o !}" , "uid", &uid + , "prefix", &prefix , "ramps", &rampsJ , "playbacks", &playbackJ , "captures", &captureJ @@ -227,7 +301,6 @@ STATIC void MixerAttachVerb(AFB_ReqT request) { , "streams", &streamsJ ); if (error) { - AFB_ApiError(mixer->api, "MixerAttachVerb: invalid-syntax mixer=%s error=%s args=%s", mixer->uid, wrap_json_get_error_string(error), json_object_get_string(argsJ)); AFB_ReqFailF(request, "invalid-syntax", "mixer=%s missing 'uid|ramps|playbacks|captures|zones|streams' error=%s args=%s", mixer->uid, wrap_json_get_error_string(error), json_object_get_string(argsJ)); goto OnErrorExit; } @@ -255,15 +328,22 @@ STATIC void MixerAttachVerb(AFB_ReqT request) { if (rampsJ) { error = ApiRampAttach(mixer, request, uid, rampsJ); if (error) goto OnErrorExit; + + json_object *resultJ = MixerInfoStreams(mixer, streamsJ, 0); + json_object_object_add(responseJ, "ramps", resultJ); } if (streamsJ) { - error = ApiStreamAttach(mixer, request, uid, streamsJ); + error = ApiStreamAttach(mixer, request, uid, prefix, streamsJ); if (error) goto OnErrorExit; + + json_object *resultJ = MixerInfoStreams(mixer, streamsJ, 0); + json_object_object_add(responseJ, "streams", resultJ); } - // return mixer info data after attach - return (MixerInfoAction(request,NULL)); + AFB_ReqSuccess(request, responseJ, NULL); + + return; OnErrorExit: return; @@ -273,7 +353,7 @@ STATIC void MixerPingVerb(AFB_ReqT request) { static int count = 0; count++; AFB_ReqNotice(request, "Controller:ping count=%d", count); - AFB_ReqSucess(request, json_object_new_int(count), NULL); + AFB_ReqSuccess(request, json_object_new_int(count), NULL); return; } @@ -289,7 +369,7 @@ STATIC AFB_ApiVerbs CtrlApiVerbs[] = { { .verb = NULL} /* marker for end of the array */ }; -STATIC int LoadStaticVerbs(SoftMixerT *mixer, AFB_ApiVerbs *verbs) { +STATIC int LoadStaticVerbs(SoftMixerT *mixer, AFB_ApiVerbs * verbs) { int errcount = 0; for (int idx = 0; verbs[idx].verb; idx++) { @@ -299,8 +379,68 @@ STATIC int LoadStaticVerbs(SoftMixerT *mixer, AFB_ApiVerbs *verbs) { return errcount; }; -CTLP_CAPI(CreateMixer, source, argsJ, responseJ) { +CTLP_CAPI(MixerAttach, source, argsJ, responseJ) { + SoftMixerT *mixer = source->context; + json_object *playbackJ = NULL, *captureJ = NULL, *zonesJ = NULL, *streamsJ = NULL, *rampsJ = NULL, *loopsJ = NULL; + const char* uid = source->uid, *prefix = NULL; + + int error; + + error = wrap_json_unpack(argsJ, "{s?s, s?o,s?o,s?o,s?o,s?o,s?o !}" + , "prefix", &rampsJ + , "ramps", &rampsJ + , "playbacks", &playbackJ + , "captures", &captureJ + , "loops", &loopsJ + , "zones", &zonesJ + , "streams", &streamsJ + ); + if (error) { + AFB_ApiError(mixer->api, "MixerAttachVerb: invalid-syntax mixer=%s error=%s args=%s", mixer->uid, wrap_json_get_error_string(error), json_object_get_string(argsJ)); + goto OnErrorExit; + } + + if (playbackJ) { + error = ApiSinkAttach(mixer, NULL, uid, playbackJ); + if (error) goto OnErrorExit; + } + + if (captureJ) { + error = ApiSourceAttach(mixer, NULL, uid, captureJ); + if (error) goto OnErrorExit; + } + + if (loopsJ) { + error = ApiLoopAttach(mixer, NULL, uid, loopsJ); + if (error) goto OnErrorExit; + } + + if (zonesJ) { + error = ApiZoneAttach(mixer, NULL, uid, zonesJ); + if (error) goto OnErrorExit; + } + + if (rampsJ) { + error = ApiRampAttach(mixer, NULL, uid, rampsJ); + if (error) goto OnErrorExit; + } + + if (streamsJ) { + error = ApiStreamAttach(mixer, NULL, uid, prefix, streamsJ); + if (error) goto OnErrorExit; + } + + // return mixer info data after attach + return 0; + +OnErrorExit: + return -1; +} + +CTLP_CAPI(MixerCreate, source, argsJ, responseJ) { SoftMixerT *mixer = calloc(1, sizeof (SoftMixerT)); + source->context = mixer; + int error; mixer->max.loops = SMIXER_DEFLT_RAMPS; mixer->max.sinks = SMIXER_DEFLT_SINKS; @@ -339,14 +479,14 @@ CTLP_CAPI(CreateMixer, source, argsJ, responseJ) { mixer->zones = calloc(mixer->max.zones + 1, sizeof (void*)); mixer->streams = calloc(mixer->max.streams + 1, sizeof (void*)); mixer->ramps = calloc(mixer->max.ramps + 1, sizeof (void*)); - + mixer->sdLoop = AFB_GetEventLoop(source->api); - mixer->api= source->api; + mixer->api = source->api; afb_dynapi_set_userdata(source->api, mixer); error = LoadStaticVerbs(mixer, CtrlApiVerbs); if (error) goto OnErrorExit; - + return 0; OnErrorExit: diff --git a/plugins/alsa/alsa-api-pcm.c b/plugins/alsa/alsa-api-pcm.c index 56a1b8b..64b852e 100644 --- a/plugins/alsa/alsa-api-pcm.c +++ b/plugins/alsa/alsa-api-pcm.c @@ -33,7 +33,7 @@ STATIC int CONVERT_PERCENT(long val, long min, long max) { if (range == 0) return 0; val -= min; - tmp = (int)rint((double) val / (double) range * 100); + tmp = (int) rint((double) val / (double) range * 100); return tmp; } @@ -149,10 +149,10 @@ OnErrorExit: return -1; } -STATIC int PcmSetControl(SoftMixerT *mixer, AlsaSndCtlT *sndcard, AlsaSndControlT *control, volumeT volType, int value) { +STATIC int PcmSetControl(SoftMixerT *mixer, AlsaSndCtlT *sndcard, AlsaSndControlT *control, volumeT volType, int *newvol, int *oldval) { snd_ctl_elem_id_t* elemId = NULL; snd_ctl_elem_info_t *elemInfo; - int error; + int error, value; long curval; assert(control->numid); @@ -185,7 +185,7 @@ STATIC int PcmSetControl(SoftMixerT *mixer, AlsaSndCtlT *sndcard, AlsaSndControl switch (snd_ctl_elem_info_get_type(elemInfo)) { case SND_CTL_ELEM_TYPE_BOOLEAN: - error = CtlElemIdSetLong(mixer, sndcard, elemId, value); + error = CtlElemIdSetLong(mixer, sndcard, elemId, *newvol); break; case SND_CTL_ELEM_TYPE_INTEGER: @@ -193,18 +193,18 @@ STATIC int PcmSetControl(SoftMixerT *mixer, AlsaSndCtlT *sndcard, AlsaSndControl switch (volType) { case RVOL_ADD: - value = CONVERT_PERCENT(curval, control->min, control->max) + value; + value = CONVERT_PERCENT(curval, control->min, control->max) + *newvol; break; case RVOL_DEL: - value = CONVERT_PERCENT(curval, control->min, control->max) - value; + value = CONVERT_PERCENT(curval, control->min, control->max) - *newvol; break; default: - value= value; + value = *newvol; } error = CtlElemIdSetLong(mixer, sndcard, elemId, CONVERT_VOLUME(value, control->min, control->max)); if (error) { - AFB_ApiError(mixer->api, "PcmSetControl sndard=%s fail to write control numid=%d value=%d", sndcard->cid.cardid, control->numid, value); + AFB_ApiError(mixer->api, "PcmSetControl sndard=%s fail to write control numid=%d value=%d", sndcard->cid.cardid, control->numid, value); goto OnErrorExit; } break; @@ -219,6 +219,8 @@ STATIC int PcmSetControl(SoftMixerT *mixer, AlsaSndCtlT *sndcard, AlsaSndControl goto OnErrorExit; } + *oldval = CONVERT_PERCENT(curval, control->min, control->max); + *newvol = value; free(elemId); return 0; @@ -229,17 +231,18 @@ OnErrorExit: STATIC void ApiPcmVerbCB(AFB_ReqT request) { apiVerbHandleT *handle = (apiVerbHandleT*) afb_request_get_vcbdata(request); - int error, doQuiet = 0, doToggle = 0, doMute = -1; + int error, verbose = 0, doInfo = 0, doToggle = 0, doMute = -1; json_object *volumeJ = NULL; - json_object *responseJ = json_object_new_object(); + json_object *responseJ = NULL; json_object *argsJ = afb_request_json(request); SoftMixerT *mixer = handle->mixer; AlsaSndCtlT *sndcard = handle->pcm->sndcard; assert(mixer && sndcard); - error = wrap_json_unpack(argsJ, "{s?b s?b,s?b,s?o !}" - , "quiet", &doQuiet + error = wrap_json_unpack(argsJ, "{s?b,s?b,s?b,s?b,s?o !}" + , "verbose", &verbose + , "info", &doInfo , "mute", &doMute , "toggle", &doToggle , "volume", &volumeJ @@ -249,10 +252,41 @@ STATIC void ApiPcmVerbCB(AFB_ReqT request) { goto OnErrorExit; } + if (verbose) responseJ=json_object_new_object(); + + if (doMute != -1) { + int mute = (int) doMute; + + error += AlsaCtlNumidSetLong(mixer, sndcard, handle->pcm->mute.numid, mute); + if (error) { + AFB_ReqFailF(request, "invalid-numid", "Fail to set pause numid=%d", handle->pcm->mute.numid); + goto OnErrorExit; + } + + if (verbose) { + json_object_object_add(responseJ, "mute", json_object_new_boolean((json_bool) mute)); + } + } + + if (doToggle) { + long mute; + + error += AlsaCtlNumidGetLong(mixer, handle->pcm->sndcard, handle->pcm->mute.numid, &mute); + error += AlsaCtlNumidSetLong(mixer, handle->pcm->sndcard, handle->pcm->mute.numid, !mute); + if (error) { + AFB_ReqFailF(request, "invalid-numid", "Fail to toogle pause numid=%d", handle->pcm->mute.numid); + goto OnErrorExit; + } + + if (verbose) { + json_object_object_add(responseJ, "mute", json_object_new_boolean((json_bool)!mute)); + } + } + if (volumeJ) { volumeT volType; - int newvol; + int newvol, oldvol; const char*volString; switch (json_object_get_type(volumeJ)) { @@ -287,19 +321,20 @@ STATIC void ApiPcmVerbCB(AFB_ReqT request) { } - error = PcmSetControl(mixer, handle->pcm->sndcard, &handle->pcm->volume, volType, newvol); + error = PcmSetControl(mixer, handle->pcm->sndcard, &handle->pcm->volume, volType, &newvol, &oldvol); if (error) { AFB_ReqFailF(request, "invalid-ctl", "Fail to set volume hal=%s card=%s numid=%d name=%s value=%d" , handle->uid, handle->pcm->sndcard->cid.cardid, handle->pcm->volume.numid, handle->pcm->volume.name, newvol); goto OnErrorExit; } - - if (!doQuiet) { - json_object_object_add(responseJ, "volume", json_object_new_int(newvol)); + + if (verbose) { + json_object_object_add(responseJ, "volnew", json_object_new_int(newvol)); + json_object_object_add(responseJ, "volold", json_object_new_int(oldvol)); } } - AFB_ReqSucess(request, responseJ, handle->uid); + AFB_ReqSuccess(request, responseJ, handle->uid); return; OnErrorExit: @@ -352,26 +387,26 @@ PUBLIC AlsaPcmHwInfoT * ApiPcmSetParams(SoftMixerT *mixer, const char *uid, json goto OnErrorExit; check_access: - AFB_ApiNotice(mixer->api, "ApiPcmSetParams:%s format set to SND_PCM_FORMAT_%s",uid, params->formatS); + AFB_ApiNotice(mixer->api, "ApiPcmSetParams:%s format set to SND_PCM_FORMAT_%s", uid, params->formatS); #define ACCESS_CHECK(arg) if (!strcmp(access,#arg)) { params->access = SND_PCM_ACCESS_##arg; goto success;} - if (!access) { + if (!access) { params->access = SND_PCM_ACCESS_RW_INTERLEAVED; goto success; } - ACCESS_CHECK(MMAP_INTERLEAVED); - ACCESS_CHECK(MMAP_NONINTERLEAVED); - ACCESS_CHECK(MMAP_COMPLEX); - ACCESS_CHECK(RW_INTERLEAVED); - ACCESS_CHECK(RW_NONINTERLEAVED); + ACCESS_CHECK(MMAP_INTERLEAVED); + ACCESS_CHECK(MMAP_NONINTERLEAVED); + ACCESS_CHECK(MMAP_COMPLEX); + ACCESS_CHECK(RW_INTERLEAVED); + ACCESS_CHECK(RW_NONINTERLEAVED); AFB_ApiNotice(mixer->api, "ApiPcmSetParams:%s(params) unsupported access 'RW_INTERLEAVED|MMAP_INTERLEAVED|MMAP_COMPLEX' access=%s", uid, access); goto OnErrorExit; success: - AFB_ApiNotice(mixer->api, "ApiPcmSetParams:%s access set to %s", uid, access); + AFB_ApiNotice(mixer->api, "ApiPcmSetParams:%s access set to %s", uid, access); return params; OnErrorExit: @@ -485,10 +520,10 @@ PUBLIC AlsaSndPcmT * ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm // create master control for this sink char *apiVerb, *apiInfo; if (direction == SND_PCM_STREAM_PLAYBACK) { - (void) asprintf(&apiVerb, "%s/playback", pcm->uid); + (void) asprintf(&apiVerb, "%s:playback", pcm->uid); (void) asprintf(&apiInfo, "HAL:%s SND_PCM_STREAM_PLAYBACK", uid); } else { - (void) asprintf(&apiVerb, "%s/capture", pcm->uid); + (void) asprintf(&apiVerb, "%s:capture", pcm->uid); (void) asprintf(&apiInfo, "HAL:%s SND_PCM_STREAM_PLAYBACK", uid); } apiVerbHandleT *handle = calloc(1, sizeof (apiVerbHandleT)); diff --git a/plugins/alsa/alsa-api-ramp.c b/plugins/alsa/alsa-api-ramp.c index 002aec0..56f4c31 100644 --- a/plugins/alsa/alsa-api-ramp.c +++ b/plugins/alsa/alsa-api-ramp.c @@ -71,7 +71,7 @@ PUBLIC int ApiRampAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, j } if (index == mixer->max.ramps) { - AFB_ReqFailF(request, "too-small", "mixer=%s hal=%s max ramp=%d argsJ= %s", mixer->uid, uid, mixer->max.ramps, json_object_get_string(argsJ)); + AFB_ReqFailF(request, "too-small", "mixer=%s hal=%s max ramp=%d", mixer->uid, uid, mixer->max.ramps); goto OnErrorExit; } @@ -88,8 +88,8 @@ PUBLIC int ApiRampAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, j case json_type_array: count = json_object_array_length(argsJ); - if (count > (mixer->max.ramps - count)) { - AFB_ReqFailF(request, "too-small", "mixer=%s hal=%s max ramp=%d argsJ= %s", mixer->uid, uid, mixer->max.ramps, json_object_get_string(argsJ)); + if (count > (mixer->max.ramps - index)) { + AFB_ReqFailF(request, "too-small", "mixer=%s hal=%s max ramp=%d", mixer->uid, uid, mixer->max.ramps); goto OnErrorExit; } diff --git a/plugins/alsa/alsa-api-sink.c b/plugins/alsa/alsa-api-sink.c index ab32276..02322de 100644 --- a/plugins/alsa/alsa-api-sink.c +++ b/plugins/alsa/alsa-api-sink.c @@ -47,7 +47,7 @@ PUBLIC int ApiSinkAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, j } if (index == mixer->max.sinks) { - AFB_ReqFailF(request, "too-small", "mixer=%s max sink=%d argsJ= %s", mixer->uid, mixer->max.sinks, json_object_get_string(argsJ)); + AFB_ReqFailF(request, "too-small", "mixer=%s max sink=%d", mixer->uid, mixer->max.sinks); goto OnErrorExit; } @@ -76,8 +76,8 @@ PUBLIC int ApiSinkAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, j case json_type_array: count = json_object_array_length(argsJ); - if (count > (mixer->max.sinks - count)) { - AFB_ReqFailF(request, "too-small", "mixer=%s max sink=%d argsJ= %s", mixer->uid, mixer->max.sinks, json_object_get_string(argsJ)); + if (count > (mixer->max.sinks - index)) { + AFB_ReqFailF(request, "too-small", "mixer=%s max sink=%d", mixer->uid, mixer->max.sinks); goto OnErrorExit; } diff --git a/plugins/alsa/alsa-api-source.c b/plugins/alsa/alsa-api-source.c index 6315a14..b6e1390 100644 --- a/plugins/alsa/alsa-api-source.c +++ b/plugins/alsa/alsa-api-source.c @@ -40,7 +40,7 @@ PUBLIC int ApiSourceAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, } if (index == mixer->max.sources) { - AFB_ReqFailF(request, "too-small", "mixer=%s max source=%d argsJ= %s", mixer->uid, mixer->max.sources, json_object_get_string(argsJ)); + AFB_ReqFailF(request, "too-small", "mixer=%s max source=%d", mixer->uid, mixer->max.sources); goto OnErrorExit; } @@ -57,8 +57,8 @@ PUBLIC int ApiSourceAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, case json_type_array: count = json_object_array_length(argsJ); - if (count > (mixer->max.sources - count)) { - AFB_ReqFailF(request, "too-small", "mixer=%s max source=%d argsJ= %s", mixer->uid, mixer->max.sources, json_object_get_string(argsJ)); + if (count > (mixer->max.sources - index)) { + AFB_ReqFailF(request, "too-small", "mixer=%s max source=%d", mixer->uid, mixer->max.sources); goto OnErrorExit; } diff --git a/plugins/alsa/alsa-api-streams.c b/plugins/alsa/alsa-api-streams.c index 876162d..0f9786a 100644 --- a/plugins/alsa/alsa-api-streams.c +++ b/plugins/alsa/alsa-api-streams.c @@ -39,27 +39,30 @@ typedef struct { STATIC void StreamApiVerbCB(AFB_ReqT request) { apiHandleT *handle = (apiHandleT*) afb_request_get_vcbdata(request); - int error, doClose = 0, doQuiet = 0, doToggle = 0, doMute = -1; - long mute, volume; - json_object *responseJ, *volumeJ = NULL, *rampJ = NULL, *argsJ = afb_request_json(request); - + int error, verbose = 0, doClose = 0, doToggle = 0, doMute = -1, doInfo = 0; + long mute, volume, curvol; + json_object *volumeJ = NULL, *rampJ = NULL, *argsJ = afb_request_json(request); + json_object *responseJ = NULL; SoftMixerT *mixer = handle->mixer; AlsaSndCtlT *sndcard = handle->sndcard; assert(mixer && sndcard); - error = wrap_json_unpack(argsJ, "{s?b s?b,s?b,s?b,s?o,s?o !}" - , "quiet", &doQuiet + error = wrap_json_unpack(argsJ, "{s?b s?b,s?b,s?b,s?b,s?o,s?o !}" , "close", &doClose , "mute", &doMute , "toggle", &doToggle + , "info", &doInfo + , "verbose", &verbose , "volume", &volumeJ , "ramp", &rampJ ); if (error) { - AFB_ReqFailF(request, "syntax-error", "Missing 'close|mute|volume|quiet' args=%s", json_object_get_string(argsJ)); + AFB_ReqFailF(request, "syntax-error", "Missing 'close|mute|volume|verbose' args=%s", json_object_get_string(argsJ)); goto OnErrorExit; } + if (verbose) responseJ = json_object_new_object(); + if (doClose) { AFB_ReqFailF(request, "internal-error", "(Fulup) Close action still to be done mixer=%s stream=%s", mixer->uid, handle->stream->uid); goto OnErrorExit; @@ -68,10 +71,31 @@ STATIC void StreamApiVerbCB(AFB_ReqT request) { if (doToggle) { error += AlsaCtlNumidGetLong(mixer, sndcard, handle->stream->mute, &mute); error += AlsaCtlNumidSetLong(mixer, sndcard, handle->stream->mute, !mute); + if (error) { + AFB_ReqFailF(request, "invalid-numid", "Fail to set/get pause numid=%d", handle->stream->mute); + goto OnErrorExit; + } + + if (verbose) { + json_object_object_add(responseJ, "mute", json_object_new_boolean(!mute)); + } + } + + if (doMute != -1) { + error = AlsaCtlNumidSetLong(mixer, handle->sndcard, handle->stream->mute, !mute); + if (error) { + AFB_ReqFailF(request, "StreamApiVerbCB", "Fail to set stream volume numid=%d value=%d", handle->stream->volume, !mute); + goto OnErrorExit; + } + + if (verbose) { + error += AlsaCtlNumidGetLong(mixer, handle->sndcard, handle->stream->mute, &mute); + json_object_object_add(responseJ, "mute", json_object_new_boolean((json_bool) mute)); + } } if (volumeJ) { - long curvol, newvol; + long newvol; const char*volString; error = AlsaCtlNumidGetLong(mixer, handle->sndcard, handle->stream->volume, &curvol); @@ -116,27 +140,29 @@ STATIC void StreamApiVerbCB(AFB_ReqT request) { AFB_ReqFailF(request, "StreamApiVerbCB", "Fail to set stream volume numid=%d value=%ld", handle->stream->volume, newvol); goto OnErrorExit; } + + if (verbose) { + json_object_object_add(responseJ, "volnew", json_object_new_int((int) newvol)); + json_object_object_add(responseJ, "volold", json_object_new_int((int) curvol)); + } } if (rampJ) { - error = AlsaVolRampApply(mixer, handle->sndcard, handle->stream, rampJ); - if (error) { - AFB_ReqFailF(request, "StreamApiVerbCB", "Fail to set stream volram numid=%d value=%s", handle->stream->volume, json_object_get_string(rampJ)); - goto OnErrorExit; + if (verbose) { + error = AlsaCtlNumidGetLong(mixer, handle->sndcard, handle->stream->volume, &curvol); + json_object_object_add(responseJ, "volold", json_object_new_int((int) curvol)); } - } - if (doMute != -1) { - error = AlsaCtlNumidSetLong(mixer, handle->sndcard, handle->stream->mute, !mute); + error += AlsaVolRampApply(mixer, handle->sndcard, handle->stream, rampJ); if (error) { - AFB_ReqFailF(request, "StreamApiVerbCB", "Fail to set stream volume numid=%d value=%d", handle->stream->volume, !mute); + AFB_ReqFailF(request, "StreamApiVerbCB", "Fail to set stream volram numid=%d value=%s", handle->stream->volume, json_object_get_string(rampJ)); goto OnErrorExit; } } - // if not in quiet mode return effective selected control values - if (doQuiet) responseJ = NULL; - else { + + if (doInfo) { + json_object_put(responseJ); // free default response. error += AlsaCtlNumidGetLong(mixer, handle->sndcard, handle->stream->volume, &volume); error += AlsaCtlNumidGetLong(mixer, handle->sndcard, handle->stream->mute, &mute); if (error) { @@ -146,14 +172,15 @@ STATIC void StreamApiVerbCB(AFB_ReqT request) { wrap_json_pack(&responseJ, "{si,sb}", "volume", volume, "mute", !mute); } - AFB_ReqSucess(request, responseJ, NULL); + + AFB_ReqSuccess(request, responseJ, NULL); return; OnErrorExit: return; } -PUBLIC int CreateOneStream(SoftMixerT *mixer, AlsaStreamAudioT *stream) { +STATIC int CreateOneStream(SoftMixerT *mixer, const char * uid, AlsaStreamAudioT * stream) { int error; long value; AlsaSndLoopT *loop = NULL; @@ -272,9 +299,9 @@ PUBLIC int CreateOneStream(SoftMixerT *mixer, AlsaStreamAudioT *stream) { } if (loop) { - (void) asprintf((char**)&stream->source, "hw:%d,%d,%d", captureDev->cardidx, loop->playback, capturePcm->cid.subdev); + (void) asprintf((char**) &stream->source, "hw:%d,%d,%d", captureDev->cardidx, loop->playback, capturePcm->cid.subdev); } else { - (void) asprintf((char**)&stream->source, "hw:%d,%d,%d", captureDev->cardidx, captureDev->device, captureDev->subdev); + (void) asprintf((char**) &stream->source, "hw:%d,%d,%d", captureDev->cardidx, captureDev->device, captureDev->subdev); } // create a dedicated verb for this stream @@ -289,7 +316,7 @@ PUBLIC int CreateOneStream(SoftMixerT *mixer, AlsaStreamAudioT *stream) { stream->volume = volNumid; stream->mute = pauseNumid; - error = afb_dynapi_add_verb(mixer->api, stream->uid, stream->info, StreamApiVerbCB, apiHandle, NULL, 0); + error = afb_dynapi_add_verb(mixer->api, stream->verb, stream->info, StreamApiVerbCB, apiHandle, NULL, 0); if (error) { AFB_ApiError(mixer->api, "CreateOneStream mixer=%s fail to Register API verb stream=%s", mixer->uid, stream->uid); goto OnErrorExit; @@ -307,7 +334,7 @@ OnErrorExit: return -1; } -STATIC AlsaStreamAudioT * AttachOneStream(SoftMixerT *mixer, const char *uid, json_object *streamJ) { +STATIC AlsaStreamAudioT * AttachOneStream(SoftMixerT *mixer, const char *uid, const char *prefix, json_object * streamJ) { AlsaStreamAudioT *stream = calloc(1, sizeof (AlsaStreamAudioT)); int error; json_object *paramsJ = NULL; @@ -317,8 +344,9 @@ STATIC AlsaStreamAudioT * AttachOneStream(SoftMixerT *mixer, const char *uid, js stream->mute = 0; stream->info = NULL; - error = wrap_json_unpack(streamJ, "{ss,s?s,ss,s?s,s?i,s?b,s?o,s?s !}" + error = wrap_json_unpack(streamJ, "{ss,s?s,s?s,ss,s?s,s?i,s?b,s?o,s?s !}" , "uid", &stream->uid + , "verb", &stream->verb , "info", &stream->info , "zone", &stream->sink , "source", &stream->source @@ -344,8 +372,16 @@ STATIC AlsaStreamAudioT * AttachOneStream(SoftMixerT *mixer, const char *uid, js if (stream->sink)stream->sink = strdup(stream->sink); if (stream->source)stream->source = strdup(stream->source); + // Prefix verb with uid|prefix + if (prefix) { + if (stream->verb) asprintf((char**) &stream->verb, "%s:%s", prefix, stream->verb); + else asprintf((char**) &stream->verb, "%s:%s", prefix, stream->uid); + } else { + if (!stream->verb) asprintf((char**) &stream->verb, stream->uid); + } + // implement stream PCM with corresponding thread and controls - error = CreateOneStream(mixer, stream); + error = CreateOneStream(mixer, uid, stream); if (error) goto OnErrorExit; return stream; @@ -355,7 +391,7 @@ OnErrorExit: return NULL; } -PUBLIC int ApiStreamAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, json_object * argsJ) { +PUBLIC int ApiStreamAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, const char *prefix, json_object * argsJ) { if (!mixer->loops) { AFB_ApiError(mixer->api, "StreamsAttach: mixer=%s No Loop found [should Registry snd_loop first]", mixer->uid); @@ -368,7 +404,7 @@ PUBLIC int ApiStreamAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, } if (index == mixer->max.streams) { - AFB_ReqFailF(request, "too-small", "mixer=%s max stream=%d argsJ= %s", mixer->uid, mixer->max.streams, json_object_get_string(argsJ)); + AFB_ReqFailF(request, "too-small", "mixer=%s max stream=%d", mixer->uid, mixer->max.streams); goto OnErrorExit; } @@ -376,7 +412,7 @@ PUBLIC int ApiStreamAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, long count; case json_type_object: - mixer->streams[index] = AttachOneStream(mixer, uid, argsJ); + mixer->streams[index] = AttachOneStream(mixer, uid, prefix, argsJ); if (!mixer->streams[index]) { AFB_ReqFailF(request, "invalid-syntax", "mixer=%s invalid stream= %s", mixer->uid, json_object_get_string(argsJ)); goto OnErrorExit; @@ -386,14 +422,14 @@ PUBLIC int ApiStreamAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, case json_type_array: count = json_object_array_length(argsJ); - if (count > (mixer->max.streams - count)) { - AFB_ReqFailF(request, "too-small", "mixer=%s max stream=%d argsJ= %s", mixer->uid, mixer->max.streams, json_object_get_string(argsJ)); + if (count > (mixer->max.streams - index)) { + AFB_ReqFailF(request, "too-small", "mixer=%s max stream=%d", mixer->uid, mixer->max.streams); goto OnErrorExit; } for (int idx = 0; idx < count; idx++) { json_object *streamJ = json_object_array_get_idx(argsJ, idx); - mixer->streams[index + idx] = AttachOneStream(mixer, uid, streamJ); + mixer->streams[index + idx] = AttachOneStream(mixer, uid, prefix, streamJ); if (!mixer->streams[index + idx]) { AFB_ReqFailF(request, "invalid-syntax", "mixer=%s invalid stream= %s", mixer->uid, json_object_get_string(streamJ)); goto OnErrorExit; diff --git a/plugins/alsa/alsa-api-zones.c b/plugins/alsa/alsa-api-zones.c index 40c36a7..cf5e995 100644 --- a/plugins/alsa/alsa-api-zones.c +++ b/plugins/alsa/alsa-api-zones.c @@ -135,7 +135,7 @@ PUBLIC int ApiZoneAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, j } if (index == mixer->max.zones) { - AFB_ReqFailF(request, "too-small", "mixer=%s max zone=%d argsJ= %s", mixer->uid, mixer->max.zones, json_object_get_string(argsJ)); + AFB_ReqFailF(request, "too-small", "mixer=%s max zone=%d", mixer->uid, mixer->max.zones); goto OnErrorExit; } @@ -159,8 +159,8 @@ PUBLIC int ApiZoneAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, j case json_type_array: count = json_object_array_length(argsJ); - if (count > (mixer->max.zones - count)) { - AFB_ReqFailF(request, "too-small", "mixer=%s max zone=%d argsJ= %s", mixer->uid, mixer->max.zones, json_object_get_string(argsJ)); + if (count > (mixer->max.zones - index)) { + AFB_ReqFailF(request, "too-small", "mixer=%s max zone=%d", mixer->uid, mixer->max.zones); goto OnErrorExit; } diff --git a/plugins/alsa/alsa-core-pcm.c b/plugins/alsa/alsa-core-pcm.c index e4936e5..aed5f22 100644 --- a/plugins/alsa/alsa-core-pcm.c +++ b/plugins/alsa/alsa-core-pcm.c @@ -277,8 +277,8 @@ PUBLIC int AlsaPcmCopy(SoftMixerT *mixer, AlsaStreamAudioT *stream, AlsaPcmCtlT // Fulup need to check https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___direct.html - AlsaDumpPcmInfo(mixer,"PcmIn",pcmIn->handle); - AlsaDumpPcmInfo(mixer,"PcmOut",pcmOut->handle); + //AlsaDumpPcmInfo(mixer,"PcmIn",pcmIn->handle); + //AlsaDumpPcmInfo(mixer,"PcmOut",pcmOut->handle); // prepare PCM for capture and replay error = AlsaPcmConf(mixer, pcmIn, opts); diff --git a/plugins/alsa/alsa-plug-rate.c b/plugins/alsa/alsa-plug-rate.c index 4c83c7f..daa8cf3 100644 --- a/plugins/alsa/alsa-plug-rate.c +++ b/plugins/alsa/alsa-plug-rate.c @@ -70,7 +70,7 @@ PUBLIC AlsaPcmCtlT* AlsaCreateRate(SoftMixerT *mixer, const char* pcmName, AlsaP } // Debug config & pcm - AlsaDumpCtlConfig(mixer, "plug-rate", pcmConfig, 1); + //AlsaDumpCtlConfig(mixer, "plug-rate", pcmConfig, 1); //AlsaDumpCtlConfig (mixer, "plug-rate", rateConfig, 1); AFB_ApiNotice(mixer->api, "AlsaCreateRate: %s done\n", pcmPlug->cid.cardid); return pcmPlug; diff --git a/plugins/alsa/alsa-plug-route.c b/plugins/alsa/alsa-plug-route.c index ac3aa1c..306ddeb 100644 --- a/plugins/alsa/alsa-plug-route.c +++ b/plugins/alsa/alsa-plug-route.c @@ -172,7 +172,7 @@ PUBLIC AlsaPcmCtlT* AlsaCreateRoute(SoftMixerT *mixer, AlsaSndZoneT *zone, int o // Debug config & pcm AFB_ApiNotice(mixer->api, "AlsaCreateRoute:zone(%s) done", zone->uid); - AlsaDumpCtlConfig(mixer, "plug-route", routeConfig, 1); + //AlsaDumpCtlConfig(mixer, "plug-route", routeConfig, 1); return pcmRoute; OnErrorExit: diff --git a/plugins/alsa/alsa-plug-vol.c b/plugins/alsa/alsa-plug-vol.c index 25e382f..879901f 100644 --- a/plugins/alsa/alsa-plug-vol.c +++ b/plugins/alsa/alsa-plug-vol.c @@ -91,7 +91,7 @@ PUBLIC AlsaPcmCtlT *AlsaCreateSoftvol(SoftMixerT *mixer, AlsaStreamAudioT *strea return pcmVol; OnErrorExit: - AlsaDumpCtlConfig (mixer, "plug-config", pcmConfig, 1); + //AlsaDumpCtlConfig (mixer, "plug-config", pcmConfig, 1); AlsaDumpCtlConfig(mixer, "plug-softvol", streamConfig, 1); AFB_ApiNotice(mixer->api, "AlsaCreateSoftvol:%s(stream) OnErrorExit\n", stream->uid); return NULL; diff --git a/plugins/alsa/alsa-softmixer.h b/plugins/alsa/alsa-softmixer.h index 8572996..77d9982 100644 --- a/plugins/alsa/alsa-softmixer.h +++ b/plugins/alsa/alsa-softmixer.h @@ -59,6 +59,11 @@ #define ALSA_PLUG_PROTO(plugin) \ int _snd_pcm_ ## plugin ## _open(snd_pcm_t **pcmp, const char *name, snd_config_t *root, snd_config_t *conf, snd_pcm_stream_t stream, int mode) +// auto switch from Log to API request depending on request presence. +#define AFB_IfReqFailF(mixer, request, status, format, ...) \ + if (request) AFB_ReqFailF(request, status, format, __VA_ARGS__); \ + else AFB_ApiError(mixer->api, format, __VA_ARGS__); + #ifndef PUBLIC #define PUBLIC #endif @@ -184,6 +189,7 @@ typedef struct { typedef struct { const char *uid; + const char *verb; const char *info; const char *sink; const char *source; @@ -274,8 +280,7 @@ PUBLIC AlsaPcmHwInfoT *ApiSinkGetParamsByZone(SoftMixerT *mixer, const char *tar PUBLIC int ApiSinkAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, json_object * argsJ); PUBLIC AlsaSndCtlT *ApiSourceFindSubdev(SoftMixerT *mixer, const char *target); PUBLIC int ApiSourceAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, json_object * argsJ); -PUBLIC int CreateOneStream(SoftMixerT *mixer, AlsaStreamAudioT *stream); -PUBLIC int ApiStreamAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, json_object * argsJ); +PUBLIC int ApiStreamAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, const char *prefix, json_object * argsJ); PUBLIC AlsaSndZoneT *ApiZoneGetByUid(SoftMixerT *mixer, const char *target); PUBLIC int ApiZoneAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, json_object * argsJ); diff --git a/plugins/alsa/alsa-utils-bypath.c b/plugins/alsa/alsa-utils-bypath.c index f950129..c5c80ce 100644 --- a/plugins/alsa/alsa-utils-bypath.c +++ b/plugins/alsa/alsa-utils-bypath.c @@ -78,6 +78,7 @@ PUBLIC AlsaPcmCtlT *AlsaByPathOpenPcm(SoftMixerT *mixer, AlsaDevInfoT *pcmDev, s pcmCtl->cid.name=NULL; pcmCtl->cid.longname=NULL; + //error = snd_pcm_open(&pcmCtl->handle, pcmCtl->cid.cardid, direction, SND_PCM_NONBLOCK); error = snd_pcm_open(&pcmCtl->handle, pcmCtl->cid.cardid, direction, SND_PCM_NONBLOCK); if (error) { AFB_ApiError(mixer->api, "AlsaByPathOpenPcm: fail openpcm cardid=%s error=%s", pcmCtl->cid.cardid, snd_strerror(error)); -- cgit 1.2.3-korg