summaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2021-09-02 03:26:56 +0000
committerJohn Stultz <john.stultz@linaro.org>2021-09-14 03:52:01 +0000
commit57a023620c924beeb26590992116d76de2e7a51b (patch)
tree95c92983ad14d794a6a63642ae966c1995e1f26d /audio
parente4ca84a8555cda76d8fd4f485522ed510a7a088b (diff)
db845c: audio_hal: Select the output/input card a bit more dynamically
This patch changes the output/input card selection from being hard-coded to chosen at runtime. The selection process is a bit "simple" in that it will try each card in order and pick the first available. Eventually, we probably need a fancier HAL to handle more dynamic audio configs (without colliding with the in-framework usb headset handling, for instance). It would be nicer to actually check the /sys/class/sound/card*/id values and be able to have a preferred name that is selected, but I figured this was a start. With this patch, adding a usb web cam (which reorders the card numbers) no longer breaks HDMI audio output. Signed-off-by: John Stultz <john.stultz@linaro.org> Change-Id: I9504a1c50da09dfed116c32247fc79255ae5646e
Diffstat (limited to 'audio')
-rw-r--r--audio/audio_hw.c31
-rw-r--r--audio/audio_hw.h2
2 files changed, 25 insertions, 8 deletions
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 5a0953c..c0cd55d 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -72,6 +72,20 @@ static int get_audio_output_port(audio_devices_t devices) {
return PORT_HDMI;
}
+static int get_audio_card(int direction, int port) {
+ struct pcm_params* params = NULL;
+ int card = 0;
+
+ while (!params && card < 8) {
+ /* Find the first input/output device that works */
+ params = pcm_params_get(card, port, direction);
+ card++;
+ }
+ pcm_params_free(params);
+
+ return card - 1;
+}
+
static void timestamp_adjust(struct timespec* ts, ssize_t frames, uint32_t sampling_rate) {
/* This function assumes the adjustment (in nsec) is less than the max value of long,
* which for 32-bit long this is 2^31 * 1e-9 seconds, slightly over 2 seconds.
@@ -173,9 +187,10 @@ static int start_output_stream(struct alsa_stream_out *out)
out->unavailable = true;
unsigned int pcm_retry_count = PCM_OPEN_RETRIES;
int out_port = get_audio_output_port(out->devices);
+ int out_card = get_audio_card(PCM_OUT, out_port);
while (1) {
- out->pcm = pcm_open(CARD_OUT, out_port, PCM_OUT | PCM_MONOTONIC, &out->config);
+ out->pcm = pcm_open(out_card, out_port, PCM_OUT | PCM_MONOTONIC, &out->config);
if ((out->pcm != NULL) && pcm_is_ready(out->pcm)) {
break;
} else {
@@ -433,9 +448,10 @@ static int start_input_stream(struct alsa_stream_in *in)
struct alsa_audio_device *adev = in->dev;
in->unavailable = true;
unsigned int pcm_retry_count = PCM_OPEN_RETRIES;
+ int in_card = get_audio_card(PCM_IN, PORT_BUILTIN_MIC);
while (1) {
- in->pcm = pcm_open(CARD_IN, PORT_BUILTIN_MIC, PCM_IN | PCM_MONOTONIC, &in->config);
+ in->pcm = pcm_open(in_card, PORT_BUILTIN_MIC, PCM_IN | PCM_MONOTONIC, &in->config);
if ((in->pcm != NULL) && pcm_is_ready(in->pcm)) {
break;
} else {
@@ -795,7 +811,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
int out_port = get_audio_output_port(devices);
- struct pcm_params* params = pcm_params_get(CARD_OUT, out_port, PCM_OUT);
+ int out_card = get_audio_card(PCM_OUT, out_port);
+ struct pcm_params* params = pcm_params_get(out_card, out_port, PCM_OUT);
if (!params) {
return -ENOSYS;
}
@@ -991,7 +1008,8 @@ static int adev_open_input_stream(struct audio_hw_device* dev, audio_io_handle_t
struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
- struct pcm_params* params = pcm_params_get(CARD_IN, PORT_BUILTIN_MIC, PCM_IN);
+ int in_card = get_audio_card(PCM_IN, PORT_BUILTIN_MIC);
+ struct pcm_params* params = pcm_params_get(in_card, PORT_BUILTIN_MIC, PCM_IN);
if (!params) {
return -ENOSYS;
}
@@ -1139,13 +1157,14 @@ static int adev_open(const hw_module_t* module, const char* name,
*device = &adev->hw_device.common;
- adev->mixer = mixer_open(CARD_OUT);
+ int out_card = get_audio_card(PCM_OUT, 0);
+ adev->mixer = mixer_open(out_card);
if (!adev->mixer) {
ALOGE("Unable to open the mixer, aborting.");
goto error_1;
}
- adev->audio_route = audio_route_init(CARD_OUT, MIXER_XML_PATH);
+ adev->audio_route = audio_route_init(out_card, MIXER_XML_PATH);
if (!adev->audio_route) {
ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
goto error_2;
diff --git a/audio/audio_hw.h b/audio/audio_hw.h
index 3e8e27c..2e45e02 100644
--- a/audio/audio_hw.h
+++ b/audio/audio_hw.h
@@ -22,10 +22,8 @@
#include "fir_filter.h"
-#define CARD_OUT 0
#define PORT_HDMI 0
#define PORT_INTERNAL_SPEAKER 1
-#define CARD_IN 0
#define PORT_BUILTIN_MIC 3
#define MIXER_XML_PATH "/vendor/etc/mixer_paths.xml"