Loading hal/audio_hw.c +76 −6 Original line number Diff line number Diff line Loading @@ -4384,6 +4384,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, struct audio_device *adev = out->dev; ssize_t ret = 0; int channels = 0; const size_t frame_size = audio_stream_out_frame_size(stream); const size_t frames = (frame_size != 0) ? bytes / frame_size : bytes; ATRACE_BEGIN("out_write"); lock_output_stream(out); Loading Loading @@ -4600,8 +4602,35 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, return ret; } else { if (out->pcm) { size_t bytes_to_write = bytes; if (out->muted) memset((void *)buffer, 0, bytes); ALOGV("%s: frames=%zu, frame_size=%zu, bytes_to_write=%zu", __func__, frames, frame_size, bytes_to_write); if (out->usecase == USECASE_INCALL_MUSIC_UPLINK) { size_t channel_count = audio_channel_count_from_out_mask(out->channel_mask); int16_t *src = (int16_t *)buffer; int16_t *dst = (int16_t *)buffer; LOG_ALWAYS_FATAL_IF(out->config.channels != 1 || channel_count != 2 || out->format != AUDIO_FORMAT_PCM_16_BIT, "out_write called for incall music use case with wrong properties"); /* * FIXME: this can be removed once audio flinger mixer supports * mono output */ /* * Code below goes over each frame in the buffer and adds both * L and R samples and then divides by 2 to convert to mono */ for (size_t i = 0; i < frames ; i++, dst++, src += 2) { *dst = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1); } bytes_to_write /= 2; } ALOGVV("%s: writing buffer (%zu bytes) to pcm device", __func__, bytes); Loading @@ -4611,12 +4640,11 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, ns = pcm_bytes_to_frames(out->pcm, bytes)*1000000000LL/ out->config.rate; bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime; request_out_focus(out, ns); bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime; if (use_mmap) ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes); ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes_to_write); else if (out->hal_op_format != out->hal_ip_format && out->convert_buffer != NULL) { Loading Loading @@ -4650,7 +4678,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, out_get_sample_rate(&out->stream.common)); ret = 0; } else ret = pcm_write(out->pcm, (void *)buffer, bytes); ret = pcm_write(out->pcm, (void *)buffer, bytes_to_write); } release_out_focus(out); Loading Loading @@ -6166,6 +6194,48 @@ int adev_open_output_stream(struct audio_hw_device *dev, create_offload_callback_thread(out); } else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) { switch (config->sample_rate) { case 0: out->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; break; case 8000: case 16000: case 48000: out->sample_rate = config->sample_rate; break; default: ALOGE("%s: Unsupported sampling rate %d for Incall Music", __func__, config->sample_rate); config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; ret = -EINVAL; goto error_open; } //FIXME: add support for MONO stream configuration when audioflinger mixer supports it switch (config->channel_mask) { case AUDIO_CHANNEL_NONE: case AUDIO_CHANNEL_OUT_STEREO: out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; break; default: ALOGE("%s: Unsupported channel mask %#x for Incall Music", __func__, config->channel_mask); config->channel_mask = AUDIO_CHANNEL_OUT_STEREO; ret = -EINVAL; goto error_open; } switch (config->format) { case AUDIO_FORMAT_DEFAULT: case AUDIO_FORMAT_PCM_16_BIT: out->format = AUDIO_FORMAT_PCM_16_BIT; break; default: ALOGE("%s: Unsupported format %#x for Incall Music", __func__, config->format); config->format = AUDIO_FORMAT_PCM_16_BIT; ret = -EINVAL; goto error_open; } ret = voice_extn_check_and_set_incall_music_usecase(adev, out); if (ret != 0) { ALOGE("%s: Incall music delivery usecase cannot be set error:%d", Loading hal/voice_extn/voice_extn.c +7 −18 Original line number Diff line number Diff line /* * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * Not a contribution. * * Copyright (C) 2013 The Android Open Source Project Loading Loading @@ -593,27 +593,16 @@ void voice_extn_in_get_parameters(struct stream_in *in, voice_extn_compress_voip_in_get_parameters(in, query, reply); } #ifdef INCALL_MUSIC_ENABLED int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev, struct stream_out *out) { uint32_t session_id = 0; session_id = get_session_id_with_state(adev, CALL_LOCAL_HOLD); if (session_id == VOICE_VSID) { out->usecase = USECASE_INCALL_MUSIC_UPLINK; } else if (session_id == VOICE2_VSID) { out->usecase = USECASE_INCALL_MUSIC_UPLINK2; } else { ALOGE("%s: Invalid session id %x", __func__, session_id); return -EINVAL; } out->config = pcm_config_incall_music; out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO; out->channel_mask = AUDIO_CHANNEL_OUT_MONO; //FIXME: add support for MONO stream configuration when audioflinger mixer supports it out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO; out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; out->config.rate = out->sample_rate; ALOGV("%s: mode=%d, usecase id=%d", __func__, adev->mode, out->usecase); return 0; } #endif hal/voice_extn/voice_extn.h +1 −6 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014, 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2014, 2016-2018, The Linux Foundation. All rights reserved. * Not a contribution. * * Copyright (C) 2013 The Android Open Source Project Loading Loading @@ -101,13 +101,8 @@ static void __unused voice_extn_out_get_parameters(struct stream_out *out __unus } #endif #ifdef INCALL_MUSIC_ENABLED int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev, struct stream_out *out); #else #define voice_extn_check_and_set_incall_music_usecase(adev, out) -ENOSYS #endif #ifdef COMPRESS_VOIP_ENABLED int voice_extn_compress_voip_close_output_stream(struct audio_stream *stream); int voice_extn_compress_voip_open_output_stream(struct stream_out *out); Loading Loading
hal/audio_hw.c +76 −6 Original line number Diff line number Diff line Loading @@ -4384,6 +4384,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, struct audio_device *adev = out->dev; ssize_t ret = 0; int channels = 0; const size_t frame_size = audio_stream_out_frame_size(stream); const size_t frames = (frame_size != 0) ? bytes / frame_size : bytes; ATRACE_BEGIN("out_write"); lock_output_stream(out); Loading Loading @@ -4600,8 +4602,35 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, return ret; } else { if (out->pcm) { size_t bytes_to_write = bytes; if (out->muted) memset((void *)buffer, 0, bytes); ALOGV("%s: frames=%zu, frame_size=%zu, bytes_to_write=%zu", __func__, frames, frame_size, bytes_to_write); if (out->usecase == USECASE_INCALL_MUSIC_UPLINK) { size_t channel_count = audio_channel_count_from_out_mask(out->channel_mask); int16_t *src = (int16_t *)buffer; int16_t *dst = (int16_t *)buffer; LOG_ALWAYS_FATAL_IF(out->config.channels != 1 || channel_count != 2 || out->format != AUDIO_FORMAT_PCM_16_BIT, "out_write called for incall music use case with wrong properties"); /* * FIXME: this can be removed once audio flinger mixer supports * mono output */ /* * Code below goes over each frame in the buffer and adds both * L and R samples and then divides by 2 to convert to mono */ for (size_t i = 0; i < frames ; i++, dst++, src += 2) { *dst = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1); } bytes_to_write /= 2; } ALOGVV("%s: writing buffer (%zu bytes) to pcm device", __func__, bytes); Loading @@ -4611,12 +4640,11 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, ns = pcm_bytes_to_frames(out->pcm, bytes)*1000000000LL/ out->config.rate; bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime; request_out_focus(out, ns); bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime; if (use_mmap) ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes); ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes_to_write); else if (out->hal_op_format != out->hal_ip_format && out->convert_buffer != NULL) { Loading Loading @@ -4650,7 +4678,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, out_get_sample_rate(&out->stream.common)); ret = 0; } else ret = pcm_write(out->pcm, (void *)buffer, bytes); ret = pcm_write(out->pcm, (void *)buffer, bytes_to_write); } release_out_focus(out); Loading Loading @@ -6166,6 +6194,48 @@ int adev_open_output_stream(struct audio_hw_device *dev, create_offload_callback_thread(out); } else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) { switch (config->sample_rate) { case 0: out->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; break; case 8000: case 16000: case 48000: out->sample_rate = config->sample_rate; break; default: ALOGE("%s: Unsupported sampling rate %d for Incall Music", __func__, config->sample_rate); config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; ret = -EINVAL; goto error_open; } //FIXME: add support for MONO stream configuration when audioflinger mixer supports it switch (config->channel_mask) { case AUDIO_CHANNEL_NONE: case AUDIO_CHANNEL_OUT_STEREO: out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; break; default: ALOGE("%s: Unsupported channel mask %#x for Incall Music", __func__, config->channel_mask); config->channel_mask = AUDIO_CHANNEL_OUT_STEREO; ret = -EINVAL; goto error_open; } switch (config->format) { case AUDIO_FORMAT_DEFAULT: case AUDIO_FORMAT_PCM_16_BIT: out->format = AUDIO_FORMAT_PCM_16_BIT; break; default: ALOGE("%s: Unsupported format %#x for Incall Music", __func__, config->format); config->format = AUDIO_FORMAT_PCM_16_BIT; ret = -EINVAL; goto error_open; } ret = voice_extn_check_and_set_incall_music_usecase(adev, out); if (ret != 0) { ALOGE("%s: Incall music delivery usecase cannot be set error:%d", Loading
hal/voice_extn/voice_extn.c +7 −18 Original line number Diff line number Diff line /* * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * Not a contribution. * * Copyright (C) 2013 The Android Open Source Project Loading Loading @@ -593,27 +593,16 @@ void voice_extn_in_get_parameters(struct stream_in *in, voice_extn_compress_voip_in_get_parameters(in, query, reply); } #ifdef INCALL_MUSIC_ENABLED int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev, struct stream_out *out) { uint32_t session_id = 0; session_id = get_session_id_with_state(adev, CALL_LOCAL_HOLD); if (session_id == VOICE_VSID) { out->usecase = USECASE_INCALL_MUSIC_UPLINK; } else if (session_id == VOICE2_VSID) { out->usecase = USECASE_INCALL_MUSIC_UPLINK2; } else { ALOGE("%s: Invalid session id %x", __func__, session_id); return -EINVAL; } out->config = pcm_config_incall_music; out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO; out->channel_mask = AUDIO_CHANNEL_OUT_MONO; //FIXME: add support for MONO stream configuration when audioflinger mixer supports it out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO; out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; out->config.rate = out->sample_rate; ALOGV("%s: mode=%d, usecase id=%d", __func__, adev->mode, out->usecase); return 0; } #endif
hal/voice_extn/voice_extn.h +1 −6 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014, 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2014, 2016-2018, The Linux Foundation. All rights reserved. * Not a contribution. * * Copyright (C) 2013 The Android Open Source Project Loading Loading @@ -101,13 +101,8 @@ static void __unused voice_extn_out_get_parameters(struct stream_out *out __unus } #endif #ifdef INCALL_MUSIC_ENABLED int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev, struct stream_out *out); #else #define voice_extn_check_and_set_incall_music_usecase(adev, out) -ENOSYS #endif #ifdef COMPRESS_VOIP_ENABLED int voice_extn_compress_voip_close_output_stream(struct audio_stream *stream); int voice_extn_compress_voip_open_output_stream(struct stream_out *out); Loading