diff options
author | Oscar Azucena <oscarazu@google.com> | 2019-06-21 16:49:49 -0700 |
---|---|---|
committer | Oscar Azucena <oscarazu@google.com> | 2019-09-10 14:15:08 -0700 |
commit | 57fb25abfc1b712574c7c1294925b75cc877f252 (patch) | |
tree | 3ec5df92a71b47238a152f1d2a4a4844bd9dd75f /emulator | |
parent | 4fded06838df8a9519618ae91695c347d79f8eec (diff) | |
download | device_generic_car-57fb25abfc1b712574c7c1294925b75cc877f252.tar.gz device_generic_car-57fb25abfc1b712574c7c1294925b75cc877f252.tar.bz2 device_generic_car-57fb25abfc1b712574c7c1294925b75cc877f252.zip |
Added logic to switch zones at right speaker
Added aae.playZoneId to allow different zones to play at right speaker
when using the car emulator.
Bug: 134524865
Test: Ran kitchen sink emulator
Change-Id: Ie05718feff62e84d7bd3e40f250e5de0a7bf585c
Diffstat (limited to 'emulator')
5 files changed, 189 insertions, 47 deletions
diff --git a/emulator/audio/audio_policy_configuration.xml b/emulator/audio/audio_policy_configuration.xml index 9b81599..0499a8a 100644 --- a/emulator/audio/audio_policy_configuration.xml +++ b/emulator/audio/audio_policy_configuration.xml @@ -59,7 +59,10 @@ <item>bus5_alarm_out</item> <item>bus6_notification_out</item> <item>bus7_system_sound_out</item> - <item>bus100_rear_seat</item> + <!-- names with _rear_seat_# are used for defined an emulator rear seat audio zone + where each number # is the zone id number --> + <item>bus100_left_rear_seat_1</item> + <item>bus200_right_rear_seat_2</item> <item>Built-In Mic</item> <item>Built-In Back Mic</item> <item>Echo-Reference Mic</item> @@ -115,12 +118,18 @@ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> - <mixPort name="mixport_bus100_rear_seat" role="source" + <mixPort name="mixport_bus100_left_rear_seat_1" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> + <mixPort name="mixport_bus200_right_rear_seat_2" role="source" + flags="AUDIO_OUTPUT_FLAG_PRIMARY"> + <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" + samplingRates="48000" + channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> + </mixPort> <mixPort name="primary input" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" @@ -205,8 +214,8 @@ minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/> </gains> </devicePort> - <devicePort tagName="bus100_rear_seat" role="sink" type="AUDIO_DEVICE_OUT_BUS" - address="bus100_rear_seat"> + <devicePort tagName="bus100_left_rear_seat_1" role="sink" type="AUDIO_DEVICE_OUT_BUS" + address="bus100_left_rear_seat_1"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> <gains> @@ -214,6 +223,15 @@ minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/> </gains> </devicePort> + <devicePort tagName="bus200_right_rear_seat_2" role="sink" type="AUDIO_DEVICE_OUT_BUS" + address="bus200_right_rear_seat_2"> + <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" + samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> + <gains> + <gain name="" mode="AUDIO_GAIN_MODE_JOINT" + minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/> + </gains> + </devicePort> <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" @@ -249,7 +267,8 @@ <route type="mix" sink="bus5_alarm_out" sources="mixport_bus5_alarm_out"/> <route type="mix" sink="bus6_notification_out" sources="mixport_bus6_notification_out"/> <route type="mix" sink="bus7_system_sound_out" sources="mixport_bus7_system_sound_out"/> - <route type="mix" sink="bus100_rear_seat" sources="mixport_bus100_rear_seat"/> + <route type="mix" sink="bus100_left_rear_seat_1" sources="mixport_bus100_left_rear_seat_1"/> + <route type="mix" sink="bus200_right_rear_seat_2" sources="mixport_bus200_right_rear_seat_2"/> <route type="mix" sink="primary input" sources="Built-In Mic,Built-In Back Mic,Echo-Reference Mic"/> <route type="mix" sink="mixport_tuner0" sources="FM Tuner"/> </routes> diff --git a/emulator/audio/car_audio_configuration.xml b/emulator/audio/car_audio_configuration.xml index 7d3cf01..a819e06 100644 --- a/emulator/audio/car_audio_configuration.xml +++ b/emulator/audio/car_audio_configuration.xml @@ -70,10 +70,10 @@ where port is the physical port of the display (See DisplayAddress.Phyisical) --> </zone> - <zone name="rear seat zone"> + <zone name="rear seat zone 1"> <volumeGroups> <group> - <device address="bus100_rear_seat"> + <device address="bus100_left_rear_seat_1"> <context context="music"/> <context context="navigation"/> <context context="voice_command"/> @@ -89,5 +89,24 @@ <display port="1"/> </displays> </zone> + <zone name="rear seat zone 2"> + <volumeGroups> + <group> + <device address="bus200_right_rear_seat_2"> + <context context="music"/> + <context context="navigation"/> + <context context="voice_command"/> + <context context="call_ring"/> + <context context="call"/> + <context context="alarm"/> + <context context="notification"/> + <context context="system_sound"/> + </device> + </group> + </volumeGroups> + <displays> + <display port="2"/> + </displays> + </zone> </zones> </carAudioConfiguration> diff --git a/emulator/audio/driver/audio_hw.c b/emulator/audio/driver/audio_hw.c index 13cb72b..40ce21e 100644 --- a/emulator/audio/driver/audio_hw.c +++ b/emulator/audio/driver/audio_hw.c @@ -53,7 +53,20 @@ #define _bool_str(x) ((x)?"true":"false") -#define PROP_KEY_SIMULATE_MULTI_ZONE_AUDIO "ro.aae.simulateMultiZoneAudio" +static const char * const PROP_KEY_SIMULATE_MULTI_ZONE_AUDIO = "ro.aae.simulateMultiZoneAudio"; +static const char * const AAE_PARAMETER_KEY_FOR_SELECTED_ZONE = "com.android.car.emulator.selected_zone"; +// Lapse time between checking audio id changes +#define DEFAULT_PLAYZONE_ID_ELAPSE_TIME_MS 300.0f +#define MILLISECONDS_TO_MICROSECONDS 1000.0f +#define SECONDS_TO_MILLISECONDS 1000.0f +#define PRIMARY_ZONE_ID 0 +#define INVALID_ZONE_ID -1 +// Note the primary zone goes to left speaker so route other zone to right speaker +#define DEFAULT_ZONE_TO_LEFT_SPEAKER (PRIMARY_ZONE_ID + 1) + +static const char * const REAR_SEAT_KEYWORD = "_rear_seat_"; + +#define SIZE_OF_PARSE_BUFFER 32 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state); @@ -66,6 +79,22 @@ static struct pcm_config pcm_config_out = { .start_threshold = 0, }; +static int get_int_value(const struct str_parms *str_parms, const char *key, int *return_value) { + char value[SIZE_OF_PARSE_BUFFER]; + int results = str_parms_get_str(str_parms, key, value, SIZE_OF_PARSE_BUFFER); + if (results >= 0) { + char *end = NULL; + errno = 0; + long val = strtol(value, &end, 10); + if ((errno == 0) && (end != NULL) && (*end == '\0') && ((int) val == val)) { + *return_value = val; + } else { + results = -EINVAL; + } + } + return results; +} + static struct pcm_config pcm_config_in = { .channels = 2, .rate = 0, @@ -76,9 +105,26 @@ static struct pcm_config pcm_config_in = { .stop_threshold = INT_MAX, }; +float time_difference_msec(struct timeval t0, struct timeval t1) { + return (t1.tv_sec - t0.tv_sec) * SECONDS_TO_MILLISECONDS + + (t1.tv_usec - t0.tv_usec) / MILLISECONDS_TO_MICROSECONDS; +} + static pthread_mutex_t adev_init_lock = PTHREAD_MUTEX_INITIALIZER; static unsigned int audio_device_ref_count = 0; +static bool is_zone_selected_to_play(struct audio_hw_device *dev, int zone_id) { + // play if current zone is enable or zone equal to primary zone + bool is_selected_zone = true; + if (zone_id != PRIMARY_ZONE_ID) { + struct generic_audio_device *adev = (struct generic_audio_device *)dev; + pthread_mutex_lock(&adev->lock); + is_selected_zone = adev->last_zone_selected_to_play == zone_id; + pthread_mutex_unlock(&adev->lock); + } + return is_selected_zone; +} + static uint32_t out_get_sample_rate(const struct audio_stream *stream) { struct generic_stream_out *out = (struct generic_stream_out *)stream; return out->req_config.sample_rate; @@ -139,10 +185,7 @@ static int out_dump(const struct audio_stream *stream, int fd) { static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) { struct generic_stream_out *out = (struct generic_stream_out *)stream; struct str_parms *parms; - char value[32]; - int ret; - long val; - char *end; + int ret = 0; pthread_mutex_lock(&out->lock); if (!out->standby) { @@ -150,17 +193,11 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) ret = -ENOSYS; } else { parms = str_parms_create_str(kvpairs); - ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, - value, sizeof(value)); + int val = 0; + ret = get_int_value(parms, AUDIO_PARAMETER_STREAM_ROUTING, &val); if (ret >= 0) { - errno = 0; - val = strtol(value, &end, 10); - if (errno == 0 && (end != NULL) && (*end == '\0') && ((int)val == val)) { - out->device = (int)val; - ret = 0; - } else { - ret = -EINVAL; - } + out->device = (int)val; + ret = 0; } str_parms_destroy(parms); } @@ -201,6 +238,19 @@ static int out_set_volume(struct audio_stream_out *stream, return -ENOSYS; } +static int get_rear_zone_id_from_name(const char *name) { + int zone_id = INVALID_ZONE_ID; + char *rear_start = strstr(name, REAR_SEAT_KEYWORD); + if (rear_start) { + char *end = NULL; + zone_id = strtol(rear_start + strlen(REAR_SEAT_KEYWORD), &end, 10); + if (end == NULL || zone_id < 0) { + return INVALID_ZONE_ID; + } + } + return zone_id; +} + static void *out_write_worker(void *args) { struct generic_stream_out *out = (struct generic_stream_out *)args; struct ext_pcm *ext_pcm = NULL; @@ -209,6 +259,18 @@ static void *out_write_worker(void *args) { int buffer_size; bool restart = false; bool shutdown = false; + int zone_id = PRIMARY_ZONE_ID; + // If it is a rear seat bus address then get zone id + if (strstr(out->bus_address, REAR_SEAT_KEYWORD)) { + zone_id = get_rear_zone_id_from_name(out->bus_address); + if (zone_id == INVALID_ZONE_ID) { + ALOGE("%s Found invalid zone id, defaulting device %s to zone %d", __func__, + out->bus_address, DEFAULT_ZONE_TO_LEFT_SPEAKER); + zone_id = DEFAULT_ZONE_TO_LEFT_SPEAKER; + } + } + ALOGD("Out worker:%s zone id %d", out->bus_address, zone_id); + while (true) { pthread_mutex_lock(&out->lock); while (out->worker_standby || restart) { @@ -265,13 +327,17 @@ static void *out_write_worker(void *args) { } int frames = audio_vbuffer_read(&out->buffer, buffer, buffer_frames); pthread_mutex_unlock(&out->lock); - int write_error = ext_pcm_write(ext_pcm, out->bus_address, + + if (is_zone_selected_to_play(out->dev, zone_id)) { + int write_error = ext_pcm_write(ext_pcm, out->bus_address, buffer, ext_pcm_frames_to_bytes(ext_pcm, frames)); - if (write_error) { - ALOGE("pcm_write failed %s address %s", ext_pcm_get_error(ext_pcm), out->bus_address); - restart = true; - } else { - ALOGV("pcm_write succeed address %s", out->bus_address); + if (write_error) { + ALOGE("pcm_write failed %s address %s", + ext_pcm_get_error(ext_pcm), out->bus_address); + restart = true; + } else { + ALOGV("pcm_write succeed address %s", out->bus_address); + } } } if (buffer) { @@ -402,8 +468,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, si } if (frames_written < frames) { - ALOGW("Hardware backing HAL too slow, could only write %zu of %zu frames", - frames_written, frames); + ALOGW("%s Hardware backing HAL too slow, could only write %zu of %zu frames", + __func__, frames_written, frames); } /* Always consume all bytes */ @@ -641,28 +707,18 @@ static int in_dump(const struct audio_stream *stream, int fd) { static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) { struct generic_stream_in *in = (struct generic_stream_in *)stream; struct str_parms *parms; - char value[32]; - int ret; - long val; - char *end; + int ret = 0; pthread_mutex_lock(&in->lock); if (!in->standby) { ret = -ENOSYS; } else { parms = str_parms_create_str(kvpairs); - - ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, - value, sizeof(value)); + int val = 0; + ret = get_int_value(parms, AUDIO_PARAMETER_STREAM_ROUTING, &val); if (ret >= 0) { - errno = 0; - val = strtol(value, &end, 10); - if ((errno == 0) && (end != NULL) && (*end == '\0') && ((int)val == val)) { - in->device = (int)val; - ret = 0; - } else { - ret = -EINVAL; - } + in->device = (int)val; + ret = 0; } str_parms_destroy(parms); @@ -1034,10 +1090,12 @@ static int adev_open_output_stream(struct audio_hw_device *dev, if (property_get_bool(PROP_KEY_SIMULATE_MULTI_ZONE_AUDIO, false)) { out->enabled_channels = strstr(out->bus_address, "rear") ? RIGHT_CHANNEL: LEFT_CHANNEL; + ALOGD("%s Routing %s to %s channel", __func__, + out->bus_address, out->enabled_channels == RIGHT_CHANNEL ? "Right" : "Left"); } } *stream_out = &out->stream; - ALOGD("%s bus:%s", __func__, out->bus_address); + ALOGD("%s bus: %s", __func__, out->bus_address); error: return ret; @@ -1067,7 +1125,19 @@ static void adev_close_output_stream(struct audio_hw_device *dev, } static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) { - return 0; + struct generic_audio_device *adev = (struct generic_audio_device *)dev; + pthread_mutex_lock(&adev->lock); + struct str_parms *parms = str_parms_create_str(kvpairs); + int value = 0; + int results = get_int_value(parms, AAE_PARAMETER_KEY_FOR_SELECTED_ZONE, &value); + if (results >= 0) { + adev->last_zone_selected_to_play = value; + results = 0; + ALOGD("%s Changed play zone id to %d", __func__, adev->last_zone_selected_to_play); + } + str_parms_destroy(parms); + pthread_mutex_unlock(&adev->lock); + return results; } static char *adev_get_parameters(const struct audio_hw_device *dev, const char *keys) { @@ -1404,6 +1474,8 @@ static int adev_open(const hw_module_t *module, *device = &adev->device.common; adev->mixer = mixer_open(PCM_CARD); + + ALOGD("%s Mixer name %s", __func__, mixer_get_name(adev->mixer)); struct mixer_ctl *ctl; // Set default mixer ctls @@ -1432,6 +1504,8 @@ static int adev_open(const hw_module_t *module, // Initialize the bus address to output stream map adev->out_bus_stream_map = hashmapCreate(5, str_hash_fn, str_eq); + adev->last_zone_selected_to_play = DEFAULT_ZONE_TO_LEFT_SPEAKER; + audio_device_ref_count++; unlock: diff --git a/emulator/audio/driver/audio_hw.h b/emulator/audio/driver/audio_hw.h index 903a9b8..6b6148a 100644 --- a/emulator/audio/driver/audio_hw.h +++ b/emulator/audio/driver/audio_hw.h @@ -33,6 +33,8 @@ struct generic_audio_device { bool mic_mute; // Protected by this->lock struct mixer *mixer; // Protected by this->lock Hashmap *out_bus_stream_map; // Extended field. Constant after init + // Play on Speaker zone selection + int last_zone_selected_to_play; // Protected by this->lock }; enum output_channel_enable { diff --git a/emulator/audio/overlay/packages/services/Car/tests/EmbeddedKitchenSinkApp/res/values/display_to_audio_device_configs.xml b/emulator/audio/overlay/packages/services/Car/tests/EmbeddedKitchenSinkApp/res/values/display_to_audio_device_configs.xml new file mode 100644 index 0000000..7f2496d --- /dev/null +++ b/emulator/audio/overlay/packages/services/Car/tests/EmbeddedKitchenSinkApp/res/values/display_to_audio_device_configs.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds. Do not translate. --> +<resources> + <string-array name="config_displayToAudioDeviceConfig"> + <!-- Add display to audio device pair as such + <item>"0,bus0_media_out"</item> + --> + <item>"0,bus0_media_out"</item> + <item>"1,bus100_left_rear_seat_1"</item> + <item>"2,bus200_right_rear_seat_2"</item> + </string-array> +</resources>
\ No newline at end of file |