From 844e09b6d3c0036e27c4baacf6536f48f975597e Mon Sep 17 00:00:00 2001 From: Jonathan Aillet Date: Tue, 5 Nov 2019 11:39:36 +0100 Subject: WIP: Add first valid PCM to get card info verb Change-Id: I8e95521bc65b5732ce53e98fecdf76497da74199 Signed-off-by: Jonathan Aillet --- alsa-binding/Alsa-ApiHat.h | 1 + alsa-binding/Alsa-RegEvt.c | 2 +- alsa-binding/Alsa-SetGet.c | 131 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 3 deletions(-) diff --git a/alsa-binding/Alsa-ApiHat.h b/alsa-binding/Alsa-ApiHat.h index 35f96bb..d953a1a 100644 --- a/alsa-binding/Alsa-ApiHat.h +++ b/alsa-binding/Alsa-ApiHat.h @@ -103,6 +103,7 @@ PUBLIC queryModeE alsaGetModeFromQuery(json_object *queryJ); // AlseCoreSetGet exports PUBLIC int getCardNbFromCardPath(char *cardPath); PUBLIC json_object *getCardInfo(int card); +PUBLIC json_object *getCardInfoWithFirstPcm(int card); PUBLIC void alsaGetInfo (afb_req_t request); PUBLIC int alsaGetPcmProcStatusFd(unsigned int card, unsigned int device, unsigned int subdevice, snd_pcm_stream_t pcmStream); PUBLIC int alsaIsPcmAvailableUsingPcmProcFd(int fd); diff --git a/alsa-binding/Alsa-RegEvt.c b/alsa-binding/Alsa-RegEvt.c index 389fc1e..cab4a4a 100644 --- a/alsa-binding/Alsa-RegEvt.c +++ b/alsa-binding/Alsa-RegEvt.c @@ -309,7 +309,7 @@ STATIC void updateSelectedAlsaCardsAvailabilityAndFireEvents(sndCardsT *sndCards sndCards->sndHandles[idx].available = 1; if(sndCards->cardMonitoring && - ! wrap_json_pack(&generatedEventJ, "{s:o}", "cardAdded", getCardInfo(idx))) + ! wrap_json_pack(&generatedEventJ, "{s:o}", "cardAdded", getCardInfoWithFirstPcm(idx))) subscriberCount = afb_event_push(sndCards->cardMonitoring->afbevt, generatedEventJ); } else if(! available && sndCards->sndHandles[idx].available) { diff --git a/alsa-binding/Alsa-SetGet.c b/alsa-binding/Alsa-SetGet.c index af96b86..54659f8 100644 --- a/alsa-binding/Alsa-SetGet.c +++ b/alsa-binding/Alsa-SetGet.c @@ -633,6 +633,103 @@ STATIC int checkIfPlaybackDeviceIsCorrespondingToQuery(queryCardInfo *queryInfo, return 1; } +STATIC int getFirstValidDevice(int card, snd_pcm_stream_t stream) +{ + int ret, device = NO_DEVICE_SELECTED; + + char *cardName = NULL; + + snd_ctl_t *cardHandle; + snd_pcm_info_t *pcmHandle; + + if(card <= NO_CARD_SELECTED || card > MAX_SND_CARD) { + AFB_ERROR("Invalid card value %i", card); + return -1; + } + + ret = asprintf(&cardName, "hw:%i", card); + if(ret < 4 || ! cardName) { + AFB_ERROR("Error when tried to allocate card name string"); + return -2; + } + + ret = snd_ctl_open(&cardHandle, cardName, 0); + if(ret) { + AFB_ERROR("Error when tried to open card %i info", card); + return -3; + } + + free(cardName); + + snd_pcm_info_alloca(&pcmHandle); + + while(! ret) { + ret = jumpToCardNextDevice(card, &device); + if(ret) { + AFB_ERROR("Error %i happened when tried to jump to next device", ret); + snd_ctl_close(cardHandle); + return -4; + } + + if(device < 0) { + AFB_ERROR("No valid device for card %i", card); + snd_ctl_close(cardHandle); + return -5; + } + + snd_pcm_info_set_device(pcmHandle, device); + snd_pcm_info_set_subdevice(pcmHandle, 0); + snd_pcm_info_set_stream(pcmHandle, stream); + + ret = snd_ctl_pcm_info(cardHandle, pcmHandle); + if(ret) + AFB_DEBUG("Device %i exist but not valid", device); + else + break; + } + + snd_ctl_close(cardHandle); + + return device; +} + +STATIC json_object * addFirstPcmToJson(int card, int device, snd_pcm_stream_t stream, json_object *toCompleteJ) +{ + int ret; + + char *pcmName = NULL; + + if(card <= NO_CARD_SELECTED || card > MAX_SND_CARD) { + AFB_ERROR("Invalid card value %i", card); + return NULL; + } + + if(device == NO_DEVICE_SELECTED) + device = getFirstValidDevice(card, stream); + + if(device <= NO_DEVICE_SELECTED || device > MAX_CARD_DEVICES) { + AFB_ERROR("Invalid device value %i", device); + return NULL; + } + + if(! toCompleteJ) { + AFB_ERROR("Invalid json object to complete"); + return NULL; + } + + ret = asprintf(&pcmName, "hw:%i,%i,0", card, device); + if(ret < 8 || ! pcmName) { + AFB_ERROR("An error happened when tried to allocate/generate pcm string"); + return NULL; + } + + json_object_object_add(toCompleteJ, + (stream == SND_PCM_STREAM_PLAYBACK) ? "firstPlaybackPcm" : "firstCapturePcm", + json_object_new_string(pcmName)); + + return toCompleteJ; +} + PUBLIC json_object *getCardInfo(int card) { int err; @@ -680,6 +777,34 @@ PUBLIC json_object *getCardInfo(int card) return cardInfoJ; } +PUBLIC json_object *getCardInfoWithFirstPcm(int card) +{ + json_object *cardInfoJ; + + if(card < 0 || card >= MAX_SND_CARD) { + AFB_ERROR("ALSA card number %i is not valid", card); + return NULL; + } + + cardInfoJ = getCardInfo(card); + if(! cardInfoJ) { + AFB_ERROR("Did not succeed to get card info json"); + return NULL; + } + + if(! addFirstPcmToJson(card, NO_DEVICE_SELECTED, SND_PCM_STREAM_PLAYBACK, cardInfoJ)) { + AFB_ERROR("Did not succeed to add playback first pcm"); + return NULL; + } + + if(! addFirstPcmToJson(card, NO_DEVICE_SELECTED, SND_PCM_STREAM_CAPTURE, cardInfoJ)) { + AFB_ERROR("Did not succeed to add capture first pcm"); + return NULL; + } + + return cardInfoJ; +} + STATIC json_object *getDeviceInfo(int card, int device) { int err; @@ -838,8 +963,10 @@ STATIC json_object *alsaCardProbe(queryCardInfo *queryInfo) { return NULL; } - if(isDeviceCorresponding) + if(isDeviceCorresponding) { correspondingDeviceJ = getDeviceInfo(correspondingCard, playbackDeviceToProbe); + correspondingDeviceJ = addFirstPcmToJson(correspondingCard, playbackDeviceToProbe, SND_PCM_STREAM_PLAYBACK, correspondingDeviceJ); + } if(queryInfo->playbackDeviceNb != NO_DEVICE_SELECTED) { playbackDeviceToProbe = NO_DEVICE_SELECTED; @@ -902,7 +1029,7 @@ PUBLIC void alsaGetInfo(afb_req_t request) { toReturnJ = json_object_new_array(); while(card >= 0) { - currentCardInfoJ = getCardInfo(card); + currentCardInfoJ = getCardInfoWithFirstPcm(card); if(currentCardInfoJ) json_object_array_add(toReturnJ, currentCardInfoJ); -- cgit 1.2.3-korg