AC63_BT_SDK/apps/common/jl_kws/jl_kws_main.c
2025-02-18 15:40:42 +08:00

307 lines
7.1 KiB
C

#include "jl_kws_common.h"
#include "jl_kws_api.h"
#if TCFG_KWS_VOICE_RECOGNITION_ENABLE
//==========================================================//
// KWS 语音识别 //
//==========================================================//
struct kws_speech_recognition {
u8 task_init;
u8 kws_state;
u8 kws_task_state;
};
static struct kws_speech_recognition jl_kws = {0};
//==============================================//
// KWS CPU频率配置 //
//==============================================//
#define KWS_BT_CALL_SYS_FREQUENCE_HZ (48 * 1000000)
#define __this (&jl_kws)
enum KWS_TASK_MSG {
KWS_SPEECH_RECOGNITION_RUN = 1,
KWS_SPEECH_RECOGNITION_STOP,
KWS_SPEECH_RECOGNITION_CLOSE,
};
enum KWS_STATE {
KWS_STATE_IDLE = 0,
KWS_STATE_INIT,
KWS_STATE_RUN,
KWS_STATE_STOP,
KWS_STATE_CLOSE,
};
enum KWS_TASK_STATE {
KWS_TASK_STATE_IDLE = 0,
KWS_TASK_STATE_INIT,
KWS_TASK_STATE_RUN,
KWS_TASK_STATE_STOP,
KWS_TASK_STATE_CLOSE,
};
//=======================================================//
// jl_kws_main //
//=======================================================//
//=========== 线程名称
#define THIS_TASK_NAME "kws"
static int kws_speech_recognition_run(void)
{
void *rbuf = 0;
u32 rbuf_len = 0;
u32 audio_data_len = 0;
int ret = JL_KWS_ERR_NONE;
int event = KWS_VOICE_EVENT_NONE;
kws_info("%s", __func__);
ret = jl_kws_audio_start();
if (ret != JL_KWS_ERR_NONE) {
return ret;
}
ret = jl_kws_algo_start();
if (ret != JL_KWS_ERR_NONE) {
return ret;
}
__this->kws_task_state = KWS_TASK_STATE_RUN;
while (1) {
if (__this->kws_state != KWS_STATE_RUN) {
break;
}
rbuf = jl_kws_algo_get_frame_buf(&rbuf_len);
if (rbuf == NULL) {
ret = JL_KWS_ERR_ALGO_NO_FRAME_BUF;
break;
}
audio_data_len = jl_kws_audio_get_data(rbuf, rbuf_len);
if (audio_data_len == rbuf_len) {
/* kws_putchar('r'); */
event = jl_kws_algo_detect_run(rbuf, rbuf_len);
if (event != KWS_VOICE_EVENT_NONE) {
jl_kws_event_state_update(event);
}
}
}
return ret;
}
static int jl_kws_speech_recognition_init(void)
{
kws_info("%s", __func__);
//1.算法初始化
int ret = 0;
ret = jl_kws_algo_init();
if (ret != JL_KWS_ERR_NONE) {
return ret;
}
//2.Audio MIC初始化
ret = jl_kws_audio_init();
if (ret != JL_KWS_ERR_NONE) {
return ret;
}
//3. event初始化
ret = jl_kws_event_init();
if (ret != JL_KWS_ERR_NONE) {
return ret;
}
return JL_KWS_ERR_NONE;
}
static int kws_speech_recognition_stop(void)
{
kws_info("%s", __func__);
if (__this->task_init) {
jl_kws_algo_stop();
jl_kws_audio_stop();
jl_kws_event_stop();
__this->kws_task_state = KWS_TASK_STATE_STOP;
}
return JL_KWS_ERR_NONE;
}
static void kws_speech_recognition_close(void)
{
kws_info("%s", __func__);
if (__this->task_init) {
jl_kws_algo_close();
jl_kws_audio_close();
jl_kws_event_close();
__this->kws_task_state = KWS_TASK_STATE_CLOSE;
//task_kill(THIS_TASK_NAME);
}
return;
}
static void kws_speech_recognition_task(void *param)
{
int msg[16];
int ret = 0;
kws_info("%s", __func__);
if (param) {
os_sem_post((OS_SEM *)(param)); //wait task ready sem
}
ret = jl_kws_speech_recognition_init();
kws_debug("ret = %d", ret);
if (ret != JL_KWS_ERR_NONE) {
kws_speech_recognition_close();
__this->task_init = 0;
task_kill(THIS_TASK_NAME);
}
__this->kws_state = KWS_STATE_INIT;
__this->kws_task_state = KWS_TASK_STATE_INIT;
while (1) {
ret = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg));
if (ret == OS_TASKQ) {
switch (msg[1]) {
case KWS_SPEECH_RECOGNITION_RUN:
kws_speech_recognition_run();
break;
case KWS_SPEECH_RECOGNITION_STOP:
kws_speech_recognition_stop();
break;
case KWS_SPEECH_RECOGNITION_CLOSE:
kws_speech_recognition_close();
os_sem_post((OS_SEM *)msg[2]);
break;
default:
break;
}
}
}
}
static u8 kws_idle_query(void)
{
return !(__this->kws_task_state == KWS_TASK_STATE_RUN);
}
REGISTER_LP_TARGET(kws_lp_target) = {
.name = "kws",
.is_idle = kws_idle_query,
};
//==========================================================//
// JL_KWS MAIN API //
//==========================================================//
int jl_kws_speech_recognition_open(void)
{
kws_info("%s", __func__);
OS_SEM ready_sem;
if (__this->task_init == 0) {
__this->task_init = 1;
os_sem_create(&ready_sem, 0);
task_create(kws_speech_recognition_task, (void *)&ready_sem, THIS_TASK_NAME);
//wait task ready
os_sem_pend(&ready_sem, 20);
}
return 0;
}
int jl_kws_speech_recognition_start(void)
{
int ret;
kws_info("%s", __func__);
if (__this->task_init) {
if (__this->kws_state == KWS_STATE_RUN) {
return 0;
}
__this->kws_state = KWS_STATE_RUN;
ret = os_taskq_post_msg(THIS_TASK_NAME, 1, KWS_SPEECH_RECOGNITION_RUN);
}
return 0;
}
void jl_kws_speech_recognition_stop(void)
{
int ret;
kws_info("%s", __func__);
if (__this->task_init) {
if (__this->kws_state == KWS_STATE_STOP) {
return;
}
__this->kws_state = KWS_STATE_STOP;
ret = os_taskq_post_msg(THIS_TASK_NAME, 1, KWS_SPEECH_RECOGNITION_STOP);
}
}
void jl_kws_speech_recognition_close(void)
{
kws_info("%s", __func__);
OS_SEM del_sem;
if (__this->task_init) {
if (__this->kws_state == KWS_STATE_CLOSE) {
return;
}
__this->kws_state = KWS_STATE_CLOSE;
os_sem_create(&del_sem, 0);
os_taskq_post_msg(THIS_TASK_NAME, 2, KWS_SPEECH_RECOGNITION_CLOSE, (void *)&del_sem);
os_sem_pend(&del_sem, 0xffff);
task_kill(THIS_TASK_NAME);
__this->task_init = 0;
}
}
//==========================================================//
// 测试代码 //
//==========================================================//
void jl_kws_main_user_demo(void)
{
//1.打开jl_kws模块
jl_kws_speech_recognition_open();
//2.在某时刻开始识别
os_time_dly(1000);
jl_kws_speech_recognition_start();
//3.在某时刻之后停止识别
os_time_dly(1500);
jl_kws_speech_recognition_stop();
//4.在某时刻之后重新开启识别
os_time_dly(2000);
jl_kws_speech_recognition_start();
//5.在某时刻之后关闭jl_kws模块
os_time_dly(2500);
jl_kws_speech_recognition_close();
}
#endif /* #if TCFG_KWS_VOICE_RECOGNITION_ENABLE */