diff options
author | John Stultz <john.stultz@linaro.org> | 2021-09-02 03:26:56 +0000 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2021-09-14 03:52:01 +0000 |
commit | 57a023620c924beeb26590992116d76de2e7a51b (patch) | |
tree | 95c92983ad14d794a6a63642ae966c1995e1f26d /audio | |
parent | e4ca84a8555cda76d8fd4f485522ed510a7a088b (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.c | 31 | ||||
-rw-r--r-- | audio/audio_hw.h | 2 |
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" |