KT24-1110_65E-HA-651B/apps/common/audio/stream/stream_src.c

196 lines
5.5 KiB
C
Raw Normal View History

2024-11-10 10:44:17 +00:00
#include "stream_src.h"
static void stream_src_irq_cb(void *hdl)
{
struct __stream_src *stream = hdl;
audio_stream_resume(&stream->entry);
}
static int stream_src_output_handler(void *hdl, void *buf, int len)
{
struct __stream_src *stream = hdl;
if (!stream) {
return 0;
}
#if 0
if (stream->out_buf) {
if (stream->out_points < stream->out_total) {
return 0;
} else {
stream->out_buf = NULL;
return stream->out_total * 2;
}
}
stream->out_buf = buf;
stream->out_points = 0;
stream->out_total = len / 2;
#endif
struct audio_data_frame frame = {0};
frame.channel = stream->channel;
frame.sample_rate = stream->target_sr;
frame.data_sync = stream->data_sync;
frame.data_len = len;
frame.data = buf;
int tlen = stream->out_points * 2;
audio_stream_run(&stream->entry, &frame);
return (stream->out_points * 2 - tlen);
}
static int stream_src_run(struct __stream_src *stream, s16 *data, int len)
{
if (stream->src_hdl == NULL) {
return 0;
}
return audio_src_resample_write(stream->src_hdl, data, len);
}
static void stream_src_output_data_process_len(struct audio_stream_entry *entry, int len)
{
struct __stream_src *stream = container_of(entry, struct __stream_src, entry);
if (stream) {
stream->out_points += len / 2;
}
}
static void stream_src_check(struct __stream_src *stream, u16 sr, u8 ch_num)
{
if ((stream->src_always == 0) && (stream->target_sr == sr)) {
audio_hw_src_stop(stream->src_hdl);
audio_hw_src_close(stream->src_hdl);
free(stream->src_hdl);
stream->src_hdl = NULL;
return ;
}
if (stream->src_hdl == NULL) {
stream->src_hdl = zalloc(sizeof(struct audio_src_handle));
ASSERT(stream->src_hdl);
stream->channel = ch_num;
audio_hw_src_open(stream->src_hdl, ch_num, SRC_TYPE_RESAMPLE);
audio_hw_src_set_rate(stream->src_hdl, sr, stream->target_sr);
audio_src_set_output_handler(stream->src_hdl, stream, stream_src_output_handler);
audio_src_set_rise_irq_handler(stream->src_hdl, stream, stream_src_irq_cb);
} else {
audio_hw_src_set_rate(stream->src_hdl, sr, stream->target_sr);
}
}
static int stream_src_data_handler(struct audio_stream_entry *entry,
struct audio_data_frame *in,
struct audio_data_frame *out)
{
struct __stream_src *stream = container_of(entry, struct __stream_src, entry);
out->sample_rate = stream->target_sr;
if (in->data_len) {
out->no_subsequent = 1;
}
#if 0
//输出剩余数据
if (stream->out_buf && (stream->out_points < stream->out_total)) {
struct audio_data_frame frame;
memset(&frame, 0, sizeof(frame));
frame.channel = in->channel;
frame.sample_rate = stream->target_sr;
frame.data_sync = in->data_sync;
while (1) {
frame.data_len = (stream->out_total - stream->out_points) * 2;
frame.data = &stream->out_buf[stream->out_points];
int len = stream->out_points;
audio_stream_run(entry, &frame);
break;
}
//未输出完退出
if (stream->out_points < stream->out_total) {
return 0;
}
} else {
//printf("=========\n");
}
#endif
stream->data_sync = in->data_sync;
//同步检查
stream_src_check(stream, in->sample_rate, in->channel);
int len = 0;
u8 cnt = 0;
len = stream_src_run(stream, in->data, in->data_len);
#if 0
if (stream->out_buf && (stream->out_points < stream->out_total)) {
struct audio_data_frame frame;
memset(&frame, 0, sizeof(frame));
frame.channel = in->channel;
frame.sample_rate = stream->target_sr;
frame.data_sync = in->data_sync;
while (1) {
frame.data_len = (stream->out_total - stream->out_points) * 2;
frame.data = &stream->out_buf[stream->out_points];
int len = stream->out_points;
audio_stream_run(entry, &frame);
break;
}
if (stream->out_points < stream->out_total) {
return len;
}
if (!len) {
len = stream_src_run(stream, in->data, in->data_len);
}
} else {
out->data_len = 0;
//printf("^^^^^^^^^^/n");
}
#endif
return len;
}
void stream_src_set_target_rate(struct __stream_src *hdl, u16 sr)
{
if (hdl) {
hdl->target_sr = sr;
}
}
struct __stream_src *stream_src_open(u16 target_sr, u8 always)
{
struct __stream_src *stream = zalloc(sizeof(struct __stream_src));
ASSERT(stream);
stream->src_always = always;
stream->target_sr = target_sr;
stream->entry.data_process_len = stream_src_output_data_process_len;
stream->entry.data_handler = stream_src_data_handler;
return stream;
}
void stream_src_close(struct __stream_src **hdl)
{
if (hdl && (*hdl)) {
struct __stream_src *stream = *hdl;
audio_stream_del_entry(&stream->entry);
if (stream->src_hdl) {
audio_hw_src_stop(stream->src_hdl);
audio_hw_src_close(stream->src_hdl);
free(stream->src_hdl);
stream->src_hdl = NULL;
}
local_irq_disable();
free(stream);
*hdl = NULL;
local_irq_enable();
}
}
void stream_src_resume(struct __stream_src *hdl)
{
if (hdl) {
audio_stream_resume(&hdl->entry);
}
}