Files
AC707N/SDK/audio/framework/nodes/ai_rx_file.c
T
2025-12-03 11:12:34 +08:00

217 lines
5.3 KiB
C

#include "system/includes.h"
#include "source_node.h"
#include "app_config.h"
#include "reference_time.h"
#include "ai_rx_player.h"
/* #include "rcsp_translator.h" */
#if TCFG_AI_RX_NODE_ENABLE
struct ai_rx_cb ai_rx_cb_t = {0};
extern const int OPUS_SRINDEX; //选择opus解码文件的帧大小,0代表一帧40字节,1代表一帧80字节,2代表一帧160字节
static int ai_fseek(void *_hdl, u32 fpos)
{
struct ai_rx_file_handle *hdl = (struct ai_rx_file_handle *)_hdl;
if (!hdl->file) {
return -1;
}
return hdl->file_ops->seek(hdl->file, fpos, SEEK_SET);
}
static int ai_fread(void *_hdl, u8 *data, int size)
{
u32 rets_addr;
__asm__ volatile("%0 = rets ;" : "=r"(rets_addr));
struct ai_rx_file_handle *hdl = (struct ai_rx_file_handle *)_hdl;
if (!hdl->file) {
return 0;
}
return hdl->file_ops->read(hdl->file, data, size);
}
static int ai_ioc_get_fmt(struct ai_rx_file_handle *hdl, struct stream_fmt *fmt)
{
return hdl->file_ops->get_fmt(hdl->file, fmt);
}
static void ai_ioc_set_file(struct ai_rx_file_handle *hdl, struct stream_file_info *info)
{
hdl->file = info->file;
hdl->file_ops = info->ops;
}
extern u32 bt_audio_conn_clock_time(void *addr);
static enum stream_node_state ai_rx_get_frame(void *file, struct stream_frame **pframe)
{
struct ai_rx_file_handle *hdl = (struct ai_rx_file_handle *)file;
if (ai_rx_cb_t.get_frame_event_cb != NULL) { // 用于ai应用的音频流播放
return ai_rx_cb_t.get_frame_event_cb(hdl, pframe);
}
struct stream_frame *frame;
u8 fram_len = 0;
switch (OPUS_SRINDEX) {
case FRAME_LEN_40:
fram_len = 40;
break;
case FRAME_LEN_80:
fram_len = 80;
break;
case FRAME_LEN_160:
fram_len = 160;
break;
default:
break;
}
frame = jlstream_get_frame(hdl->node->oport, fram_len);
if (frame == NULL) {
*pframe = NULL;
return NODE_STA_RUN;
}
int rlen = fread(frame->data, fram_len, 1, hdl->file);
frame->len = rlen;
*pframe = frame;
return NODE_STA_RUN;
}
static void *ai_rx_file_init(void *priv, struct stream_node *node)
{
struct ai_rx_file_handle *hdl = (struct ai_rx_file_handle *)zalloc(sizeof(struct ai_rx_file_handle));
hdl->node = node;
node->type |= NODE_TYPE_FLOW_CTRL;//NODE_TYPE_IRQ;
return hdl;
}
static int ai_rx_file_set_bt_addr(struct ai_rx_file_handle *hdl, void *bt_addr)
{
hdl->bt_addr = (void *)bt_addr;
return 0;
}
static void ai_rx_tick_handler(void *priv, u8 source)
{
struct ai_rx_file_handle *hdl = (struct ai_rx_file_handle *)priv;
if (hdl->start && (hdl->node->state & NODE_STA_SOURCE_NO_DATA)) {
jlstream_wakeup_thread(NULL, hdl->node, NULL);
}
}
static int ai_rx_file_get_fmt(struct ai_rx_file_handle *hdl, struct stream_fmt *fmt)
{
#if 0
fmt->coding_type = AUDIO_CODING_OPUS;
fmt->sample_rate = 16000;
fmt->channel_mode = AUDIO_CH_MIX;
#else
extern const int CONFIG_OGG_OPUS_DEC_SUPPORT;
#if TCFG_DEC_OGG_OPUS_ENABLE
if (CONFIG_OGG_OPUS_DEC_SUPPORT) {
fmt->sample_rate = 48000;
}
return hdl->file_ops->get_fmt(hdl->file, fmt);
#else
fmt->coding_type = hdl->param.coding_type;
fmt->sample_rate = hdl->param.sample_rate;
fmt->channel_mode = hdl->param.channel_mode;
fmt->frame_dms = hdl->param.frame_dms;
fmt->bit_rate = hdl->param.bit_rate;
printf("%s 0x%x, %d, %d, %d, %d\n", __FUNCTION__, fmt->coding_type, fmt->sample_rate, fmt->channel_mode, fmt->frame_dms, fmt->bit_rate);
#endif
#endif
return 0;
}
static int ai_rx_file_start(struct ai_rx_file_handle *hdl)
{
if (hdl->start) {
return 0;
}
hdl->start = 1;
return 0;
}
static int ai_rx_file_stop(struct ai_rx_file_handle *hdl)
{
if (!hdl->start) {
return 0;
}
hdl->start = 0;
if (hdl->reference) {
audio_reference_clock_exit(hdl->reference);
}
return 0;
}
static int ai_rx_file_ioctl(void *file, int cmd, int arg)
{
int err = 0;
struct ai_rx_file_handle *hdl = (struct ai_rx_file_handle *)file;
switch (cmd) {
case NODE_IOC_SET_BTADDR:
ai_rx_file_set_bt_addr(hdl, (void *)arg);
break;
case NODE_IOC_SET_FMT:
memcpy(&hdl->param, (struct ai_rx_player_param *)arg, sizeof(struct ai_rx_player_param));
break;
case NODE_IOC_GET_FMT:
ai_rx_file_get_fmt(hdl, (struct stream_fmt *)arg);
break;
case NODE_IOC_SET_FILE:
ai_ioc_set_file(hdl, (struct stream_file_info *)arg);
break;
case NODE_IOC_START:
ai_rx_file_start(hdl);
break;
case NODE_IOC_SET_PARAM:
hdl->source = (u8)arg;
break;
case NODE_IOC_SUSPEND:
case NODE_IOC_STOP:
ai_rx_file_stop(hdl);
break;
}
return 0;
}
static void ai_rx_file_release(void *file)
{
struct ai_rx_file_handle *hdl = (struct ai_rx_file_handle *)file;
free(hdl);
}
REGISTER_SOURCE_NODE_PLUG(AI_RX_file_plug) = {
.uuid = NODE_UUID_AI_RX,
.init = ai_rx_file_init,
#if TCFG_DEC_OGG_OPUS_ENABLE
.read = ai_fread,
.seek = ai_fseek,
#else
.get_frame = ai_rx_get_frame,
#endif
.ioctl = ai_rx_file_ioctl,
.release = ai_rx_file_release,
};
#endif /*TCFG_AI_RX_NODE_ENABLE*/