doubao_chat/apps/common/example/audio/virtual_enc/main.c

171 lines
4.6 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 "system/includes.h"
#include "server/audio_server.h"
#include "app_config.h"
#include "os/os_api.h"
#ifdef USE_VIRTUAL_ENC_TEST
struct enc_server_handle {
void *enc_server;
FILE *in_file;
FILE *out_file;
};
static struct enc_server_handle enc_server_handle;
#define __this (&enc_server_handle)
//关闭virtual编码操作
static enc_server_test_close(void)
{
puts("--------enc_server_test_close---------");
union audio_req req = {0};
if (__this->enc_server) {
req.enc.cmd = AUDIO_ENC_CLOSE;
server_request(__this->enc_server, AUDIO_REQ_ENC, &req);
server_close(__this->enc_server);
__this->enc_server = NULL;
}
if (__this->out_file) {
fclose(__this->out_file);
__this->out_file = NULL;
}
}
//编码服务注册的回调函数
static void enc_server_server_event_handler(void *priv, int argc, int *argv)
{
switch (argv[0]) {
case AUDIO_SERVER_EVENT_ERR:
case AUDIO_SERVER_EVENT_END:
printf("VIRTUAL_AUDIO_SERVER_EVENT_END");
enc_server_test_close();
break;
case AUDIO_SERVER_EVENT_SPEAK_START:
printf("speak start ! \n");
break;
case AUDIO_SERVER_EVENT_SPEAK_STOP:
printf("speak stop ! \n");
break;
default:
break;
}
}
//编码虚拟源输入
static u32 enc_server_read_input(u8 *buf, u32 len)
{
int rlen;
if (__this->in_file) {
rlen = fread(buf, len, 1, __this->in_file);
if (rlen == len) {
return rlen;
} else {
fclose(__this->in_file);
__this->in_file = NULL;
return rlen;
}
} else {
return -1; //read_input返回-1表示输入数据完成,没有数据输入,让编码服务发结束消息出来AUDIO_SERVER_EVENT_END去进行结束编码的操作
}
}
//编码输出数据
static int enc_server_vfs_fwrite(void *file, void *data, u32 len)
{
//不要做长时间堵塞操作
return fwrite(data, len, 1, __this->out_file);
}
static int enc_server_vfs_fclose(void *file)
{
return 0;
}
static const struct audio_vfs_ops enc_server_vfs_ops = {
.fwrite = enc_server_vfs_fwrite,
.fclose = enc_server_vfs_fclose,
};
//线程接收编码服务回调消息队列方式
/*static void server_back()
{
while(1){
int msg[32];
os_time_dly(2);
os_taskq_pend("taskq",msg,ARRAY_SIZE(msg));
}
}*/
static int enc_server_thread()
{
int err = 0;
//1.等待sd挂载,打开输入文件和创建输出文件
extern int storage_device_ready(void);
while (!storage_device_ready()) {//等待sd文件系统挂载完成
printf("wait sd mount in");
os_time_dly(2);
}
__this->in_file = fopen(CONFIG_ROOT_PATH"4.pcm", "r");
if (__this->in_file == NULL) {
printf("open in_file fail!!!!");
}
__this->out_file = fopen(CONFIG_ROOT_PATH"out_file.mp3", "w+");
if (__this->out_file == NULL) {
printf("open out_file fail!!!!");
}
//2.开启编码服务和注册编码服务回调
if (!__this->enc_server) {
__this->enc_server = server_open("audio_server", "enc");
if (!__this->enc_server) {
return -1;
}
//a.将编码服务回调函数注册到“app_core”消息队列 常用方式
server_register_event_handler_to_task(__this->enc_server, NULL, enc_server_server_event_handler, "app_core");
//b.将编码服务回调函数注册到创建的线程中接收消息队列
/* thread_fork("server_back", 10, 1024, 32, NULL, server_back, NULL); */
/* server_register_event_handler_to_task(__this->enc_server, NULL, enc_server_server_event_handler,"server_back"); */
} else {
return -1;
}
//3.设置编码参数,请求打开编码器
union audio_req req = {0};
req.enc.cmd = AUDIO_ENC_OPEN;
req.enc.channel = 2;
req.enc.volume = 100;
req.enc.output_buf = NULL;
req.enc.output_buf_len = 3200 * 8;
req.enc.sample_rate = 16000;
req.enc.format = "mp3";
req.enc.frame_size = 3200; //frame_size为read_input的len
req.enc.sample_source = "virtual";
req.enc.read_input = enc_server_read_input;
req.enc.vfs_ops = &enc_server_vfs_ops;
req.enc.vir_data_wait = 1; //等待数据编码完成才进行下一帧数据编码,数据完整
/* req.enc.no_header = 1; */
/* req.enc.bitrate = 16000; */
err = server_request(__this->enc_server, AUDIO_REQ_ENC, &req);
return 0;
}
static void main()
{
puts("----------virtual_enc_test--------");
thread_fork("enc_server_thread", 12, 1024, 0, 0, enc_server_thread, 0);
}
late_initcall(main);
#endif