/* * Copyright (C) 2017 Amlogic Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "audio_control" //#define LOG_NDEBUG 0 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "aml_audio_timer.h" #include "aml_malloc_debug.h" #include "aml_audio_stream.h" #include "audio_hw_ms12_v2.h" #include "audio_hw_ms12_common.h" #include "audio_hw_utils.h" #include "dolby_lib_api.h" #include #include "tv_patch_format_parser.h" #include "aml_capture_output.h" #include "audio_controls_utils.h" #define AUDIO_CONTROL_CAPTURE_OPEN "cap_buffer=cap_for_lge,24576" #define AUDIO_CONTROL_CAPTURE_CLOSE "cap_buffer=cap_for_lge,0" aml_audio_control g_actrl; aml_audio_control* get_audio_control(void) { return &g_actrl; } static aml_audio_patch_handle g_ptle; static const char* outputMaskType2Str(audio_output_type_e type) { ENUM_TYPE_TO_STR_START("AUDIO_OUTPUT_TYPE_"); ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_NONE) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_SPK) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_OPTIC) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_OPTIC_LG) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_BLUETOOTH) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_HP) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_ARC) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_WISA) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_SE_BT) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_CAPTURE) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_SE_ARC) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_BT_SUR) ENUM_TYPE_TO_STR(AUDIO_OUTPUT_TYPE_MAX) ENUM_TYPE_TO_STR_END } void parse_earc_coding_type(int codec_type, int *coding_type) { switch (codec_type) { case SNDOUT_CODEC_PCM: *coding_type = EARC_STEREO_LPCM; break; case SNDOUT_CODEC_AC3: *coding_type = EARC_AC3; break; case SNDOUT_CODEC_AAC: *coding_type = EARC_UNDEFINED; break; case SNDOUT_CODEC_DTS: *coding_type = EARC_DTS; break; case SNDOUT_CODEC_EAC3: *coding_type = EARC_EAC3; break; case SNDOUT_CODEC_TRUEHD: *coding_type = EARC_MLP; break; case SNDOUT_CODEC_MAT2PCM: *coding_type = EARC_MLP; break; case SNDOUT_CODEC_DTSHD: *coding_type = EARC_DTS_HD; break; case SNDOUT_CODEC_MPEG4_AAC: *coding_type = EARC_UNDEFINED; break; default: break; } } static void set_optput_device_gain(output_device_idx_e output_type, int vol) { struct audio_port_config config; struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); memset(&config, 0, sizeof(config)); config.type = AUDIO_PORT_TYPE_DEVICE; config.config_mask = AUDIO_PORT_CONFIG_GAIN; config.role = AUDIO_PORT_ROLE_SINK; if (output_type == OUTPUT_DEVICE_SPK) { config.ext.device.type = AUDIO_DEVICE_OUT_SPEAKER; } else if (output_type == OUTPUT_DEVICE_HP) { config.ext.device.type = AUDIO_DEVICE_OUT_WIRED_HEADPHONE; } else if (output_type == OUTPUT_DEVICE_ARC) { if (is_STB(aml_dev)) { aml_dev->hw_device.set_master_volume(&aml_dev->hw_device, (float)(vol/100.0)); return; } else config.ext.device.type = AUDIO_DEVICE_OUT_HDMI_ARC; } else if (output_type == OUTPUT_DEVICE_OPTIC || output_type == OUTPUT_DEVICE_OPTIC_LG) { config.ext.device.type = AUDIO_DEVICE_OUT_SPDIF; } else if (output_type == OUTPUT_DEVICE_BLUETOOTH) { config.ext.device.type = AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; } else if (output_type == OUTPUT_DEVICE_SE_BT) { config.ext.device.type = AUDIO_DEVICE_OUT_BLUETOOTH_SCO; } else if (output_type == OUTPUT_DEVICE_SE_BT_SUR) { config.ext.device.type = OUTPORT_BT_SCO_HEADSET; } config.gain.values[0] = AmplToDb(vol/100.0) * 100; aml_dev->hw_device.set_audio_port_config(&aml_dev->hw_device, &config); } static int map_source_to_audio_device_type(input_source_type_e source_type) { int ret = -1; switch (source_type) { case INPUT_SOURCE_ATV: ret = AUDIO_DEVICE_IN_FM_TUNER; break; case INPUT_SOURCE_DTV: ret = AUDIO_DEVICE_IN_TV_TUNER; break; case INPUT_SOURCE_AV: ret = AUDIO_DEVICE_IN_LINE; break; case INPUT_SOURCE_HDMI: ret = AUDIO_DEVICE_IN_HDMI; break; default: ret = AUDIO_DEVICE_IN_LINE; break; } return ret; } static void mute_amixer_by_id(int device_id, int mute) { aml_audio_control *aml_actrl = get_audio_control(); aml_actrl->amixer_mute[device_id] = mute; if (mute) { aml_actrl->amixer_gain[device_id].target_gain = 0; } else { aml_actrl->amixer_gain[device_id].target_gain = aml_actrl->amixer_gain[device_id].save_gain; } // when mute or unmute , we fadeing 5ms aml_actrl->amixer_gain[device_id].fade_frames = 5 * 48;// YY to do : duration * sample_rate, but now I do not know the sample rate aml_actrl->amixer_gain[device_id].gain_step = (aml_actrl->amixer_gain[device_id].target_gain - aml_actrl->amixer_gain[device_id].current_gain) / aml_actrl->amixer_gain[device_id].fade_frames; ALOGI("[%s:%d] device_id(%d) mute(%d) target_gain(%f) current_gain(%f) fade_frames(%d) gain_step(%f)", __FUNCTION__, __LINE__, device_id, mute, aml_actrl->amixer_gain[device_id].target_gain, aml_actrl->amixer_gain[device_id].current_gain, aml_actrl->amixer_gain[device_id].fade_frames, aml_actrl->amixer_gain[device_id].gain_step); } int get_set_audio_handle(input_source_type_e source_type, audio_patch_handle_t handle_id, int mode) { if (mode) { switch (source_type) { case INPUT_SOURCE_ATV : g_ptle.atv_patch_handle = handle_id; break; case INPUT_SOURCE_DTV : g_ptle.dtv_patch_handle = handle_id; break; case INPUT_SOURCE_AV : g_ptle.av_patch_handle = handle_id; break; case INPUT_SOURCE_HDMI : g_ptle.hdmi_patch_handle = handle_id; break; default: break; } } else { switch (source_type) { case INPUT_SOURCE_ATV : return g_ptle.atv_patch_handle; case INPUT_SOURCE_DTV : return g_ptle.dtv_patch_handle; case INPUT_SOURCE_AV : return g_ptle.av_patch_handle; case INPUT_SOURCE_HDMI : return g_ptle.hdmi_patch_handle; default: break; } } return 0; } static void mapping_codec_from_kernel_to_hal(adec_src_codec_type_t adec_codec, audio_format_t* hal_codec) { switch (adec_codec) { case ADEC_CODEC_PCM: case ADEC_CODEC_SIF: case ADEC_CODEC_SIF_BTSC: case ADEC_CODEC_SIF_A2: *hal_codec = AUDIO_FORMAT_PCM_16_BIT; break; case ADEC_CODEC_AC3: *hal_codec = AUDIO_FORMAT_AC3; break; case ADEC_CODEC_EAC3: case ADEC_CODEC_EAC3_ATMOS: *hal_codec = AUDIO_FORMAT_E_AC3; break; case ADEC_CODEC_AC4: case ADEC_CODEC_AC4_ATMOS: *hal_codec = AUDIO_FORMAT_AC4; break; case ADEC_CODEC_MAT: case ADEC_CODEC_MAT_ATMOS: *hal_codec = AUDIO_FORMAT_MAT; break; case ADEC_CODEC_TRUEHD: case ADEC_CODEC_TRUEHD_ATMOS: *hal_codec = AUDIO_FORMAT_DOLBY_TRUEHD; break; case ADEC_CODEC_AAC: *hal_codec = AUDIO_FORMAT_AAC; break; case ADEC_CODEC_HEAAC: *hal_codec = AUDIO_FORMAT_HE_AAC_V1; break; case ADEC_CODEC_MPEG: case ADEC_CODEC_MPEG_H: *hal_codec = AUDIO_FORMAT_MP3;// to do : ?? break; case ADEC_CODEC_DRA: *hal_codec = AUDIO_FORMAT_PCM_16_BIT;// to do : ?? break; case ADEC_CODEC_DTS: case ADEC_CODEC_DTS_HD_MA: case ADEC_CODEC_DTS_EXPRESS: case ADEC_CODEC_DTS_CD: *hal_codec = AUDIO_FORMAT_DTS; break; default: *hal_codec = AUDIO_FORMAT_PCM_16_BIT; break; } } static int source_connect(input_source_type_e source_type) { struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); aml_audio_control *aml_actrl = get_audio_control(); struct audio_port_config source; struct audio_port_config sink; int ret = -1; memset(&source, 0 , sizeof(struct audio_port_config)); source.id = 1; source.role = AUDIO_PORT_ROLE_SOURCE; source.type = AUDIO_PORT_TYPE_DEVICE; source.ext.device.type = map_source_to_audio_device_type(source_type); memset(&sink, 0 , sizeof(struct audio_port_config)); sink.id = 2; sink.role = AUDIO_PORT_ROLE_SINK; sink.type = AUDIO_PORT_TYPE_DEVICE; sink.ext.device.type = AUDIO_DEVICE_OUT_SPEAKER; ret = aml_dev->hw_device.create_audio_patch(&aml_dev->hw_device, 1, &source, 1, &sink, &aml_actrl->patch_handle); get_set_audio_handle(source_type, aml_actrl->patch_handle, 1); if (0 == ret) { ALOGI("[%s:%d] connect to source(%d) success", __FUNCTION__, __LINE__, source_type); } else { ALOGE("[%s:%d] connect to source(%d) fail", __FUNCTION__, __LINE__, source_type); } return ret; } static int source_disconnect(input_source_type_e source_type) { struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); aml_audio_control *aml_actrl = get_audio_control(); aml_actrl->patch_handle = get_set_audio_handle(source_type, aml_actrl->patch_handle, 0); int ret = -1; ret = aml_dev->hw_device.release_audio_patch(&aml_dev->hw_device, aml_actrl->patch_handle); if (0 == ret) { ALOGI("[%s:%d] disconnect source(%d) success, handle is %d", __FUNCTION__, __LINE__, source_type, aml_actrl->patch_handle); } else { ALOGE("[%s:%d] disconnect source(%d) fail", __FUNCTION__, __LINE__, source_type); } return ret; } static int adec_stop(adec_index_t adec_id) { aml_audio_control *aml_actrl = get_audio_control(); int ret = -1; switch (aml_actrl->adec_play_info[adec_id].src_id) { case ADEC_SRC_ATP0: case ADEC_SRC_ATP1: //ret = dtv_stop(&(aml_actrl->adec_play_info[adec_id])); break; case ADEC_SRC_HDMI_PORT0: case ADEC_SRC_HDMI_PORT1: case ADEC_SRC_HDMI_PORT2: case ADEC_SRC_HDMI_PORT3: ret = source_disconnect(INPUT_SOURCE_HDMI); break; case ADEC_SRC_AAD: ret = source_disconnect(INPUT_SOURCE_ATV); aml_actrl->sif_play_state = SIF_STATE_INIT; break; default: break; } return ret; } static int adec_start(adec_index_t adec_id) { aml_audio_control *aml_actrl = get_audio_control(); int ret = -1; switch (aml_actrl->adec_play_info[adec_id].src_id) { case ADEC_SRC_ATP0: case ADEC_SRC_ATP1: //ret = dtv_start(&(aml_actrl->adec_play_info[adec_id])); break; case ADEC_SRC_HDMI_PORT0: case ADEC_SRC_HDMI_PORT1: case ADEC_SRC_HDMI_PORT2: case ADEC_SRC_HDMI_PORT3: ret = source_connect(INPUT_SOURCE_HDMI); break; case ADEC_SRC_AAD: if (aml_actrl->sif_play_state == SIF_STATE_CONNECTED) { ret = 0; } else if (aml_actrl->sif_play_state == SIF_STATE_INIT) { ret = source_connect(INPUT_SOURCE_ATV); aml_actrl->sif_play_state = SIF_STATE_CONNECTED; } break; default: break; } return ret; } static const char* outputType2Str(output_device_idx_e type) { ENUM_TYPE_TO_STR_START("OUTPUT_DEVICE_"); ENUM_TYPE_TO_STR(OUTPUT_DEVICE_UNKNOWN) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_SPK) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_OPTIC) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_OPTIC_LG) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_BLUETOOTH) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_HP) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_ARC) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_WISA) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_SE_BT) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_CAPTURE) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_SE_ARC) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_SE_BT_SUR) ENUM_TYPE_TO_STR(OUTPUT_DEVICE_MAX) ENUM_TYPE_TO_STR_END } static const char* inputType2Str(input_type_e type) { ENUM_TYPE_TO_STR_START("INPUT_"); ENUM_TYPE_TO_STR(INPUT_UNKNOWN) ENUM_TYPE_TO_STR(INPUT_ADEC) ENUM_TYPE_TO_STR(INPUT_AMIXER) ENUM_TYPE_TO_STR_END } void control_utils(char *msg) { ALOGI("========================================================\n"); /*for (int i = 0; i < UEVENT_MSG_LEN; i++) { ALOGI("[%d]=%c ", i, msg[i]); }*/ aml_audio_control *aml_actrl = get_audio_control(); //char tmpstr[256] = {0}; while (*msg) { AM_LOGI("msg= %s", msg); if (!strncmp(msg, "GAIN_INPUT=", 11)) { int input_type = 0; int input_port_num = 0; int gain = 0; int duration = 0; //struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); msg += 11; sscanf(msg ,"%d %d %d %d", &input_type, &input_port_num, &gain, &duration); ALOGI("[%s:%d] msg=%s input_type=(%s) input_port_num=%d, gain=%d duration=%d", __FUNCTION__, __LINE__, msg, inputType2Str(input_type), input_port_num, gain, duration); if (duration == 0) { duration = 50; // when set volume, do 50ms fading } if (input_type == INPUT_ADEC) { aml_actrl->adec_gain[input_port_num] = gain; if (aml_actrl->adec_mute[input_port_num] == 0) {// unmute //adev_set_master_volume (aml_dev, (float)gain/VOLUME_GAIN_0DB); } } else if (input_type == INPUT_AMIXER) { int device_id = input_port_num; aml_actrl->amixer_gain[device_id].save_gain = (float)gain/VOLUME_GAIN_0DB; if (aml_actrl->amixer_mute[device_id] == 0) { aml_actrl->amixer_gain[device_id].target_gain = aml_actrl->amixer_gain[device_id].save_gain; aml_actrl->amixer_gain[device_id].duration = duration;// YY to do : The unit of duration is ms, but I do not know the unit of LG. aml_actrl->amixer_gain[device_id].fade_frames = duration * 48;// YY to do : duration * sample_rate, but now I do not know the sample rate aml_actrl->amixer_gain[device_id].gain_step = (aml_actrl->amixer_gain[device_id].target_gain - aml_actrl->amixer_gain[device_id].current_gain) / aml_actrl->amixer_gain[device_id].fade_frames; } ALOGI("[%s:%d] AMIXER_GAIN_INPUT_DURATION device_id(%d) mute(%d) gain(0x%x)(%f) current_gain(%f) duration(%d) fade_frames(%d) gain_step(%f)", __FUNCTION__, __LINE__, device_id, aml_actrl->amixer_mute[device_id], gain, aml_actrl->amixer_gain[device_id].target_gain, aml_actrl->amixer_gain[device_id].current_gain, duration,aml_actrl->amixer_gain[device_id].fade_frames, aml_actrl->amixer_gain[device_id].gain_step); } } else if (!strncmp(msg, "GAIN_OUTPUT=", 12)) { int output_type = 0; int output_gain = 0; msg += 12; sscanf(msg ,"%d %d", &output_type, &output_gain); if (output_gain > VOLUME_GAIN_0DB) { output_gain = VOLUME_GAIN_0DB; } else if (output_gain < 0) { output_gain = 0; } aml_actrl->output_device_gain[output_type] = output_gain * 100 / VOLUME_GAIN_0DB; //struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); ALOGI("[%s:%d] GAIN_OUTPUT=%s output_type=(%s) output_gain=%d output_device_gain=%d", __FUNCTION__, __LINE__, msg, outputType2Str(output_type), output_gain, aml_actrl->output_device_gain[output_type]); if (aml_actrl->output_device_mute[output_type] == 0) {// when unmute, set gain to hal if (output_type == OUTPUT_DEVICE_SPK /*&& aml_dev->is_TV*/) { ALOGE("***in TV, use 'lgse_var_fn009' to control spk vol"); } else { set_optput_device_gain(output_type, aml_actrl->output_device_gain[output_type]); } } //to do : need to implement other output gain } else if (!strncmp(msg, "lgse_var_fn009=", 15)) { output_device_idx_e output_type = OUTPUT_DEVICE_SPK; int output_gain = 0; msg += 15; sscanf(msg ,"%d", &output_gain); if (output_gain > 100) { output_gain = 100; } else if (output_gain < 0) { output_gain = 0; } aml_actrl->output_device_gain[output_type] = output_gain; ALOGI("[%s:%d] msg: %s, output_gain=%d", __FUNCTION__, __LINE__,msg, output_gain); if (aml_actrl->output_device_mute[output_type] == 0) {// when unmute, set gain to hal set_optput_device_gain(output_type, aml_actrl->output_device_gain[output_type]); } //to do : need to implement other output gain } else if (!strncmp(msg, "MUTE_INPUT=", 11)) { int input_type = 0; int input_port_num = 0; int mute = 0; msg += 11; sscanf(msg ,"%d %d %d", &input_type, &input_port_num, &mute); ALOGI("[%s:%d] MUTE_INPUT=%s input_type=(%s) input_port_num=%d mute=%d", __FUNCTION__, __LINE__, msg, inputType2Str(input_type), input_port_num, mute); if (input_type == INPUT_ADEC) { aml_actrl->adec_mute[input_port_num] = mute; if (mute) {//mute //adev_set_master_volume (aml_dev, (float)0); } else {//unmute //adev_set_master_volume (aml_dev, (float)aml_actrl->adec_gain[input_port_num]/VOLUME_GAIN_0DB); } } else if (input_type == INPUT_AMIXER) { mute_amixer_by_id(input_port_num, mute); } } else if (!strncmp(msg, "MUTE_OUTPUT=", 12)) { int output_type = 0; int output_mute = 0; msg += 12; sscanf(msg ,"%d %d", &output_type, &output_mute); aml_actrl->output_device_mute[output_type] = output_mute; ALOGI("[%s:%d] MUTE_OUTPUT=%s output_type=(%s) output_mute=%d", __FUNCTION__, __LINE__, msg, outputType2Str(output_type), output_mute); if (aml_actrl->output_device_mute[output_type]) { // mute set_optput_device_gain(output_type, 0); } else { // unmute set_optput_device_gain(output_type, aml_actrl->output_device_gain[output_type]); } } else if (!strncmp(msg, "GAIN_AUDIODESCRIPTION=", 22)) { struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); struct aml_stream_out *aml_out = direct_active(aml_dev); aml_dec_t *aml_dec = NULL; if (aml_out != NULL) { aml_dec = aml_out->aml_dec; } else { ALOGI("[%s:%d] aml_out is NULL", __FUNCTION__, __LINE__); } struct dolby_ms12_desc *ms12 = &(aml_dev->ms12); int ad_gain = 0; msg += 22; sscanf(msg ,"%d", &ad_gain); if (ad_gain > VOLUME_GAIN_0DB) { ad_gain = VOLUME_GAIN_0DB; } else if (ad_gain < 0) { ad_gain = 0; } aml_dev->advol_level = ad_gain * 100 / VOLUME_GAIN_0DB; ALOGI("[%s:%d] GAIN_AUDIODESCRIPTION=%s ad_gain=%d aml_dev->advol_level=%d", __FUNCTION__, __LINE__, msg, ad_gain, aml_dev->advol_level); if (aml_out != NULL && aml_dev->advol_level != aml_out->dec_config.advol_level) { aml_out->dec_config.advol_level = aml_dev->advol_level; if (aml_dec != NULL) { aml_decoder_set_config(aml_dec, AML_DEC_CONFIG_AD_VOL, &aml_out->dec_config); } else { ALOGI("[%s:%d] aml_dec is NULL", __FUNCTION__, __LINE__); } } if (eDolbyMS12Lib == aml_dev->dolby_lib_type_last && ms12->dolby_ms12_enable) { pthread_mutex_lock(&ms12->lock); //set_ms12_ad_vol(ms12, aml_dev->advol_level); pthread_mutex_unlock(&ms12->lock); } } else if (!strncmp(msg, "ADC_CONNECT", 11)) { struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); if (is_TV(aml_dev)) source_connect(INPUT_SOURCE_AV); } else if (!strncmp(msg, "ADC_DISCONNECT", 14)) { struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); if (is_TV(aml_dev)) source_disconnect(INPUT_SOURCE_AV); } else if (!strncmp(msg, "ADEC_CONNECT=", 13)) { msg += 13; AM_LOGI("msg=%s", msg); int adec_idx = 0; int src_type = 0; sscanf(msg ,"%d %d", &adec_idx, &src_type); AM_LOGI("adec_idx=%d src_type=%d", adec_idx, src_type); aml_actrl->adec_play_info[adec_idx].src_id = src_type; aml_actrl->adec_play_info[adec_idx].adec_state = ADEC_STATE_CONNECTED; } else if (!strncmp(msg, "ADEC_DISCONNECT=", 16)) { msg += 16; AM_LOGI("msg=%s", msg); int adec_idx = 0; int ret = -1; struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); sscanf(msg ,"%d", &adec_idx); AM_LOGI("adec_idx=%d, src_type=%d sif_play_state =%d", adec_idx, aml_actrl->adec_play_info[adec_idx].src_id, aml_actrl->sif_play_state); if (aml_actrl->sif_play_state == SIF_STATE_CONNECTED) { ret = source_disconnect(INPUT_SOURCE_ATV); aml_actrl->sif_play_state = SIF_STATE_INIT; } else if ((aml_actrl->adec_play_info[adec_idx].src_id == ADEC_SRC_ATP0 || aml_actrl->adec_play_info[adec_idx].src_id == ADEC_SRC_ATP1) && aml_actrl->adec_play_info[adec_idx].adec_state == ADEC_STATE_RUNNING) { ret = adec_stop(adec_idx); } else if (is_TV(aml_dev) && ((aml_actrl->adec_play_info[adec_idx].src_id == ADEC_SRC_HDMI_PORT0) || (aml_actrl->adec_play_info[adec_idx].src_id == ADEC_SRC_HDMI_PORT1) || (aml_actrl->adec_play_info[adec_idx].src_id == ADEC_SRC_HDMI_PORT2) || (aml_actrl->adec_play_info[adec_idx].src_id == ADEC_SRC_HDMI_PORT3)) && aml_actrl->adec_play_info[adec_idx].adec_state == ADEC_STATE_RUNNING) { ret = source_disconnect(INPUT_SOURCE_HDMI); } if (!ret) { aml_actrl->adec_play_info[adec_idx].adec_state = ADEC_STATE_INIT; aml_actrl->adec_play_info[adec_idx].src_id = ADEC_SRC_UNKNOWN; aml_actrl->adec_play_info[adec_idx].adec_codec = ADEC_CODEC_UNKNOWN; } } else if (!strncmp(msg, "ADEC_DOWNMIXMODE=", 17)) { msg += 17; AM_LOGI("msg=%s", msg); int adec_index = 0; int downmix_mode = 0; //adec_downmix_mode_ext_type_t 0-LORO 1-LTRT sscanf(msg ,"%d %d", &adec_index, &downmix_mode); // to do : how to support dual decoder? struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); int audio_hal_downmix_mode = 0;// 0-LTRT 1-LORO if (downmix_mode == 0) { audio_hal_downmix_mode = 1; } else if (downmix_mode == 1) { audio_hal_downmix_mode = 0; } snprintf(tmp_msg, 50, "ms12_runtime=-dmx %d", audio_hal_downmix_mode); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "ADEC_CODEC=", 11)) { msg += 11; AM_LOGI("msg=%s", msg); int adec_idx = 0; int codec = 0; sscanf(msg ,"%d %d", &adec_idx, &codec); ALOGI("[%s:%d] adec_idx=%d codec=%d", __FUNCTION__, __LINE__, adec_idx, codec); audio_format_t hal_codec; mapping_codec_from_kernel_to_hal((adec_src_codec_type_t)codec, &hal_codec); aml_actrl->adec_play_info[adec_idx].adec_codec = hal_codec; } else if (!strncmp(msg, "ADEC_START=", 11)) { msg += 11; AM_LOGI("msg=%s", msg); int adec_idx = 0; sscanf(msg ,"%d", &adec_idx); AM_LOGI("adec_idx=%d, src=%d, state %d", adec_idx, aml_actrl->adec_play_info[adec_idx].src_id, aml_actrl->adec_play_info[adec_idx].adec_state); if (aml_actrl->adec_play_info[adec_idx].adec_state == ADEC_STATE_CONNECTED) { int ret = adec_start(adec_idx); if (!ret) { aml_actrl->adec_play_info[adec_idx].adec_state = ADEC_STATE_RUNNING; } } } else if (!strncmp(msg, "ADEC_STOP=", 10)) { msg += 10; AM_LOGI("msg=%s", msg); int adec_idx = 0; sscanf(msg ,"%d", &adec_idx); AM_LOGI("adec_idx=%d. src=%d, state %d", adec_idx, aml_actrl->adec_play_info[adec_idx].src_id, aml_actrl->adec_play_info[adec_idx].adec_state); if (aml_actrl->adec_play_info[adec_idx].adec_state == ADEC_STATE_RUNNING) { int ret = adec_stop(adec_idx); if (!ret) { aml_actrl->adec_play_info[adec_idx].adec_state = ADEC_STATE_CONNECTED; } } } else if (!strncmp(msg, "ADEC_TP_DECODER_OUTPUTMODE=", 27)) { msg += 27; AM_LOGI("msg=%s", msg); int adec_index = 0; int DualMonoMode = 0;//adec_dualmono_mode_t struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); AM_AOUT_OutputMode_t output_mode = DualMonoMode; char tmp_msg[50]; sscanf(msg ,"%d %d", &adec_index, &DualMonoMode); // to do //我们的处理在audio_hal_data_processing,LG预期在adec中... memset(tmp_msg, 0x00, sizeof(tmp_msg)); if (DualMonoMode == 3) {//ADEC_DUALMONO_MODE_MIX in alsa-ext-adec.h output_mode = AM_AOUT_OUTPUT_LRMIX; } snprintf(tmp_msg, 50, "sound_track=%d", output_mode); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "ADEC_SYNCMODE=", 14)) { msg += 14; AM_LOGI("msg=%s", msg); int adec_index = 0; int sync_onoff = 0; sscanf(msg ,"%d %d", &adec_index, &sync_onoff); // to do } else if (!strncmp(msg, "ADEC_DOLBYDRCMODE=", 18)) { //set DRC mode : https://confluence.amlogic.com/pages/viewpage.action?pageId=100813927 msg += 18; AM_LOGI("msg=%s", msg); int adec_index = 0; int dolyb_drc_mode = 0; sscanf(msg ,"%d %d", &adec_index, &dolyb_drc_mode); // to do : how to support dual decoder? //Does this setting will affect our original DRC setting flow? // TO DO #if 0 if (dolyb_drc_mode == 0) { // line reference adec_dolbydrc_mode_ext_type_t in alsa-ext-adec.h system("echo drcmode 2 > /sys/class/audiodsp/ac3_drc_control"); system("echo drchighcutscale 64 > /sys/class/audiodsp/ac3_drc_control"); system("echo drclowboostscale 64 > /sys/class/audiodsp/ac3_drc_control"); } else if (dolyb_drc_mode == 1) { //RF system("echo drcmode 3 > /sys/class/audiodsp/ac3_drc_control"); system("echo drchighcutscale 0 > /sys/class/audiodsp/ac3_drc_control"); system("echo drclowboostscale 0 > /sys/class/audiodsp/ac3_drc_control"); } else if (dolyb_drc_mode == 2) { //off system("echo drcmode 2 > /sys/class/audiodsp/ac3_drc_control"); system("echo drchighcutscale 0 > /sys/class/audiodsp/ac3_drc_control"); system("echo drclowboostscale 0 > /sys/class/audiodsp/ac3_drc_control"); } #endif } else if (!strncmp(msg, "ADEC_DEFAULTPRL=", 16)) { msg += 16; AM_LOGI("msg=%s", msg); int adec_index = 0; int default_prl = 0; sscanf(msg ,"%d %d", &adec_index, &default_prl); // to do : What is prl? } else if (!strncmp(msg, "ADEC_AC4_AUTO1STLANG=", 21)) { msg += 21; AM_LOGI("msg=%s", msg); int adec_index = 0; int lang_type = 0;//adec_ac4_lang_code_ext_type_t int first_lang = 0; sscanf(msg ,"%d %d %d", &adec_index, &lang_type, &first_lang); // to do : how to support dual decoder? if (lang_type == 0) {//ISO639_1 //to do //mapping ISO639_1 to ISO639_2 ; } struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; char lang[4]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); lang[0] = first_lang >> 24; lang[1] = (first_lang >> 16) & 0xff; lang[2] = (first_lang >> 8) & 0xff; lang[3] = '\0'; snprintf(tmp_msg, 50, "ms12_runtime=-lang %s", lang); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "ADEC_AC4_AUTO2NDLANG=", 21)) { msg += 21; AM_LOGI("msg=%s", msg); int adec_index = 0; int lang_type = 0;//adec_ac4_lang_code_ext_type_t int second_lang = 0; sscanf(msg ,"%d %d %d", &adec_index, &lang_type, &second_lang); // to do : how to support dual decoder? if (lang_type == 0) {//ISO639_1 //to do //mapping ISO639_1 to ISO639_2 ; } struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; char lang[4]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); lang[0] = second_lang >> 24; lang[1] = (second_lang >> 16) & 0xff; lang[2] = (second_lang >> 8) & 0xff; lang[3] = '\0'; snprintf(tmp_msg, 50, "ms12_runtime=-lang2 %s", lang); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "ADEC_AC4_AUTO_ADTYPE=", 21)) { msg += 21; AM_LOGI("msg=%s", msg); int adec_index = 0; int ad_type = 0;//adec_ac4_ad_ext_type_t sscanf(msg ,"%d %d", &adec_index, &ad_type); // to do : how to support dual decoder? struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); snprintf(tmp_msg, 50, "ms12_runtime=-at %d", ad_type); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "ADEC_AC4_AUTO_PRIORITIZE_ADTYPE=", 32)) { msg += 32; AM_LOGI("msg=%s", msg); int adec_index = 0; int ac4_prioritize_ad_type = 0;//true or flase sscanf(msg ,"%d %d", &adec_index, &ac4_prioritize_ad_type); // to do : how to support dual decoder? struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); snprintf(tmp_msg, 50, "ms12_runtime=-pat %d", ac4_prioritize_ad_type); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "ADEC_AC4_DIALOGENHANCEGAIN=", 27)) { msg += 27; AM_LOGI("msg=%s", msg); int adec_index = 0; int dialogenhance_gain = 0;//true or flase sscanf(msg ,"%d %d", &adec_index, &dialogenhance_gain); // to do : how to support dual decoder? struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); snprintf(tmp_msg, 50, "hal_param_dialogue_enhancement=%d", dialogenhance_gain); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "ADEC_AC4_AUTO_ADMIXING=", 23)) { msg += 23; AM_LOGI("msg=%s", msg); int adec_index = 0; int ac4_admixing = 0;//true or flase sscanf(msg ,"%d %d", &adec_index, &ac4_admixing); // to do : } else if (!strncmp(msg, "ADEC_AC4_PRES_GROUP_IDX=", 24)) { msg += 24; AM_LOGI("msg=%s", msg); int adec_index = 0; int ac4_pres_group_idx = 0; sscanf(msg ,"%d %d", &adec_index, &ac4_pres_group_idx); // to do : how to support dual decoder? struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); snprintf(tmp_msg, 50, "ms12_runtime=-ac4_pres_group_idx %d", ac4_pres_group_idx); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "ADEC_DOLBY_OTTMODE=", 19)) { msg += 19; AM_LOGI("msg=%s", msg); int ott_mode = 0; // for linux, dolby always continues output int atmos_lock = 0; sscanf(msg ,"%d %d", &ott_mode, &atmos_lock); // to do : how to support dual decoder? struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); snprintf(tmp_msg, 50, "ms12_runtime=-atmos_lock %d", atmos_lock); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "ADEC_AC4_ASSOCIATE_AUDIO_VOLUME=", 32)) { msg += 32; AM_LOGI("msg=%s", msg); int ott_mode = 0; // for linux, dolby always continues output int ac4_associate_volume = 0; sscanf(msg ,"%d %d", &ott_mode, &ac4_associate_volume); // to do : how to support dual decoder? struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); snprintf(tmp_msg, 50, "ms12_runtime=-xu %d", ac4_associate_volume); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else if (!strncmp(msg, "SNDOUT_CONNECT=", 15)) { int output = 0; int input = 0; int input_port_number = 0; msg += 15; sscanf(msg ,"%d %d %d", &output, &input, &input_port_number); ALOGI("[%s:%d] SNDOUT_CONNECT=%s output=%s(%x) input=%s input_port_number=%d", __FUNCTION__, __LINE__, msg, outputMaskType2Str(output), output, inputType2Str(input), input_port_number); aml_actrl->audio_output_type |= output; if (input == INPUT_AMIXER) { /* workaround for socts "alsa-sndout-adv-0013: DisconnectTestAdv" (no 'gain_input' setting at beginning in this case). still mute if last case run SNDOUT_DISCONNECT ever*/ mute_amixer_by_id(input_port_number, 0); } } else if (!strncmp(msg, "SNDOUT_DISCONNECT=", 18)) { int output = 0; int input = 0; int input_port_number = 0; msg += 18; sscanf(msg ,"%d %d %d", &output, &input, &input_port_number); ALOGI("[%s:%d] SNDOUT_DISCONNECT=%s output=%s(%x) input=%s input_port_number=%d", __FUNCTION__, __LINE__, msg, outputMaskType2Str(output), output, inputType2Str(input), input_port_number); aml_actrl->audio_output_type &= ~output; if (input == INPUT_AMIXER) { mute_amixer_by_id(input_port_number, 1);// workaround for socts-alsa-sndout "alsa-sndout-adv-0013: DisconnectTestAdv", if disconnect amixer from output device, not mix it data } } else if (!strncmp(msg, "SNDOUT_MAINAUDIO_OUTPUT=", 24)) { msg += 24; AM_LOGI("msg=%s", msg); int input_type= 0; // common_input_ext_type_t int port_number= 0; sscanf(msg ,"%d %d", &input_type, &port_number); // to do : need dual decoder } else if (!strncmp(msg, "SNDOUT_SPDIF_OUTPUTTYPE=", 24)) { int optic_type = 0;// sndout_optic_mode_ext_type_t int arc_type = 0;//sndout_arc_mode_ext_type_t in alsa-ext-sndout.h struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; memset(tmp_msg, 0x00, sizeof(tmp_msg)); msg += 24; sscanf(tmp_msg ,"%d %d", &optic_type, &arc_type); ALOGI("[%s:%d] SNDOUT_SPDIF_OUTPUTTYPE=%s optic_type=%d arc_type=%d", __FUNCTION__, __LINE__, tmp_msg, optic_type, arc_type); if (arc_type == 1) {//SNDOUT_ARC_PCM snprintf(tmp_msg, 50, "digital_output_format=pcm"); } else if (arc_type >= 2 && arc_type <= 9) {//SNDOUT_ARC_AUTO-SNDOUT_ARC_HALF_AUTO_EAC3_AAC snprintf(tmp_msg, 50, "digital_output_format=auto"); } else if (arc_type == 10) {//SNDOUT_ARC_FORCED_AC3 snprintf(tmp_msg, 50, "digital_output_format=dd"); } else if (arc_type == 11) {//SNDOUT_ARC_FORCED_EAC3 snprintf(tmp_msg, 50, "digital_output_format=ddp"); } else if (arc_type >= 12 && arc_type <= 16) {//SNDOUT_ARC_BYPASS-SNDOUT_ARC_BYPASS_EAC3_MPEG4_AAC snprintf(tmp_msg, 50, "digital_output_format=bypass"); } aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); }/* else if (!strncmp(msg, "SNDOUT_SPDIF_COPYPROTECTIONINFO=", 32)) { msg += 32; AM_LOGI("msg=%s", msg); int optic_cp = 0; int arc_cp = 0; sscanf(msg ,"%d %d", &optic_cp, &arc_cp); // to do : } else if (!strncmp(msg, "SNDOUT_SPDIF_CATERGORYCODE=", 27)) { msg += 27; AM_LOGI("msg=%s", msg); int optic_category = 0; int arc_category = 0; sscanf(msg ,"%d %d", &optic_category, &arc_category); // to do : }*/ else if (!strncmp(msg, "SNDOUT_OPTIC_LIGHTONOFF=", 24)) { msg += 24; AM_LOGI("msg=%s", msg); int light_onoff = 0; sscanf(msg ,"%d", &light_onoff); // to do : } else if (!strncmp(msg, "SNDOUT_ARC_ONOFF=", 17)) { msg += 17; AM_LOGI("msg=%s", msg); int arc_onoff = 0; sscanf(msg ,"%d", &arc_onoff); ALOGI("[%s:%d] SNDOUT_ARC_ONOFF=%s arc_onoff=%d\n", __FUNCTION__, __LINE__, msg, arc_onoff); struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); if (aml_dev == NULL) { open_mixer_handle(&aml_dev->alsa_mixer); } aml_mixer_ctrl_set_int(&aml_dev->alsa_mixer, AML_MIXER_ID_ARC_EARC_TX_ENABLE, arc_onoff); } else if (!strncmp(msg, "SNDOUT_OPTIC_LG=", 16)) { msg += 16; AM_LOGI("msg=%s", msg); int barID = 0; int volume = 0; int bMuteOnOff = 0; int bPowerOnOff = 0; sscanf(msg ,"%d %d %d %d", &barID, &volume, &bMuteOnOff, &bPowerOnOff); // to do : } else if (!strncmp(msg, "SNDOUT_SPK_OUTPUT=", 18)) { msg += 18; AM_LOGI("msg=%s", msg); int spk_out_channel = 0; sscanf(msg ,"%d", &spk_out_channel); // to do : } else if (!strncmp(msg, "SNDOUT_CAPTURE_DISABLE=", 23)) { msg += 23; AM_LOGI("msg=%s", msg); int capture_disable_onoff = 0; sscanf(msg ,"%d", &capture_disable_onoff); // to do : } else if (!strncmp(msg, "SNDOUT_CAPTURE_OUTPUT_RESAMPLING=", 33)) { msg += 33; AM_LOGI("msg=%s", msg); int sample_rate = 0; sscanf(msg ,"%d", &sample_rate); // to do : } else if (!strncmp(msg, "SNDOUT_EARC_ONOFF=", 18)) { msg += 18; AM_LOGI("msg=%s", msg); int earc_onoff = 0; sscanf(msg ,"%d", &earc_onoff); ALOGI("[%s:%d] SNDOUT_EARC_ONOFF=%s earc_onoff=%d\n", __FUNCTION__, __LINE__, msg, earc_onoff); struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); if (aml_dev == NULL) { open_mixer_handle(&aml_dev->alsa_mixer); } aml_mixer_ctrl_set_int(&aml_dev->alsa_mixer, AML_MIXER_ID_EARC_TX_EARC_MODE, earc_onoff); } else if (!strncmp(msg, "SNDOUT_EARC_OUTPUT_TYPE=", 24)) { msg += 24; AM_LOGI("msg=%s", msg); int set_type = 0; int codec_type = 0; int channel_num = 0; int sample_rate = 0; int mix_option = 0; int coding_type = 0; sscanf(msg ,"%d %d %d %d %d", &set_type, &codec_type, &channel_num, &sample_rate, &mix_option); ALOGI("[%s:%d] SNDOUT_EARC_OUTPUT_TYPE=%s set_type=%d codec_type=%d channel_num=%d sample_rate=%d mix_option=%d\n", __FUNCTION__, __LINE__, msg, set_type, codec_type, channel_num, sample_rate, mix_option); struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); parse_earc_coding_type(codec_type, &coding_type); aml_mixer_ctrl_set_int(&aml_dev->alsa_mixer, AML_MIXER_ID_EARC_TX_AUDIO_TYPE, codec_type); } else if (!strncmp(msg, "SNDOUT_EAC3_ATMOS_ENCODE_ONOFF=", 31)) { struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); char tmp_msg[50]; int onoff = 0; msg += 31; sscanf(msg ,"%d", &onoff); ALOGI("[%s:%d] SNDOUT_EAC3_ATMOS_ENCODE_ONOFF=%s onoff=%d", __FUNCTION__, __LINE__, msg, onoff); memset(tmp_msg, 0x00, sizeof(tmp_msg)); if (onoff) { snprintf(tmp_msg, 50, "ms12_runtime=-atmos_lock 1"); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); snprintf(tmp_msg, 50, "ms12_runtime=-legacy_ddplus_out 0"); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } else { snprintf(tmp_msg, 50, "ms12_runtime=-atmos_lock 0"); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); snprintf(tmp_msg, 50, "ms12_runtime=-legacy_ddplus_out 1"); aml_dev->hw_device.set_parameters(&aml_dev->hw_device, tmp_msg); } } else if (!strncmp(msg, "SNDOUT_OPTIC_OUTPUT_TYPE=", 25)) { msg += 25; AM_LOGI("msg=%s", msg); int set_type = 0; int codec_type = 0; int channel_num = 0; int sample_rate = 0; int mix_option = 0; sscanf(msg ,"%d %d %d %d %d", &set_type, &codec_type, &channel_num, &sample_rate, &mix_option); // to do : } else if (!strncmp(msg, "SNDOUT_ARC_OUTPUT_TYPE=", 23)) { msg += 23; AM_LOGI("msg=%s", msg); int set_type = 0; int codec_type = 0; int channel_num = 0; int sample_rate = 0; int mix_option = 0; int coding_type = 0; sscanf(msg ,"%d %d %d %d %d", &set_type, &codec_type, &channel_num, &sample_rate, &mix_option); ALOGI("[%s:%d] SNDOUT_ARC_OUTPUT_TYPE=%s set_type=%d codec_type=%d channel_num=%d sample_rate=%d mix_option=%d\n", __FUNCTION__, __LINE__, msg, set_type, codec_type, channel_num, sample_rate, mix_option); parse_earc_coding_type(codec_type, &coding_type); struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); aml_mixer_ctrl_set_int(&aml_dev->alsa_mixer, AML_MIXER_ID_EARC_TX_AUDIO_TYPE, codec_type); } else if (!strncmp(msg, "SNDOUT_CAPTURE_PATH_POINT=", 26)) { msg += 26; AM_LOGI("msg=%s", msg); int capture_path = 0; sscanf(msg ,"%d", &capture_path); // to do : } else if (!strncmp(msg, "AENC_INFO=", 10)) { msg += 10; AM_LOGI("msg=%s", msg); int adec_idx = 0, bit_rate = 0, fmt = 0; sscanf(msg, "%d %d %d", &adec_idx, &fmt, &bit_rate); AM_LOGI("adec_idx = %d, enc_fmt = %d, bitrate = %d", adec_idx, fmt, bit_rate); struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); memset(&aml_dev->encoder_ctx.enc_cfg, 0, sizeof(aml_dev->encoder_ctx.enc_cfg)); aml_dev->encoder_ctx.enc_cfg.bitrate = bit_rate; aml_dev->encoder_ctx.enc_cfg.format = (enc_encoding_format_t)fmt; } else if (!strncmp(msg, "AENC_VOLUME=", 12)) { msg += 12; AM_LOGI("[%s:%d] msg=%s", __FUNCTION__, __LINE__, msg); long val = 0; sscanf(msg ,"%ld", &val); float vol = (float)val/VOLUME_GAIN_0DB; AM_LOGI("val = %ld, vol=%f", val, vol); struct aml_audio_device *aml_dev = (struct aml_audio_device *)adev_get_handle(); aml_dev->encoder_ctx.enc_cfg.volume = vol; aml_encoder_config(aml_dev->encoder_ctx.enc_handle, AML_ENC_CONFIG_VOLUME, &aml_dev->encoder_ctx.enc_cfg); } while (*msg++) ; } /*ALOGI("event { '%s', '%s', '%s', '%s', %d, %d }\n", luther_gliethttp->action, luther_gliethttp->path, luther_gliethttp->subsystem, luther_gliethttp->firmware, luther_gliethttp->major, luther_gliethttp->minor);*/ return; } void audio_control_init(struct aml_audio_device * adev) { //int ret = 0; aml_audio_control *aml_actrl = get_audio_control(); memset(aml_actrl->amixer_mute, 0x00, sizeof(aml_actrl->amixer_mute)); memset(aml_actrl->amixer_gain, 0x00, sizeof(aml_actrl->amixer_gain)); for (int i = 0; i < DEVICE_NUM; i++) { aml_actrl->amixer_gain[i].target_gain = 1;//set default gain value to 1 for socts-alsa-sndout "alsa-sndout-adv-0013: DisconnectTestAdv" aml_actrl->amixer_gain[i].save_gain = 1; } for (int i = CAPTURE_START_INDEX; i < CAPTURE_END_INDEX + 1; i++) pthread_mutex_init(&aml_actrl->capture_param[i - CAPTURE_START_INDEX].cap_handle_lock, NULL); /*init for adec (adec's source include av/atv/dtv/hdmi)*/ memset(aml_actrl->adec_gain, 0x00, sizeof(aml_actrl->adec_gain)); memset(aml_actrl->adec_mute, 0x00, sizeof(aml_actrl->adec_mute)); memset(aml_actrl->adec_play_info, 0x00, sizeof(aml_actrl->adec_play_info)); /*init for output*/ for (int i = 0; i < OUTPUT_DEVICE_NUM; i++) { aml_actrl->output_device_gain[i] = 100; } memset(aml_actrl->output_device_mute, 0x00, sizeof(aml_actrl->output_device_mute)); /*init for encoder*/ //aml_dev->enc_handle = NULL; return; } void audio_control_deinit() { aml_audio_control *aml_actrl = get_audio_control(); if (aml_actrl->aud_dev_fd > 0) { int ret = close(aml_actrl->aud_dev_fd); if (ret != 0) { AM_LOGE("close fd[%d] fail, Error:%s", aml_actrl->aud_dev_fd, strerror(errno)); } else { AM_LOGD("close fd[%d] ok", aml_actrl->aud_dev_fd); aml_actrl->aud_dev_fd = 0; } } /*deinit for mixer (alsa c0d0~c0d7 playback)*/ aml_actrl->input_mixer_thread_exit = 1; aml_actrl->output_mixer_thread_exit = 1; pthread_join(aml_actrl->input_mixer_threadID, NULL); pthread_join(aml_actrl->mixer_output_threadID, NULL); ring_buffer_release(&aml_actrl->input_mixer_ring_buffer); /*deinit for uevent*/ aml_actrl->uevent_thread_exit = 1; pthread_join(aml_actrl->uevent_threadID, NULL); }