193 lines
5.3 KiB
C
193 lines
5.3 KiB
C
#include "stream_sync.h"
|
|
|
|
static void stream_sync_irq_cb(void *hdl)
|
|
{
|
|
struct __stream_sync *stream = hdl;
|
|
audio_stream_resume(&stream->entry);
|
|
}
|
|
|
|
static int stream_sync_output_handler(void *hdl, void *buf, int len)
|
|
{
|
|
struct __stream_sync *stream = hdl;
|
|
if (!stream) {
|
|
return 0;
|
|
}
|
|
|
|
if (stream->out_buf) {
|
|
if (stream->out_points < stream->out_total) {
|
|
return 0;
|
|
} else {
|
|
stream->out_buf = NULL;
|
|
return len;
|
|
}
|
|
}
|
|
|
|
stream->out_buf = buf;
|
|
stream->out_points = 0;
|
|
stream->out_total = len / 2;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int stream_sync_run(struct __stream_sync *stream, s16 *data, int len)
|
|
{
|
|
int data_size = stream->cb.get_size(stream->cb.priv);
|
|
stream->sync.start = 1;
|
|
audio_buf_sync_adjust(&stream->sync, data_size);
|
|
return audio_src_resample_write(stream->sync.src_sync, data, len);
|
|
}
|
|
|
|
static void stream_sync_output_data_process_len(struct audio_stream_entry *entry, int len)
|
|
{
|
|
struct __stream_sync *stream = container_of(entry, struct __stream_sync, entry);
|
|
if (stream) {
|
|
stream->out_points += len / 2;
|
|
}
|
|
}
|
|
|
|
static int stream_sync_data_handler(struct audio_stream_entry *entry,
|
|
struct audio_data_frame *in,
|
|
struct audio_data_frame *out)
|
|
{
|
|
struct __stream_sync *stream = container_of(entry, struct __stream_sync, entry);
|
|
out->sample_rate = stream->sample_rate;
|
|
if (in->data_len) {
|
|
out->no_subsequent = 1;
|
|
}
|
|
//输出剩余数据
|
|
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->sample_rate;
|
|
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);
|
|
#if 0
|
|
if (len == stream->out_points) {
|
|
break;
|
|
}
|
|
if (stream->out_points == stream->out_total) {
|
|
break;
|
|
}
|
|
#else
|
|
break;
|
|
#endif
|
|
}
|
|
//未输出完退出
|
|
if (stream->out_points < stream->out_total) {
|
|
return 0;
|
|
}
|
|
} else {
|
|
//printf("=========\n");
|
|
}
|
|
|
|
int len = 0;
|
|
u8 cnt = 0;
|
|
len = stream_sync_run(stream, in->data, in->data_len);
|
|
|
|
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->sample_rate;
|
|
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);
|
|
#if 0
|
|
if (len == stream->out_points) {
|
|
break;
|
|
}
|
|
if (stream->out_points == stream->out_total) {
|
|
break;
|
|
}
|
|
#else
|
|
break;
|
|
#endif
|
|
}
|
|
if (stream->out_points < stream->out_total) {
|
|
return len;
|
|
}
|
|
if (!len) {
|
|
len = stream_sync_run(stream, in->data, in->data_len);
|
|
}
|
|
|
|
} else {
|
|
out->data_len = 0;
|
|
//printf("^^^^^^^^^^/n");
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
|
|
struct __stream_sync *stream_sync_open(struct stream_sync_info *info, u8 always)
|
|
{
|
|
struct audio_buf_sync_open_param param = {0};
|
|
|
|
struct __stream_sync *stream = zalloc(sizeof(struct __stream_sync));
|
|
ASSERT(stream);
|
|
|
|
param.total_len = info->get_total(info->priv);
|
|
param.begin_per = info->begin_per;
|
|
param.top_per = info->top_per;
|
|
param.bottom_per = info->bottom_per;
|
|
param.inc_step = info->inc_step;
|
|
param.dec_step = info->dec_step;
|
|
param.max_step = info->max_step;
|
|
param.in_sr = info->i_sr;
|
|
param.out_sr = info->o_sr;
|
|
param.ch_num = info->ch_num;
|
|
if (always) {
|
|
param.check_in_out = 0;
|
|
} else {
|
|
param.check_in_out = 1;
|
|
}
|
|
param.output_hdl = stream;
|
|
param.output_handler = stream_sync_output_handler;
|
|
int ret = audio_buf_sync_open(&stream->sync, ¶m);
|
|
ASSERT(ret == true);
|
|
audio_src_set_rise_irq_handler(stream->sync.src_sync, stream, stream_sync_irq_cb);
|
|
|
|
stream->sample_rate = info->o_sr;
|
|
stream->cb.priv = info->priv;
|
|
stream->cb.get_size = info->get_size;
|
|
stream->cb.get_total = info->get_total;
|
|
|
|
stream->entry.data_process_len = stream_sync_output_data_process_len;
|
|
stream->entry.data_handler = stream_sync_data_handler;
|
|
r_f_printf("stream_sync_open ok !!!!!\n");
|
|
|
|
return stream;
|
|
}
|
|
|
|
void stream_sync_close(struct __stream_sync **hdl)
|
|
{
|
|
if (hdl && (*hdl)) {
|
|
struct __stream_sync *stream = *hdl;
|
|
audio_stream_del_entry(&stream->entry);
|
|
stream->sync.start = 0;
|
|
audio_buf_sync_close(&stream->sync);
|
|
local_irq_disable();
|
|
free(stream);
|
|
*hdl = NULL;
|
|
local_irq_enable();
|
|
}
|
|
}
|
|
|
|
void stream_sync_resume(struct __stream_sync *hdl)
|
|
{
|
|
if (hdl) {
|
|
audio_stream_resume(&hdl->entry);
|
|
}
|
|
}
|
|
|
|
|