Merge "hal: soundtrigger: update stream status callback to include device info"
diff --git a/hal/audio_extn/hw_loopback.c b/hal/audio_extn/hw_loopback.c
index 7753747..c046782 100644
--- a/hal/audio_extn/hw_loopback.c
+++ b/hal/audio_extn/hw_loopback.c
@@ -66,17 +66,6 @@
#include <sound/compress_offload.h>
#include <system/audio.h>
-/*
-* Unique patch handle ID = (unique_patch_handle_type << 8 | patch_handle_num)
-* Eg : HDMI_IN_SPKR_OUT handles can be 0x1000, 0x1001 and so on..
-*/
-typedef enum patch_handle_type {
- AUDIO_PATCH_HDMI_IN_SPKR_OUT=0x10,
- AUDIO_PATCH_SPDIF_IN_SPKR_OUT,
- AUDIO_PATCH_MIC_IN_SPKR_OUT,
- AUDIO_PATCH_MIC_IN_HDMI_OUT
-} patch_handle_type_t;
-
typedef enum patch_state {
PATCH_INACTIVE,// Patch is not created yet
PATCH_CREATED, // Patch created but not in running state yet, probably due
@@ -103,8 +92,10 @@
typedef struct audio_loopback {
struct audio_device *adev;
patch_db_t patch_db;
- audio_usecase_t uc_id;
- usecase_type_t uc_type;
+ audio_usecase_t uc_id_rx;
+ audio_usecase_t uc_id_tx;
+ usecase_type_t uc_type_rx;
+ usecase_type_t uc_type_tx;
pthread_mutex_t lock;
} audio_loopback_t;
@@ -188,9 +179,12 @@
/* Get patch type based on source and sink ports configuration */
/* Only ports of type 'DEVICE' are supported */
-patch_handle_type_t get_loopback_patch_type(loopback_patch_t* loopback_patch)
+audio_patch_handle_t get_loopback_patch_type(loopback_patch_t* loopback_patch)
{
- bool is_source_hdmi=false, is_sink_supported=false;
+ bool is_source_supported = false, is_sink_supported = false;
+ audio_devices_t source_device = loopback_patch->loopback_source.ext.device.type;
+ audio_devices_t sink_device = loopback_patch->loopback_sink.ext.device.type;
+
if (loopback_patch->patch_handle_id != PATCH_HANDLE_INVALID) {
ALOGE("%s, Patch handle already exists", __func__);
return loopback_patch->patch_handle_id;
@@ -199,8 +193,8 @@
if (loopback_patch->loopback_source.role == AUDIO_PORT_ROLE_SOURCE) {
switch (loopback_patch->loopback_source.type) {
case AUDIO_PORT_TYPE_DEVICE :
- if ((loopback_patch->loopback_source.config_mask &
- AUDIO_PORT_CONFIG_FORMAT) && (loopback_patch->loopback_source.ext.device.type & AUDIO_DEVICE_IN_HDMI)) {
+ if ((loopback_patch->loopback_source.config_mask & AUDIO_PORT_CONFIG_FORMAT)) {
+ if (loopback_patch->loopback_source.ext.device.type & AUDIO_DEVICE_IN_HDMI) {
switch (loopback_patch->loopback_source.format) {
case AUDIO_FORMAT_PCM:
case AUDIO_FORMAT_PCM_16_BIT:
@@ -209,10 +203,13 @@
case AUDIO_FORMAT_IEC61937:
case AUDIO_FORMAT_AC3:
case AUDIO_FORMAT_E_AC3:
- is_source_hdmi = true;
+ is_source_supported = true;
break;
+ }
+ } else if (loopback_patch->loopback_source.ext.device.type & AUDIO_DEVICE_IN_LINE) {
+ is_source_supported = true;
+ }
}
- }
break;
default :
break;
@@ -245,8 +242,8 @@
//Unsupported as of now, need to extend for other sink types
}
}
- if (is_source_hdmi && is_sink_supported) {
- return AUDIO_PATCH_HDMI_IN_SPKR_OUT;
+ if (is_source_supported && is_sink_supported) {
+ return source_device | sink_device;
}
ALOGE("%s, Unsupported source or sink port config", __func__);
return loopback_patch->patch_handle_id;
@@ -257,15 +254,15 @@
int32_t release_loopback_session(loopback_patch_t *active_loopback_patch)
{
int32_t ret = 0;
- struct audio_usecase *uc_info;
+ struct audio_usecase *uc_info_rx, *uc_info_tx;
struct audio_device *adev = audio_loopback_mod->adev;
struct stream_inout *inout = &active_loopback_patch->patch_stream;
struct audio_port_config *source_patch_config = &active_loopback_patch->
loopback_source;
- int32_t pcm_dev_asm_rx_id = platform_get_pcm_device_id(USECASE_AUDIO_TRANSCODE_LOOPBACK,
+ int32_t pcm_dev_asm_rx_id = platform_get_pcm_device_id(USECASE_AUDIO_TRANSCODE_LOOPBACK_RX,
PCM_PLAYBACK);
- /* 1. Close the PCM devices */
+ /* Close the PCM devices */
if (active_loopback_patch->source_stream) {
compress_close(active_loopback_patch->source_stream);
active_loopback_patch->source_stream = NULL;
@@ -281,8 +278,26 @@
__func__);
}
- uc_info = get_usecase_from_list(adev, audio_loopback_mod->uc_id);
- if (uc_info == NULL) {
+ uc_info_tx = get_usecase_from_list(adev, audio_loopback_mod->uc_id_tx);
+ if (uc_info_tx == NULL) {
+ ALOGE("%s: Could not find the loopback usecase (%d) in the list",
+ __func__, active_loopback_patch->patch_handle_id);
+ return -EINVAL;
+ }
+
+ disable_audio_route(adev, uc_info_tx);
+
+ /* Disable tx device */
+ disable_snd_device(adev, uc_info_tx->in_snd_device);
+
+ /* Reset backend device to default state */
+ platform_invalidate_backend_config(adev->platform,uc_info_tx->in_snd_device);
+
+ list_remove(&uc_info_tx->list);
+ free(uc_info_tx);
+
+ uc_info_rx = get_usecase_from_list(adev, audio_loopback_mod->uc_id_rx);
+ if (uc_info_rx == NULL) {
ALOGE("%s: Could not find the loopback usecase (%d) in the list",
__func__, active_loopback_patch->patch_handle_id);
return -EINVAL;
@@ -293,18 +308,14 @@
active_loopback_patch->patch_state = PATCH_INACTIVE;
- /* 2. Get and set stream specific mixer controls */
- disable_audio_route(adev, uc_info);
+ /* Get and set stream specific mixer controls */
+ disable_audio_route(adev, uc_info_rx);
- /* 3. Disable the rx and tx devices */
- disable_snd_device(adev, uc_info->out_snd_device);
- disable_snd_device(adev, uc_info->in_snd_device);
+ /* Disable the rx device */
+ disable_snd_device(adev, uc_info_rx->out_snd_device);
- /* 4. Reset backend device to default state */
- platform_invalidate_backend_config(adev->platform,uc_info->in_snd_device);
-
- list_remove(&uc_info->list);
- free(uc_info);
+ list_remove(&uc_info_rx->list);
+ free(uc_info_rx);
adev->active_input = get_next_active_input(adev);
@@ -368,7 +379,7 @@
int create_loopback_session(loopback_patch_t *active_loopback_patch)
{
int32_t ret = 0, bits_per_sample;
- struct audio_usecase *uc_info;
+ struct audio_usecase *uc_info_rx, *uc_info_tx;
int32_t pcm_dev_asm_rx_id, pcm_dev_asm_tx_id;
char dummy_write_buf[64];
struct audio_device *adev = audio_loopback_mod->adev;
@@ -385,21 +396,38 @@
ALOGD("%s: Create loopback session begin", __func__);
- uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
+ uc_info_rx = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
- if (!uc_info) {
+ if (!uc_info_rx) {
ALOGE("%s: Failure to open loopback session", __func__);
return -ENOMEM;
}
- uc_info->id = USECASE_AUDIO_TRANSCODE_LOOPBACK;
- uc_info->type = audio_loopback_mod->uc_type;
- uc_info->stream.inout = &active_loopback_patch->patch_stream;
- uc_info->devices = active_loopback_patch->patch_stream.out_config.devices;
- uc_info->in_snd_device = SND_DEVICE_NONE;
- uc_info->out_snd_device = SND_DEVICE_NONE;
+ uc_info_tx = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
- list_add_tail(&adev->usecase_list, &uc_info->list);
+ if (!uc_info_tx) {
+ free(uc_info_rx);
+ ALOGE("%s: Failure to open loopback session", __func__);
+ return -ENOMEM;
+ }
+
+ uc_info_rx->id = USECASE_AUDIO_TRANSCODE_LOOPBACK_RX;
+ uc_info_rx->type = audio_loopback_mod->uc_type_rx;
+ uc_info_rx->stream.inout = &active_loopback_patch->patch_stream;
+ uc_info_rx->devices = active_loopback_patch->patch_stream.out_config.devices;
+ uc_info_rx->in_snd_device = SND_DEVICE_NONE;
+ uc_info_rx->out_snd_device = SND_DEVICE_NONE;
+
+
+ uc_info_tx->id = USECASE_AUDIO_TRANSCODE_LOOPBACK_TX;
+ uc_info_tx->type = audio_loopback_mod->uc_type_tx;
+ uc_info_tx->stream.inout = &active_loopback_patch->patch_stream;
+ uc_info_tx->devices = active_loopback_patch->patch_stream.in_config.devices;
+ uc_info_tx->in_snd_device = SND_DEVICE_NONE;
+ uc_info_tx->out_snd_device = SND_DEVICE_NONE;
+
+ list_add_tail(&adev->usecase_list, &uc_info_rx->list);
+ list_add_tail(&adev->usecase_list, &uc_info_tx->list);
loopback_source_stream.source = AUDIO_SOURCE_UNPROCESSED;
loopback_source_stream.device = inout->in_config.devices;
@@ -408,23 +436,24 @@
loopback_source_stream.sample_rate = inout->in_config.sample_rate;
loopback_source_stream.format = inout->in_config.format;
- memcpy(&loopback_source_stream.usecase, uc_info,
+ memcpy(&loopback_source_stream.usecase, uc_info_rx,
sizeof(struct audio_usecase));
adev->active_input = &loopback_source_stream;
- select_devices(adev, uc_info->id);
+ select_devices(adev, uc_info_rx->id);
+ select_devices(adev, uc_info_tx->id);
- pcm_dev_asm_rx_id = platform_get_pcm_device_id(uc_info->id, PCM_PLAYBACK);
- pcm_dev_asm_tx_id = platform_get_pcm_device_id(uc_info->id, PCM_CAPTURE);
+ pcm_dev_asm_rx_id = platform_get_pcm_device_id(uc_info_rx->id, PCM_PLAYBACK);
+ pcm_dev_asm_tx_id = platform_get_pcm_device_id(uc_info_tx->id, PCM_CAPTURE);
if (pcm_dev_asm_rx_id < 0 || pcm_dev_asm_tx_id < 0 ) {
- ALOGE("%s: Invalid PCM devices (asm: rx %d tx %d) for the usecase(%d)",
- __func__, pcm_dev_asm_rx_id, pcm_dev_asm_tx_id, uc_info->id);
+ ALOGE("%s: Invalid PCM devices (asm: rx %d tx %d) for the RX usecase(%d), TX usecase(%d)",
+ __func__, pcm_dev_asm_rx_id, pcm_dev_asm_tx_id, uc_info_rx->id, uc_info_tx->id);
ret = -EIO;
goto exit;
}
- ALOGD("%s: LOOPBACK PCM devices (rx: %d tx: %d) usecase(%d)",
- __func__, pcm_dev_asm_rx_id, pcm_dev_asm_tx_id, uc_info->id);
+ ALOGD("%s: LOOPBACK PCM devices (rx: %d tx: %d) RX usecase(%d) TX usecase(%d)",
+ __func__, pcm_dev_asm_rx_id, pcm_dev_asm_tx_id, uc_info_rx->id, uc_info_tx->id);
/* setup a channel for client <--> adsp communication for stream events */
inout->dev = adev;
@@ -442,7 +471,7 @@
}
if (audio_extn_ip_hdlr_intf_supported(source_patch_config->format,false, true)) {
ret = audio_extn_ip_hdlr_intf_init(&inout->ip_hdlr_handle, NULL, NULL, adev,
- USECASE_AUDIO_TRANSCODE_LOOPBACK);
+ USECASE_AUDIO_TRANSCODE_LOOPBACK_RX);
if (ret < 0) {
ALOGE("%s: audio_extn_ip_hdlr_intf_init failed %d", __func__, ret);
inout->ip_hdlr_handle = NULL;
@@ -537,7 +566,7 @@
}
if (inout->ip_hdlr_handle) {
ret = audio_extn_ip_hdlr_intf_open(inout->ip_hdlr_handle, true, inout,
- USECASE_AUDIO_TRANSCODE_LOOPBACK);
+ USECASE_AUDIO_TRANSCODE_LOOPBACK_RX);
if (ret < 0) {
ALOGE("%s: audio_extn_ip_hdlr_intf_open failed %d",__func__, ret);
goto exit;
@@ -579,7 +608,7 @@
audio_patch_handle_t *handle)
{
int status = 0;
- patch_handle_type_t loopback_patch_type=0x0;
+ audio_patch_handle_t loopback_patch_id = 0x0;
loopback_patch_t loopback_patch, *active_loopback_patch = NULL;
ALOGV("%s : Create audio patch begin", __func__);
@@ -622,9 +651,9 @@
audio_port_config));
/* Get loopback patch type based on source and sink ports configuration */
- loopback_patch_type = get_loopback_patch_type(active_loopback_patch);
+ loopback_patch_id = get_loopback_patch_type(active_loopback_patch);
- if (loopback_patch_type == PATCH_HANDLE_INVALID) {
+ if (loopback_patch_id == PATCH_HANDLE_INVALID) {
ALOGE("%s, Unsupported patch type", __func__);
status = -EINVAL;
goto exit_create_patch;
@@ -636,8 +665,7 @@
&active_loopback_patch->loopback_sink);
// Lock patch database, create patch handle and add patch handle to the list
- active_loopback_patch->patch_handle_id = (loopback_patch_type << 8 |
- audio_loopback_mod->patch_db.num_patches);
+ active_loopback_patch->patch_handle_id = loopback_patch_id;
/* Is usecase transcode loopback? If yes, invoke loopback driver */
if ((active_loopback_patch->loopback_source.type == AUDIO_PORT_TYPE_DEVICE)
@@ -878,8 +906,10 @@
ret = init_patch_database(&audio_loopback_mod->patch_db);
- audio_loopback_mod->uc_id = USECASE_AUDIO_TRANSCODE_LOOPBACK;
- audio_loopback_mod->uc_type = TRANSCODE_LOOPBACK;
+ audio_loopback_mod->uc_id_rx = USECASE_AUDIO_TRANSCODE_LOOPBACK_RX;
+ audio_loopback_mod->uc_id_tx = USECASE_AUDIO_TRANSCODE_LOOPBACK_TX;
+ audio_loopback_mod->uc_type_rx = TRANSCODE_LOOPBACK_RX;
+ audio_loopback_mod->uc_type_tx = TRANSCODE_LOOPBACK_TX;
loopback_done:
if (ret != 0) {
diff --git a/hal/audio_extn/ip_hdlr_intf.c b/hal/audio_extn/ip_hdlr_intf.c
index ece7af3..649c99f 100755
--- a/hal/audio_extn/ip_hdlr_intf.c
+++ b/hal/audio_extn/ip_hdlr_intf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -164,7 +164,7 @@
stream_info = node_to_item(node, struct ip_hdlr_stream, list);
/* send the error if rtic failure notifcation is received */
if ((stream_info->stream == aud_sess_handle) &&
- (stream_info->usecase == USECASE_AUDIO_TRANSCODE_LOOPBACK)) {
+ (stream_info->usecase == USECASE_AUDIO_TRANSCODE_LOOPBACK_RX)) {
struct stream_inout *inout = (struct stream_inout *)aud_sess_handle;
usecase = stream_info->usecase;
adev = inout->dev;
@@ -230,7 +230,7 @@
stream_info = node_to_item(node, struct ip_hdlr_stream, list);
/* send the error if rtic failure notifcation is received */
if ((stream_info->stream == aud_sess_handle) &&
- (stream_info->usecase == USECASE_AUDIO_TRANSCODE_LOOPBACK)) {
+ (stream_info->usecase == USECASE_AUDIO_TRANSCODE_LOOPBACK_RX)) {
struct stream_inout *inout = (struct stream_inout *)aud_sess_handle;
pthread_mutex_lock(&inout->pre_lock);
pthread_mutex_lock(&inout->lock);
@@ -288,7 +288,7 @@
param->payload_length = sizeof(struct reg_event);
param->payload = reg_ev;
- if (usecase == USECASE_AUDIO_TRANSCODE_LOOPBACK) {
+ if (usecase == USECASE_AUDIO_TRANSCODE_LOOPBACK_RX) {
inout = (struct stream_inout *)stream_handle;
adsp_hdlr_stream_handle = inout->adsp_hdlr_stream_handle;
dev = inout->dev;
@@ -408,7 +408,7 @@
ALOGD("%s:[%d] handle = %p, usecase = %d",__func__, ip_hdlr->ref_cnt, handle, usecase);
if (is_dsp_decode) {
- if (usecase == USECASE_AUDIO_TRANSCODE_LOOPBACK) {
+ if (usecase == USECASE_AUDIO_TRANSCODE_LOOPBACK_RX) {
struct stream_inout *inout = (struct stream_inout *)aud_sess_handle;
adsp_hdlr_stream_handle = inout->adsp_hdlr_stream_handle;
} else {
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 6aab347..bd3fa7c 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -704,13 +704,14 @@
struct stream_format *sf_info;
char value[PROPERTY_VALUE_MAX] = {0};
- if ((bit_width >= 24) &&
- (devices & AUDIO_DEVICE_OUT_SPEAKER)) {
- int32_t bw = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
- if (-ENOSYS != bw)
+ if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ int bw = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
+ if ((-ENOSYS != bw) && (bit_width > (uint32_t)bw))
bit_width = (uint32_t)bw;
+ else if (-ENOSYS == bw)
+ bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
- ALOGI("%s Allowing 24-bit playback on speaker ONLY at default sampling rate", __func__);
+ ALOGI("%s Allowing 24 and above bits playback on speaker ONLY at default sampling rate", __func__);
}
property_get("vendor.audio.playback.mch.downsample",value,"");
@@ -851,7 +852,7 @@
&usecase->stream.in->app_type_cfg);
ALOGV("%s Selected apptype: %d", __func__, usecase->stream.in->app_type_cfg.app_type);
break;
- case TRANSCODE_LOOPBACK :
+ case TRANSCODE_LOOPBACK_RX :
audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
usecase->stream.inout->out_config.devices,
@@ -911,7 +912,7 @@
platform_get_snd_device_name(split_snd_device));
if (usecase->type != PCM_PLAYBACK && usecase->type != PCM_CAPTURE &&
- usecase->type != TRANSCODE_LOOPBACK) {
+ usecase->type != TRANSCODE_LOOPBACK_RX) {
ALOGE("%s: not a playback/capture path, no need to cfg app type", __func__);
rc = 0;
goto exit_send_app_type_cfg;
@@ -921,7 +922,7 @@
(usecase->id != USECASE_AUDIO_PLAYBACK_MULTI_CH) &&
(usecase->id != USECASE_AUDIO_PLAYBACK_ULL) &&
(usecase->id != USECASE_AUDIO_PLAYBACK_VOIP) &&
- (usecase->id != USECASE_AUDIO_TRANSCODE_LOOPBACK) &&
+ (usecase->id != USECASE_AUDIO_TRANSCODE_LOOPBACK_RX) &&
(!is_interactive_usecase(usecase->id)) &&
(!is_offload_usecase(usecase->id)) &&
(usecase->type != PCM_CAPTURE)) {
@@ -937,7 +938,7 @@
goto exit_send_app_type_cfg;
}
- if (usecase->type == PCM_PLAYBACK || usecase->type == TRANSCODE_LOOPBACK) {
+ if (usecase->type == PCM_PLAYBACK || usecase->type == TRANSCODE_LOOPBACK_RX) {
pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
"Audio Stream %d App Type Cfg", pcm_device_id);
@@ -1073,7 +1074,7 @@
__func__, app_type, acdb_dev_id, sample_rate, snd_device_be_idx);
} else {
app_type = platform_get_default_app_type_v2(adev->platform, usecase->type);
- if(usecase->type == TRANSCODE_LOOPBACK) {
+ if(usecase->type == TRANSCODE_LOOPBACK_RX) {
sample_rate = usecase->stream.inout->out_config.sample_rate;
app_type = usecase->stream.inout->out_app_type_cfg.app_type;
}
@@ -1103,7 +1104,7 @@
switch (usecase->type) {
case PCM_PLAYBACK:
- case TRANSCODE_LOOPBACK:
+ case TRANSCODE_LOOPBACK_RX:
ALOGD("%s: usecase->out_snd_device %s",
__func__, platform_get_snd_device_name(usecase->out_snd_device));
/* check for out combo device */
@@ -1446,7 +1447,7 @@
platform_send_audio_calibration(adev->platform, usecase,
platform_get_default_app_type_v2(adev->platform, usecase->type),
48000);
- } else if (type == TRANSCODE_LOOPBACK && usecase->stream.inout != NULL) {
+ } else if (type == TRANSCODE_LOOPBACK_RX && usecase->stream.inout != NULL) {
int snd_device = usecase->out_snd_device;
snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ?
platform_get_spkr_prot_snd_device(snd_device) : snd_device;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index cef64a7..f31991a 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -337,7 +337,8 @@
[USECASE_AUDIO_PLAYBACK_SILENCE] = "silence-playback",
/* Transcode loopback cases */
- [USECASE_AUDIO_TRANSCODE_LOOPBACK] = "audio-transcode-loopback",
+ [USECASE_AUDIO_TRANSCODE_LOOPBACK_RX] = "audio-transcode-loopback-rx",
+ [USECASE_AUDIO_TRANSCODE_LOOPBACK_TX] = "audio-transcode-loopback-tx",
[USECASE_AUDIO_PLAYBACK_VOIP] = "audio-playback-voip",
[USECASE_AUDIO_RECORD_VOIP] = "audio-record-voip",
@@ -963,7 +964,7 @@
ALOGV("%s: enter: usecase(%d)", __func__, usecase->id);
- if (usecase->type == PCM_CAPTURE)
+ if (usecase->type == PCM_CAPTURE || usecase->type == TRANSCODE_LOOPBACK_TX)
snd_device = usecase->in_snd_device;
else
snd_device = usecase->out_snd_device;
@@ -1001,7 +1002,7 @@
return -EINVAL;
ALOGV("%s: enter: usecase(%d)", __func__, usecase->id);
- if (usecase->type == PCM_CAPTURE)
+ if (usecase->type == PCM_CAPTURE || usecase->type == TRANSCODE_LOOPBACK_TX)
snd_device = usecase->in_snd_device;
else
snd_device = usecase->out_snd_device;
@@ -1257,7 +1258,7 @@
snd_device_t d2 = new_snd_device;
switch (uc->type) {
- case TRANSCODE_LOOPBACK :
+ case TRANSCODE_LOOPBACK_RX :
a1 = uc->stream.inout->out_config.devices;
a2 = new_uc->stream.inout->out_config.devices;
break;
@@ -1929,7 +1930,8 @@
bool is_it_true_mode = false;
if (usecase->type == PCM_CAPTURE ||
- usecase->type == TRANSCODE_LOOPBACK) {
+ usecase->type == TRANSCODE_LOOPBACK_RX ||
+ usecase->type == TRANSCODE_LOOPBACK_TX) {
return false;
}
@@ -2043,7 +2045,7 @@
usecase->stream.out);
in_snd_device = platform_get_input_snd_device(adev->platform, usecase->stream.out->devices);
usecase->devices = usecase->stream.out->devices;
- } else if (usecase->type == TRANSCODE_LOOPBACK ) {
+ } else if (usecase->type == TRANSCODE_LOOPBACK_RX) {
if (usecase->stream.inout == NULL) {
ALOGE("%s: stream.inout is NULL", __func__);
return -EINVAL;
@@ -2054,8 +2056,14 @@
stream_out.channel_mask = usecase->stream.inout->out_config.channel_mask;
out_snd_device = platform_get_output_snd_device(adev->platform,
&stream_out);
+ usecase->devices = out_snd_device;
+ } else if (usecase->type == TRANSCODE_LOOPBACK_TX ) {
+ if (usecase->stream.inout == NULL) {
+ ALOGE("%s: stream.inout is NULL", __func__);
+ return -EINVAL;
+ }
in_snd_device = platform_get_input_snd_device(adev->platform, AUDIO_DEVICE_NONE);
- usecase->devices = (out_snd_device | in_snd_device);
+ usecase->devices = in_snd_device;
} else {
/*
* If the voice call is active, use the sound devices of voice call usecase
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 8cb395f..ba8a99c 100755
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -195,7 +195,8 @@
USECASE_AUDIO_PLAYBACK_SILENCE,
- USECASE_AUDIO_TRANSCODE_LOOPBACK,
+ USECASE_AUDIO_TRANSCODE_LOOPBACK_RX,
+ USECASE_AUDIO_TRANSCODE_LOOPBACK_TX,
USECASE_AUDIO_PLAYBACK_INTERACTIVE_STREAM1,
USECASE_AUDIO_PLAYBACK_INTERACTIVE_STREAM2,
@@ -404,7 +405,8 @@
VOICE_CALL,
VOIP_CALL,
PCM_HFP_CALL,
- TRANSCODE_LOOPBACK
+ TRANSCODE_LOOPBACK_RX,
+ TRANSCODE_LOOPBACK_TX
} usecase_type_t;
union stream_ptr {
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 25ce892..d05c5ed 100755
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -384,7 +384,8 @@
[USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
AFE_PROXY_RECORD_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_SILENCE] = {MULTIMEDIA9_PCM_DEVICE, -1},
- [USECASE_AUDIO_TRANSCODE_LOOPBACK] = {TRANSCODE_LOOPBACK_RX_DEV_ID, TRANSCODE_LOOPBACK_TX_DEV_ID},
+ [USECASE_AUDIO_TRANSCODE_LOOPBACK_RX] = {TRANSCODE_LOOPBACK_RX_DEV_ID, -1},
+ [USECASE_AUDIO_TRANSCODE_LOOPBACK_TX] = {-1, TRANSCODE_LOOPBACK_TX_DEV_ID},
[USECASE_AUDIO_PLAYBACK_VOIP] = {AUDIO_PLAYBACK_VOIP_PCM_DEVICE, AUDIO_PLAYBACK_VOIP_PCM_DEVICE},
[USECASE_AUDIO_RECORD_VOIP] = {AUDIO_RECORD_VOIP_PCM_DEVICE, AUDIO_RECORD_VOIP_PCM_DEVICE},
@@ -929,6 +930,8 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_AFE_PROXY)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_AFE_PROXY)},
{TO_NAME_INDEX(USECASE_AUDIO_EC_REF_LOOPBACK)},
+ {TO_NAME_INDEX(USECASE_AUDIO_TRANSCODE_LOOPBACK_RX)},
+ {TO_NAME_INDEX(USECASE_AUDIO_TRANSCODE_LOOPBACK_TX)},
};
#define NO_COLS 2
@@ -3515,7 +3518,7 @@
snd_device = voice_get_incall_rec_snd_device(usecase->in_snd_device);
else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE))
snd_device = usecase->in_snd_device;
- else if (usecase->type == TRANSCODE_LOOPBACK)
+ else if (usecase->type == TRANSCODE_LOOPBACK_RX)
snd_device = usecase->out_snd_device;
acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(snd_device)];
@@ -6423,7 +6426,7 @@
backend_idx = platform_get_backend_index(snd_device);
- if (usecase->type == TRANSCODE_LOOPBACK) {
+ if (usecase->type == TRANSCODE_LOOPBACK_RX) {
backend_cfg.bit_width = usecase->stream.inout->out_config.bit_width;
backend_cfg.sample_rate = usecase->stream.inout->out_config.sample_rate;
backend_cfg.format = usecase->stream.inout->out_config.format;
@@ -6584,7 +6587,7 @@
backend_cfg.passthrough_enabled = false;
- if (usecase->type == TRANSCODE_LOOPBACK) {
+ if (usecase->type == TRANSCODE_LOOPBACK_TX) {
backend_cfg.bit_width = usecase->stream.inout->in_config.bit_width;
backend_cfg.sample_rate = usecase->stream.inout->in_config.sample_rate;
backend_cfg.format = usecase->stream.inout->in_config.format;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
old mode 100755
new mode 100644
index 313c067..2870c6b
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -368,7 +368,8 @@
[USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
AFE_PROXY_RECORD_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_SILENCE] = {MULTIMEDIA9_PCM_DEVICE, -1},
- [USECASE_AUDIO_TRANSCODE_LOOPBACK] = {TRANSCODE_LOOPBACK_RX_DEV_ID, TRANSCODE_LOOPBACK_TX_DEV_ID},
+ [USECASE_AUDIO_TRANSCODE_LOOPBACK_RX] = {TRANSCODE_LOOPBACK_RX_DEV_ID, -1},
+ [USECASE_AUDIO_TRANSCODE_LOOPBACK_TX] = {-1, TRANSCODE_LOOPBACK_TX_DEV_ID},
[USECASE_AUDIO_PLAYBACK_VOIP] = {AUDIO_PLAYBACK_VOIP_PCM_DEVICE, AUDIO_PLAYBACK_VOIP_PCM_DEVICE},
[USECASE_AUDIO_RECORD_VOIP] = {AUDIO_RECORD_VOIP_PCM_DEVICE, AUDIO_RECORD_VOIP_PCM_DEVICE},
@@ -910,6 +911,8 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_AFE_PROXY)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_AFE_PROXY)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_SILENCE)},
+ {TO_NAME_INDEX(USECASE_AUDIO_TRANSCODE_LOOPBACK_RX)},
+ {TO_NAME_INDEX(USECASE_AUDIO_TRANSCODE_LOOPBACK_TX)},
};
#define NO_COLS 2
@@ -3295,7 +3298,7 @@
snd_device = voice_get_incall_rec_snd_device(usecase->in_snd_device);
else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE))
snd_device = usecase->in_snd_device;
- else if (usecase->type == TRANSCODE_LOOPBACK)
+ else if (usecase->type == TRANSCODE_LOOPBACK_RX)
snd_device = usecase->out_snd_device;
acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(snd_device)];
@@ -6267,11 +6270,14 @@
* backend with speaker, and these devices are restricited to 48kHz.
*/
if (platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, snd_device)) {
-
- if (bit_width >= 24) {
- bit_width = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
+ int bw = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
+ if ((-ENOSYS != bw) && (bit_width > (uint32_t)bw)) {
+ bit_width = (uint32_t)bw;
ALOGD("%s:becf: afe: reset bitwidth to %d (based on supported"
- " value for this platform)", __func__, bit_width);
+ " value for this platform)", __func__, bit_width);
+ } else if (-ENOSYS == bw) {
+ bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ ALOGD("%s:becf: afe: reset to default bitwidth %d", __func__, bit_width);
}
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
ALOGD("%s:becf: afe: playback on codec device not supporting native playback set "
@@ -6366,7 +6372,7 @@
backend_idx = platform_get_backend_index(snd_device);
- if (usecase->type == TRANSCODE_LOOPBACK) {
+ if (usecase->type == TRANSCODE_LOOPBACK_RX) {
backend_cfg.bit_width = usecase->stream.inout->out_config.bit_width;
backend_cfg.sample_rate = usecase->stream.inout->out_config.sample_rate;
backend_cfg.format = usecase->stream.inout->out_config.format;
@@ -6525,7 +6531,7 @@
backend_cfg.passthrough_enabled = false;
- if (usecase->type == TRANSCODE_LOOPBACK) {
+ if (usecase->type == TRANSCODE_LOOPBACK_TX) {
backend_cfg.bit_width = usecase->stream.inout->in_config.bit_width;
backend_cfg.sample_rate = usecase->stream.inout->in_config.sample_rate;
backend_cfg.format = usecase->stream.inout->in_config.format;
diff --git a/qahw_api/test/trans_loopback_test.c b/qahw_api/test/trans_loopback_test.c
index f1d897a..6f5cb75 100644
--- a/qahw_api/test/trans_loopback_test.c
+++ b/qahw_api/test/trans_loopback_test.c
@@ -95,9 +95,6 @@
#define TRANSCODE_LOOPBACK_SOURCE_PORT_ID 0x4C00
#define TRANSCODE_LOOPBACK_SINK_PORT_ID 0x4D00
-#define DEVICE_SOURCE 0
-#define DEVICE_SINK 1
-
#define MAX_MODULE_NAME_LENGTH 100
#define DEV_NODE_CHECK(node_name,node_id) strncmp(node_name,node_id,strlen(node_name))
@@ -110,7 +107,8 @@
SOURCE_PORT_NONE,
SOURCE_PORT_HDMI,
SOURCE_PORT_SPDIF,
- SOURCE_PORT_MIC
+ SOURCE_PORT_MIC,
+ SOURCE_PORT_BT
} source_port_type_t;
typedef enum source_port_state {
@@ -449,12 +447,15 @@
{
int status =0;
source_port_type_t source_port_type = transcode_loopback_config->source_port_config.source_port_type;
- status = read_and_set_source_config(source_port_type,&transcode_loopback_config->source_config);
- if ( status )
- {
- fprintf(log_file,"\nFailure in source port configuration with status: %d\n", status);
- return;
+ if (source_port_type == SOURCE_PORT_HDMI) {
+ status = read_and_set_source_config(source_port_type,&transcode_loopback_config->source_config);
+ if (status) {
+ fprintf(log_file,"\nFailure in source port configuration with status: %d\n", status);
+ return;
+ }
+ } else {
+ transcode_loopback_config->source_port_config.source_port_state = SOURCE_PORT_CONFIG_CHANGED;
}
fprintf(log_file,"\nSource port state : %d\n", transcode_loopback_config->source_port_config.source_port_state);
@@ -545,17 +546,27 @@
exit_process_thread = true;
}
-void set_device(uint32_t device_type, uint32_t device_id)
+void set_device(uint32_t source_device, uint32_t sink_device)
{
transcode_loopback_config_t *transcode_loopback_config = &g_trnscode_loopback_config;
- switch( device_type )
- {
- case DEVICE_SINK:
- transcode_loopback_config->sink_config.ext.device.type = device_id;
- break;
- case DEVICE_SOURCE:
- transcode_loopback_config->source_config.ext.device.type = device_id;
- break;
+
+ transcode_loopback_config->sink_config.ext.device.type = sink_device;
+ transcode_loopback_config->source_config.ext.device.type = source_device;
+
+ switch (source_device) {
+ case AUDIO_DEVICE_IN_SPDIF:
+ g_trnscode_loopback_config.source_port_config.source_port_type = SOURCE_PORT_SPDIF;
+ break;
+ case AUDIO_DEVICE_IN_BLUETOOTH_A2DP:
+ g_trnscode_loopback_config.source_port_config.source_port_type = SOURCE_PORT_BT;
+ break;
+ case AUDIO_DEVICE_IN_LINE:
+ g_trnscode_loopback_config.source_port_config.source_port_type = SOURCE_PORT_MIC;
+ break;
+ case AUDIO_DEVICE_IN_HDMI:
+ default:
+ g_trnscode_loopback_config.source_port_config.source_port_type = SOURCE_PORT_HDMI;
+ break;
}
}
@@ -563,6 +574,7 @@
int status = 0;
uint32_t play_duration_in_seconds = 600,play_duration_elapsed_msec = 0,play_duration_in_msec = 0, sink_device = 2, volume_in_millibels = 0;
+ uint32_t source_device = AUDIO_DEVICE_IN_HDMI;
source_port_type_t source_port_type = SOURCE_PORT_NONE;
log_file = stdout;
transcode_loopback_config_t *transcode_loopback_config = NULL;
@@ -570,7 +582,8 @@
struct option long_options[] = {
/* These options set a flag. */
- {"sink-device", required_argument, 0, 'd'},
+ {"sink-device", required_argument, 0, 'o'},
+ {"source-device", required_argument, 0, 'i'},
{"play-duration", required_argument, 0, 'p'},
{"play-volume", required_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
@@ -582,15 +595,18 @@
while ((opt = getopt_long(argc,
argv,
- "-d:p:v:h",
+ "-o:i:p:v:h",
long_options,
&option_index)) != -1) {
fprintf(log_file, "for argument %c, value is %s\n", opt, optarg);
switch (opt) {
- case 'd':
- sink_device = atoi(optarg);
+ case 'o':
+ sink_device = atoll(optarg);
+ break;
+ case 'i':
+ source_device = atoll(optarg);
break;
case 'p':
play_duration_in_seconds = atoi(optarg);
@@ -606,6 +622,7 @@
}
}
+ fprintf(log_file, "source %#x sink %#x\n", source_device, sink_device);
fprintf(log_file,"\nTranscode loopback test begin\n");
if (play_duration_in_seconds < 0 | play_duration_in_seconds > 360000) {
fprintf(log_file,
@@ -626,7 +643,7 @@
transcode_loopback_config = &g_trnscode_loopback_config;
/* Set devices */
- set_device(DEVICE_SINK,sink_device);
+ set_device(source_device, sink_device);
/* Load HAL */
fprintf(log_file,"\nLoading HAL for loopback usecase begin\n");