KT26-0607_AC695n-BTE-SDK312/cpu/br23/audio_dec/lfwordana_enc_api.c
2026-06-07 19:38:16 +08:00

162 lines
5.7 KiB
C
Raw 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.

#include "lfwordana_enc_api.h"
//使用内置flash音源时(默认使用)
#define MIDI_W2S_SOUCE_FILE_PATH SDFILE_RES_ROOT_PATH"nihao.raw\0"
//使用内置flash、外挂flash 或者sd卡音源时
#define MIDI_W2S_SOUCE_FILE_PATH2 SDFILE_RES_ROOT_PATH"nihao.raw\0"
#if defined(MIDI_SUPPORT_W2S) && MIDI_SUPPORT_W2S
#define REC_LEN 3000 //预处理输出长度
struct ana_process {
struct lfwordana_encoder *ana;
OS_MUTEX mutex;
short rec_outdata[REC_LEN];
struct audio_adc_output_hdl adc_output;
struct adc_mic_ch mic_ch;
cbuffer_t cbuf;
short *mic_out_buf;
u8 source;
void *data_in;
int data_in_len;
u8 *out_path;
void *w2s_fp;//句柄预留
u16 timer;
void *in_fp;
};
#define SOURCE_FROM_MIC 0
#define SOURCE_FROM_FILE 1
#define SOURCE_FROM_BUF 2
struct ana_process *ana_proc = NULL;
static void lfwordana_process_task(void *priv)
{
struct ana_process *ana_p = priv;
struct lfwordana_encoder *ana = ana_p->ana;
int ret = 0;
u32 len = 0;
while (1) {
if ((ana_p->source == SOURCE_FROM_MIC) || (ana_p->source == SOURCE_FROM_FILE)) {
os_sem_pend(&ana_p->mutex, 0);
void *data = cbuf_read_alloc(&ana_p->cbuf, &len);
ret = lfwordana_encoder_run(ana, data, len);
cbuf_read_updata(&ana_p->cbuf, len);
} else if (ana_p->source == SOURCE_FROM_BUF) {
if (ana_p->data_in) {
ret = lfwordana_encoder_run(ana, ana_p->data_in, ana_p->data_in_len);
}
}
if (!ret) {
if (ana_p->w2s_fp) { //保存预处理后的数据
ret = fwrite(ana_p->w2s_fp, ana_p->ana->w2s_parmIn.rec_data, ana_p->ana->w2s_parmIn.rec_len);
if (ret != ana_p->ana->w2s_parmIn.rec_len) {
log_e("lfwordana write err\n");
}
fclose(ana_p->w2s_fp);
ana_p->w2s_fp = NULL;
}
midi_w2s_parm_set(&ana->w2s_parmOut, sizeof(MIDI_W2S_STRUCT));//保存预处理输出的参数
if (ana_p->source == SOURCE_FROM_MIC) {
audio_mic_close(&ana_p->mic_ch, &ana_p->adc_output);
if (ana_p->mic_out_buf) {
free(ana_p->mic_out_buf);
}
}
lfwordana_encoder_close(ana_p->ana);
free(ana_p);
ana_proc = ana_p = NULL;
os_task_del("audio_enc");//线程自杀
break;
}
}
}
static void adc_output_to_enc(void *priv, s16 *data, int len)
{
struct ana_process *ana_p = priv;
int ret = cbuf_write(&ana_p->cbuf, data, len);
if (!ret) {
log_e("mic data lose \n");
}
os_mutex_post(&ana_p->mutex);
}
void input_file_process(void *p)
{
struct ana_process *ana_p = (struct ana_process *)p;
if (ana_p->in_fp) {
int len;
void *ptr = cbuf_write_alloc(&ana_p->cbuf, &len);
if (!len) {
log_e("mic data lose \n");
return;
}
if (len > 512) {
len = 512;
}
len = fread(ana_p->in_fp, ptr, len);
cbuf_write_updata(&ana_p->cbuf, len);
os_mutex_post(&ana_p->mutex);
}
}
void lfwordana_process()
{
if (!ana_proc) {
ana_proc = zalloc(sizeof(struct ana_process));
}
struct ana_process *ana_p = &ana_proc;
REC_W2S_STUCT parm = {0};
parm.toneadjust_enable = 1; //滤波使能
parm.multi_enable = 0; //是否区分多字的情况buf大的时候考虑做buf小的时候不考虑
parm.rec_data = ana_p->rec_outdata; //输出数据地址【保证short对齐】
parm.rec_len = REC_LEN; //输出地址长度【按short】
parm.energy_thresh = 3000; //能量阈值
ana_p->out_path = MIDI_W2S_FILE_PATH;//"storage/sd0/C/W2S/W2S.raw\0";
struct lfwordana_encoder *ana = lfwordana_encoder_open(&parm);
ana_p->ana = ana;
ana_p->w2s_fp = fopen(ana_p->out_path, "wb");
/* ana_p->source = SOURCE_FROM_FILE; */
ana_p->source = SOURCE_FROM_BUF;
u32 mic_out_buf_len = 2048;
if (ana_p->source == SOURCE_FROM_MIC) { //算法库未支持多次输入
u8 gain = 8;
u32 sample_rate = 16000;
ana_p->mic_out_buf = malloc(mic_out_buf_len);
cbuf_init(&ana_p->cbuf, ana_p->mic_out_buf, mic_out_buf_len);
os_sem_create(&ana_p->mutex, 0);
ana_p->adc_output.handler = adc_output_to_enc;
ana_p->adc_output.priv = ana_p;
if (audio_mic_open(&ana_p->mic_ch, sample_rate, gain) == 0) {
audio_mic_add_output(&ana_p->adc_output);
audio_mic_start(&ana_p->mic_ch);
}
} else if (ana_p->source == SOURCE_FROM_BUF) {
void *fp = fopen(MIDI_W2S_SOUCE_FILE_PATH, "r");//在内置flash的pcm音源文件
if (!fp) {
lfwordana_encoder_close(ana_p->ana);
return;
}
struct vfs_attr attr = {0};
fget_attrs(fp, &attr);
ana_p->data_in = (void *)attr.sclust;
ana_p->data_in_len = attr.fsize;
fclose(fp);
/* ana_p->data_in = your_data_addr; //输入数据地址内置flash可用文件簇地址 */
/* ana_p->data_in_len = your_data_len;//输入出数据总长度 */
} else if (ana_p->source == SOURCE_FROM_FILE) { //算法库未支持多次输入
ana_p->mic_out_buf = malloc(mic_out_buf_len);
cbuf_init(&ana_p->cbuf, ana_p->mic_out_buf, mic_out_buf_len);
os_sem_create(&ana_p->mutex, 0);
ana_p->in_fp = fopen(MIDI_W2S_SOUCE_FILE_PATH2, "r");//在内置flash、外挂flash、sd卡等路径的pcm音源文件
ana_p->timer = sys_timer_add(ana_p, input_file_process, 50);
}
task_create(lfwordana_process_task, ana_p, "audio_enc");
}
#endif/* MIDI_SUPPORT_W2S */