Files
2026-08-24 10:03:24 +08:00

1111 lines
49 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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 <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <inttypes.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/prctl.h>
#include <cutils/atomic.h>
#include <cutils/str_parms.h>
#include <linux/ioctl.h>
#include <hardware/hardware.h>
#include <system/audio.h>
#include <audio_utils/channels.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#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 <aml_alsa_mixer.h>
#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);
}