audio: Mmap audio fixes
Mmmap audio fixes for mmap playback and record create buffers,
mmap record standby issue and adding aaudio props
Change-Id: I0187bb66474d1487179c6f4d9b8677a4f3cb2dc9
diff --git a/configs/kona/kona.mk b/configs/kona/kona.mk
index 6e234fb..9c6e918 100644
--- a/configs/kona/kona.mk
+++ b/configs/kona/kona.mk
@@ -259,6 +259,14 @@
PRODUCT_PROPERTY_OVERRIDES += \
vendor.audio.hal.output.suspend.supported=true
+#Enable AAudio MMAP/NOIRQ data path
+#2 is AAUDIO_POLICY_AUTO so it will try MMAP then fallback to Legacy path
+PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_policy=2
+#Allow EXCLUSIVE then fall back to SHARED.
+PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_exclusive_policy=2
+PRODUCT_PROPERTY_OVERRIDES += aaudio.hw_burst_min_usec=2000
+
+
#enable mirror-link feature
PRODUCT_PROPERTY_OVERRIDES += \
vendor.audio.enable.mirrorlink=true
diff --git a/configs/msmnile/msmnile.mk b/configs/msmnile/msmnile.mk
index 1ae6282..9c2f5da 100644
--- a/configs/msmnile/msmnile.mk
+++ b/configs/msmnile/msmnile.mk
@@ -254,6 +254,13 @@
PRODUCT_PROPERTY_OVERRIDES += \
vendor.audio.hal.output.suspend.supported=true
+#Enable AAudio MMAP/NOIRQ data path
+#2 is AAUDIO_POLICY_AUTO so it will try MMAP then fallback to Legacy path
+PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_policy=2
+#Allow EXCLUSIVE then fall back to SHARED.
+PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_exclusive_policy=2
+PRODUCT_PROPERTY_OVERRIDES += aaudio.hw_burst_min_usec=2000
+
#enable mirror-link feature
PRODUCT_PROPERTY_OVERRIDES += \
vendor.audio.enable.mirrorlink=false
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index bb4db48..7b0379e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -90,6 +90,7 @@
#define DIRECT_PCM_NUM_FRAGMENTS 2
#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
#define VOIP_PLAYBACK_VOLUME_MAX 0x2000
+#define MMAP_PLAYBACK_VOLUME_MAX 0x2000
#define PCM_PLAYBACK_VOLUME_MAX 0x2000
#define DSD_VOLUME_MIN_DB (-110)
@@ -488,6 +489,7 @@
static int check_a2dp_restore_l(struct audio_device *adev, struct stream_out *out, bool restore);
static int out_set_compr_volume(struct audio_stream_out *stream, float left, float right);
+static int out_set_mmap_volume(struct audio_stream_out *stream, float left, float right);
static int out_set_voip_volume(struct audio_stream_out *stream, float left, float right);
static int out_set_pcm_volume(struct audio_stream_out *stream, float left, float right);
@@ -3308,6 +3310,7 @@
__func__, adev->snd_card, out->pcm_device_id, out->config.format);
if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) {
+ ALOGD("%s: Starting MMAP stream", __func__);
if (out->pcm == NULL || !pcm_is_ready(out->pcm)) {
ALOGE("%s: pcm stream not ready", __func__);
goto error_open;
@@ -3317,6 +3320,7 @@
ALOGE("%s: MMAP pcm_start failed ret %d", __func__, ret);
goto error_open;
}
+ out_set_mmap_volume(&out->stream, out->volume_l, out->volume_r);
} else if (!is_offload_usecase(out->usecase)) {
unsigned int flags = PCM_OUT;
unsigned int pcm_open_retry_count = 0;
@@ -4593,6 +4597,37 @@
return db;
}
+static int out_set_mmap_volume(struct audio_stream_out *stream, float left,
+ float right)
+{
+ struct stream_out *out = (struct stream_out *)stream;
+ long volume = 0;
+ char mixer_ctl_name[128] = "";
+ struct audio_device *adev = out->dev;
+ struct mixer_ctl *ctl = NULL;
+ int pcm_device_id = platform_get_pcm_device_id(out->usecase,
+ PCM_PLAYBACK);
+
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Playback %d Volume", pcm_device_id);
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+ if (left != right)
+ ALOGW("%s: Left and right channel volume mismatch:%f,%f",
+ __func__, left, right);
+ volume = (long)(left * (MMAP_PLAYBACK_VOLUME_MAX*1.0));
+ if (mixer_ctl_set_value(ctl, 0, volume) < 0){
+ ALOGE("%s:ctl for mixer cmd - %s, volume %ld returned error",
+ __func__, mixer_ctl_name, volume);
+ return -EINVAL;
+ }
+ return 0;
+}
+
static int out_set_compr_volume(struct audio_stream_out *stream, float left,
float right)
{
@@ -4685,6 +4720,7 @@
int volume[2];
int ret = 0;
+ ALOGD("%s: called with left_vol=%f, right_vol=%f", __func__, left, right);
if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
/* only take left channel into account: the API is for stereo anyway */
out->muted = (left == 0.0f);
@@ -4713,7 +4749,7 @@
return 0;
} else {
pthread_mutex_lock(&out->compr_mute_lock);
- ALOGE("%s: compress mute %d", __func__, out->a2dp_compress_mute);
+ ALOGV("%s: compress mute %d", __func__, out->a2dp_compress_mute);
if (!out->a2dp_compress_mute)
ret = out_set_compr_volume(stream, left, right);
out->volume_l = left;
@@ -4733,6 +4769,13 @@
out->volume_l = left;
out->volume_r = right;
return ret;
+ } else if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) {
+ ALOGV("%s: MMAP set volume called", __func__);
+ if (!out->standby)
+ ret = out_set_mmap_volume(stream, left, right);
+ out->volume_l = left;
+ out->volume_r = right;
+ return ret;
} else if (out->usecase == USECASE_AUDIO_PLAYBACK_LOW_LATENCY ||
out->usecase == USECASE_AUDIO_PLAYBACK_DEEP_BUFFER ||
out->usecase == USECASE_AUDIO_PLAYBACK_ULL) {
@@ -5564,8 +5607,9 @@
unsigned int frames1 = 0;
const char *step = "";
uint32_t mmap_size;
+ uint32_t buffer_size;
- ALOGV("%s", __func__);
+ ALOGD("%s", __func__);
lock_output_stream(out);
pthread_mutex_lock(&adev->lock);
@@ -5595,7 +5639,7 @@
adjust_mmap_period_count(&out->config, min_size_frames);
- ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
+ ALOGD("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
__func__, adev->snd_card, out->pcm_device_id, out->config.channels);
out->pcm = pcm_open(adev->snd_card, out->pcm_device_id,
(PCM_OUT | PCM_MMAP | PCM_NOIRQ | PCM_MONOTONIC), &out->config);
@@ -5618,14 +5662,22 @@
goto exit;
}
info->buffer_size_frames = pcm_get_buffer_size(out->pcm);
+ buffer_size = pcm_frames_to_bytes(out->pcm, info->buffer_size_frames);
info->burst_size_frames = out->config.period_size;
ret = platform_get_mmap_data_fd(adev->platform,
out->pcm_device_id, 0 /*playback*/,
&info->shared_memory_fd,
&mmap_size);
if (ret < 0) {
- step = "get_mmap_fd";
- goto exit;
+ // Fall back to non exclusive mode
+ info->shared_memory_fd = pcm_get_poll_fd(out->pcm);
+ } else {
+ if (mmap_size < buffer_size) {
+ step = "mmap";
+ goto exit;
+ }
+ // FIXME: indicate exclusive mode support by returning a negative buffer size
+ info->buffer_size_frames *= -1;
}
memset(info->shared_memory_address, 0, pcm_frames_to_bytes(out->pcm,
info->buffer_size_frames));
@@ -5639,7 +5691,7 @@
out->standby = false;
ret = 0;
- ALOGV("%s: got mmap buffer address %p info->buffer_size_frames %d",
+ ALOGD("%s: got mmap buffer address %p info->buffer_size_frames %d",
__func__, info->shared_memory_address, info->buffer_size_frames);
exit:
@@ -5770,13 +5822,14 @@
audio_extn_cin_stop_input_stream(in);
}
- if (do_stop) {
- if (in->pcm) {
- ATRACE_BEGIN("pcm_in_close");
- pcm_close(in->pcm);
- ATRACE_END();
- in->pcm = NULL;
- }
+ if (in->pcm) {
+ ATRACE_BEGIN("pcm_in_close");
+ pcm_close(in->pcm);
+ ATRACE_END();
+ in->pcm = NULL;
+ }
+
+ if(do_stop) {
adev->enable_voicerx = false;
platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
status = stop_input_stream(in);
@@ -6332,6 +6385,8 @@
unsigned int offset1 = 0;
unsigned int frames1 = 0;
const char *step = "";
+ uint32_t mmap_size = 0;
+ uint32_t buffer_size = 0;
pthread_mutex_lock(&adev->lock);
ALOGV("%s in %p", __func__, in);
@@ -6387,12 +6442,27 @@
step = "begin";
goto exit;
}
- info->buffer_size_frames = pcm_get_buffer_size(in->pcm);
- info->burst_size_frames = in->config.period_size;
- info->shared_memory_fd = pcm_get_poll_fd(in->pcm);
- memset(info->shared_memory_address, 0, pcm_frames_to_bytes(in->pcm,
- info->buffer_size_frames));
+ info->buffer_size_frames = pcm_get_buffer_size(in->pcm);
+ buffer_size = pcm_frames_to_bytes(in->pcm, info->buffer_size_frames);
+ info->burst_size_frames = in->config.period_size;
+ ret = platform_get_mmap_data_fd(adev->platform,
+ in->pcm_device_id, 1 /*capture*/,
+ &info->shared_memory_fd,
+ &mmap_size);
+ if (ret < 0) {
+ // Fall back to non exclusive mode
+ info->shared_memory_fd = pcm_get_poll_fd(in->pcm);
+ } else {
+ if (mmap_size < buffer_size) {
+ step = "mmap";
+ goto exit;
+ }
+ // FIXME: indicate exclusive mode support by returning a negative buffer size
+ info->buffer_size_frames *= -1;
+ }
+
+ memset(info->shared_memory_address, 0, buffer_size);
ret = pcm_mmap_commit(in->pcm, 0, MMAP_PERIOD_SIZE);
if (ret < 0) {