summaryrefslogtreecommitdiff
authorxiaojing.huang <xiaojing.huang@amlogic.com>2018-05-04 15:13:31 (GMT)
committer xiaojing.huang <xiaojing.huang@amlogic.com>2018-05-04 15:13:58 (GMT)
commit3f7ef8a9461b5cadaaad0f3ccf81bbaf4567f215 (patch)
tree1c0ed9e59c74f7d63d9d19f4bfdf900c165c5682
parent9a85caf05941e1c758f4450221ab277f97611720 (diff)
downloadamlogic-o-amlogic.zip
amlogic-o-amlogic.tar.gz
amlogic-o-amlogic.tar.bz2
fix Google assistant can't work via mic after switching HDMI input
PD#165452 Change-Id: I88c84c67b08dddae94a1684e91e85b2f9b39aba9
Diffstat
-rwxr-xr-x[-rw-r--r--]audio/audio_hal/aml_hw_mixer.c41
-rwxr-xr-x[-rw-r--r--]audio/audio_hal/audio_hw.c130
2 files changed, 99 insertions, 72 deletions
diff --git a/audio/audio_hal/aml_hw_mixer.c b/audio/audio_hal/aml_hw_mixer.c
index d725a4f..2928fc7 100644..100755
--- a/audio/audio_hal/aml_hw_mixer.c
+++ b/audio/audio_hal/aml_hw_mixer.c
@@ -86,12 +86,15 @@ int aml_hw_mixer_write(struct aml_hw_mixer *mixer, const void *w_buf, uint size)
unsigned write_size = size;
unsigned tail = 0;
+ if (!mixer->start_buf)
+ return size;
pthread_mutex_lock(&mixer->lock);
space = aml_hw_mixer_get_space(mixer);
+ space &= ~63;
if (space < size) {
- ALOGI("write data no space,space %d,size %d,rp %d,wp %d,reset all ptr\n", space, size, mixer->rp, mixer->wp);
- mixer->wp = 0;
- mixer->rp = 0;
+ // ALOGI("write data no space,space %d,size %d,rp %d,wp %d,reset all ptr\n", space, size, mixer->rp, mixer->wp);
+ // mixer->wp = 0;
+ // mixer->rp = 0;
}
//TODO
if (write_size > space) {
@@ -110,7 +113,7 @@ int aml_hw_mixer_write(struct aml_hw_mixer *mixer, const void *w_buf, uint size)
}
pthread_mutex_unlock(&mixer->lock);
- return size;
+ return write_size;
}
static inline short CLIPSHORT(int r)
{
@@ -118,11 +121,19 @@ static inline short CLIPSHORT(int r)
(r < -0x8000) ? 0x8000 :
r;
}
-
+static inline int CLIPINT(int r)
+{
+ /*
+ return (r > 0x7fffffff) ? 0x7fffffff :
+ (r < -0x80000000) ? 0x80000000 :
+ r;
+ */
+ return r;
+}
int aml_hw_mixer_mixing(struct aml_hw_mixer *mixer, void *mbuf, int size)
{
- int16_t *main_buf = (int16_t *)mbuf;
- int16_t *cached_buf;
+ int32_t *main_buf = (int32_t *)mbuf;
+ int32_t *cached_buf;
int32_t read_size = size;
int32_t cached_size = 0;
int32_t tail = 0, tmp;
@@ -140,24 +151,24 @@ int aml_hw_mixer_mixing(struct aml_hw_mixer *mixer, void *mbuf, int size)
return 0;
}
- cached_buf = (int16_t *)(mixer->start_buf + mixer->rp);
+ cached_buf = (int32_t *)(mixer->start_buf + mixer->rp);
if (read_size + mixer->rp > mixer->buf_size) {
tail = mixer->buf_size - mixer->rp;
- for (i = 0; i < tail/2; i++) {
+ for (i = 0; i < tail/4; i++) {
tmp = *main_buf + *cached_buf++;
- *main_buf++ = CLIPSHORT(tmp);
+ *main_buf++ = CLIPINT(tmp);
}
read_size -= tail;
- cached_buf = (int16_t *)mixer->start_buf;
- for (i = 0; i < read_size/2; i++) {
+ cached_buf = (int32_t *)mixer->start_buf;
+ for (i = 0; i < read_size; i++) {
tmp = *main_buf + *cached_buf++;
- *main_buf++ = CLIPSHORT(tmp);
+ *main_buf++ = CLIPINT(tmp);
}
mixer->rp = read_size;
} else {
- for (i = 0; i < read_size/2; i++) {
+ for (i = 0; i < read_size/4; i++) {
tmp = *main_buf + *cached_buf++;
- *main_buf++ = CLIPSHORT(tmp);
+ *main_buf++ = CLIPINT(tmp);
}
mixer->rp += read_size;
mixer->rp %= AML_HW_MIXER_BUF_SIZE;
diff --git a/audio/audio_hal/audio_hw.c b/audio/audio_hal/audio_hw.c
index 1117557..aa70136 100644..100755
--- a/audio/audio_hal/audio_hw.c
+++ b/audio/audio_hal/audio_hw.c
@@ -70,9 +70,9 @@
#include <SPDIFEncoderAD.h>
#include "audio_hw_ms12.h"
#endif
-/*#if defined(IS_ATOM_PROJECT)
+/* #if defined(IS_ATOM_PROJECT)
#include "audio_aec_process.h"
-#endif*/
+#endif */
/* set proprety */
#ifdef ENABLE_HUITONG
@@ -616,22 +616,21 @@ static int check_input_parameters(uint32_t sample_rate, audio_format_t format, i
return 0;
}
-static size_t get_input_buffer_size (unsigned int period_size, uint32_t sample_rate, audio_format_t format, int channel_count)
+static size_t get_input_buffer_size(unsigned int period_size, uint32_t sample_rate, audio_format_t format, int channel_count)
{
size_t size;
/* take resampling into account and return the closest majoring
multiple of 16 frames, as audioflinger expects audio buffers to
be a multiple of 16 frames */
- if (period_size == 0) {
+ if (period_size == 0)
period_size = (pcm_config_in.period_size * sample_rate) / pcm_config_in.rate;
- }
- size = (period_size +15)/16*16;
+ size = (period_size + 15) / 16 * 16;
if (format == AUDIO_FORMAT_PCM_32_BIT)
- return size * channel_count * sizeof(int32_t);
- else
- return size * channel_count * sizeof (int16_t);
+ return size * channel_count * sizeof(int32_t);
+ else
+ return size * channel_count * sizeof(int16_t);
}
static uint32_t out_get_sample_rate(const struct audio_stream *stream)
@@ -1153,11 +1152,11 @@ static char *out_get_parameters (const struct audio_stream *stream, const char *
if (out->flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
ALOGI ("Amlogic - return hard coded sample_rate list for primary output stream.\n");
cap = strdup ("sup_sampling_rates=8000|11025|16000|22050|24000|32000|44100|48000");
- } else if (out->out_device & AUDIO_DEVICE_OUT_SPDIF){
- cap = strdup ("sup_sampling_rates=32000|44100|48000");
} else {
if (out->out_device & AUDIO_DEVICE_OUT_HDMI_ARC) {
cap = (char *) strdup_hdmi_arc_cap_default (AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES, format);
+ } else if (out->out_device & AUDIO_DEVICE_OUT_SPDIF){
+ cap = strdup ("sup_sampling_rates=32000|44100|48000");
} else {
cap = (char *) get_hdmi_sink_cap (AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES,format);
}
@@ -2670,6 +2669,10 @@ static int start_input_stream(struct aml_stream_in *in)
}
/* check to update port */
port = alsa_device_get_pcm_index(port);
+#if defined(IS_ATOM_PROJECT)
+ if (in->device & AUDIO_DEVICE_IN_BUILTIN_MIC)
+ port = 2;
+#endif
ALOGI("%s: card(%d), port(%d)", __func__, card, port);
/* this assumes routing is done previously */
in->pcm = pcm_open(card, port, PCM_IN, &in->config);
@@ -2703,8 +2706,8 @@ static int in_set_sample_rate(struct audio_stream *stream __unused, uint32_t rat
static size_t in_get_buffer_size(const struct audio_stream *stream)
{
- size_t size;
struct aml_stream_in *in = (struct aml_stream_in *)stream;
+ size_t size;
#if defined(IS_ATOM_PROJECT)
audio_channel_mask_t channel_mask = in->hal_channel_mask;
audio_format_t format = in->hal_format;
@@ -2713,20 +2716,21 @@ static size_t in_get_buffer_size(const struct audio_stream *stream)
channel_mask = AUDIO_CHANNEL_OUT_STEREO;
format = AUDIO_FORMAT_PCM_32_BIT;
}
- ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__,
- channel_mask, in->requested_rate, format);
- size = get_input_buffer_size(in->config.period_size, in->requested_rate,
- format,
- audio_channel_count_from_in_mask(channel_mask));
+ ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__,
+ channel_mask, in->requested_rate, format);
+ size = get_input_buffer_size(in->config.period_size, in->requested_rate,
+ format,
+ audio_channel_count_from_in_mask(channel_mask));
#else
- ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__,
- in->hal_channel_mask, in->requested_rate, in->hal_format);
- size = get_input_buffer_size(in->config.period_size, in->requested_rate,
- in->hal_format,
- audio_channel_count_from_in_mask(in->hal_channel_mask));
+ ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__,
+ in->hal_channel_mask, in->requested_rate, in->hal_format);
+ size = get_input_buffer_size(in->config.period_size, in->requested_rate,
+ in->hal_format,
+ audio_channel_count_from_in_mask(in->hal_channel_mask));
#endif
- ALOGD("%s: exit: buffer_size = %zu", __func__, size);
- return size;
+ ALOGD("%s: exit: buffer_size = %zu", __func__, size);
+
+ return size;
}
static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
@@ -2787,7 +2791,7 @@ static int in_standby(struct audio_stream *stream)
struct aml_stream_in *in = (struct aml_stream_in *)stream;
int status;
- if ((in->device & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_LINE)) && in->ref_count == 2) {
+ if ((in->device & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_LINE)) && in->ref_count == 2) {
ALOGD("%s: ref_count = %d", __func__, in->ref_count);
return 0;
}
@@ -2999,7 +3003,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte
struct aml_audio_parser *parser = adev->aml_parser;
int channel_count = audio_channel_count_from_in_mask(in->hal_channel_mask);
size_t in_frames = bytes / audio_stream_in_frame_size(&in->stream);
- size_t cur_in_bytes, cur_in_frames;
+ size_t cur_in_bytes, cur_in_frames;
int ret, in_mute = 0, parental_mute = 0;
/* acquiring hw device mutex systematically is useful if a low priority thread is waiting
@@ -3015,11 +3019,11 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte
if (ret < 0)
goto exit;
in->standby = 0;
-/*#if defined(IS_ATOM_PROJECT)
- if (in->device & AUDIO_DEVICE_IN_BUILTIN_MIC)
- adev->mic_running = 1;
-#endif*/
}
+/* #if defined(IS_ATOM_PROJECT)
+ if ((in->device & AUDIO_DEVICE_IN_BUILTIN_MIC) && !adev->mic_running)
+ adev->mic_running = 1;
+#endif */
/* if audio patch type is hdmi to mixer, check audio format from hdmi*/
if (adev->patch_src == SRC_HDMIIN && parser != NULL) {
@@ -3087,7 +3091,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte
mic_buf[2 * i] = tmp_buffer_8ch[8 * i + 6];
mic_buf[2 * i + 1] = tmp_buffer_8ch[8 * i + 7];
}
- /* if (in->device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ /* if (in->device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
int read_bytes = in->requested_rate == 16000 ? 60 + cur_in_bytes : 20 + cur_in_bytes;
if (adev->spk_buf_size < cur_in_bytes) {
ALOGI("%s: realloc spk_buf size from %zu to %zu", __func__, adev->spk_buf_size, cur_in_bytes);
@@ -3848,7 +3852,7 @@ static int adev_set_parameters (struct audio_hw_device *dev, const char *kvpairs
ret = aml_audio_output_routing (dev, adev->active_outport, true);
if (ret < 0)
ALOGE ("%s() output routing failed", __func__);
- goto exit;
+ goto exit;
}
ret = str_parms_get_str(parms, "spdif_raw_enable", value, sizeof(value));
if (ret >= 0) {
@@ -4128,17 +4132,19 @@ static int adev_get_mic_mute (const struct audio_hw_device *dev, bool *state)
static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev __unused,
const struct audio_config *config)
{
- size_t size;
int channel_count = audio_channel_count_from_in_mask(config->channel_mask);
+ size_t size;
- ALOGD("%s: channel_mask(%#x) rate(%d) format(%#x)", __func__,
+ ALOGD("%s: enter: channel_mask(%#x) rate(%d) format(%#x)", __func__,
config->channel_mask, config->sample_rate, config->format);
if (check_input_parameters(config->sample_rate, config->format, channel_count) < 0)
return -EINVAL;
-
- size = get_input_buffer_size(config->frame_count, config->sample_rate, config->format, channel_count);
-
+
+ size = get_input_buffer_size(config->frame_count, config->sample_rate, config->format, channel_count);
+
+ ALOGD("%s: exit: buffer_size = %zu", __func__, size);
+
return size;
}
@@ -4282,26 +4288,28 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
}
#endif
#if defined(IS_ATOM_PROJECT)
- if (aux_mic_devce) {
- in->config.channels = 8;
- in->config.format = PCM_FORMAT_S32_LE;
- adev->aux_mic_in = in;
- }
exit:
- if (aux_mic_devce & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- /* aec_spk_mic_init();
- if (!adev->spk_ring_buf.start_addr)
- ring_buffer_init(&adev->spk_ring_buf, 4 * (20 + 2 * 4 * DEFAULT_PLAYBACK_PERIOD_SIZE) * PLAYBACK_PERIOD_COUNT);
- else
- ring_buffer_reset(&adev->spk_ring_buf); */
- if (in->ref_count > 0) {
- in->requested_rate = config->sample_rate;
- in->hal_channel_mask = config->channel_mask;
- in->hal_format = config->format;
+ if (aux_mic_devce) {
+ if (in->ref_count == 0) {
+ in->config.channels = 8;
+ in->config.format = PCM_FORMAT_S32_LE;
+ adev->aux_mic_in = in;
+ }
+ if (aux_mic_devce & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ /* aec_spk_mic_init();
+ if (!adev->spk_ring_buf.start_addr)
+ ring_buffer_init(&adev->spk_ring_buf, 4 * (20 + 2 * 4 * DEFAULT_PLAYBACK_PERIOD_SIZE) * PLAYBACK_PERIOD_COUNT);
+ else
+ ring_buffer_reset(&adev->spk_ring_buf); */
+ if (in->ref_count > 0) {
+ in->requested_rate = config->sample_rate;
+ in->hal_channel_mask = config->channel_mask;
+ in->hal_format = config->format;
+ }
+ set_audio_source(LINEIN);
}
- }
- if (aux_mic_devce)
in->device |= aux_mic_devce;
+ }
in->ref_count++;
#endif
*stream_in = &in->stream;
@@ -5154,12 +5162,20 @@ ssize_t mixer_aux_buffer_write (struct audio_stream_out *stream, const void *buf
if (ret == 0)
bytes = used_size;
#else
- aml_hw_mixer_write (&adev->hw_mixer, buffer, bytes);
+ ret = aml_hw_mixer_write (&adev->hw_mixer, buffer, bytes);
+ if (ret == (int)bytes) {
+ usleep(bytes * 1000000 / audio_stream_out_frame_size (stream) /
+ out_get_sample_rate (&stream->common) * 15 / 16);
+ } else {
+ usleep(bytes * 1000000 / audio_stream_out_frame_size (stream) /
+ out_get_sample_rate (&stream->common) * 15 / 16)*2;
+ }
#endif
+ in_frames = ret/frame_size;
clock_gettime (CLOCK_MONOTONIC, &aml_out->timestamp);
aml_out->frame_write_sum += in_frames;
aml_out->last_frames_postion = aml_out->frame_write_sum;
- return bytes;
+ return ret;
}
ssize_t process_buffer_write(struct audio_stream_out *stream,
@@ -5959,7 +5975,7 @@ static int adev_create_audio_patch(struct audio_hw_device *dev,
// tell atv or dtv source and decide to create or not.
// One more case is ATV->ATV, should recreate audio patch.
if (input_src != ATV || (input_src == ATV && aml_dev->patch_src == SRC_ATV)) {
- set_audio_source (input_src);
+ set_audio_source(input_src);
ret = create_patch(dev, sources->ext.device.type, sinks->ext.device.type);
if (ret) {
ALOGE("%s: create patch failed", __func__);