From 9c88fd2aaf454b4ab5d4cfcb5e510196da3b74b4 Mon Sep 17 00:00:00 2001 From: fulup Date: Sun, 10 Jun 2018 22:44:07 +0200 Subject: Autorize direct zone to point on sndcard --- plugins/alsa/alsa-api-sink.c | 29 +++++++++++++++++++++-------- plugins/alsa/alsa-api-streams.c | 38 +++++++++++++++++++++++++++++++------- plugins/alsa/alsa-plug-vol.c | 15 ++------------- plugins/alsa/alsa-softmixer.h | 3 ++- 4 files changed, 56 insertions(+), 29 deletions(-) (limited to 'plugins/alsa') diff --git a/plugins/alsa/alsa-api-sink.c b/plugins/alsa/alsa-api-sink.c index 02322de..e38621a 100644 --- a/plugins/alsa/alsa-api-sink.c +++ b/plugins/alsa/alsa-api-sink.c @@ -22,23 +22,36 @@ PUBLIC AlsaPcmHwInfoT *ApiSinkGetParamsByZone(SoftMixerT *mixer, const char *target) { + // try to attach a zone as stream playback sink AlsaSndZoneT *zone = ApiZoneGetByUid(mixer, target); - if (!zone || !zone->sinks) return NULL; + if (zone && zone->sinks) { - // use 1st channel to find attached sound card. - const char *channel = zone->sinks[0]->uid; + // use 1st channel to find attached sound card. + const char *channel = zone->sinks[0]->uid; - // search for channel uid into mixer sinks - for (int idx = 0; mixer->sinks[idx]; idx++) { - for (int jdx = 0; jdx < mixer->sinks[idx]->ccount; jdx++) { - if (mixer->sinks[idx]->channels[jdx]->uid && !strcasecmp(channel, mixer->sinks[idx]->channels[jdx]->uid)) { - return mixer->sinks[idx]->sndcard->params; + // search for channel uid into mixer sinks and derive sound card + for (int idx = 0; mixer->sinks[idx]; idx++) { + for (int jdx = 0; jdx < mixer->sinks[idx]->ccount; jdx++) { + if (mixer->sinks[idx]->channels[jdx]->uid && !strcasecmp(channel, mixer->sinks[idx]->channels[jdx]->uid)) { + return mixer->sinks[idx]->sndcard->params; + } } } } return NULL; } +PUBLIC AlsaSndPcmT *ApiSinkGetByUid(SoftMixerT *mixer, const char *target) { + // if no attached zone found, then try direct sink attachment + for (int idx = 0; mixer->sinks[idx]; idx++) { + if (mixer->sinks[idx]->uid && !strcasecmp(mixer->sinks[idx]->uid, target)) { + return mixer->sinks[idx]; + } + } + + return NULL; +} + PUBLIC int ApiSinkAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, json_object * argsJ) { int index; diff --git a/plugins/alsa/alsa-api-streams.c b/plugins/alsa/alsa-api-streams.c index 0f9786a..c8702ed 100644 --- a/plugins/alsa/alsa-api-streams.c +++ b/plugins/alsa/alsa-api-streams.c @@ -188,7 +188,9 @@ STATIC int CreateOneStream(SoftMixerT *mixer, const char * uid, AlsaStreamAudioT AlsaSndCtlT *captureCard; AlsaDevInfoT *captureDev = alloca(sizeof (AlsaDevInfoT)); AlsaLoopSubdevT *loopDev; - char * captureName; + AlsaSndZoneT *zone; + char *volSlaveId; + char *captureName; loopDev = ApiLoopFindSubdev(mixer, stream->uid, stream->source, &loop); if (loopDev) { @@ -225,15 +227,37 @@ STATIC int CreateOneStream(SoftMixerT *mixer, const char * uid, AlsaStreamAudioT if (error) goto OnErrorExit; } - AlsaSndZoneT *zone = ApiZoneGetByUid(mixer, stream->sink); - if (!zone) { - AFB_ApiError(mixer->api, "CreateOneStream: mixer=%s stream=%s fail to find sink zone='%s'", mixer->uid, stream->uid, stream->sink); - goto OnErrorExit; + if (mixer->zones[0]) { + // if zones exist then retrieve zone pcmid and channel count + zone = ApiZoneGetByUid(mixer, stream->sink); + if (!zone) { + AFB_ApiError(mixer->api, "CreateOneStream: mixer=%s stream=%s fail to find sink zone='%s'", mixer->uid, stream->uid, stream->sink); + goto OnErrorExit; + } + + // route PCM should have been create during zones attach phase. + (void) asprintf(&volSlaveId, "route-%s", zone->uid); + + } else { + AlsaSndPcmT *playback = ApiSinkGetByUid(mixer, stream->sink); + if (!playback) { + AFB_ApiError(mixer->api, "CreateOneStream: mixer=%s stream=%s fail to find sink playback='%s'", mixer->uid, stream->uid, stream->sink); + goto OnErrorExit; + } + + // retrieve channel count from route and push it to stream + (void) asprintf(&volSlaveId, "dmix-%s", playback->uid); + + // create a fake zone for rate converter selection + zone=alloca(sizeof(AlsaSndZoneT)); + zone->uid= playback->uid; + zone->params = playback->sndcard->params; + zone->ccount = playback->ccount; } // retrieve channel count from route and push it to stream stream->params->channels = zone->ccount; - + // create mute control and Registry it as pause/resume ctl) char *runName; (void) asprintf(&runName, "pause-%s", stream->uid); @@ -249,7 +273,7 @@ STATIC int CreateOneStream(SoftMixerT *mixer, const char * uid, AlsaStreamAudioT (void) asprintf(&volName, "vol-%s", stream->uid); // create stream and delay pcm opening until vol control is created - streamPcm = AlsaCreateSoftvol(mixer, stream, zone, captureCard, volName, VOL_CONTROL_MAX, 0); + streamPcm = AlsaCreateSoftvol(mixer, stream, volSlaveId, captureCard, volName, VOL_CONTROL_MAX, 0); if (!streamPcm) { AFB_ApiError(mixer->api, "CreateOneStream: mixer=%s stream=%s fail to create stream", mixer->uid, stream->uid); goto OnErrorExit; diff --git a/plugins/alsa/alsa-plug-vol.c b/plugins/alsa/alsa-plug-vol.c index 879901f..968ae73 100644 --- a/plugins/alsa/alsa-plug-vol.c +++ b/plugins/alsa/alsa-plug-vol.c @@ -22,26 +22,15 @@ ALSA_PLUG_PROTO(softvol); // stream uses softvol plugin -PUBLIC AlsaPcmCtlT *AlsaCreateSoftvol(SoftMixerT *mixer, AlsaStreamAudioT *stream, AlsaSndZoneT *zone, AlsaSndCtlT *sndcard, char* ctlName, int max, int open) { +PUBLIC AlsaPcmCtlT *AlsaCreateSoftvol(SoftMixerT *mixer, AlsaStreamAudioT *stream, char* slaveid, AlsaSndCtlT *sndcard, char* ctlName, int max, int open) { snd_config_t *streamConfig, *elemConfig, *slaveConfig, *controlConfig,*pcmConfig; AlsaPcmCtlT *pcmVol= calloc(1,sizeof(AlsaPcmCtlT)); int error = 0; - - // assert static/global softmixer handle get requited info - AlsaSndZoneT **pcmZones = mixer->zones; - if (!pcmZones) { - AFB_ApiError(mixer->api, "AlsaCreateSoftvol:%s(stream) No Zone found [should Registry zones first]", stream->uid); - goto OnErrorExit; - } - + char *cardid; (void) asprintf(&cardid, "softvol-%s", stream->uid); pcmVol->cid.cardid = (const char *) cardid; - char *slaveid; - (void)asprintf(&slaveid, "route-%s", zone->uid); - // Fulup debug (void) asprintf(&slaveid, "dmix-%s", "8CH-USB"); - // refresh global alsalib config and create PCM top config snd_config_update(); error += snd_config_top(&streamConfig); diff --git a/plugins/alsa/alsa-softmixer.h b/plugins/alsa/alsa-softmixer.h index 3a3cf05..f435b3f 100644 --- a/plugins/alsa/alsa-softmixer.h +++ b/plugins/alsa/alsa-softmixer.h @@ -265,7 +265,7 @@ PUBLIC int AlsaPcmCopy(SoftMixerT *mixer, AlsaStreamAudioT *stream, AlsaPcmCtlT // alsa-plug-*.c _snd_pcm_PLUGIN_open_ see macro ALSA_PLUG_PROTO(plugin) PUBLIC int AlsaPcmConf(SoftMixerT *mixer, AlsaPcmCtlT *pcm, AlsaPcmHwInfoT *opts); PUBLIC int AlsaPcmCopy(SoftMixerT *mixer, AlsaStreamAudioT *streamAudio, AlsaPcmCtlT *pcmIn, AlsaPcmCtlT *pcmOut, AlsaPcmHwInfoT * opts); -PUBLIC AlsaPcmCtlT* AlsaCreateSoftvol(SoftMixerT *mixer, AlsaStreamAudioT *stream, AlsaSndZoneT *zone, AlsaSndCtlT *sndcard, char* ctlName, int max, int open); +PUBLIC AlsaPcmCtlT* AlsaCreateSoftvol(SoftMixerT *mixer, AlsaStreamAudioT *stream, char *slaveid, AlsaSndCtlT *sndcard, char* ctlName, int max, int open); PUBLIC AlsaPcmCtlT* AlsaCreateRoute(SoftMixerT *mixer, AlsaSndZoneT *zone, int open); PUBLIC AlsaPcmCtlT* AlsaCreateRate(SoftMixerT *mixer, const char* pcmName, AlsaPcmCtlT *pcmSlave, AlsaPcmHwInfoT *params, int open); PUBLIC AlsaPcmCtlT* AlsaCreateDmix(SoftMixerT *mixer, const char* pcmName, AlsaSndPcmT *pcmSlave, int open); @@ -279,6 +279,7 @@ PUBLIC AlsaVolRampT *ApiRampGetByUid(SoftMixerT *mixer, const char *uid); PUBLIC int ApiRampAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, json_object *argsJ); PUBLIC AlsaPcmHwInfoT *ApiSinkGetParamsByZone(SoftMixerT *mixer, const char *target); PUBLIC int ApiSinkAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, json_object * argsJ); +PUBLIC AlsaSndPcmT *ApiSinkGetByUid(SoftMixerT *mixer, const char *target); PUBLIC AlsaSndCtlT *ApiSourceFindSubdev(SoftMixerT *mixer, const char *target); PUBLIC int ApiSourceAttach(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); -- cgit 1.2.3-korg