148 lines
3.8 KiB
C
148 lines
3.8 KiB
C
#ifdef SUPPORT_MS_EXTENSIONS
|
|
#pragma bss_seg(".ai_tx_node.data.bss")
|
|
#pragma data_seg(".ai_tx_node.data")
|
|
#pragma const_seg(".ai_tx_node.text.const")
|
|
#pragma code_seg(".ai_tx_node.text")
|
|
#endif
|
|
|
|
#include "jlstream.h"
|
|
/* #include "classic/hci_lmp.h" */
|
|
#include "media/audio_base.h"
|
|
#include "app_config.h"
|
|
#include "codec/opus_codec_api.h"
|
|
|
|
#if TCFG_AI_TX_NODE_ENABLE
|
|
|
|
struct ai_tx_hdl {
|
|
u8 start;
|
|
struct stream_fmt fmt;
|
|
OPUS_ENC_PARA param;
|
|
int (*tx_func)(u8 *buf, u32 len);
|
|
};
|
|
|
|
|
|
extern int rec_enc_output(void *priv, void *buf, int len);
|
|
static void ai_tx_handle_frame(struct stream_iport *iport, struct stream_note *note)
|
|
{
|
|
struct ai_tx_hdl *hdl = (struct ai_tx_hdl *)iport->private_data;
|
|
struct stream_frame *frame;
|
|
|
|
while (1) {
|
|
frame = jlstream_pull_frame(iport, note);
|
|
if (!frame) {
|
|
break;
|
|
}
|
|
#if (BT_MIC_EN)
|
|
rec_enc_output(NULL, frame->data, frame->len);
|
|
#endif
|
|
if (hdl->tx_func) {
|
|
hdl->tx_func(frame->data, frame->len);
|
|
}
|
|
jlstream_free_frame(frame);
|
|
}
|
|
}
|
|
|
|
static int ai_tx_bind(struct stream_node *node, u16 uuid)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static void ai_tx_open_iport(struct stream_iport *iport)
|
|
{
|
|
struct ai_tx_hdl *hdl = zalloc(sizeof(*hdl));
|
|
|
|
|
|
iport->private_data = hdl;
|
|
iport->handle_frame = ai_tx_handle_frame;
|
|
}
|
|
static int ai_tx_ioc_fmt_nego(struct ai_tx_hdl *hdl, struct stream_iport *iport)
|
|
/* static int ai_tx_ioc_fmt_nego(struct stream_iport *iport) */
|
|
{
|
|
struct stream_fmt *in_fmt = &iport->prev->fmt;
|
|
#if 0
|
|
in_fmt->coding_type = hdl->fmt.coding_type;
|
|
in_fmt->sample_rate = 16000;
|
|
in_fmt->channel_mode = AUDIO_CH_MIX;
|
|
#else
|
|
|
|
|
|
|
|
if (in_fmt->coding_type != AUDIO_CODING_UNKNOW) {
|
|
hdl->fmt.coding_type = in_fmt->coding_type;
|
|
} else {
|
|
in_fmt->coding_type = hdl->fmt.coding_type;
|
|
}
|
|
hdl->fmt.sample_rate = in_fmt->sample_rate;
|
|
hdl->fmt.frame_dms = in_fmt->frame_dms;
|
|
hdl->fmt.channel_mode = in_fmt->channel_mode;
|
|
hdl->fmt.bit_rate = in_fmt->bit_rate;
|
|
|
|
/* printf("ai_tx: coding_type: %x", in_fmt->coding_type); */
|
|
/* printf("ai_tx: sample_rate: %d", in_fmt->sample_rate); */
|
|
/* printf("ai_tx: frame_dms: %d", in_fmt->frame_dms); */
|
|
/* printf("ai_tx: channel_mode: %d", hdl->fmt.channel_mode); */
|
|
/* printf("ai_tx: bit_rate: %d", hdl->fmt.bit_rate); */
|
|
|
|
if (in_fmt->coding_type == AUDIO_CODING_UNKNOW) {
|
|
g_printf("ai_tx coding_type nego fail\n");
|
|
return NEGO_STA_CONTINUE;
|
|
}
|
|
if (in_fmt->sample_rate == 0) {
|
|
return NEGO_STA_CONTINUE;
|
|
}
|
|
|
|
#endif
|
|
|
|
return NEGO_STA_ACCPTED;
|
|
}
|
|
|
|
static int ai_tx_ioctl(struct stream_iport *iport, int cmd, int arg)
|
|
{
|
|
struct ai_tx_hdl *hdl = (struct ai_tx_hdl *)iport->private_data;
|
|
|
|
switch (cmd) {
|
|
case NODE_IOC_OPEN_IPORT:
|
|
ai_tx_open_iport(iport);
|
|
break;
|
|
case NODE_IOC_CLOSE_IPORT:
|
|
free(hdl);
|
|
break;
|
|
case NODE_IOC_SET_FMT:
|
|
struct stream_fmt *fmt = (struct stream_fmt *)arg;
|
|
hdl->fmt.coding_type = fmt->coding_type;
|
|
hdl->fmt.sample_rate = fmt->sample_rate;
|
|
hdl->fmt.bit_rate = fmt->sample_rate;
|
|
hdl->fmt.channel_mode = fmt->channel_mode;
|
|
/* hdl->fmt.frame_dms = fmt->frame_dms; */
|
|
break;
|
|
case NODE_IOC_SET_PRIV_FMT:
|
|
hdl->tx_func = (int (*)(u8 *, u32))arg;
|
|
break;
|
|
case NODE_IOC_NEGOTIATE:
|
|
*(int *)arg |= ai_tx_ioc_fmt_nego(hdl, iport);
|
|
break;
|
|
case NODE_IOC_GET_DELAY:
|
|
break;
|
|
/* return lmp_private_get_ai_tx_packet_num() * 75; */
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void ai_tx_release(struct stream_node *node)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
REGISTER_STREAM_NODE_ADAPTER(ai_tx_adapter) = {
|
|
.name = "ai_tx",
|
|
.uuid = NODE_UUID_AI_TX,
|
|
.bind = ai_tx_bind,
|
|
.ioctl = ai_tx_ioctl,
|
|
.release = ai_tx_release,
|
|
};
|
|
|
|
#endif
|
|
|