Files
BPI-CM9-Linux/aml-comp/multimedia/aml_audio_hal/projects/audio_controls_utils.c
T

1111 lines
49 KiB
C
Raw Normal View History

2026-08-13 11:28:40 +08:00
/*
* 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);
}