summaryrefslogtreecommitdiffstats
path: root/emulator
diff options
context:
space:
mode:
authorOscar Azucena <oscarazu@google.com>2019-06-21 16:49:49 -0700
committerOscar Azucena <oscarazu@google.com>2019-09-10 14:15:08 -0700
commit57fb25abfc1b712574c7c1294925b75cc877f252 (patch)
tree3ec5df92a71b47238a152f1d2a4a4844bd9dd75f /emulator
parent4fded06838df8a9519618ae91695c347d79f8eec (diff)
downloaddevice_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')
-rw-r--r--emulator/audio/audio_policy_configuration.xml29
-rw-r--r--emulator/audio/car_audio_configuration.xml23
-rw-r--r--emulator/audio/driver/audio_hw.c154
-rw-r--r--emulator/audio/driver/audio_hw.h2
-rw-r--r--emulator/audio/overlay/packages/services/Car/tests/EmbeddedKitchenSinkApp/res/values/display_to_audio_device_configs.xml28
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