This commit is contained in:
huxi
2025-12-03 11:12:34 +08:00
parent c23ae4f24c
commit bc195654bf
8163 changed files with 3799544 additions and 92 deletions
@@ -0,0 +1,539 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".jlstream_event_handler.data.bss")
#pragma data_seg(".jlstream_event_handler.data")
#pragma const_seg(".jlstream_event_handler.text.const")
#pragma code_seg(".jlstream_event_handler.text")
#endif
#include "jlstream.h"
#include "overlay_code.h"
#include "media/audio_base.h"
#include "media/audio_general.h"
#include "clock_manager/clock_manager.h"
#include "a2dp_player.h"
#include "esco_player.h"
#include "app_tone.h"
#include "app_config.h"
#include "effects/effects_adj.h"
#include "audio_manager.h"
#include "file_player.h"
#include "linein_player.h"
#include "fm_player.h"
#include "spdif_player.h"
#include "pc_spk_player.h"
#include "app_main.h"
#include "classic/tws_api.h"
#include "call/call_common.h"
#define PIPELINE_UUID_TONE_NORMAL 0x7674
#define PIPELINE_UUID_A2DP 0xD96F
#define PIPELINE_UUID_ESCO 0xBA11
#define PIPELINE_UUID_LINEIN 0x1207
#define PIPELINE_UUID_SPDIF 0x96BE
#define PIPELINE_UUID_MUSIC 0x2A09
#define PIPELINE_UUID_FM 0x05FB
#define PIPELINE_UUID_MIC_EFFECT 0x9C2D
#define PIPELINE_UUID_MEDIA 0x1408
#define PIPELINE_UUID_A2DP_DUT 0xC9DB
#define PIPELINE_UUID_PC_AUDIO 0xDC8D
#define PIPELINE_UUID_RECODER 0x49EC
#define PIPELINE_UUID_AI_VOICE 0x5475
#define PIPELINE_UUID_AVI_VOICE 0x10BB
#if TCFG_A2DP_PREEMPTED_ENABLE
const int CONFIG_A2DP_ENERGY_CALC_ENABLE = 0;
#else
const int CONFIG_A2DP_ENERGY_CALC_ENABLE = 1;
#endif
static u8 g_a2dp_slience;
static u32 g_a2dp_slience_begin;
static void a2dp_energy_detect_handler(int *arg)
{
// cppcheck-suppress knownConditionTrueFalse
if (CONFIG_A2DP_ENERGY_CALC_ENABLE == 0) {
return;
}
int energy = arg[0];
if (energy == 0) {
if (g_a2dp_slience_begin == 0) {
g_a2dp_slience_begin = jiffies_msec();
} else {
int msec = jiffies_msec2offset(g_a2dp_slience_begin, jiffies_msec());
if (msec >= 2000 && g_a2dp_slience == 0) {
g_a2dp_slience = 1;
audio_event_to_user(AUDIO_EVENT_A2DP_NO_ENERGY);
}
}
} else {
g_a2dp_slience = 0;
g_a2dp_slience_begin = 0;
}
}
int get_system_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_TONE_NORMAL, par);
}
int get_media_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_MEDIA, par);
}
int get_esco_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_ESCO, par);
}
int get_mic_eff_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_MIC_EFFECT, par);
}
int get_usb_audio_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_PC_AUDIO, par);
}
static int get_pipeline_uuid(const char *name)
{
#if defined(MEDIA_UNIFICATION_EN)&&MEDIA_UNIFICATION_EN
if (!strcmp(name, "tone")) {
return PIPELINE_UUID_TONE_NORMAL;
}
if (!strcmp(name, "ring")) {
clock_alloc("esco", 48 * 1000000UL);
return PIPELINE_UUID_TONE_NORMAL;
}
if (!strcmp(name, "esco")) {
clock_alloc("esco", 48 * 1000000UL);
return PIPELINE_UUID_ESCO;
}
if (!strcmp(name, "mic_effect")) {
clock_alloc("mic_effect", 24 * 1000000UL);
return PIPELINE_UUID_MIC_EFFECT;
}
if (!strcmp(name, "pc_spk")) {
clock_alloc("pc_spk", 96 * 1000000UL);
return PIPELINE_UUID_PC_AUDIO;
}
if (!strcmp(name, "pc_mic")) {
clock_alloc("pc_mic", 96 * 1000000UL);
return PIPELINE_UUID_PC_AUDIO;
}
if (!strcmp(name, "mix_recorder")) {
return PIPELINE_UUID_RECODER;
}
if (!strcmp(name, "ai_voice")) {
/* clock_alloc("a2dp", 24 * 1000000UL); */
return PIPELINE_UUID_AI_VOICE;
}
if (!strcmp(name, "avi_voice")) {
/* clock_alloc("a2dp", 24 * 1000000UL); */
return PIPELINE_UUID_AVI_VOICE;
}
if (!strcmp(name, "a2dp")) {
clock_alloc("a2dp", 24 * 1000000UL);
#if TCFG_AUDIO_DUT_ENABLE
if (audio_dec_dut_en_get(0)) {
return PIPELINE_UUID_A2DP_DUT;
}
#endif
}
if (!strcmp(name, "music")) {
clock_alloc("music", 24 * 1000000UL);
}
if (!strcmp(name, "linein")) {
//此处设置时钟不低于120M是由于切时钟会停止cpu,多次切会导致DAC缓存少于1ms
clock_alloc("linein", 120 * 1000000UL);
}
if (!strcmp(name, "fm")) {
clock_alloc("fm", 48 * 1000000UL);
}
if (!strcmp(name, "iis")) {
clock_alloc("iis", 48 * 1000000UL);
}
return PIPELINE_UUID_MEDIA;
#else
if (!strcmp(name, "tone")) {
if (a2dp_player_runing()) {
return PIPELINE_UUID_A2DP;
}
if (esco_player_runing()) {
return PIPELINE_UUID_ESCO;
}
if (ring_player_runing()) {
return PIPELINE_UUID_ESCO;
}
if (music_player_runing()) {
return PIPELINE_UUID_MUSIC;
}
if (linein_player_runing()) {
return PIPELINE_UUID_LINEIN;
}
return PIPELINE_UUID_TONE_NORMAL;
}
if (!strcmp(name, "ring")) {
clock_alloc("esco", 48 * 1000000UL);
return PIPELINE_UUID_ESCO;
}
if (!strcmp(name, "esco")) {
clock_alloc("esco", 48 * 1000000UL);
return PIPELINE_UUID_ESCO;
}
if (!strcmp(name, "a2dp")) {
clock_alloc("a2dp", 24 * 1000000UL);
return PIPELINE_UUID_A2DP;
}
if (!strcmp(name, "music")) {
clock_alloc("music", 24 * 1000000UL);
return PIPELINE_UUID_MUSIC;
}
if (!strcmp(name, "linein")) {
struct app_mode *mode = app_get_current_mode();
if (mode && mode->name == APP_MODE_BT) {
clock_alloc("a2dp", 24 * 1000000UL);
return PIPELINE_UUID_A2DP;
} else {
clock_alloc("linein", 24 * 1000000UL);
return PIPELINE_UUID_LINEIN;
}
}
if (!strcmp(name, "mix_recorder")) {
return PIPELINE_UUID_RECODER;
}
if (!strcmp(name, "spdif")) {
//spdif 192k采样率输入,同步节点硬件SRC,时钟至少为160MHz
clock_alloc("spdif", 160 * 1000000UL);
return PIPELINE_UUID_SPDIF;
}
if (!strcmp(name, "fm")) {
clock_alloc("fm", 48 * 1000000UL);
return PIPELINE_UUID_FM;
}
if (!strcmp(name, "mic_effect")) {
clock_alloc("mic_effect", 24 * 1000000UL);
return PIPELINE_UUID_MIC_EFFECT;
}
if (!strcmp(name, "a2dp_dut")) {
clock_alloc("a2dp", 24 * 1000000UL);
return PIPELINE_UUID_A2DP_DUT;
}
if (!strcmp(name, "ai_voice")) {
/* clock_alloc("a2dp", 24 * 1000000UL); */
return PIPELINE_UUID_AI_VOICE;
}
#endif
return 0;
}
static void player_close_handler(const char *name)
{
if (!strcmp(name, "a2dp") || !strcmp(name, "a2dp_dut")) {
clock_free("a2dp");
} else if (!strcmp(name, "esco") || !strcmp(name, "ring")) {
clock_free("esco");
} else if (!strcmp(name, "linein")) {
clock_free("linein");
} else if (!strcmp(name, "music")) {
clock_free("music");
} else if (!strcmp(name, "mic_effect")) {
clock_free("mic_effect");
} else if (!strcmp(name, "fm")) {
clock_free("fm");
} else if (!strcmp(name, "pc_spk")) {
clock_free("pc_spk");
} else if (!strcmp(name, "pc_mic")) {
clock_free("pc_mic");
}
if (!strcmp(name, "iis")) {
clock_free("iis");
}
}
#if TCFG_CODE_RUN_RAM_AAC_CODE
static void *aac_code_run_addr = NULL;
extern u32 __aac_movable_slot_start[];
extern u32 __aac_movable_slot_end[];
extern u8 __aac_movable_region_start[];
extern u8 __aac_movable_region_end[];
#endif
#if TCFG_CODE_RUN_RAM_AEC_CODE
static void *aec_code_run_addr = NULL;
extern u32 __aec_movable_slot_start[];
extern u32 __aec_movable_slot_end[];
extern u8 __aec_movable_region_start[];
extern u8 __aec_movable_region_end[];
#endif
void aac_code_movable_load(void)
{
#if TCFG_CODE_RUN_RAM_AAC_CODE
int aac_code_size = __aac_movable_region_end - __aac_movable_region_start;
mem_stats();
if (aac_code_size && !aac_code_run_addr) {
aac_code_run_addr = phy_malloc(aac_code_size);
}
if (!aac_code_run_addr) {
return;
}
code_movable_load(__aac_movable_region_start, aac_code_size, aac_code_run_addr, __aac_movable_slot_start, __aac_movable_slot_end);
printf("aac code load addr : 0x%x, size : %d\n", (u32)aac_code_run_addr, aac_code_size);
mem_stats();
#endif
}
void aac_code_movable_unload(void)
{
#if TCFG_CODE_RUN_RAM_AAC_CODE
if (aac_code_run_addr) {
mem_stats();
code_movable_unload(__aac_movable_region_start, __aac_movable_slot_start, __aac_movable_slot_end);
phy_free(aac_code_run_addr);
aac_code_run_addr = NULL;
printf("aac code unload\n");
mem_stats();
}
#endif
}
void aec_code_movable_load(void)
{
#if TCFG_CODE_RUN_RAM_AEC_CODE
int aec_code_size = __aec_movable_region_end - __aec_movable_region_start;
mem_stats();
if (aec_code_size && !aec_code_run_addr) {
aec_code_run_addr = phy_malloc(aec_code_size);
}
if (!aec_code_run_addr) {
return;
}
code_movable_load(__aec_movable_region_start, aec_code_size, aec_code_run_addr, __aec_movable_slot_start, __aec_movable_slot_end);
printf("aec code load addr : 0x%x, size : %d\n", (u32)aec_code_run_addr, aec_code_size);
mem_stats();
#endif
}
void aec_code_movable_unload(void)
{
#if TCFG_CODE_RUN_RAM_AEC_CODE
if (aec_code_run_addr) {
mem_stats();
code_movable_unload(__aec_movable_region_start, __aec_movable_slot_start, __aec_movable_slot_end);
phy_free(aec_code_run_addr);
aec_code_run_addr = NULL;
printf("aec code unload\n");
mem_stats();
}
#endif
}
static int load_decoder_handler(struct stream_decoder_info *info)
{
if (info->coding_type == AUDIO_CODING_AAC) {
/*printf("overlay_lode_code: aac\n");*/
aac_code_movable_load();
}
if (info->scene == STREAM_SCENE_A2DP) {
g_a2dp_slience = 0;
g_a2dp_slience_begin = 0;
info->task_name = "a2dp_dec";
}
if (info->scene == STREAM_SCENE_ESCO) { //AEC PLC共用overlay
}
if (info->scene == STREAM_SCENE_MUSIC) {
info->task_name = "file_dec";
}
return 0;
}
static void unload_decoder_handler(u32 coding_type)
{
if (coding_type == AUDIO_CODING_AAC) {
aac_code_movable_unload();
}
}
static int load_encoder_handler(struct stream_encoder_info *info)
{
if (info->scene == STREAM_SCENE_ESCO) {
//AEC overlay归节点自己管理, 不依赖编码
/* printf("overlay_lode_code: aec\n"); */
/* overlay_load_code(OVERLAY_AEC); */
/* aec_code_movable_load(); */
}
return 0;
}
static void unload_encoder_handler(struct stream_encoder_info *info)
{
if (info->scene == STREAM_SCENE_ESCO) {
/* aec_code_movable_unload(); */
}
}
/*
*获取需要指定得默认配置
* */
static int get_node_parm(int arg)
{
int ret = 0;
ret = get_eff_default_param(arg);
return ret ;
}
/*
*获取ram内在线音效参数
*/
static int get_eff_online_parm(int arg)
{
int ret = 0;
#if TCFG_CFG_TOOL_ENABLE
ASSERT(arg);
struct eff_parm {
int uuid;
char name[16];
u8 data[0];
};
struct eff_parm *parm = (struct eff_parm *)arg;
/* printf("eff_online_uuid %x, %s\n", parm->uuid, parm->name); */
ret = get_eff_online_param(parm->uuid, parm->name, (void *)arg);
#endif
return ret;
}
static int tws_switch_get_status()
{
int state = tws_api_get_tws_state();
if (state & TWS_STA_SIBLING_DISCONNECTED) {
return 0;
}
return 1;
}
static int a2dp_switch_get_status()
{
#if TCFG_USER_EMITTER_ENABLE
extern u8 *get_cur_connect_emitter_mac_addr(void);
void *bt_addr = get_cur_connect_emitter_mac_addr();
if (bt_addr) {
return 1;
}
#endif
return 0;
}
static int dac_switch_get_status()
{
if (!a2dp_switch_get_status()) {
return 1;
}
return 0;
}
static int get_switch_node_callback(const char *arg)
{
if (!strcmp(arg, "TWS_Switch")) {
return (int)tws_switch_get_status;
}
if (!strcmp(arg, "Switch_a2dp")) {
return (int)a2dp_switch_get_status;
}
if (!strcmp(arg, "Switch_dac")) {
return (int)dac_switch_get_status;
}
return 0;
}
static int jlstream_get_cvp_mode(void)
{
#if TCFG_SIRI_MODE_AEC_BYPASS /*SIRI模式省ram方式*/
if (call_ctrl_get_status() != BT_SIRI_STATE) {
return 1;
}
#endif
return 0;
}
int jlstream_event_notify(enum stream_event event, int arg)
{
int ret = 0;
switch (event) {
case STREAM_EVENT_LOAD_DECODER:
ret = load_decoder_handler((struct stream_decoder_info *)arg);
break;
case STREAM_EVENT_UNLOAD_DECODER:
unload_decoder_handler((u32)arg);
break;
case STREAM_EVENT_LOAD_ENCODER:
ret = load_encoder_handler((struct stream_encoder_info *)arg);
break;
case STREAM_EVENT_UNLOAD_ENCODER:
unload_encoder_handler((struct stream_encoder_info *)arg);
break;
case STREAM_EVENT_GET_PIPELINE_UUID:
ret = get_pipeline_uuid((const char *)arg);
r_printf("pipeline_uuid: %x\n", ret);
clock_refurbish();
break;
case STREAM_EVENT_CLOSE_PLAYER:
player_close_handler((const char *)arg);
break;
case STREAM_EVENT_INC_SYS_CLOCK:
clock_refurbish();
break;
case STREAM_EVENT_GET_NODE_PARM:
ret = get_node_parm(arg);
break;
case STREAM_EVENT_GET_EFF_ONLINE_PARM:
ret = get_eff_online_parm(arg);
break;
case STREAM_EVENT_A2DP_ENERGY:
a2dp_energy_detect_handler((int *)arg);
break;
#if TCFG_SWITCH_NODE_ENABLE
case STREAM_EVENT_GET_SWITCH_CALLBACK:
ret = get_switch_node_callback((const char *)arg);
break;
#endif
#if TCFG_SIRI_MODE_AEC_BYPASS
case STREAM_EVENT_GET_CVP_MODE:
ret = jlstream_get_cvp_mode();
break;
#endif
default:
break;
}
return ret;
}
+233
View File
@@ -0,0 +1,233 @@
#include "typedef.h"
#include "app_main.h"
#include "app_config.h"
#include "vol_sync.h"
#include "audio_config.h"
#include "app_tone.h"
#include "volume_node.h"
#include "mix_record_api.h"
#include "system/includes.h"
#include "app_action.h"
#include "default_event_handler.h"
#include "bt.h"
#include "tone_player.h"
#include "dev_manager.h"
#include "file_recorder.h"
#if TCFG_MIX_RECORD_ENABLE
struct mix_recode_handle {
void *recorder;
FILE *old_file;
FILE *new_file;
char logo[20];
int status;
const char *suffix;
};
static struct mix_recode_handle g_rec_hdl = {
.status = 0,
};
int mix_record_device_msg_handler(int *msg)
{
const char *logo = NULL;
int err = 0;
switch (msg[0]) {
case DRIVER_EVENT_FROM_SD0:
case DRIVER_EVENT_FROM_SD1:
case DRIVER_EVENT_FROM_SD2:
logo = (char *)msg[2];
case DEVICE_EVENT_FROM_USB_HOST:
if (!strncmp((char *)msg[2], "udisk", 5)) {
logo = (char *)msg[2];
}
if (msg[1] == DEVICE_EVENT_IN) {
} else if (msg[1] == DEVICE_EVENT_OUT) {
if (g_rec_hdl.recorder) {
if (!strcmp(g_rec_hdl.logo, logo)) {
mix_recorder_stop();
}
}
}
break;
default:
break;
}
return false;
}
static FILE *mix_recorder_open_file()
{
char folder[] = {TCFG_REC_FOLDER_NAME}; //录音文件夹名称
char filename[] = {TCFG_REC_FILE_NAME}; //录音文件名,不需要加后缀
#if (TCFG_NOR_REC)
char logo[] = {"rec_nor"}; //外挂flash录音
#elif (FLASH_INSIDE_REC_ENABLE)
char logo[] = {"rec_sdfile"}; //内置flash录音
#else
/* char *logo = dev_manager_get_phy_logo(dev_manager_find_active(0));//普通设备录音,获取最后活动设备 */
char logo[] = {RECODER_DEVICE_LOGO}; //sd卡录音
#endif
snprintf(g_rec_hdl.logo, sizeof(g_rec_hdl.logo), "%s", logo);
char *root_path = dev_manager_get_root_path_by_logo(logo);
char path[64] = {};
snprintf(path, sizeof(path), "%s%s/%s.%s", root_path, folder, filename, g_rec_hdl.suffix);
FILE *file = fopen(path, "w+");
if (!file) {
printf("recorder_open_file_faild: %s\n", path);
} else {
fget_name(file, (u8 *)path, 64);
printf("recorder_open_file_suss: %s\n", path);
}
return file;
}
static void file_ops_in_app_task(void *p)
{
switch ((int)p) {
case SEAMLESS_OPEN_FILE:
g_rec_hdl.new_file = mix_recorder_open_file();
break;
case SEAMLESS_CHANGE_FILE:
if (g_rec_hdl.old_file) {
fclose(g_rec_hdl.old_file);
g_rec_hdl.old_file = NULL;
}
break;
case -ENOENT:
mix_recorder_stop();
break;
}
}
/*
* 此回调函数在音频流任务中调用,不能执行耗时长的操作,否则可能导致音频播放卡顿
*/
static int change_file_in_stream_task(void *priv, enum change_file_step step)
{
int msg[4] = { (int)file_ops_in_app_task, 1, step};
if (step == SEAMLESS_CHANGE_FILE) {
g_rec_hdl.old_file = file_recorder_change_file(g_rec_hdl.recorder, g_rec_hdl.new_file);
if (g_rec_hdl.new_file) {
g_rec_hdl.new_file = NULL;
} else {
msg[2] = -ENOENT;
}
}
return os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
}
void mix_recorder_start()
{
int err;
void *recorder;
u16 uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"mix_recorder");
recorder = file_recorder_open(uuid, NODE_UUID_ADC);
/* recorder = file_recorder_open(uuid, NODE_UUID_ZERO_ACTIVE); */
if (!recorder) {
puts("file_recorder_open_faild\n");
return;
}
struct stream_enc_fmt fmt;
err = file_recorder_get_fmt(recorder, &fmt);
if (err) {
file_recorder_close(recorder, 0);
return;
}
printf("recorder_fmt: ch %d, sample rate %d\n", fmt.channel, fmt.sample_rate);
switch (fmt.coding_type) {
case AUDIO_CODING_PCM:
g_rec_hdl.suffix = "pcm";
break;
case AUDIO_CODING_WAV:
g_rec_hdl.suffix = "wav";
break;
case AUDIO_CODING_MP3:
g_rec_hdl.suffix = "mp3";
break;
case AUDIO_CODING_AMR:
g_rec_hdl.suffix = "amr";
break;
default:
g_rec_hdl.suffix = "bin";
break;
}
FILE *file = mix_recorder_open_file();
if (!file) {
file_recorder_close(recorder, 0);
return;
}
file_recorder_set_file(recorder, file, NULL);
struct seamless_recording seamless = {
.advance_time = 10, //提前10s创建新文件
.time = 3600, //单个文件录音时长
.priv = recorder,
.change_file = change_file_in_stream_task,
};
file_recorder_seamless_set(recorder, &seamless);
err = file_recorder_start(recorder);
if (err) {
printf("file_recorder_err: %d\n", err);
file_recorder_close(recorder, 1);
return;
}
g_rec_hdl.status = 1;
g_rec_hdl.recorder = recorder;
mem_stats();
}
void mix_recorder_stop()
{
// 先停掉录音,会有淡出操作
file_recorder_stop(g_rec_hdl.recorder, 1);
// 再关闭音源
g_rec_hdl.status = 0;
os_time_dly(1);
if (g_rec_hdl.old_file) {
fclose(g_rec_hdl.old_file);
g_rec_hdl.old_file = NULL;
}
if (g_rec_hdl.new_file) {
fdelete(g_rec_hdl.new_file);
g_rec_hdl.new_file = NULL;
}
file_recorder_release(g_rec_hdl.recorder);
g_rec_hdl.recorder = NULL;
}
int get_mix_recorder_status(void)
{
return g_rec_hdl.status ? 1 : 0;
}
static u8 mix_record_idle_query(void)
{
return g_rec_hdl.status ? 0 : 1;
}
REGISTER_LP_TARGET(mix_record_lp_target) = {
.name = "mix_record",
.is_idle = mix_record_idle_query,
};
#endif // TCFG_MIX_RECORD_ENABLE
+341
View File
@@ -0,0 +1,341 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".scene_switch.data.bss")
#pragma data_seg(".scene_switch.data")
#pragma const_seg(".scene_switch.text.const")
#pragma code_seg(".scene_switch.text")
#endif
#include "jlstream.h"
#include "effects/effects_adj.h"
#include "node_param_update.h"
#include "scene_switch.h"
#include "app_main.h"
#include "effects/audio_vocal_remove.h"
static u8 music_scene = 0; //记录音乐场景序号
static u8 music_eq_preset_index = 0; //记录 Eq0Media EQ配置序号
static u8 mic_scene = 0; //记录混响场景序号
/* 命名规则:节点名+模式名,如 SurBt、CrossAux、Eq0File */
#if defined(MEDIA_UNIFICATION_EN)&&MEDIA_UNIFICATION_EN
static char *music_mode[] = {"Media", "Media", "Media", "Media", "Media"};
#else
static char *music_mode[] = {"Bt", "Aux", "File", "Fm", "Spd"};
#endif
static char *sur_name[] = {"Sur"};
static char *crossover_name[] = {"Cross"};
static char *band_merge_name[] = {"Band"};
static char *bass_treble_name[] = {"Bass"};
static char *smix_name[] = {"Smix0", "Smix1"};
static char *eq_name[] = {"Eq0", "Eq1", "Eq2", "Eq3"};
static char *drc_name[] = {"Drc0", "Drc1", "Drc2", "Drc3", "Drc4"};
static char *vbass_name[] = {"VBass"};
static char *gain_name[] = {"Gain"};
static char *harmonic_exciter_name[] = {"Hexciter"};
static char *dy_eq_name[] = {"DyEq"};
/* 混响模块命名 */
static char *mic_name = "Eff";
static char *mic_bass_treble_name[] = {"BassTre"};
static char *mic_noisegate_name[] = {"NoiseGate"};
static char *mic_crossover_name[] = {"Crossover"};
static char *mic_band_merge_name[] = {"BMerge1", "BMerge2"};
static char *mic_howling_fs_name[] = {"Fshift"};
static char *mic_howling_supress_name[] = {"Hspress"};
static char *mic_voice_changer_name[] = {"Vchanger"};
static char *mic_autotune_name[] = {"Atune"};
static char *mic_plate_reverb_advance_name[] = {"PReverb"};
static char *mic_echo_name[] = {"Echo"};
static char *mic_eq_name[] = {"Eq1", "Eq2", "Eq3", "Eq4", "Eq5", "Eq6"};
static char *mic_drc_name[] = {"Drc1", "Drc2", "Drc3", "Drc4", "Drc5", "Drc6", "Drc7"};
/* 获取音乐模式场景序号 */
u8 get_current_scene()
{
return music_scene;
}
/* 获取mic混响模式场景序号 */
u8 get_mic_current_scene()
{
return mic_scene;
}
void set_default_scene(u8 index)
{
music_scene = index;
}
/* 获EQ0 配置序号 */
u8 get_music_eq_preset_index(void)
{
return music_eq_preset_index;
}
void set_music_eq_preset_index(u8 index)
{
music_eq_preset_index = index;
syscfg_write(CFG_EQ0_INDEX, &music_eq_preset_index, 1);
}
/* 获取当前处于的模式 */
u8 get_current_mode_index()
{
struct app_mode *mode;
mode = app_get_current_mode();
switch (mode->name) {
case APP_MODE_BT:
return BT_MODE;
case APP_MODE_LINEIN:
return AUX_MODE;
case APP_MODE_MUSIC:
return FILE_MODE;
case APP_MODE_FM:
return FM_MODE;
case APP_MODE_SPDIF:
return SPDIF_MODE;
case APP_MODE_PC:
return PC_MODE;
default:
printf("mode not support scene switch %d\n", mode->name);
return NOT_SUPPORT_MODE;
}
}
/* 获取当前模式中场景个数 */
int get_mode_scene_num()
{
struct app_mode *mode;
mode = app_get_current_mode();
u16 uuid;
u8 scene_num;
switch (mode->name) {
case APP_MODE_BT:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"a2dp");
break;
case APP_MODE_LINEIN:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"linein");
break;
case APP_MODE_MUSIC:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"music");
break;
case APP_MODE_FM:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"fm");
break;
case APP_MODE_SPDIF:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"spdif");
break;
case APP_MODE_PC:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"pc_spk");
break;
default:
printf("mode not support scene switch %d\n", mode->name);
return -1;
}
jlstream_read_pipeline_param_group_num(uuid, &scene_num);
return scene_num;
}
/* 音乐模式:根据参数组序号进行场景切换 */
void effect_scene_set(u8 scene)
{
int scene_num = get_mode_scene_num();
if (scene >= scene_num) {
printf("err : without this scene %d\n", scene);
return;
}
music_scene = scene;
printf("current music scene : %d\n", scene);
syscfg_write(CFG_SCENE_INDEX, &music_scene, 1);
char tar_name[16];
u8 cur_mode = get_current_mode_index();
for (int i = 0; i < ARRAY_SIZE(sur_name); i++) {
sprintf(tar_name, "%s%s", sur_name[i], music_mode[cur_mode]);
surround_effect_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(crossover_name); i++) {
sprintf(tar_name, "%s%s", crossover_name[i], music_mode[cur_mode]);
crossover_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(band_merge_name); i++) {
sprintf(tar_name, "%s%s", band_merge_name[i], music_mode[cur_mode]);
band_merge_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(bass_treble_name); i++) {
sprintf(tar_name, "%s%s", bass_treble_name[i], music_mode[cur_mode]);
bass_treble_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(smix_name); i++) {
sprintf(tar_name, "%s%s", smix_name[i], music_mode[cur_mode]);
stereo_mix_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(eq_name); i++) {
sprintf(tar_name, "%s%s", eq_name[i], music_mode[cur_mode]);
if (i == 0) {
eq_update_parm(scene, tar_name, music_eq_preset_index);
} else {
eq_update_parm(scene, tar_name, 0);
}
}
for (int i = 0; i < ARRAY_SIZE(drc_name); i++) {
sprintf(tar_name, "%s%s", drc_name[i], music_mode[cur_mode]);
drc_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(vbass_name); i++) {
sprintf(tar_name, "%s%s", vbass_name[i], music_mode[cur_mode]);
virtual_bass_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(gain_name); i++) {
sprintf(tar_name, "%s%s", gain_name[i], music_mode[cur_mode]);
gain_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(harmonic_exciter_name); i++) {
sprintf(tar_name, "%s%s", harmonic_exciter_name[i], music_mode[cur_mode]);
harmonic_exciter_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(dy_eq_name); i++) {
sprintf(tar_name, "%s%s", dy_eq_name[i], music_mode[cur_mode]);
dynamic_eq_update_parm(scene, tar_name, 0);
}
}
/* 音乐模式:根据参数组个数顺序切换场景 */
void effect_scene_switch()
{
int scene_num = get_mode_scene_num();
if (!scene_num) {
puts("scene switch err\n");
return;
}
music_scene++;
if (music_scene >= scene_num) {
music_scene = 0;
}
effect_scene_set(music_scene);
}
/* mic混响:获取场景个数 */
static u8 get_mic_effect_scene_num()
{
u8 scene_num;
u16 uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"mic_effect");
jlstream_read_pipeline_param_group_num(uuid, &scene_num);
return scene_num;
}
/* mic混响:根据参数组序号进行场景切换 */
void mic_effect_scene_set(u8 scene)
{
u8 scene_num = get_mic_effect_scene_num();
if (scene >= scene_num) {
printf("err : without this scene %d\n", scene);
return;
}
mic_scene = scene;
char tar_name[16];
for (int i = 0; i < ARRAY_SIZE(mic_noisegate_name); i++) {
sprintf(tar_name, "%s%s", mic_noisegate_name[i], mic_name);
noisegate_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_crossover_name); i++) {
sprintf(tar_name, "%s%s", mic_crossover_name[i], mic_name);
crossover_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_band_merge_name); i++) {
sprintf(tar_name, "%s%s", mic_band_merge_name[i], mic_name);
band_merge_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_howling_fs_name); i++) {
sprintf(tar_name, "%s%s", mic_howling_fs_name[i], mic_name);
howling_frequency_shift_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_howling_supress_name); i++) {
sprintf(tar_name, "%s%s", mic_howling_supress_name[i], mic_name);
howling_suppress_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_voice_changer_name); i++) {
sprintf(tar_name, "%s%s", mic_voice_changer_name[i], mic_name);
voice_changer_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_autotune_name); i++) {
sprintf(tar_name, "%s%s", mic_autotune_name[i], mic_name);
autotune_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_plate_reverb_advance_name); i++) {
sprintf(tar_name, "%s%s", mic_plate_reverb_advance_name[i], mic_name);
reverb_advance_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_echo_name); i++) {
sprintf(tar_name, "%s%s", mic_echo_name[i], mic_name);
echo_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_eq_name); i++) {
sprintf(tar_name, "%s%s", mic_eq_name[i], mic_name);
eq_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_drc_name); i++) {
sprintf(tar_name, "%s%s", mic_drc_name[i], mic_name);
drc_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_bass_treble_name); i++) {
sprintf(tar_name, "%s%s", mic_bass_treble_name[i], mic_name);
bass_treble_update_parm(scene, tar_name, 0);
}
}
/* mic混响:根据参数组个数顺序切换场景 */
void mic_effect_scene_switch()
{
int scene_num = get_mic_effect_scene_num();
if (!scene_num) {
puts("scene switch err\n");
return;
}
mic_scene++;
if (mic_scene >= scene_num) {
mic_scene = 0;
}
mic_effect_scene_set(mic_scene);
}
static u8 vocla_remove_mark = 0xff;//
//实时更新media数据流中人声消除bypass参数,启停人声消除功能
void music_vocal_remover_switch(void)
{
#if TCFG_VOCAL_REMOVER_NODE_ENABLE
vocal_remover_param_tool_set cfg = {0};
char *vocal_node_name = "VocalRemovMedia";
int ret = jlstream_read_form_data(0, vocal_node_name, 0, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, vocal_node_name);
return;
}
if (vocla_remove_mark == 0xff) {
vocla_remove_mark = cfg.is_bypass;
}
vocla_remove_mark ^= 1;
cfg.is_bypass = vocla_remove_mark;
jlstream_set_node_param(NODE_UUID_VOCAL_REMOVER, vocal_node_name, &cfg, sizeof(cfg));
#endif
}
//media数据流启动后更新人声消除bypass参数
void music_vocal_remover_update_parm()
{
#if TCFG_VOCAL_REMOVER_NODE_ENABLE
vocal_remover_param_tool_set cfg = {0};
char *vocal_node_name = "VocalRemovMedia";
int ret = jlstream_read_form_data(0, vocal_node_name, 0, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, vocal_node_name);
return;
}
if (vocla_remove_mark == 0xff) {
vocla_remove_mark = cfg.is_bypass;
}
cfg.is_bypass = vocla_remove_mark;
jlstream_set_node_param(NODE_UUID_VOCAL_REMOVER, vocal_node_name, &cfg, sizeof(cfg));
#endif
}
u8 get_music_vocal_remover_statu(void)
{
return vocla_remove_mark ;
}
+121
View File
@@ -0,0 +1,121 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".tone_table.data.bss")
#pragma data_seg(".tone_table.data")
#pragma const_seg(".tone_table.text.const")
#pragma code_seg(".tone_table.text")
#endif
#include "app_config.h"
#include "app_tone.h"
#include "fs/resfile.h"
static const struct tone_files chinese_tone_files = {
.num = {
"tone_zh/0.*",
"tone_zh/1.*",
"tone_zh/2.*",
"tone_zh/3.*",
"tone_zh/4.*",
"tone_zh/5.*",
"tone_zh/6.*",
"tone_zh/7.*",
"tone_zh/8.*",
"tone_zh/9.*",
},
.power_on = "tone_zh/power_on.*",
.power_off = "tone_zh/power_off.*",
.bt_mode = "tone_zh/bt.*",
.bt_connect = "tone_zh/bt_conn.*",
.bt_disconnect = "tone_zh/bt_dconn.*",
.phone_in = "tone_zh/ring.*",
.phone_out = "tone_zh/ring.*",
.low_power = "tone_zh/low_power.*",
.max_vol = "tone_zh/vol_max.*",
.tws_connect = "tone_zh/tws_conn.*",
.tws_disconnect = "tone_zh/tws_dconn.*",
.normal = "tone_zh/normal.*",
.low_latency_in = "tone_zh/game_in.*",
.low_latency_out = "tone_zh/game_out.*",
.anc_on = "tone_zh/anc_on.*",
.anc_trans = "tone_zh/anc_trans.*",
.anc_off = "tone_zh/anc_off.*",
.key_tone = "tone_zh/key_tone.*",
.music_mode = "tone_zh/music.*",
.record_mode = "tone_zh/record.*",
.device_sd = "tone_zh/sd.*",
.device_udisk = "tone_zh/udisk.*",
.fm_mode = "tone_zh/fm.*",
.linein_mode = "tone_zh/linein.*",
.pc_mode = "tone_zh/pc.*",
.rtc_mode = "tone_zh/rtc.*",
.spdif_mode = "tone_zh/spdif.*",
};
static const struct tone_files english_tone_files = {
.num = {
"tone_en/0.*",
"tone_en/1.*",
"tone_en/2.*",
"tone_en/3.*",
"tone_en/4.*",
"tone_en/5.*",
"tone_en/6.*",
"tone_en/7.*",
"tone_en/8.*",
"tone_en/9.*",
},
.power_on = "tone_en/power_on.*",
.power_off = "tone_en/power_off.*",
.bt_mode = "tone_en/bt.*",
.bt_connect = "tone_en/bt_conn.*",
.bt_disconnect = "tone_en/bt_dconn.*",
.phone_in = "tone_en/ring.*",
.phone_out = "tone_en/ring.*",
.low_power = "tone_en/low_power.*",
.max_vol = "tone_en/vol_max.*",
.tws_connect = "tone_en/tws_conn.*",
.tws_disconnect = "tone_en/tws_dconn.*",
.normal = "tone_en/normal.*",
.low_latency_in = "tone_en/game_in.*",
.low_latency_out = "tone_en/game_out.*",
.anc_on = "tone_en/anc_on.*",
.anc_trans = "tone_en/anc_trans.*",
.anc_off = "tone_en/anc_off.*",
.key_tone = "tone_en/key_tone.*",
.music_mode = "tone_en/music.*",
.record_mode = "tone_en/record.*",
.device_sd = "tone_en/sd.*",
.device_udisk = "tone_en/udisk.*",
.fm_mode = "tone_en/fm.*",
.linein_mode = "tone_en/linein.*",
.pc_mode = "tone_en/pc.*",
.rtc_mode = "tone_en/rtc.*",
.spdif_mode = "tone_en/spdif.*",
};
#if TCFG_TONE_EN_ENABLE
static enum tone_language g_lang_used = TONE_ENGLISH;
#else
static enum tone_language g_lang_used = TONE_CHINESE;
#endif
enum tone_language tone_language_get()
{
return g_lang_used;
}
void tone_language_set(enum tone_language lang)
{
g_lang_used = lang;
}
const struct tone_files *get_tone_files()
{
#if TCFG_TONE_ZH_ENABLE
if (g_lang_used == TONE_CHINESE) {
return &chinese_tone_files;
}
#endif
return &english_tone_files;
}
+183
View File
@@ -0,0 +1,183 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".vol_sync.data.bss")
#pragma data_seg(".vol_sync.data")
#pragma const_seg(".vol_sync.text.const")
#pragma code_seg(".vol_sync.text")
#endif
#include "typedef.h"
#include "app_main.h"
#include "app_config.h"
#include "vol_sync.h"
#include "audio_config.h"
#include "app_tone.h"
#include "volume_node.h"
#include "jlui_app/ui_api.h"
u8 vol_sys_tab[17] = {0, 2, 3, 4, 6, 8, 10, 11, 12, 14, 16, 18, 19, 20, 22, 23, 25};
const u8 vol_sync_tab[17] = {0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 127};
static s16 max_vol = 100;
void vol_sys_tab_init(void)
{
#if TCFG_BT_VOL_SYNC_ENABLE
#if 1
u8 i = 0;
max_vol = app_audio_volume_max_query(AppVol_BT_MUSIC);
for (i = 0; i < 17; i++) {
vol_sys_tab[i] = i * max_vol / 16;
}
#else
u8 i = 0;
max_vol = app_audio_volume_max_query(AppVol_BT_MUSIC);
vol_sys_tab[0] = 0;
//最大音量<16,补最大值
if (max_vol <= 16) {
for (i = 1; i <= max_vol; i++) {
vol_sys_tab[i] = i;
}
for (; i < 17; i++) {
vol_sys_tab[i] = max_vol;
}
} else {
u8 j = max_vol - 16;
u8 k = 1;
for (i = 1; i <= max_vol; i++) {
/* g_printf("i=%d j=%d k=%d",i,j,k); */
if (i % 2) {
} else {
//忽略多余的级数
if (j > 0) {
j--;
continue;
}
}
if (k < 17) {
vol_sys_tab[k] = i;
}
k++;
}
vol_sys_tab[16] = max_vol;
}
#endif
#if 0
for (i = 0; i < 17; i++) {
g_printf("[%d]:%d ", i, vol_sys_tab[i]);
}
#endif
#endif
}
//注册给库的回调函数,用户手机设置设备音量
void set_music_device_volume(int volume)
{
r_printf("set_music_device_volume=%d\n", volume);
#if TCFG_BT_VOL_SYNC_ENABLE
s16 music_volume;
//音量同步最大是127,请计数比例
if (volume > 127) {
/*log_info("vol %d invalid\n", volume);*/
#if TCFG_VOL_RESET_WHEN_NO_SUPPORT_VOL_SYNC
/*不支持音量同步的设备,默认设置到最大值,可以根据实际需要进行修改。
注意如果不是最大值,设备又没有按键可以调音量到最大,则输出也就达不到最大*/
music_volume = max_vol;
log_i("unsupport vol_sync,reset vol:%d\n", music_volume);
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, music_volume, 1);
#endif
return;
}
if (tone_player_runing() || ring_player_runing() || bt_get_esco_coder_busy_flag()) {
log_i("It's not smart to sync a2dp vol now\n");
//app_var.music_volume = vol_sys_tab[(volume + 1) / 8];
app_var.music_volume = ((volume + 1) * max_vol) / 127;
return;
}
#if 1
/*
*0~16,总共17级
*这里将手机的0~127的音量值换成实际的dac音量等级
*/
music_volume = ((volume + 1) * max_vol) / 127;
#else
music_volume = vol_sys_tab[(volume + 1) / 8];
#endif
y_printf("phone_vol:%d,dac_vol:%d", volume, music_volume);
app_var.opid_play_vol_sync = vol_sync_tab[(volume + 1) / 8];
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, music_volume, 1);
app_audio_set_volume_def_state(0);
#endif
#if (defined CONFIG_JL_UI_ENABLE)&&CONFIG_JL_UI_ENABLE
UI_MSG_POST("volume");
#endif
}
//注册给库的回调函数,用于手机获取当前设备音量
int phone_get_device_vol(void)
{
//音量同步最大是127,请计数比例
#if 0
return (app_var.sys_vol_l * max_vol / 127) ;
#else
return app_var.opid_play_vol_sync;
#endif
}
void opid_play_vol_sync_fun(s16 *vol, u8 mode)
{
#if TCFG_BT_VOL_SYNC_ENABLE
vol_sys_tab[16] = max_vol;
if (*vol == 0) {
if (mode) {
*vol = vol_sys_tab[1];
app_var.opid_play_vol_sync = vol_sync_tab[1];
} else {
*vol = vol_sys_tab[0];
app_var.opid_play_vol_sync = vol_sync_tab[0];
}
} else if (*vol >= max_vol) {
if (mode) {
*vol = vol_sys_tab[16];
app_var.opid_play_vol_sync = vol_sync_tab[16];
} else {
*vol = vol_sys_tab[15];
app_var.opid_play_vol_sync = vol_sync_tab[15];
}
} else {
for (u8 i = 0; i < sizeof(vol_sys_tab) / sizeof(vol_sys_tab[0]); i++) {
if (*vol == vol_sys_tab[i]) {
if (mode) {
app_var.opid_play_vol_sync = vol_sync_tab[i + 1];
*vol = vol_sys_tab[i + 1];
} else {
app_var.opid_play_vol_sync = vol_sync_tab[i - 1];
*vol = vol_sys_tab[i - 1];
}
break;
} else if (*vol < vol_sys_tab[i]) {
if (mode) {
*vol = vol_sys_tab[i + 1];
app_var.opid_play_vol_sync = vol_sync_tab[i];
} else {
*vol = vol_sys_tab[i - 1];
app_var.opid_play_vol_sync = vol_sync_tab[i - 1];
}
break;
}
}
}
#endif
}