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

1226 lines
38 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.
/*f
* 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.
*/
#ifndef _AUDIO_HW_H_
#define _AUDIO_HW_H_
#include <audio_utils/resampler.h>
#include <hardware/audio.h>
#include <cutils/list.h>
/* ALSA ports for AML */
#if (ENABLE_HUITONG == 0)
#define PORT_MM 1
#endif
#include "audio_buffer.h"
#include "audio_hwsync.h"
#include "audio_post_process.h"
#include "aml_hw_mixer.h"
#include "audio_eq_drc_compensation.h"
#include "aml_DRC_param_gen.h"
#include "aml_EQ_param_gen.h"
#include "aml_audio_types_def.h"
#include "aml_alsa_mixer.h"
#include "aml_audio_ms12.h"
#include "audio_port.h"
#include "aml_audio_ease.h"
#include "aml_malloc_debug.h"
#include "hdmirx_utils.h"
#include "aml_audio_aec.h"
#include "component_picture_mode.h"
#include "aml_audio_delay.h"
#ifdef USE_MSYNC
#include <aml_avsync.h>
#include <aml_avsync_log.h>
#else
#include "aml_avsync_stub.h"
#endif
#include "aml_audio_resample_manager.h"
#include "aml_audio_resampler.h"
#include "aml_dec_api.h"
#include "aml_dtshd_dec_api.h"
#include "aml_dtsx_dec_api.h"
#include "tv_patch_format_parser.h"
#include "aml_audio_heaacparser.h"
#include "aml_audio_scaletempo.h"
#include "hal_clipmeta.h"
#include "audio_hw_resource_def.h"
#include "device_patch_mgr.h"
#include "aml_audio_port.h"
#include "aml_audio_unit.h"
#include "dolby_lib_api.h"
#include "aml_audio_input.h"
#include "aml_enc_api.h"
#include "aml_audio_ai_core.h"
/* number of frames per period */
/*
* change DEFAULT_PERIOD_SIZE from 1024 to 512 for passing CTS
* test case test4_1MeasurePeakRms(android.media.cts.VisualizerTest)
*/
#define DEFAULT_PLAYBACK_PERIOD_SIZE 512//1024
#define DEFAULT_CAPTURE_PERIOD_SIZE 1024
#define DEFAULT_PLAYBACK_PERIOD_CNT 6
#define LOW_LATENCY_PLAYBACK_PERIOD_SIZE 256
#define LOW_LATENCY_CAPTURE_PERIOD_SIZE 256
#define GAME_MODE_PLAYBACK_PERIOD_COUNT 4
/* number of ICE61937 format frames per period */
#define DEFAULT_IEC_SIZE 6144
#define PATCH_PERIOD_COUNT 4
/* minimum sleep time in out_write() when write threshold is not reached */
#define MIN_WRITE_SLEEP_US 5000
#define RESAMPLER_BUFFER_FRAMES (DEFAULT_PLAYBACK_PERIOD_SIZE * 6)
#define RESAMPLER_BUFFER_SIZE (4 * RESAMPLER_BUFFER_FRAMES)
#define DEFAULT_OUT_SAMPLING_RATE 48000
/* sampling rate when using MM low power port */
#define MM_LOW_POWER_SAMPLING_RATE 44100
/* sampling rate when using MM full power port */
#define MM_FULL_POWER_SAMPLING_RATE 48000
#define AUDIO_PARAMETER_STREAM_EQ "audioeffect_eq"
#define AUDIO_PARAMETER_STREAM_SRS "audioeffect_srs_param"
#define AUDIO_PARAMETER_STREAM_SRS_GAIN "audioeffect_srs_gain"
#define AUDIO_PARAMETER_STREAM_SRS_SWITCH "audioeffect_srs_switch"
/* Get a new HW synchronization source identifier.
* Return a valid source (positive integer) or AUDIO_HW_SYNC_INVALID if an error occurs
* or no HW sync is available. */
#define AUDIO_PARAMETER_HW_AV_SYNC "hw_av_sync"
#define AUDIO_PARAMETER_HW_AV_EAC3_SYNC "HwAvSyncEAC3Supported"
#define SYS_NODE_EARC "/sys/class/extcon/earcrx/state"
#define DDP_FRAME_SIZE (768)
#define EAC3_MULTIPLIER (4) //EAC3 bitstream in IEC61937
#define HBR_MULTIPLIER (16) //MAT or DTSHD bitstream in IEC61937
#define JITTER_DURATION_MS (3)
#define FLOAT_ZERO (0.00002) /* the APM mute volume is 0.00001, less than 0.00002 we think is mute. */
#define TV_SPEAKER_OUTPUT_CH_NUM 10
#define STREAM_NUM_MAX 12
#define DIALOGUE_ENHANCEMENT_OFF 0
#define DIALOGUE_ENHANCEMENT_LOW 1
#define DIALOGUE_ENHANCEMENT_MEDIUM 2
#define DIALOGUE_ENHANCEMENT_HIGH 3
#define SOUND_DMX_MODE_SURROUND 0
#define SOUND_DMX_MODE_STEREO 1
/* Maximum string length in audio hal. */
#define AUDIO_HAL_CHAR_MAX_LEN (256)
#define EOS_EASE_DURATION_FRAMES (20*48) //20ms
struct renderpts_item {
struct listnode list;
uint64_t cur_outapts;
uint64_t out_start_apts;
};
/*the same as "AUDIO HAL FORMAT" in kernel*/
enum audio_hal_format {
TYPE_PCM = 0,
TYPE_DTS_EXPRESS = 1,
TYPE_AC3 = 2,
TYPE_DTS = 3,
TYPE_EAC3 = 4,
TYPE_DTS_HD = 5 ,
TYPE_MULTI_PCM = 6,
TYPE_TRUE_HD = 7,
TYPE_DTS_HD_MA = 8,//should not used after we unify DTS-HD&DTS-HD MA
TYPE_PCM_HIGH_SR = 9,
TYPE_AC4 = 10,
TYPE_MAT = 11,
TYPE_DDP_ATMOS = 12,
TYPE_TRUE_HD_ATMOS = 13,
TYPE_MAT_ATMOS = 14,
TYPE_AC4_ATMOS = 15,
TYPE_DTS_HP = 16,
TYPE_DDP_ATMOS_PROMPT_ON_ATMOS = 17,
TYPE_TRUE_HD_ATMOS_PROMPT_ON_ATMOS = 18,
TYPE_MAT_ATMOS_PROMPT_ON_ATMOS = 19,
TYPE_AC4_ATMOS_PROMPT_ON_ATMOS = 20,
TYPE_AAC = 21,
TYPE_HEAAC = 22,
TYPE_DTSX = 23,
TYPE_MPEGH = 24,
TYPE_MPEGH_ASI_UPDATE = 25,
TYPE_MPEGH_CLOSE = 26,
TYPE_NOT_SUPPORT = 27
};
#define FRAMESIZE_16BIT_STEREO 4
#define FRAMESIZE_32BIT_STEREO 8
#define FRAMESIZE_32BIT_3ch 12
#define FRAMESIZE_32BIT_5ch 20
#define FRAMESIZE_32BIT_8ch 32
/* copy from VTS */
/* hardware/interfaces/audio/core/all-versions/default/include/core/default/Util.h */
/*
0 -> Result::OK
-EINVAL -> Result::INVALID_ARGUMENTS
-ENODATA -> Result::INVALID_STATE
-ENODEV -> Result::NOT_INITIALIZED
-ENOSYS -> Result::NOT_SUPPORTED
*/
enum Result {
OK,
NOT_INITIALIZED,
INVALID_ARGUMENTS,
INVALID_STATE,
NOT_SUPPORTED,
RESULT_TOO_BIG
};
enum SCALE_STATUS {
SCALE_NULL = 0,
SCALE_START = 1,
SCALE_WAIT = 2,
SCALE_BUTT
};
#define SYSTEM_APP_SOUND_MIXING_ON 1
#define SYSTEM_APP_SOUND_MIXING_OFF 0
struct drc_data {
uint32_t band_id;
uint32_t attrack_time;
uint32_t release_time;
float threshold;
unsigned int fc;
unsigned int estimate_time;
float K;
float offset;
};
struct eq_data {
double G;
double Q;
unsigned int fc;
unsigned int type;
unsigned int band_id;
};
typedef enum {
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_UNKNOWN = 0,
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_C,/**< Center */
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_MONO = TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_C,
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_R,/**< Left and right speakers */
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_STEREO = TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_R,
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_C_R,/**< Left, center and right speakers */
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_R_S,/**< Left, right and surround speakers */
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_C_R_S,/**< Left,center right and surround speakers */
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_R_SL_RS,/**< Left, right, surround left and surround right */
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_C_R_SL_SR,/**< Left, center, right, surround left and surround right */
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_C_R_SL_SR_LFE,/**< Left, center, right, surround left, surround right and lfe*/
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_5_1 = TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_C_R_SL_SR_LFE,
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_C_R_SL_SR_RL_RR_LFE, /**< Left, center, right, surround left, surround right, rear left, rear right and lfe */
TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_7_1 = TIF_HAL_PLAYBACK_AUDIO_SOURCE_CHANNEL_CONFIGURATION_L_C_R_SL_SR_RL_RR_LFE
} TIF_HAL_Playback_AudioSourceChannelConfiguration_t;
typedef enum stream_type {
STREAM_MAIN_INPUT = 0,
STREAM_AUX_INPUT = 1,
STREAM_DEEP_INPUT = 2,
STREAM_APP_INPUT = 3,
STREAM_AD_INPUT = 4,
STREAM_HWMIXER_INPUT = 5,
STREAM_TYPE_MAX = 6,
} stream_type_t;
typedef enum stream_source_type {
MEDIA_SRC = 0,
DTV_SRC = 1,
ATV_SRC = 2,
AV_SRC = 3,
HDMI_SRC = 4,
HDMI1_SRC = 5,
}stream_source_type_t;
// https://confluence.amlogic.com/pages/viewpage.action?spaceKey=SW&title=Audio+HAL++output+device+matrix
typedef enum alsa_device {
I2S_DEVICE = 0, /*speaker output pcm case*/
DIGITAL_DEVICE, /*for spdifa*/
TDM_DEVICE, /*HBR audio output on I2S interface. (Usually >= S5)*/
EARC_DEVICE,
DIGITAL_DEVICE2, /*for spdifb*/
EXTERNAL_USB, /*usb spk*/
EXTERNAL_BT, /*bluetooth*/
ALSA_DEVICE_CNT
} alsa_device_t;
#if defined(IS_ATOM_PROJECT)
typedef enum atom_stream_type {
STREAM_ANDROID = 0,
STREAM_HDMI,
STREAM_OPTAUX
} atom_stream_type_t;
#endif
typedef union {
unsigned long long timeStamp;
unsigned char tsB[8];
} aec_timestamp;
struct aml_audio_mixer;
typedef struct audio_hal_info{
audio_format_t format;
bool is_dolby_atmos;
bool is_decoding; /*store the decoder status*/
bool first_decoding_frame;
bool dts_type_is_updated;
int update_type;
int update_cnt;
int channel_number;
int sample_rate;
int lfepresent;
int channel_mode;
int digital_audio_info;
} audio_hal_info_t;
struct aml_bt_output {
bool active;
struct pcm *pcm_bt;
char *bt_out_buffer;
size_t bt_out_frames;
struct resampler_itfe *resampler;
struct resampler_buffer_provider buf_provider;
int16_t *resampler_buffer;
size_t resampler_buffer_size_in_frames;
size_t resampler_in_frames;
};
#define HDMI_ARC_MAX_FORMAT 20
enum {
EASE_SETTING_INIT = 0,
EASE_SETTING_START = 1,
EASE_SETTING_PENDING = 2
};
enum {
GAP_PASSTHROUGH_STATE_IDLE = 0,
GAP_PASSTHROUGH_STATE_SET,
GAP_PASSTHROUGH_STATE_WAIT_START,
GAP_PASSTHROUGH_STATE_INSERT,
GAP_PASSTHROUGH_STATE_DONE,
};
enum dtv_standards {
DTV_STANDARDS_EUDVB = 0,
DTV_STANDARDS_ATSC = 1,
DTV_STANDARDS_DTMB = 2,
DTV_STANDARDS_ISDB = 3,
DTV_STANDARDS_SDTVB = 4,
};
enum ms12_config {
MS12_CONFIG_Y = 0, /*not support dap*/
MS12_CONFIG_X = 1, /*support dap, but not support atmos*/
MS12_CONFIG_Z = 2, /*support dap, and support atmos*/
};
typedef struct audio_hal_vol{
ease_setting_t ease_setting;
/* is_new_setting:
* When this variable is true, it indicates that there is a new ease setting;
* when it is false, it indicates that the current processing is volume processing rather than ease processing */
bool is_new_setting;
} audio_hal_vol_t;
/* EQ_DRC param*/
#define EQ_HW_BAND_MAX_NUM 15
typedef struct eq_hw_band_data {
unsigned int eq_type;
unsigned int Fc;
double G;
double Q;
} eq_hw_band_data_s;
enum filter_type {
FILTER_TYPE_BANDPASS = 0,
FILTER_TYPE_HPF = 1,
FILTER_TYPE_LPF = 2,
};
typedef enum spdif_handle_index {
SPDIF_HANDLE_1, /*used for multi-channel,dd, ddp, mat, truehd, dts*/
SPDIF_HANDLE_2, /*only for dd when dual output*/
SPDIF_HANDLE_CNT
} spdif_handle_index_t;
struct aml_low_latency_param
{
bool is_reading_data;
bool is_game_mode_inited;
bool is_signal_stable;
int input_channel;
void *tmp_buf;
int tmp_buf_size;
};
typedef enum aml_audio_device_out_type {
/* define AUDIO_DEVICE_OUT_DEFAULT 0x40000000u*/
AML_AUDIO_DEVICE_OUT_EXTERNAL_SPEAKER = AUDIO_DEVICE_OUT_DEFAULT + 1,
} aml_audio_device_out_type_t;
struct aml_audio_device {
struct audio_hw_device hw_device;
/* see note below on mutex acquisition order */
pthread_mutex_t lock;
pthread_mutex_t pcm_write_lock;
/*
if dolby ms12 is enabled, the ms12 thread will change the
stream information depending on the main input format.
we need protect the risk and this case.
*/
pthread_mutex_t trans_lock;
pthread_mutex_t low_latency_param_lock;
void* low_latency_buf;
int low_latency_buf_size;
struct aml_low_latency_param low_latency_param;
aml_port usb_port;
aml_port bt_port;
void *usb_handle;
void *bt_handle;
pthread_mutex_t external_handle_lock;
int mode;
audio_devices_t in_device;
audio_devices_t out_device;
int in_call;
struct aml_stream_in *active_input;
bool mic_mute;
bool speaker_mute;
unsigned int card;
struct echo_reference_itfe *echo_reference;
bool low_power;
struct pcm *pcm;
struct aml_bt_output bt_output;
bool pcm_paused;
unsigned hdmi_arc_ad[HDMI_ARC_MAX_FORMAT];
bool audio_patching;
/* audio configuration for dolby HDMI/SPDIF output */
int hdmi_format;
int pre_hdmi_format;
int spdif_format;
bool spdif_enable;
int hdmi_is_pth_active;
int disable_pcm_mixing;
/* mute/unmute for vchip lock control */
bool decoder_mute;
int routing;
struct audio_config output_config;
struct component_picture_mode pic_mode;
/* Modularized shared resource management */
struct patch_manager *patch_manager;
struct audio_hw_resource_mgr *hw_resource_mgr;
struct hdmi_capability_manager *hdmi_cap_mgr;
int a2dp_updated;
bool need_reset_a2dp;
void * a2dp_hal;
int hdmi_format_updated;
struct aml_native_postprocess native_postprocess;
/* for port config infos */
float sink_gain[OUTPORT_MAX];
float last_volume[OUTPORT_MAX];
enum OUT_PORT active_outport;
bool active_outport_changed;
/* message to handle usecase changes */
bool usecase_changed;
struct aml_stream_out *active_outputs[STREAM_NUM_MAX];
pthread_mutex_t active_outputs_lock;
pthread_mutex_t patch_lock;
pthread_mutex_t dtv_patch_lock;//this only use for locking adev->audio_patch in dtv source,
//since ms12_output will use adev->audio_patch to do media sync
/* Now only two pcm handle supported: I2S, SPDIF */
//pthread_mutex_t alsa_pcm_lock;
//struct pcm *pcm_handle[ALSA_DEVICE_CNT];
//int pcm_refs[ALSA_DEVICE_CNT];
//bool is_paused[ALSA_DEVICE_CNT];
struct aml_hw_mixer hw_mixer;
audio_format_t sink_format;
bool sink_format_changed; // [SWPL-103792]
unsigned int sink_max_channels;
bool sink_allow_max_channel;
audio_format_t optical_format;
audio_format_t sink_capability;
audio_format_t last_sink_capability;
/* Dynamical config sink dolby/dts capability by hal_param cmd. */
bool auto_test_debug_flag;
audio_format_t sink_configured_dolby_capability; /* Option:mat/ddp/dd/pcm */
audio_format_t sink_configured_dts_capability; /* Option: dtshd/dts/pcm */
bool dual_spdifenc_inited;
/* Dolby MS12 lib variable start */
struct dolby_ms12_desc ms12;
bool dolby_ms12_need_recovery;
uint64_t a2dp_no_reconfig_ms12;
/* Dolby MS12 lib variable end */
/**
* enum eDolbyLibType
* DolbyDcvLib = dcv dec lib , libHwAudio_dcvdec.so
* DolbyMS12Lib = dolby MS12 lib, libdolbyms12.so
*/
int dolby_lib_type;
int dolby_lib_type_last;
aml_ms12_version_t *aml_dolby_lib_version;
int dev_ms12_version;
int dolby_decode_enable; /*it can decode dolby, not passthrough lib*/
int dts_lib_type;
int dts_decode_enable;
int dts_x_spk_drc_cut;
int dts_x_spk_drc_boost;
int dts_x_spk_drc_curve;
int dts_x_hdmi_drc_cut;
int dts_x_hdmi_drc_boost;
int dts_x_hdmi_drc_curve;
int dts_x_spdif_drc_cut;
int dts_x_spdif_drc_boost;
int dts_x_spdif_drc_curve;
int dts_x_hp_drc_cut;
int dts_x_hp_drc_boost;
int dts_x_hp_drc_curve;
bool dtsx_drc_enable;
/*used for dts decoder*/
struct dca_dts_dec dts_hd;
/**
* buffer pointer whose data output to headphone
* buffer size equal to efect_buf_size
*/
void *spk_output_buf;
void *hp_output_buf;
void *spdif_output_buf;
void *tmp_process_buf;
size_t tmp_process_buf_size;
void *effect_buf;
size_t effect_buf_size;
size_t spk_tuning_lvl;
/* ringbuffer for tuning latency total buf size */
size_t spk_tuning_buf_size;
ring_buffer_t spk_tuning_rbuf;
bool mix_init_flag;
struct eq_drc_data eq_data;
struct drc_data Drc_data;
struct eq_data Eq_data;
/*used for high pricision A/V from amlogic amadec decoder*/
unsigned first_apts;
/*
first apts flag for alsa hardware prepare,true,need set apts to hw.
by default it is false as we do not need set the first apts in normal use case.
*/
bool first_apts_flag;
size_t frame_trigger_thred;
void *dev_to_mix_parser;
int delay_disable_continuous;
bool atoms_lock_flag;
bool need_remove_conti_mode;
int exiting_ms12;
bool doing_reinit_ms12; /*we are doing reinit ms12*/
bool doing_cleanup_ms12; /*we are doing cleanup ms12*/
bool ms12_to_be_cleanup;
struct timespec last_write_ts;
bool stream_write_data;
bool last_stream_write_data;
struct timespec ms12_exiting_start;
int debug_flag;
int dcvlib_bypass_enable;
int dtslib_bypass_enable;
float dts_post_gain;
/*atsc has video in program*/
bool is_has_video;
bool patch_mute;//it is only used for HDMI/AV/ATV source
bool dtv_mute; // it is only used for DTV source
/*amlogic soft ware noise gate fot analog TV source*/
int source_mute;
int system_app_mixing_status;
int audio_type;
struct aml_mixer_handle alsa_mixer;
struct amlAudioMixer *audio_mixer;
pthread_mutex_t audio_mixer_lock;
bool useSubMix;
//int cnt_stream_using_mixer;
int tsync_fd;
/* After parameters are delivered to a running pcm device, or the raw is converted to pcm,
enabling this flag indicates that the pcm device needs restart
1. When spdif/eARC devices close, we set this flag to restart pcm device and enable samesource.
2. For some kctrls that cannot be set runtime, we set this flag to restart pcm device and make these kctrls take effect.
*/
bool restart_device_flag;
bool is_netflix;
bool is_netflix_hide;
uint64_t netflix_hide_fadeout_startTime;
int dtv_aformat;
int need_reset_ringbuffer;
unsigned int tv_mute;
bool compensate_video_enable;
int count;
int sound_track_mode;
void *alsa_handle[ALSA_DEVICE_CNT];
pthread_mutex_t alsa_lock[ALSA_DEVICE_CNT];
void *spdif_handle[SPDIF_HANDLE_CNT];
pthread_mutex_t spdif_handle_lock[SPDIF_HANDLE_CNT];
void *input_handle[AUDIO_INPUT_TYPE_CNT];
pthread_mutex_t input_handle_lock[AUDIO_INPUT_TYPE_CNT];
int32_t *tmp_buffer_8ch;
size_t tmp_buffer_8ch_size;
int FactoryChannelReverse;
int audio_process_bitwidth;
bool dual_spdif_support; /*1 means supports spdif_a & spdif_b & spdif interface*/
bool ms12_force_ddp_out; /*1 force ms12 output ddp*/
int ms12_cpu_affinity;
int ms12_thread_priority;
int out_write_thread_priority;
uint64_t sys_audio_frame_written;
uint64_t deep_buf_audio_frame_written;
struct aec_t *aec;
struct aec_context *aml_aec;
bool bt_wbs;
int security_mem_level;
int dolby_ms12_dap_init_mode;
enum ms12_config dolby_ms12_audio_config;
/* display audio format on UI, both streaming and hdmiin*/
audio_hal_info_t audio_hal_info;
bool is_ms12_tuning_dat; /* a flag to determine the MS12 tuning data file is existing */
char ms12_tuning_dat_path[AUDIO_HAL_CHAR_MAX_LEN];
/*
defined for default speaker output channels:
stb: default 2 channels.
tv: default 8 channels(2ch speaker,2ch spdif,2ch headphone)
soundbar:depending on the prop defined by device
*/
int default_alsa_ch;
uint64_t gap_offset;
uint32_t gap_pts;
bool gap_ignore_pts;
int gap_passthrough_state;
uint32_t gap_passthrough_ms12_no_output_counter;
bool arc_connected_reconfig; /*when arc connected, set it as to true*/
float master_volume;
bool master_mute;
/*A consistent loudness level must be maintained at the PCM output, for the Dolby or other audio formats. */
/*It is desirable that the bitstream output(over S/PDIF, HDMI, or eARC) should be played back at a consistent level.*/
int loudness_level;//Specify the loudness level of decoding output
int vol_ease_setting_state;
int vol_ease_setting_gain;
int vol_ease_setting_duration;
int vol_ease_setting_shape;
float record_volume_before_mute;//Record the master volume before mute
#ifndef NO_AUDIO_CAP
/* CapTure IpcBuffer */
void * capture_handle;
pthread_mutex_t cap_handle_lock;
int cap_delay;
#endif
int synctype; //tsplayer TS mode input set
int injection_enable;
#ifdef USE_MEDIAINFO
void *minfo_h;
uint32_t info_rid;
int minfo_atmos_flag;
#endif
bool audio_focus_enable;
int audio_focus_volume;
float audio_focus_ratio;
uint32_t decoder_drc_control;
uint32_t dap_drc_control;
bool drc_mode_ui_config;
uint32_t downmix_type;
/* board specific json configs */
int hdmitx_src; /* HDMITX src select for TDM */
bool spdif_independent; /*spdif output can be independent with HDMI output*/
enum AML_SRC_TO_HDMITX hdmitx_multi_ch_src;
enum AML_SRC_TO_HDMITX hdmitx_hbr_src;
aml_dec_info_t dec_stream_info;
bool reset_hdmitx_audio;
/* -End- */
bool user_setting_scaletempo;
bool is_hdmi_arc_interact_done;
bool ms12_dynamic_sleep;
struct aml_post_effect_ctrl effect_ctrl;
#ifdef NO_SERVER
pthread_t audio_debug_thread; //add for NO_SERVER
bool audio_debug_thread_exit;
#endif
bool audio_low_latency; //add for NTS LLP
void * kara_manager;
enum dtv_standards dvb_standards;
ring_buffer_t spdif_rbuf;
//output channel
int output_multipcm_ch;
int output_pcm_ch;
int output_dd_ch;
int output_ddp_ch;
int output_mat_ch;
int gap_passthrough_ms12_skip_output_counter;
int advol_level;
int mixing_level;
volatile int32_t next_unique_ID;
bool eq_enable;
char eq_param[256];
eq_hw_band_data_s eq_hw_band_data[EQ_HW_BAND_MAX_NUM];
bool hpf_enable;
char Hdmi_EDID[EDID_ARRAY_MAX_LEN];//EDID from json config
uint32_t Hdmi_EDID_len;//EDID length from json config
bool low_latency_mode;
bool low_latency_mode_changed;
bool is_early_suspend;
bool has_hwmixer;
pthread_mutex_t hwmixer_mgr_lock;
void * hwmixer_manager;
void * hwmixer_handle;
audio_hbbtvsync_t hbbtvsync_info;
bool enable_soundbar_mode;
bool enable_deep_unit;
audio_unit *deep_unit;
audio_unit *mixer_unit;
int sbr_spk_ott_hbr_same_tdm;
void *llp_ctx;
pthread_mutex_t llp_lock;
int max_audio_delay;
void *aml_command_worker;
struct aml_enc_ctx encoder_ctx;
void *headphone_limiter;
void *mpegh_ui_persistencemem;
void *mpegh_base64_encode_mem;
int mpegh_ui_persistencememsize;
int mpegh_decode_enable;
eAmlAiAudioType aml_ai_audio_type;
int ai_external_isolate_latency;
char *mpegh_audioscenexml;
size_t mpegh_audioscenexmlsize;
};
struct meta_data {
uint32_t frame_size;
uint64_t pts;
uint64_t payload_offset;
};
struct meta_data_list {
struct listnode list;
struct meta_data mdata;
};
typedef enum {
AUDIO_PARAMTYPE_DEC_STATUS = 0,
AUDIO_PARAMTYPE_PTS,
AUDIO_PARAMTYPE_SAMPLE_RATE,
AUDIO_PARAMTYPE_CHANNEL_MODE,
AUDIO_PARAMTYPE_DIGITAL_AUDIO_INFO,
} audio_paramtype;
typedef enum audio_data_handle_state {
AUDIO_DATA_HANDLE_NONE = 0,
AUDIO_DATA_HANDLE_START,
AUDIO_DATA_HANDLE_DETECT,
AUDIO_DATA_HANDLE_DETECTED,
AUDIO_DATA_HANDLE_EASE_CONFIG,
AUDIO_DATA_HANDLE_EASING,
AUDIO_DATA_HANDLE_FINISHED,
AUDIO_DATA_HANDLE_MAX
} audio_data_handle_state_t;
typedef struct aml_dec_param {
int ad_mix_enable;
int advol_level;
int mixing_level;
int ac4_ad_type;
int ac4_prefer_presentation_selection;
int ac4_presentation_id;
int ac4_de;
/* <2 int>
- de_enable (0,1, def: 0)
- de_amount (0...16, def: 0)
*/
int dap_de[2]; //For STB dap, dap is in codec graph (de_enable,de_amount)
/*
*-dap_leveler * <2 int>
* - leveler_setting (0, 1, 2 def: 0)
* 0:OFF
* 1:ON
* 2:AUTO
* - leveler_amount (0...10, def: 4)
*/
int dap_leveler[2]; //For STB dap, dap is in codec graph
unsigned int hal_decode_block_size;
float dec_gain;
char ac4_1st_lang[4];
char ac4_2nd_lang[4];
} aml_dec_param_t;
enum {
AVSYNC_TYPE_NULL = 0,
AVSYNC_TYPE_TSYNC = 1,
AVSYNC_TYPE_MSYNC = 2,
AVSYNC_TYPE_MEDIASYNC = 3,
};
typedef struct aml_spdif_data_info {
audio_format_t data_format;
int data_ch;
int data_sr;
} aml_spdif_data_info_t;
typedef struct mixer_buf {
struct audio_buffer mix_buffer;
unsigned int buf_size;
bool consumed; //this buffer is consumed or not
pthread_mutex_t lock;
pthread_cond_t cond;
} mix_buf_t;
struct aml_stream_out {
struct audio_stream_out stream;
/* see note below on mutex acquisition order */
pthread_mutex_t lock;
struct audio_config audioCfg;
/* config which set to ALSA device */
struct pcm_config config;
/* channel mask exposed to AudioFlinger. */
audio_channel_mask_t hal_channel_mask;
/* format mask exposed to AudioFlinger. */
audio_format_t hal_format;
/* samplerate exposed to AudioFlinger. */
unsigned int hal_rate;
unsigned int hal_ch;
unsigned int hal_frame_size;
aml_dec_param_t dec_param;
audio_output_flags_t flags;
audio_devices_t out_device;
struct pcm *pcm;
size_t buffer_frames;
bool standby;
struct aml_audio_device *dev;
int write_threshold;
bool low_power;
int codec_type;
uint64_t frame_write_sum;
uint64_t last_frames_position;
bool pause_status;
bool need_sync;
bool with_header;
bool internal_mute;//internal mute
bool external_mute;// external mute
bool final_mute;
float volume_l_org;
float volume_r_org;
float last_volume_l_org; //record stream volume before mute
float last_volume_r_org;
float volume_l;
float volume_r;
float last_volume_l;
float last_volume_r;
float drc_mode_volume;
float last_drc_mode_volume;
int last_codec_type;
audio_header_t *pheader;
struct timespec timestamp;
struct timespec lasttimestamp;
stream_type_t stream_type;
/**
* flag indicates that this stream need do mixing
* int is_in_mixing: 1;
* Normal pcm may not hold alsa pcm device.
*/
int is_normal_pcm;
unsigned int card;
alsa_device_t device;
ssize_t (*write)(struct audio_stream_out *stream, struct audio_buffer *abuffer);
audio_format_t hal_internal_format;
bool dual_output_flag;
uint64_t input_bytes_size;
uint64_t continuous_audio_offset;
bool direct_raw_config;
bool is_device_differ_with_ms12;
uint64_t total_write_size;
uint64_t payload_offset;
int ddp_frame_size;
int dropped_size;
unsigned long long mute_bytes;
bool is_get_mute_bytes;
uint32_t latency_frames;
int inputPortID;
int inputPortType;
int exiting;
pthread_mutex_t cond_lock;
pthread_cond_t cond;
struct hw_avsync_header_extractor *hwsync_extractor;
struct listnode mdata_list;
pthread_mutex_t mdata_lock;
bool first_pts_set;
bool need_first_sync;
uint64_t last_pts;
uint64_t next_parsered_pts;
uint64_t last_payload_offset;
audio_channel_mask_t last_channel_mask;
int debug_stream;
uint64_t us_used_last_write;
bool offload_mute;
bool need_convert;
size_t last_playload_used;
int ddp_frame_nblks;
uint64_t total_ddp_frame_nblks;
int framevalid_flag;
bool bypass_submix;
int position_update;
bool spdifenc_init;
bool hal_input_is_float; /* AF writes PCM float; HAL works as PCM16 after convert */
void *spdifenc_handle;
bool dual_spdif;
int codec_type2; /*used for dual bitstream output*/
struct pcm *pcm2; /*used for dual bitstream output*/
int pcm2_mute_cnt;
bool tv_src_stream;
uint64_t last_frame_reported;
struct timespec last_timestamp_reported;
void *pstMmapAudioParam; // aml_mmap_audio_param_st (aml_mmap_audio.h)
struct resample_para aml_resample;
unsigned char *resample_outbuf;
bool restore_hdmitx_selection;
bool restore_continuous;
bool restore_dolby_lib_type;
void * aml_parser;
void * mpegh_uimanager_handle;
int64_t last_mmap_nano_second;
int32_t last_mmap_position;
uint64_t main_input_ns;
bool is_sink_format_prepared;
bool is_ms12_main_decoder;
aml_dec_config_t dec_config; /*store the decode config*/
aml_dec_t *aml_dec; /*store the decoder handle*/
struct dolby_ms12_dec_desc *ms12_dec_handle;
int ad_substream_supported;
aml_audio_resample_t *resample_handle;
/*spdif output related info start*/
audio_format_t optical_format;
aml_spdif_data_info_t spdif_data_info;
/*spdif output related info end*/
bool is_add2active_output;
uint32_t alsa_write_cnt;
uint64_t alsa_write_frames;
aml_audio_ease_t *vol_process_handle;// this is only used for ms12 case
audio_hal_vol_t stream_vol_setting;
aml_audio_ease_t *audio_stream_ease;
audio_data_handle_state_t audio_data_handle_state;
uint16_t easing_time;
float output_speed;
uint64_t write_time;
uint64_t pause_time;
int write_count;
int avsync_type;
avsync_ctx_t *avsync_ctx;
bool is_dtscd;
bool dts_check;
/*flag indicate the ms12 2ch lock is on*/
bool ms12_acmod2ch_lock_disable;
bool frame_write_sum_updated;
uint64_t dolby_ms12_input_main_sum;
uint64_t parse_consumed_size;
unsigned int parser_frame_size;
//DTV sync
bool set_init_avsync_policy;
bool enable_scaletempo;
struct scale_tempo * scaletempo;
bool b_install_sync_callback;
bool will_pause;
bool will_flush;
int fast_quit;
bool eos;
//partial audio frame
clip_meta_t *clip_meta;
bool b_install_clip_callback;
uint64_t clip_offset;
/* for dcvlib clip only start */
uint64_t dec_cachedsize;
uint64_t consumedsize;
/* for dcvlib clip only end */
int64_t drop_start; //pts90
int64_t drop_duration; //pts90
float source_volume;
stream_source_type_t source_type;
struct aml_hw_mixer *mixer_handle;
struct mixer_buf *mix_buf;
int32_t unique_ID; //stream id
int32_t decoder_id; //this for up-layer binding stream.
int scale_state;
int64_t scale_start_apts;
float rate;
uint64_t u64DecOutFrame;
aml_port *deep_inport;
int get_dec_info_count;
uint32_t eos_ease_timer;
aml_pcm_downmix_st pcm_downmix;
void *downmix_tmp_buf;
size_t downmix_tmp_buf_size;
void *float_to_s32_tmp_buf;
size_t float_to_s32_tmp_buf_size;
bool is_airplay;
bool is_aacpcm;
bool async_resume;
};
typedef ssize_t (*write_func)(struct audio_stream_out *stream, const void *buffer, size_t bytes);
#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */
struct aml_stream_in {
struct audio_stream_in stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
struct pcm_config config;
audio_input_type_e input_type;
audio_devices_t device;// For patch stream, this value can indicate the patch source, such as AUDIO_DEVICE_IN_LINE...
audio_channel_mask_t hal_channel_mask;
audio_format_t hal_format;
struct resampler_itfe *resampler;
struct resampler_buffer_provider buf_provider;
int16_t *buffer;
size_t frames_in;
unsigned int requested_rate;
uint32_t main_channels;
bool standby;
int source;
struct echo_reference_itfe *echo_reference;
bool need_echo_reference;
effect_handle_t preprocessors[MAX_PREPROCESSORS];
int num_preprocessors;
int16_t *proc_buf;
size_t proc_buf_size;
size_t proc_frames_in;
int16_t *ref_buf;
size_t ref_buf_size;
size_t ref_frames_in;
int read_status;
struct aml_audio_device *dev;
unsigned int frames_read;
uint64_t timestamp_nsec;
bool bt_sco_active;
int32_t unique_ID; //stream id
aml_port *capture_port;
};
typedef enum {
CALLBACK_SCALE_TEMPO = 0,
CALLBACK_LLP_BUFFER = 1,
CALLBACK_CLIP_META = 2,
} ms12_callback_type_t;
typedef int (*do_standby_func)(struct audio_stream *out);
static inline bool direct_continous(struct audio_stream_out *stream)
{
struct aml_stream_out *out = (struct aml_stream_out *)stream;
if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
return true;
} else {
return false;
}
}
/* called when adev locked */
static inline int dolby_stream_active(struct aml_audio_device *adev)
{
int i = 0;
int is_dolby = 0;
struct aml_stream_out *out = NULL;
for (i = 0 ; i < STREAM_NUM_MAX; i++) {
out = adev->active_outputs[i];
if (out && (out->hal_internal_format == AUDIO_FORMAT_AC3
|| out->hal_internal_format == AUDIO_FORMAT_E_AC3
|| out->hal_internal_format == AUDIO_FORMAT_DOLBY_TRUEHD
|| out->hal_internal_format == AUDIO_FORMAT_AC4
|| out->hal_internal_format == AUDIO_FORMAT_MAT
|| out->hal_internal_format == AUDIO_FORMAT_HE_AAC_V1
|| out->hal_internal_format == AUDIO_FORMAT_HE_AAC_V2)) {
is_dolby = 1;
break;
}
}
return is_dolby;
}
/* called when adev locked */
static inline int dts_stream_active(struct aml_audio_device *adev)
{
int i = 0;
int is_dts = 0;
struct aml_stream_out *out = NULL;
for (i = 0 ; i < STREAM_NUM_MAX; i++) {
out = adev->active_outputs[i];
if (out && (out->hal_internal_format == AUDIO_FORMAT_DTS
|| out->hal_internal_format == AUDIO_FORMAT_DTS_HD)) {
is_dts = 1;
break;
}
}
return is_dts;
}
/* called when adev locked */
static inline int hwsync_lpcm_active(struct aml_audio_device *adev)
{
int i = 0;
int is_hwsync_lpcm = 0;
struct aml_stream_out *out = NULL;
for (i = 0 ; i < STREAM_NUM_MAX; i++) {
out = adev->active_outputs[i];
if (out && audio_is_linear_pcm(out->hal_internal_format) && (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC)) {
is_hwsync_lpcm = 1;
break;
}
}
return is_hwsync_lpcm;
}
static inline struct aml_stream_out *direct_active(struct aml_audio_device *adev)
{
int i = 0;
struct aml_stream_out *out = NULL;
for (i = 0 ; i < STREAM_NUM_MAX; i++) {
out = adev->active_outputs[i];
if (out && (out->flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
return out;
}
}
return NULL;
}
static inline bool is_bypass_submix_active(struct aml_audio_device *adev)
{
int i = 0;
struct aml_stream_out *out = NULL;
for (i = 0 ; i < STREAM_NUM_MAX; i++) {
out = adev->active_outputs[i];
if (out && (out->bypass_submix)) {
return true;
}
}
return false;
}
/* called when adev locked */
static inline int get_mmap_pcm_active_count(struct aml_audio_device *adev)
{
int i = 0;
int count = 0;
struct aml_stream_out *out = NULL;
for (i = 0 ; i < STREAM_NUM_MAX; i++) {
out = adev->active_outputs[i];
if (out && audio_is_linear_pcm(out->hal_internal_format) && (out->stream_type == STREAM_APP_INPUT)) {
count ++;
}
}
return count;
}
/*
*@brief get_output_format get the output format always return the "sink_format" of adev
*/
audio_format_t get_output_format(struct audio_stream_out *stream);
int do_output_standby_l(struct audio_stream *stream);
int dsp_process_output(struct aml_audio_device *adev, void *in_buffer,
size_t bytes);
enum hwsync_status check_hwsync_status (uint32_t apts_gap);
bool is_low_latency_mode_changed(struct aml_audio_device *aml_dev);
bool is_low_latency_mode(struct aml_audio_device *aml_dev);
void update_low_latency_mode(struct aml_audio_device *aml_dev);
int reconfig_encoder(struct audio_stream_out *stream);
int out_standby_direct (struct audio_stream *stream);
int adev_update_decoder_mute_state (struct audio_hw_device *dev);
void *adev_get_handle();
int start_input_stream(struct aml_stream_in *in);
int do_input_standby (struct aml_stream_in *in);
int adev_ms12_prepare(struct audio_hw_device *dev);
void adev_ms12_cleanup(struct audio_hw_device *dev);
int aml_decoder_reset_wrapper(struct audio_stream_out *stream);
int aml_decoder_init_wrapper(struct audio_stream_out *stream);
int ms12_clipmeta(void *priv_data, void *info, unsigned long long offset);
void out_set_playback_rate (struct audio_stream *stream, float rate);
int get_stream_source_volume(struct aml_stream_out *aml_out);
void set_rate_to_sync (struct aml_stream_out *aml_out, float rate);
void out_set_stream_mute (struct audio_stream_out *stream, bool mute, bool is_external_mute);
void set_ms12_focus_by_stream_volume (struct aml_audio_device *adev);
/* 'bytes' are the number of bytes written to audio FIFO, for which 'timestamp' is valid.
* 'available' is the number of frames available to read (for input) or yet to be played
* (for output) frames in the PCM buffer.
* timestamp and available are updated by pcm_get_htimestamp(), so they use the same
* datatypes as the corresponding arguments to that function. */
struct aec_info {
struct timespec timestamp;
uint64_t timestamp_usec;
unsigned int available;
size_t bytes;
};
/* Capture codec parameters */
/* Set up a capture period of 32 ms:
* CAPTURE_PERIOD = PERIOD_SIZE / SAMPLE_RATE, so (32e-3) = PERIOD_SIZE / (16e3)
* => PERIOD_SIZE = 512 frames, where each "frame" consists of 1 sample of every channel (here, 2ch) */
#define CAPTURE_PERIOD_MULTIPLIER 16
#define CAPTURE_PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * CAPTURE_PERIOD_MULTIPLIER)
#define CAPTURE_PERIOD_START_THRESHOLD 4
#define CAPTURE_CODEC_SAMPLING_RATE 16000
#define CODEC_BASE_FRAME_COUNT 32
#define PLAYBACK_PERIOD_MULTIPLIER 32 /* 21 ms */
#define PLAYBACK_PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * PLAYBACK_PERIOD_MULTIPLIER)
#define CHANNEL_STEREO 2
#define PLAYBACK_CODEC_SAMPLING_RATE 48000
#endif