/* * Copyright (C) 2018 "IoT.bzh" * Author Fulup Ar Foll * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #define _GNU_SOURCE // needed for vasprintf #include "alsa-softmixer.h" #include // Set stream volume control in % #define VOL_CONTROL_MAX 100 #define VOL_CONTROL_MIN 0 #define VOL_CONTROL_STEP 1 PUBLIC AlsaVolRampT *ApiRampGetByUid(SoftMixerT *mixer, const char *uid) { AlsaVolRampT *ramp = NULL; cds_list_for_each_entry(ramp, &mixer->ramps.list, list) { if (!strcasecmp(ramp->uid, uid)) return ramp; } return NULL; } STATIC AlsaVolRampT *AttachOneRamp(SoftMixerT *mixer, const char *uid, json_object *rampJ) { const char * rampUid; AlsaVolRampT *ramp = calloc(1, sizeof (AlsaVolRampT)); if (ramp == NULL) { SOFTMIXER_NOMEM(mixer->api); goto fail; } CDS_INIT_LIST_HEAD(&ramp->list); int error = wrap_json_unpack(rampJ, "{ss,si,si,si !}" , "uid", &rampUid , "delay", &ramp->delay , "up", &ramp->stepUp , "down", &ramp->stepDown ); if (error) { AFB_ApiError(mixer->api, "%s mixer=%s hal=%s error=%s json=%s", __func__, mixer->uid, uid, wrap_json_get_error_string(error), json_object_get_string(rampJ)); goto fail_ramp; } ramp->delay = ramp->delay * 1000; // move from ms to us ramp->uid = strdup(rampUid); if (ramp->uid == NULL) { SOFTMIXER_NOMEM(mixer->api); goto fail_ramp; } return ramp; fail_ramp: free(ramp); fail: return NULL; } static void rampDestroy(SoftMixerT * mixer, void * arg) { AlsaVolRampT * ramp = (AlsaVolRampT*) arg; AFB_ApiDebug(mixer->api, "%s... %s not implemented", __func__, ramp->uid); } static AlsaVolRampT * rampCreate(SoftMixerT * mixer, const char * uid, json_object *argsJ) { AlsaVolRampT * newRamp = AttachOneRamp(mixer, uid, argsJ); if (!newRamp) { goto fail; } mixer->nbRamps++; cds_list_add_tail(&newRamp->list, &mixer->ramps.list); AlsaMixerTransactionObjectAdd(mixer->transaction, newRamp, rampDestroy); fail: return newRamp; } PUBLIC int ApiRampAttach(SoftMixerT *mixer, AFB_ReqT request, const char * uid, json_object *argsJ) { if (mixer->nbRamps >= mixer->max.ramps) { AFB_ReqFailF(request, "too-small", "mixer=%s hal=%s max ramp=%d", mixer->uid, uid, mixer->max.ramps); goto fail; } AlsaVolRampT * newRamp = NULL; switch (json_object_get_type(argsJ)) { long count; case json_type_object: newRamp = rampCreate(mixer, uid, argsJ); if (!newRamp) { AFB_ReqFailF(request, "bad-ramp", "mixer=%s hal=%s invalid ramp= %s", mixer->uid, uid, json_object_get_string(argsJ)); goto fail; } break; case json_type_array: count = json_object_array_length(argsJ); if (count > (mixer->max.ramps - mixer->nbRamps)) { AFB_ReqFailF(request, "too-small", "mixer=%s hal=%s max ramp=%d", mixer->uid, uid, mixer->max.ramps); goto fail; } for (int idx = 0; idx < count; idx++) { json_object *streamAudioJ = json_object_array_get_idx(argsJ, idx); newRamp = rampCreate(mixer, uid, streamAudioJ); if (!newRamp) { AFB_ReqFailF(request, "bad-ramp", "mixer=%s hal=%s invalid ramp= %s", mixer->uid, uid, json_object_get_string(argsJ)); goto fail; } } break; default: AFB_ReqFailF(request, "invalid-syntax", "mixer=%s hal=%s ramps invalid argsJ= %s", mixer->uid, uid, json_object_get_string(argsJ)); goto fail; } return 0; fail: return -1; }