aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/alsa/alsa-utils-bypath.c
diff options
context:
space:
mode:
authorFulup Ar Foll <fulup@iot.bzh>2018-05-11 01:18:43 +0200
committerFulup Ar Foll <fulup@iot.bzh>2018-05-11 01:18:43 +0200
commit1dd1509a02fee564ff87f80c2f29055d7aad889c (patch)
tree031a0a9e912fa3f9ab94a268ad6058d774e6f8dd /plugins/alsa/alsa-utils-bypath.c
parente904b7da51297b0417df31ab79568c3f1243fb64 (diff)
Initial version with softvol control and DMIX
Diffstat (limited to 'plugins/alsa/alsa-utils-bypath.c')
-rw-r--r--plugins/alsa/alsa-utils-bypath.c75
1 files changed, 45 insertions, 30 deletions
diff --git a/plugins/alsa/alsa-utils-bypath.c b/plugins/alsa/alsa-utils-bypath.c
index e4a8833..8fba1f0 100644
--- a/plugins/alsa/alsa-utils-bypath.c
+++ b/plugins/alsa/alsa-utils-bypath.c
@@ -34,78 +34,93 @@
// Clone of AlsaLib snd_card_load2 static function
-PUBLIC snd_ctl_card_info_t *AlsaByPathInfo (CtlSourceT *source, const char *devpath) {
+
+PUBLIC snd_ctl_card_info_t *AlsaByPathInfo(CtlSourceT *source, const char *devpath) {
int open_dev;
snd_ctl_card_info_t *cardInfo = malloc(snd_ctl_card_info_sizeof());
if (!devpath) goto OnErrorExit;
-
+
open_dev = open(devpath, O_RDONLY);
if (open_dev < 0) goto OnErrorExit;
-
+
int rc = ioctl(open_dev, SNDRV_CTL_IOCTL_CARD_INFO(snd_ctl_card_info_sizeof()), cardInfo);
if (rc < 0) {
close(open_dev);
goto OnErrorExit;
}
-
+
close(open_dev);
return cardInfo;
-
+
OnErrorExit:
- AFB_ApiError(source->api,"AlsaCardInfoByPath: fail to find sndcard by path= %s", devpath);
+ AFB_ApiError(source->api, "AlsaCardInfoByPath: fail to find sndcard by path= %s", devpath);
return NULL;
}
-PUBLIC snd_pcm_t* AlsaByPathOpenPcm(CtlSourceT *source, AlsaDevByPathT *dev, snd_pcm_stream_t direction) {
- char pcmName[32];
- int error;
- snd_pcm_t *pcmHandle;
+PUBLIC int AlsaByPathDevid(CtlSourceT *source, AlsaPcmInfoT *dev) {
// get card info from /dev/snd/xxx if not use hw:x,x,x
- snd_ctl_card_info_t *cardInfo=NULL;
+ snd_ctl_card_info_t *cardInfo = NULL;
if (dev->devpath) cardInfo = AlsaByPathInfo(source, dev->devpath);
- else if (dev->devid) cardInfo = AlsaCtlGetInfo (source, dev->devid);
+ else if (dev->devid) cardInfo = AlsaCtlGetInfo(source, dev->devid);
if (!cardInfo) {
- AFB_ApiError(source->api, "AlsaByPathOpenPcm: fail to find sndcard by path=%s id=%s", dev->devpath, dev->devid);
+ AFB_ApiWarning(source->api, "AlsaByPathOpenPcm: fail to find sndcard by path=%s id=%s", dev->devpath, dev->devid);
goto OnErrorExit;
}
// extract useful info from cardInfo handle
- int cardIdx = snd_ctl_card_info_get_card(cardInfo);
- const char *cardName = snd_ctl_card_info_get_name(cardInfo);
+ dev->cardid = snd_ctl_card_info_get_card(cardInfo);
+
+ // if not provided build a valid PCM devid
+ if (!dev->devid) {
+ #define DEVID_MAX_LEN 32
+ dev->devid=malloc(DEVID_MAX_LEN);
+ if (dev->subdev) snprintf((char*)dev->devid, DEVID_MAX_LEN, "hw:%i,%i,%i", dev->cardid, dev->device, dev->subdev);
+ else if (dev->device) snprintf((char*)dev->devid, DEVID_MAX_LEN, "hw:%i,%i", dev->cardid, dev->device);
+ else snprintf((char*)dev->devid, DEVID_MAX_LEN, "hw:%i", dev->cardid);
+ }
+ return 0;
- // build a valid name and open sndcard
- snprintf(pcmName, sizeof (pcmName), "hw:%i,%i,%i", cardIdx, dev->device, dev->subdev);
- error = snd_pcm_open(&pcmHandle, pcmName, direction, SND_PCM_NONBLOCK);
+OnErrorExit:
+ return -1;
+}
+
+PUBLIC AlsaPcmInfoT* AlsaByPathOpenPcm(CtlSourceT *source, AlsaPcmInfoT *dev, snd_pcm_stream_t direction) {
+ int error;
+
+ error = AlsaByPathDevid(source, dev);
+ if (error) goto OnErrorExit;
+
+ error = snd_pcm_open(&dev->handle, dev->devid, direction, SND_PCM_NONBLOCK);
if (error) {
- AFB_ApiError(source->api, "AlsaByPathOpenPcm: fail openpcm (hw:%d -> %s name=%i subdev=%d): %s"
- , cardIdx, cardName, dev->device, dev->subdev, snd_strerror(error));
+ AFB_ApiError(source->api, "AlsaByPathOpenPcm: fail openpcm (devid=%s idxdev=%i subdev=%d): %s"
+ , dev->devid, dev->device, dev->subdev, snd_strerror(error));
goto OnErrorExit;
}
-
- return (pcmHandle);
+
+ return (dev);
OnErrorExit:
return NULL;
}
-PUBLIC snd_ctl_t *AlsaByPathOpenCtl (CtlSourceT *source, AlsaDevByPathT *dev) {
+PUBLIC snd_ctl_t *AlsaByPathOpenCtl(CtlSourceT *source, AlsaPcmInfoT *dev) {
int err;
char devid[32];
snd_ctl_t *handle;
-
+
// get card info from /dev/snd/xxx if not use hw:x,x,x
- snd_ctl_card_info_t *cardInfo=NULL;
+ snd_ctl_card_info_t *cardInfo = NULL;
if (dev->devpath) cardInfo = AlsaByPathInfo(source, dev->devpath);
- else if (dev->devid) cardInfo = AlsaCtlGetInfo (source, dev->devid);
+ else if (dev->devid) cardInfo = AlsaCtlGetInfo(source, dev->devid);
if (!cardInfo) {
AFB_ApiError(source->api, "AlsaByPathOpenCtl: fail to find sndcard by path=%s id=%s", dev->devpath, dev->devid);
goto OnErrorExit;
}
-
+
// extract useful info from cardInfo handle
int cardIndex = snd_ctl_card_info_get_card(cardInfo);
const char *cardId = snd_ctl_card_info_get_id(cardInfo);
@@ -114,14 +129,14 @@ PUBLIC snd_ctl_t *AlsaByPathOpenCtl (CtlSourceT *source, AlsaDevByPathT *dev) {
// build a valid name and open sndcard
snprintf(devid, sizeof (devid), "hw:%i", cardIndex);
if ((err = snd_ctl_open(&handle, devid, 0)) < 0) {
- AFB_ApiError(source->api,"control open (hw:%d -> %s): %s", cardIndex, cardName, snd_strerror(err));
+ AFB_ApiError(source->api, "control open (hw:%d -> %s): %s", cardIndex, cardName, snd_strerror(err));
goto OnErrorExit;
}
AFB_ApiNotice(source->api, "AlsaCtlOpenByPath: sndcard hw:%d id=%s name=%s", cardIndex, cardId, cardName);
- free (cardInfo);
+ free(cardInfo);
return handle;
-
+
OnErrorExit:
return NULL;
}