初版
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".surround_demo_node.data.bss")
|
||||
#pragma data_seg(".surround_demo_node.data")
|
||||
#pragma const_seg(".surround_demo_node.text.const")
|
||||
#pragma code_seg(".surround_demo_node.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "jlstream.h"
|
||||
#include "overlay_code.h"
|
||||
|
||||
#if TCFG_SURROUND_DEMO_NODE_ENABLE
|
||||
|
||||
struct surround_demo_node_hdl {
|
||||
u8 bypass;
|
||||
u8 out_channel;
|
||||
};
|
||||
|
||||
int surround_demo_data_run(void *priv, s16 *data, int len)
|
||||
{
|
||||
int wlen = len;
|
||||
/* struct surround_demo_node_hdl *hdl = (struct surround_demo_node_hdl *)priv; */
|
||||
|
||||
return wlen;
|
||||
}
|
||||
|
||||
static void surround_demo_handle_frame(struct stream_iport *iport, struct stream_note *note)
|
||||
{
|
||||
struct stream_frame *in_frame;
|
||||
struct stream_frame *out_frame;
|
||||
struct stream_node *node = iport->node;
|
||||
struct surround_demo_node_hdl *hdl = (struct surround_demo_node_hdl *)iport->private_data;
|
||||
|
||||
while (1) {
|
||||
in_frame = jlstream_pull_frame(iport, note);
|
||||
if (!in_frame) {
|
||||
break;
|
||||
}
|
||||
if (hdl->bypass) {
|
||||
/*bypas时,输入输出通道一样,数据直接往下推*/
|
||||
if (node->oport) {
|
||||
jlstream_push_frame(node->oport, in_frame);
|
||||
} else {
|
||||
jlstream_free_frame(in_frame);
|
||||
}
|
||||
} else {
|
||||
/*输入数据是双声道*/
|
||||
out_frame = jlstream_get_frame(node->oport, in_frame->len);
|
||||
memcpy(out_frame->data, in_frame->data, in_frame->len);
|
||||
out_frame->len = in_frame->len;
|
||||
|
||||
/*音效处理*/
|
||||
surround_demo_data_run(hdl, (s16 *)out_frame->data, out_frame->len);
|
||||
|
||||
/*输入数据是双声道,根据输出声道做声道转换*/
|
||||
int pcm_frames = (out_frame->len >> 2);//点数
|
||||
s16 *pcm_buf = (s16 *)out_frame->data;
|
||||
int i = 0, tmp = 0;
|
||||
switch (hdl->out_channel) {
|
||||
case AUDIO_CH_L:
|
||||
for (i = 0; i < pcm_frames; i++) {
|
||||
pcm_buf[i] = pcm_buf[i * 2];
|
||||
}
|
||||
out_frame->len /= 2;
|
||||
break;
|
||||
case AUDIO_CH_R:
|
||||
for (i = 0; i < pcm_frames; i++) {
|
||||
pcm_buf[i] = pcm_buf[i * 2 + 1];
|
||||
}
|
||||
out_frame->len /= 2;
|
||||
break;
|
||||
case AUDIO_CH_MIX:
|
||||
for (i = 0; i < pcm_frames; i++) {
|
||||
tmp = pcm_buf[i * 2] + pcm_buf[i * 2 + 1];
|
||||
pcm_buf[i] = tmp / 2;
|
||||
}
|
||||
out_frame->len /= 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
jlstream_push_frame(node->oport, out_frame);
|
||||
jlstream_free_frame(in_frame);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*节点预处理-在ioctl之前*/
|
||||
static int surround_demo_adapter_bind(struct stream_node *node, u16 uuid)
|
||||
{
|
||||
struct surround_demo_node_hdl *hdl = malloc(sizeof(*hdl));
|
||||
memset(hdl, 0, sizeof(*hdl));
|
||||
node->private_data = hdl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*打开改节点输入接口*/
|
||||
static void surround_demo_ioc_open_iport(struct stream_iport *iport)
|
||||
{
|
||||
iport->handle_frame = surround_demo_handle_frame;
|
||||
iport->private_data = iport->node->private_data;
|
||||
}
|
||||
|
||||
/*节点参数协商*/
|
||||
static int surround_demo_ioc_negotiate(struct stream_iport *iport)
|
||||
{
|
||||
struct stream_oport *oport = iport->node->oport;
|
||||
struct stream_fmt *in_fmt = &iport->prev->fmt;
|
||||
struct surround_demo_node_hdl *hdl = (struct surround_demo_node_hdl *)iport->private_data;
|
||||
int ret = NEGO_STA_ACCPTED;
|
||||
|
||||
/*数据通道协商*/
|
||||
if (!hdl->bypass) {
|
||||
/*固定要求输入为双声道*/
|
||||
if (in_fmt->channel_mode != AUDIO_CH_LR) {
|
||||
in_fmt->channel_mode = AUDIO_CH_LR;
|
||||
ret = NEGO_STA_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*记录输出通道数*/
|
||||
hdl->out_channel = oport->fmt.channel_mode;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*节点start函数*/
|
||||
static void surround_demo_ioc_start(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*节点stop函数*/
|
||||
static void surround_demo_ioc_stop(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*节点ioctl函数*/
|
||||
static int surround_demo_adapter_ioctl(struct stream_iport *iport, int cmd, int arg)
|
||||
{
|
||||
int ret = 0;
|
||||
struct surround_demo_node_hdl *hdl = (struct surround_demo_node_hdl *)iport->private_data;
|
||||
|
||||
switch (cmd) {
|
||||
case NODE_IOC_OPEN_IPORT:
|
||||
surround_demo_ioc_open_iport(iport);
|
||||
break;
|
||||
case NODE_IOC_NEGOTIATE:
|
||||
*(int *)arg |= surround_demo_ioc_negotiate(iport);
|
||||
break;
|
||||
case NODE_IOC_START:
|
||||
surround_demo_ioc_start();
|
||||
break;
|
||||
case NODE_IOC_SUSPEND:
|
||||
case NODE_IOC_STOP:
|
||||
surround_demo_ioc_stop();
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*节点用完释放函数*/
|
||||
static void surround_demo_adapter_release(struct stream_node *node)
|
||||
{
|
||||
free(node->private_data);
|
||||
}
|
||||
|
||||
REGISTER_STREAM_NODE_ADAPTER(surround_demo_node_adapter) = {
|
||||
.name = "surround_demo",
|
||||
.uuid = NODE_UUID_SURROUND_DEMO,
|
||||
.bind = surround_demo_adapter_bind,
|
||||
.ioctl = surround_demo_adapter_ioctl,
|
||||
.release = surround_demo_adapter_release,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user