Loading hal/audio_extn/audio_extn.c +70 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ #define MAX_SLEEP_RETRY 100 #define WIFI_INIT_WAIT_SLEEP 50 #define MAX_NUM_CHANNELS 8 #define Q14_GAIN_UNITY 0x4000 struct audio_extn_module { bool anc_enabled; Loading Loading @@ -301,6 +303,74 @@ void audio_extn_customstereo_set_parameters(struct audio_device *adev, ALOGV("%s: Setting custom stereo state success", __func__); } } void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out) { struct audio_device *adev = out->dev; struct mixer_ctl *ctl; char mixer_ctl_name[128]; int cust_ch_mixer_cfg[128], len = 0; int ip_channel_cnt = audio_channel_count_from_out_mask(out->channel_mask); int pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK); int op_channel_cnt = 2; int i, j, err; ALOGV("%s", __func__); if (!out->started) { out->set_dual_mono = true; goto exit; } ALOGD("%s: i/p channel count %d, o/p channel count %d, pcm id %d", __func__, ip_channel_cnt, op_channel_cnt, pcm_device_id); snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Audio Stream %d Channel Mix Cfg", pcm_device_id); ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); if (!ctl) { ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s", __func__, mixer_ctl_name); goto exit; } /* Output channel count corresponds to backend configuration channels. * Input channel count corresponds to ASM session channels. * Set params is called with channels that need to be selected from * input to generate output. * ex: "8,2" to downmix from 8 to 2 i.e. to downmix from 8 to 2, * * This mixer control takes values in the following sequence: * - input channel count(m) * - output channel count(n) * - weight coeff for [out ch#1, in ch#1] * .... * - weight coeff for [out ch#1, in ch#m] * * - weight coeff for [out ch#2, in ch#1] * .... * - weight coeff for [out ch#2, in ch#m] * * - weight coeff for [out ch#n, in ch#1] * .... * - weight coeff for [out ch#n, in ch#m] * * To get dualmono ouptu weightage coeff is calculated as Unity gain * divided by number of input channels. */ cust_ch_mixer_cfg[len++] = ip_channel_cnt; cust_ch_mixer_cfg[len++] = op_channel_cnt; for (i = 0; i < op_channel_cnt; i++) { for (j = 0; j < ip_channel_cnt; j++) { cust_ch_mixer_cfg[len++] = Q14_GAIN_UNITY/ip_channel_cnt; } } err = mixer_ctl_set_array(ctl, cust_ch_mixer_cfg, len); if (err) ALOGE("%s: ERROR. Mixer ctl set failed", __func__); exit: return; } #endif /* CUSTOM_STEREO_ENABLED */ #ifndef DTS_EAGLE Loading hal/audio_extn/audio_extn.h +7 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ #include "ip_hdlr_intf.h" #include "battery_listener.h" #define AUDIO_PARAMETER_DUAL_MONO "dual_mono" #ifndef AFE_PROXY_ENABLED #define AUDIO_DEVICE_OUT_PROXY 0x40000 #endif Loading Loading @@ -1132,4 +1134,9 @@ int audio_extn_ext_hw_plugin_get_mic_mute(void *plugin, bool *mute); int audio_extn_ext_hw_plugin_set_audio_gain(void *plugin, struct audio_usecase *usecase, uint32_t gain); #endif #ifndef CUSTOM_STEREO_ENABLED #define audio_extn_send_dual_mono_mixing_coefficients(out) (0) #else void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out); #endif #endif /* AUDIO_EXTN_H */ hal/audio_hw.c +12 −2 Original line number Diff line number Diff line Loading @@ -3213,6 +3213,8 @@ int start_output_stream(struct stream_out *out) } break; } platform_set_stream_channel_map(adev->platform, out->channel_mask, out->pcm_device_id, &out->channel_map_param.channel_map[0]); ALOGV("%s: pcm_prepare", __func__); if (pcm_is_ready(out->pcm)) { Loading @@ -3226,8 +3228,6 @@ int start_output_stream(struct stream_out *out) goto error_open; } } platform_set_stream_channel_map(adev->platform, out->channel_mask, out->pcm_device_id, &out->channel_map_param.channel_map[0]); // apply volume for voip playback after path is set up if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) out_set_voip_volume(&out->stream, out->volume_l, out->volume_r); Loading Loading @@ -4023,6 +4023,13 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) pthread_mutex_unlock(&out->lock); } err = str_parms_get_str(parms, AUDIO_PARAMETER_DUAL_MONO, value, sizeof(value)); if (err >= 0) { if (!strncmp("true", value, sizeof("true")) || atoi(value)) audio_extn_send_dual_mono_mixing_coefficients(out); } err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_PROFILE, value, sizeof(value)); if (err >= 0) { strlcpy(out->profile, value, sizeof(out->profile)); Loading Loading @@ -4633,6 +4640,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, ret = -EINVAL; goto exit; } if (out->set_dual_mono) audio_extn_send_dual_mono_mixing_coefficients(out); } if (adev->is_channel_status_set == false && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)){ Loading Loading @@ -6005,6 +6014,7 @@ int adev_open_output_stream(struct audio_hw_device *dev, out->a2dp_compress_mute = false; out->hal_output_suspend_supported = 0; out->dynamic_pm_qos_config_supported = 0; out->set_dual_mono = false; if ((flags & AUDIO_OUTPUT_FLAG_BD) && (property_get_bool("vendor.audio.matrix.limiter.enable", false))) Loading hal/audio_hw.h +1 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,7 @@ struct stream_out { bool stream_config_changed; mix_matrix_params_t pan_scale_params; mix_matrix_params_t downmix_params; bool set_dual_mono; }; struct stream_in { Loading qahw_api/test/qahw_playback_test.c +14 −1 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ static void init_streams(void) stream_param[i].ethread_data = nullptr; stream_param[i].device_url = "stream"; stream_param[i].play_later = false; stream_param[i].set_params = nullptr; pthread_mutex_init(&stream_param[i].write_lock, (const pthread_mutexattr_t *)NULL); pthread_cond_init(&stream_param[i].write_cond, (const pthread_condattr_t *) NULL); Loading Loading @@ -797,6 +798,14 @@ void *start_stream_playback (void* stream_data) if (bytes_to_read <= 0) read_complete_file = true; if (params->set_params) { rc = qahw_out_set_parameters(params->out_handle, params->set_params); if (rc) { fprintf(log_file, "stream %s: failed to set kvpairs\n", params->set_params); fprintf(stderr, "stream %s: failed to set kvpairs\n", params->set_params); } } while (!exit && !stop_playback) { if (!bytes_remaining) { fprintf(log_file, "\nstream %d: reading bytes %zd\n", params->stream_index, bytes_wanted); Loading Loading @@ -2095,7 +2104,7 @@ int main(int argc, char* argv[]) { while ((opt = getopt_long(argc, argv, "-f:r:c:b:d:s:v:V:l:t:a:w:k:PD:KF:Ee:A:u:m:S:C:p::x:y:qQh:i:h:g:", "-f:r:c:b:d:s:v:V:l:t:a:w:k:PD:KF:Ee:A:u:m:S:C:p::x:y:qQh:i:h:g:O:", long_options, &option_index)) != -1) { Loading Loading @@ -2233,6 +2242,9 @@ int main(int argc, char* argv[]) { case 'K': kpi_mode = true; break; case 'O': stream_param[i].set_params = optarg; break; case 'F': stream_param[i].flags = atoll(optarg); stream_param[i].flags_set = true; Loading Loading @@ -2533,6 +2545,7 @@ int main(int argc, char* argv[]) { fprintf(log_file, "stream %d: Bitwidth:%d\n", stream->stream_index, stream->config.offload_info.bit_width); fprintf(log_file, "stream %d: AAC Format Type:%d\n", stream->stream_index, stream->aac_fmt_type); fprintf(log_file, "stream %d: Kvpair Values:%s\n", stream->stream_index, stream->kvpair_values); fprintf(log_file, "stream %d: set params Values:%s\n", stream->stream_index, stream->set_params); fprintf(log_file, "Log file:%s\n", log_filename); fprintf(log_file, "Volume level:%f\n", vol_level); Loading Loading
hal/audio_extn/audio_extn.c +70 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ #define MAX_SLEEP_RETRY 100 #define WIFI_INIT_WAIT_SLEEP 50 #define MAX_NUM_CHANNELS 8 #define Q14_GAIN_UNITY 0x4000 struct audio_extn_module { bool anc_enabled; Loading Loading @@ -301,6 +303,74 @@ void audio_extn_customstereo_set_parameters(struct audio_device *adev, ALOGV("%s: Setting custom stereo state success", __func__); } } void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out) { struct audio_device *adev = out->dev; struct mixer_ctl *ctl; char mixer_ctl_name[128]; int cust_ch_mixer_cfg[128], len = 0; int ip_channel_cnt = audio_channel_count_from_out_mask(out->channel_mask); int pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK); int op_channel_cnt = 2; int i, j, err; ALOGV("%s", __func__); if (!out->started) { out->set_dual_mono = true; goto exit; } ALOGD("%s: i/p channel count %d, o/p channel count %d, pcm id %d", __func__, ip_channel_cnt, op_channel_cnt, pcm_device_id); snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Audio Stream %d Channel Mix Cfg", pcm_device_id); ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); if (!ctl) { ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s", __func__, mixer_ctl_name); goto exit; } /* Output channel count corresponds to backend configuration channels. * Input channel count corresponds to ASM session channels. * Set params is called with channels that need to be selected from * input to generate output. * ex: "8,2" to downmix from 8 to 2 i.e. to downmix from 8 to 2, * * This mixer control takes values in the following sequence: * - input channel count(m) * - output channel count(n) * - weight coeff for [out ch#1, in ch#1] * .... * - weight coeff for [out ch#1, in ch#m] * * - weight coeff for [out ch#2, in ch#1] * .... * - weight coeff for [out ch#2, in ch#m] * * - weight coeff for [out ch#n, in ch#1] * .... * - weight coeff for [out ch#n, in ch#m] * * To get dualmono ouptu weightage coeff is calculated as Unity gain * divided by number of input channels. */ cust_ch_mixer_cfg[len++] = ip_channel_cnt; cust_ch_mixer_cfg[len++] = op_channel_cnt; for (i = 0; i < op_channel_cnt; i++) { for (j = 0; j < ip_channel_cnt; j++) { cust_ch_mixer_cfg[len++] = Q14_GAIN_UNITY/ip_channel_cnt; } } err = mixer_ctl_set_array(ctl, cust_ch_mixer_cfg, len); if (err) ALOGE("%s: ERROR. Mixer ctl set failed", __func__); exit: return; } #endif /* CUSTOM_STEREO_ENABLED */ #ifndef DTS_EAGLE Loading
hal/audio_extn/audio_extn.h +7 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ #include "ip_hdlr_intf.h" #include "battery_listener.h" #define AUDIO_PARAMETER_DUAL_MONO "dual_mono" #ifndef AFE_PROXY_ENABLED #define AUDIO_DEVICE_OUT_PROXY 0x40000 #endif Loading Loading @@ -1132,4 +1134,9 @@ int audio_extn_ext_hw_plugin_get_mic_mute(void *plugin, bool *mute); int audio_extn_ext_hw_plugin_set_audio_gain(void *plugin, struct audio_usecase *usecase, uint32_t gain); #endif #ifndef CUSTOM_STEREO_ENABLED #define audio_extn_send_dual_mono_mixing_coefficients(out) (0) #else void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out); #endif #endif /* AUDIO_EXTN_H */
hal/audio_hw.c +12 −2 Original line number Diff line number Diff line Loading @@ -3213,6 +3213,8 @@ int start_output_stream(struct stream_out *out) } break; } platform_set_stream_channel_map(adev->platform, out->channel_mask, out->pcm_device_id, &out->channel_map_param.channel_map[0]); ALOGV("%s: pcm_prepare", __func__); if (pcm_is_ready(out->pcm)) { Loading @@ -3226,8 +3228,6 @@ int start_output_stream(struct stream_out *out) goto error_open; } } platform_set_stream_channel_map(adev->platform, out->channel_mask, out->pcm_device_id, &out->channel_map_param.channel_map[0]); // apply volume for voip playback after path is set up if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) out_set_voip_volume(&out->stream, out->volume_l, out->volume_r); Loading Loading @@ -4023,6 +4023,13 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) pthread_mutex_unlock(&out->lock); } err = str_parms_get_str(parms, AUDIO_PARAMETER_DUAL_MONO, value, sizeof(value)); if (err >= 0) { if (!strncmp("true", value, sizeof("true")) || atoi(value)) audio_extn_send_dual_mono_mixing_coefficients(out); } err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_PROFILE, value, sizeof(value)); if (err >= 0) { strlcpy(out->profile, value, sizeof(out->profile)); Loading Loading @@ -4633,6 +4640,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, ret = -EINVAL; goto exit; } if (out->set_dual_mono) audio_extn_send_dual_mono_mixing_coefficients(out); } if (adev->is_channel_status_set == false && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)){ Loading Loading @@ -6005,6 +6014,7 @@ int adev_open_output_stream(struct audio_hw_device *dev, out->a2dp_compress_mute = false; out->hal_output_suspend_supported = 0; out->dynamic_pm_qos_config_supported = 0; out->set_dual_mono = false; if ((flags & AUDIO_OUTPUT_FLAG_BD) && (property_get_bool("vendor.audio.matrix.limiter.enable", false))) Loading
hal/audio_hw.h +1 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,7 @@ struct stream_out { bool stream_config_changed; mix_matrix_params_t pan_scale_params; mix_matrix_params_t downmix_params; bool set_dual_mono; }; struct stream_in { Loading
qahw_api/test/qahw_playback_test.c +14 −1 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ static void init_streams(void) stream_param[i].ethread_data = nullptr; stream_param[i].device_url = "stream"; stream_param[i].play_later = false; stream_param[i].set_params = nullptr; pthread_mutex_init(&stream_param[i].write_lock, (const pthread_mutexattr_t *)NULL); pthread_cond_init(&stream_param[i].write_cond, (const pthread_condattr_t *) NULL); Loading Loading @@ -797,6 +798,14 @@ void *start_stream_playback (void* stream_data) if (bytes_to_read <= 0) read_complete_file = true; if (params->set_params) { rc = qahw_out_set_parameters(params->out_handle, params->set_params); if (rc) { fprintf(log_file, "stream %s: failed to set kvpairs\n", params->set_params); fprintf(stderr, "stream %s: failed to set kvpairs\n", params->set_params); } } while (!exit && !stop_playback) { if (!bytes_remaining) { fprintf(log_file, "\nstream %d: reading bytes %zd\n", params->stream_index, bytes_wanted); Loading Loading @@ -2095,7 +2104,7 @@ int main(int argc, char* argv[]) { while ((opt = getopt_long(argc, argv, "-f:r:c:b:d:s:v:V:l:t:a:w:k:PD:KF:Ee:A:u:m:S:C:p::x:y:qQh:i:h:g:", "-f:r:c:b:d:s:v:V:l:t:a:w:k:PD:KF:Ee:A:u:m:S:C:p::x:y:qQh:i:h:g:O:", long_options, &option_index)) != -1) { Loading Loading @@ -2233,6 +2242,9 @@ int main(int argc, char* argv[]) { case 'K': kpi_mode = true; break; case 'O': stream_param[i].set_params = optarg; break; case 'F': stream_param[i].flags = atoll(optarg); stream_param[i].flags_set = true; Loading Loading @@ -2533,6 +2545,7 @@ int main(int argc, char* argv[]) { fprintf(log_file, "stream %d: Bitwidth:%d\n", stream->stream_index, stream->config.offload_info.bit_width); fprintf(log_file, "stream %d: AAC Format Type:%d\n", stream->stream_index, stream->aac_fmt_type); fprintf(log_file, "stream %d: Kvpair Values:%s\n", stream->stream_index, stream->kvpair_values); fprintf(log_file, "stream %d: set params Values:%s\n", stream->stream_index, stream->set_params); fprintf(log_file, "Log file:%s\n", log_filename); fprintf(log_file, "Volume level:%f\n", vol_level); Loading