1111 lines
49 KiB
C
1111 lines
49 KiB
C
/*
|
||
* 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);
|
||
}
|