audio: Dedicated usecase for voip call (uplink and downlink)
Add dedicated usecases for voip call.
coauthored-by: Vikram Panduranga <vpandura@codeaurora.org>
Bug: 62393776
Test: hangout call
Change-Id: Iff8911aa8d4f072923e2f2649098a44a4bc4485c
Signed-off-by: David Lin <dtwlin@google.com>
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index cca56ec..44a0216 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -67,6 +67,7 @@
/* ToDo: Check and update a proper value in msec */
#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
+#define VOIP_PLAYBACK_VOLUME_MAX 0x2000
#define PROXY_OPEN_RETRY_COUNT 100
#define PROXY_OPEN_WAIT_TIME 20
@@ -204,6 +205,14 @@
.avail_min = MMAP_PERIOD_SIZE, //1 ms
};
+struct pcm_config pcm_config_voip = {
+ .channels = 1,
+ .period_count = 2,
+ .format = PCM_FORMAT_S16_LE,
+ .stop_threshold = INT_MAX,
+ .avail_min = 0,
+};
+
#define AFE_PROXY_CHANNEL_COUNT 2
#define AFE_PROXY_SAMPLING_RATE 48000
@@ -270,6 +279,8 @@
[USECASE_INCALL_REC_DOWNLINK] = "incall-rec-downlink",
[USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = "incall-rec-uplink-and-downlink",
+ [USECASE_AUDIO_PLAYBACK_VOIP] = "audio-playback-voip",
+ [USECASE_AUDIO_RECORD_VOIP] = "audio-record-voip",
};
@@ -1440,7 +1451,6 @@
error_config:
adev->active_input = NULL;
ALOGW("%s: exit: status(%d)", __func__, ret);
-
return ret;
}
@@ -1896,17 +1906,18 @@
return 0;
}
-static size_t get_input_buffer_size(uint32_t sample_rate,
- audio_format_t format,
- int channel_count,
- bool is_low_latency)
+static size_t get_stream_buffer_size(size_t duration_ms,
+ uint32_t sample_rate,
+ audio_format_t format,
+ int channel_count,
+ bool is_low_latency)
{
size_t size = 0;
if (check_input_parameters(sample_rate, format, channel_count) != 0)
return 0;
- size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000;
+ size = (sample_rate * duration_ms) / 1000;
if (is_low_latency)
size = configured_low_latency_capture_period_size;
@@ -2366,6 +2377,23 @@
volume[1] = (int)(right * COMPRESS_PLAYBACK_VOLUME_MAX);
mixer_ctl_set_array(ctl, volume, sizeof(volume)/sizeof(volume[0]));
return 0;
+ } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
+ int gain_cfg[4];
+ const char *mixer_ctl_name = "App Type Gain";
+ struct audio_device *adev = out->dev;
+ struct mixer_ctl *ctl;
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get volume ctl mixer %s", __func__,
+ mixer_ctl_name);
+ return -EINVAL;
+ }
+ gain_cfg[0] = 0;
+ gain_cfg[1] = out->app_type_cfg.app_type;
+ gain_cfg[2] = (int)(left * VOIP_PLAYBACK_VOLUME_MAX);
+ gain_cfg[3] = (int)(right * VOIP_PLAYBACK_VOLUME_MAX);
+ mixer_ctl_set_array(ctl, gain_cfg, sizeof(gain_cfg)/sizeof(gain_cfg[0]));
+ return 0;
}
return -ENOSYS;
@@ -2900,7 +2928,6 @@
static size_t in_get_buffer_size(const struct audio_stream *stream)
{
struct stream_in *in = (struct stream_in *)stream;
-
return in->config.period_size * in->af_period_multiplier *
audio_stream_in_frame_size((const struct audio_stream_in *)stream);
}
@@ -3572,6 +3599,27 @@
out->usecase = USECASE_AUDIO_PLAYBACK_AFE_PROXY;
out->config = pcm_config_afe_proxy_playback;
adev->voice_tx_output = out;
+ } else if ((out->dev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
+ (out->flags == (AUDIO_OUTPUT_FLAG_DIRECT |
+ AUDIO_OUTPUT_FLAG_VOIP_RX))) {
+ uint32_t buffer_size, frame_size;
+ out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
+ out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
+ out->usecase = USECASE_AUDIO_PLAYBACK_VOIP;
+ out->config = pcm_config_voip;
+ out->config.format = pcm_format_from_audio_format(config->format);
+ out->config.rate = config->sample_rate;
+ out->config.channels =
+ audio_channel_count_from_out_mask(config->channel_mask);
+ buffer_size = get_stream_buffer_size(VOIP_PLAYBACK_PERIOD_DURATION_MSEC,
+ config->sample_rate,
+ config->format,
+ out->config.channels,
+ false /*is_low_latency*/);
+ frame_size = audio_bytes_per_sample(config->format) * out->config.channels;
+ out->config.period_size = buffer_size / frame_size;
+ out->config.period_count = VOIP_PLAYBACK_PERIOD_COUNT;
+ out->af_period_multiplier = 1;
} else {
if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
@@ -3983,8 +4031,10 @@
{
int channel_count = audio_channel_count_from_in_mask(config->channel_mask);
- return get_input_buffer_size(config->sample_rate, config->format, channel_count,
- false /* is_low_latency: since we don't know, be conservative */);
+ return get_stream_buffer_size(AUDIO_CAPTURE_PERIOD_DURATION_MSEC,
+ config->sample_rate, config->format,
+ channel_count,
+ false /* is_low_latency: since we don't know, be conservative */);
}
static bool adev_input_allow_hifi_record(struct audio_device *adev,
@@ -4161,10 +4211,11 @@
in->usecase = USECASE_AUDIO_RECORD_HIFI;
in->config = pcm_config_audio_capture;
frame_size = audio_stream_in_frame_size(&in->stream);
- buffer_size = get_input_buffer_size(config->sample_rate,
- config->format,
- channel_count,
- false /*is_low_latency*/);
+ buffer_size = get_stream_buffer_size(AUDIO_CAPTURE_PERIOD_DURATION_MSEC,
+ config->sample_rate,
+ config->format,
+ channel_count,
+ false /*is_low_latency*/);
in->config.period_size = buffer_size / frame_size;
in->config.rate = config->sample_rate;
in->af_period_multiplier = 1;
@@ -4181,10 +4232,11 @@
if (!in->realtime) {
in->config = pcm_config_audio_capture;
frame_size = audio_stream_in_frame_size(&in->stream);
- buffer_size = get_input_buffer_size(config->sample_rate,
- config->format,
- channel_count,
- is_low_latency);
+ buffer_size = get_stream_buffer_size(AUDIO_CAPTURE_PERIOD_DURATION_MSEC,
+ config->sample_rate,
+ config->format,
+ channel_count,
+ is_low_latency);
in->config.period_size = buffer_size / frame_size;
in->config.rate = config->sample_rate;
in->af_period_multiplier = 1;
@@ -4204,13 +4256,33 @@
in->stream.get_mmap_position = in_get_mmap_position;
in->af_period_multiplier = 1;
ALOGV("%s: USECASE_AUDIO_RECORD_MMAP", __func__);
+ } else if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
+ in->dev->mode == AUDIO_MODE_IN_COMMUNICATION &&
+ (config->sample_rate == 8000 ||
+ config->sample_rate == 16000 ||
+ config->sample_rate == 32000 ||
+ config->sample_rate == 48000) &&
+ channel_count == 1) {
+ in->usecase = USECASE_AUDIO_RECORD_VOIP;
+ in->config = pcm_config_audio_capture;
+ frame_size = audio_stream_in_frame_size(&in->stream);
+ buffer_size = get_stream_buffer_size(VOIP_CAPTURE_PERIOD_DURATION_MSEC,
+ config->sample_rate,
+ config->format,
+ channel_count, false /*is_low_latency*/);
+ in->config.period_size = buffer_size / frame_size;
+ in->config.period_count = VOIP_CAPTURE_PERIOD_COUNT;
+ in->config.rate = config->sample_rate;
+ in->af_period_multiplier = 1;
+ in->flags |= AUDIO_INPUT_FLAG_VOIP_TX;
} else {
in->config = pcm_config_audio_capture;
frame_size = audio_stream_in_frame_size(&in->stream);
- buffer_size = get_input_buffer_size(config->sample_rate,
- config->format,
- channel_count,
- is_low_latency);
+ buffer_size = get_stream_buffer_size(AUDIO_CAPTURE_PERIOD_DURATION_MSEC,
+ config->sample_rate,
+ config->format,
+ channel_count,
+ is_low_latency);
in->config.period_size = buffer_size / frame_size;
in->config.rate = config->sample_rate;
in->af_period_multiplier = 1;
@@ -4220,6 +4292,7 @@
}
in->config.channels = channel_count;
+ in->sample_rate = in->config.rate;
/* This stream could be for sound trigger lab,
get sound trigger pcm if present */