aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/alsa/alsa-api-sink.c29
-rw-r--r--plugins/alsa/alsa-api-streams.c38
-rw-r--r--plugins/alsa/alsa-plug-vol.c15
-rw-r--r--plugins/alsa/alsa-softmixer.h3
4 files changed, 56 insertions, 29 deletions
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);