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
+300
View File
@@ -0,0 +1,300 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".bt_slience_detect.data.bss")
#pragma data_seg(".bt_slience_detect.data")
#pragma const_seg(".bt_slience_detect.text.const")
#pragma code_seg(".bt_slience_detect.text")
#endif
#include "system/includes.h"
#include "classic/tws_api.h"
#include "btstack/avctp_user.h"
#include "btstack/a2dp_media_codec.h"
#include "bt_slience_detect.h"
#include "bt_audio_energy_detection.h"
#include "app_config.h"
#include "app_main.h"
#if TCFG_APP_BT_EN
struct detect_handler {
u8 codec_type;
u8 unmute_packet_cnt;
u8 energy_check_stop;
u8 ingore_packet_num;
u8 bt_addr[6];
u16 ingore_to_seqn;
u16 slience_timer;
void *file;
};
static struct detect_handler *g_detect_hdl[2] = {NULL, NULL};
static struct detect_handler *get_detect_handler(u8 *bt_addr)
{
for (int i = 0; i < 2; i++) {
if (g_detect_hdl[i] && memcmp(g_detect_hdl[i]->bt_addr, bt_addr, 6) == 0) {
return g_detect_hdl[i];
}
}
return NULL;
}
static struct detect_handler *create_detect_handler()
{
for (int i = 0; i < 2; i++) {
if (!g_detect_hdl[i]) {
g_detect_hdl[i] = zalloc(sizeof(struct detect_handler));
return g_detect_hdl[i];
}
}
return NULL;
}
static void close_energy_detect(u8 codec_type)
{
for (int i = 0; i < 2; i++) {
if (g_detect_hdl[i] && g_detect_hdl[i]->codec_type == codec_type) { //判断要关闭的类型是否还在使用
return;
}
}
bt_audio_energy_detect_close(codec_type);//关闭对应类型的能量检测
}
static void a2dp_slience_detect(void *_detect)
{
int len;
struct a2dp_media_frame frame;
int seqn = -1;
struct detect_handler *detect = (struct detect_handler *)_detect;
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
return;
}
for (int i = 0; i < 2; i++) {
if (detect == g_detect_hdl[i]) {
goto __check;
}
}
return;
__check:
if (!detect->file) {
return;
}
while (1) {
len = a2dp_media_try_get_packet(detect->file, &frame);
if (len <= 0) {
break;
}
u8 *packet = frame.packet;
seqn = (packet[2] << 8) | packet[3];
/*
* 不检测,一直丢包
*/
#if 0//TCFG_A2DP_PREEMPTED_ENABLE == 0
seqn += 10;
if ((seqn & 0xffff) == 0) {
seqn = 1;
}
a2dp_media_free_packet(detect->file, packet);
break;
#endif
extern u8 bt_get_a2dp_en_status();
if (!bt_get_a2dp_en_status()) {
a2dp_media_free_packet(detect->file, packet);
detect->ingore_to_seqn = 0;
detect->unmute_packet_cnt = 0;
detect->energy_check_stop = 0;
break;
}
if (detect->ingore_to_seqn == 0) {
detect->ingore_to_seqn = seqn + detect->ingore_packet_num;
if (detect->ingore_to_seqn == 0) {
detect->ingore_to_seqn = 1;
}
a2dp_media_free_packet(detect->file, packet);
seqn = detect->ingore_to_seqn;
break;
}
//能量检测
int energy = 0;
int unmute_packet_num = 0;
if (detect->codec_type == A2DP_CODEC_SBC) { //20ms
energy = bt_audio_energy_detect_run(detect->codec_type, packet, len);
unmute_packet_num = TCFG_BT_BACKGROUND_DETECT_TIME / 20;
} else if (detect->codec_type == A2DP_CODEC_MPEG24) { //25ms
energy = bt_audio_energy_detect_run(detect->codec_type, packet, len);
unmute_packet_num = TCFG_BT_BACKGROUND_DETECT_TIME / 25;
} else if (detect->codec_type == A2DP_CODEC_LDAC) {
energy = bt_audio_energy_detect_run(detect->codec_type, packet, len);
unmute_packet_num = TCFG_BT_BACKGROUND_DETECT_TIME / 25;
}
printf("-energy: %d, %d, %d\n", seqn, energy, detect->unmute_packet_cnt);
if (energy >= 10) {
if (++detect->unmute_packet_cnt < unmute_packet_num) {
a2dp_media_free_packet(detect->file, packet);
continue;
}
} else {
if (energy >= 0) {
detect->unmute_packet_cnt >>= 1;
}
a2dp_media_free_packet(detect->file, packet);
continue;
}
a2dp_media_free_packet(detect->file, packet);
sys_timer_del(detect->slience_timer);
detect->slience_timer = 0;
seqn += 10;
if ((seqn & 0xffff) == 0) {
seqn = 1;
}
a2dp_media_clear_packet_before_seqn(detect->file, seqn);
printf("slience_detect_over: clear_to_seqn: %d\n", seqn);
a2dp_close_media_file(detect->file);
detect->file = NULL;
u8 codec_type = detect->codec_type;
if (detect->codec_type == A2DP_CODEC_MPEG24) {
detect->codec_type = 0xff;
}
close_energy_detect(codec_type);
int msg[4];
msg[0] = APP_MSG_BT_A2DP_START;
memcpy(msg + 1, detect->bt_addr, 6);
app_send_message_from(MSG_FROM_APP, 12, msg);
return;
}
if (seqn > 0) {
a2dp_media_clear_packet_before_seqn(detect->file, seqn);
}
}
void bt_start_a2dp_slience_detect(u8 *bt_addr, int ingore_packet_num)
{
void *file = a2dp_open_media_file(bt_addr);
if (!file) {
puts("open_a2dp_file_faild\n");
return;
}
struct detect_handler *detect = get_detect_handler(bt_addr);
if (!detect) {
detect = create_detect_handler();
if (!detect) {
a2dp_close_media_file(file);
return;
}
}
if (detect->slience_timer) {
sys_timer_del(detect->slience_timer);
}
detect->file = file;
detect->codec_type = a2dp_media_get_codec_type(detect->file);
detect->ingore_packet_num = ingore_packet_num;
detect->ingore_to_seqn = 0;
detect->unmute_packet_cnt = 0;
detect->energy_check_stop = 0;
memcpy(detect->bt_addr, bt_addr, 6);
detect->slience_timer = sys_timer_add(detect, a2dp_slience_detect, 80);
g_printf("bt_start_a2dp_slience_detect:");
put_buf(bt_addr, 6);
}
void bt_stop_a2dp_slience_detect(u8 *bt_addr)
{
struct detect_handler *detect;
u8 codec_type = 0;
for (int i = 0; i < 2; i++) {
detect = g_detect_hdl[i];
if (!detect) {
continue;
}
if (bt_addr && memcmp(detect->bt_addr, bt_addr, 6)) {
continue;
}
codec_type = g_detect_hdl[i]->codec_type;
g_detect_hdl[i] = NULL;
if (detect->slience_timer) {
sys_timer_del(detect->slience_timer);
detect->slience_timer = 0;
g_printf("bt_stop_a2dp_slience_detect");
}
if (detect->file) {
a2dp_close_media_file(detect->file);
detect->file = NULL;
}
free(detect);
detect = NULL;
}
close_energy_detect(codec_type);
}
void bt_reset_a2dp_slience_detect()
{
struct detect_handler *detect;
for (int i = 0; i < 2; i++) {
detect = g_detect_hdl[i];
if (!detect || detect->slience_timer == 0) {
return;
}
detect->ingore_to_seqn = 0;
detect->unmute_packet_cnt = 0;
detect->energy_check_stop = 0;
}
}
int bt_slience_detect_get_result(u8 *bt_addr)
{
struct detect_handler *detect = get_detect_handler(bt_addr);
if (!detect) {
return BT_SLIENCE_NO_DETECTING;
}
if (detect->unmute_packet_cnt) {
return BT_SLIENCE_HAVE_ENERGY;
}
return BT_SLIENCE_NO_ENERGY;
}
int bt_slience_get_detect_addr(u8 *bt_addr)
{
struct detect_handler *detect;
for (int i = 0; i < 2; i++) {
detect = g_detect_hdl[i];
if (!detect) {
continue;
}
memcpy(bt_addr, detect->bt_addr, 6);
return 1;
}
return 0;
}
#endif /* #if TCFG_APP_BT_EN */