first
This commit is contained in:
271
apps/earphone/wireless_mic/audio/adapter_adc.c
Normal file
271
apps/earphone/wireless_mic/audio/adapter_adc.c
Normal file
@ -0,0 +1,271 @@
|
||||
#include "adapter_adc.h"
|
||||
#include "media/includes.h"
|
||||
#include "audio_config.h"
|
||||
#include "asm/dac.h"
|
||||
#include "audio_splicing.h"
|
||||
#include "app_config.h"
|
||||
|
||||
#if (TCFG_WIRELESS_MIC_ENABLE)
|
||||
#if (TCFG_AUDIO_ADC_ENABLE)
|
||||
|
||||
#define ADAPTER_ADC_MIC_BUF_NUM 3
|
||||
#if (TCFG_WIRELESS_MIC_STEREO_EN)
|
||||
#define ADAPTER_ADC_MIC_ADC_CH 2
|
||||
#else
|
||||
#define ADAPTER_ADC_MIC_ADC_CH 1
|
||||
#endif
|
||||
|
||||
#define BUF_ALIN(var,al) ((((var)+(al)-1)/(al))*(al))
|
||||
|
||||
static u16 adapter_adc_irq_points = 0;
|
||||
|
||||
extern struct audio_adc_hdl adc_hdl;
|
||||
extern struct audio_dac_hdl dac_hdl;
|
||||
extern struct adc_platform_data adc_data;
|
||||
|
||||
void adapter_adc_init(void)
|
||||
{
|
||||
audio_adc_init(&adc_hdl, &adc_data);
|
||||
#if TCFG_AUDIO_DAC_ENABLE
|
||||
//dac要开一下然后关一下, 否则mic不正常
|
||||
audio_dac_start(&dac_hdl);
|
||||
audio_dac_stop(&dac_hdl);
|
||||
#endif//TCFG_AUDIO_DAC_ENABLE
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct __adapter_adc_mic {
|
||||
s16 *adc_buf;//[ADAPTER_ADC_MIC_BUF_SIZE]; //align 4Bytes
|
||||
u8 *pcm_buf;//[ADAPTER_PCM_BUF_SIZE];
|
||||
struct audio_adc_output_hdl adc_output;
|
||||
struct adc_mic_ch mic_ch;
|
||||
cbuffer_t cbuf;
|
||||
u16 skip_cnt; //用来丢掉刚开mic时的前几包异常数据
|
||||
volatile u8 start;
|
||||
|
||||
void *resume_priv;
|
||||
void (*resume)(void *resume_priv);
|
||||
|
||||
void *data_callback_priv;
|
||||
void (*data_callback)(void *data_callback_priv, u8 *data, u16 len);
|
||||
};
|
||||
|
||||
|
||||
short test_sin_441k[441] = {
|
||||
0x0000, 0x122d, 0x23fb, 0x350f, 0x450f, 0x53aa, 0x6092, 0x6b85, 0x744b, 0x7ab5, 0x7ea2, 0x7fff, 0x7ec3, 0x7af6, 0x74ab, 0x6c03,
|
||||
0x612a, 0x545a, 0x45d4, 0x35e3, 0x24db, 0x1314, 0x00e9, 0xeeba, 0xdce5, 0xcbc6, 0xbbb6, 0xad08, 0xa008, 0x94fa, 0x8c18, 0x858f,
|
||||
0x8181, 0x8003, 0x811d, 0x84ca, 0x8af5, 0x9380, 0x9e3e, 0xaaf7, 0xb969, 0xc94a, 0xda46, 0xec06, 0xfe2d, 0x105e, 0x223a, 0x3365,
|
||||
0x4385, 0x5246, 0x5f5d, 0x6a85, 0x7384, 0x7a2d, 0x7e5b, 0x7ffa, 0x7f01, 0x7b75, 0x7568, 0x6cfb, 0x6258, 0x55b7, 0x4759, 0x3789,
|
||||
0x2699, 0x14e1, 0x02bc, 0xf089, 0xdea7, 0xcd71, 0xbd42, 0xae6d, 0xa13f, 0x95fd, 0x8ce1, 0x861a, 0x81cb, 0x800b, 0x80e3, 0x844e,
|
||||
0x8a3c, 0x928c, 0x9d13, 0xa99c, 0xb7e6, 0xc7a5, 0xd889, 0xea39, 0xfc5a, 0x0e8f, 0x2077, 0x31b8, 0x41f6, 0x50de, 0x5e23, 0x697f,
|
||||
0x72b8, 0x799e, 0x7e0d, 0x7fee, 0x7f37, 0x7bed, 0x761f, 0x6ded, 0x6380, 0x570f, 0x48db, 0x392c, 0x2855, 0x16ad, 0x048f, 0xf259,
|
||||
0xe06b, 0xcf20, 0xbed2, 0xafd7, 0xa27c, 0x9705, 0x8db0, 0x86ab, 0x821c, 0x801a, 0x80b0, 0x83da, 0x8988, 0x919c, 0x9bee, 0xa846,
|
||||
0xb666, 0xc603, 0xd6ce, 0xe86e, 0xfa88, 0x0cbf, 0x1eb3, 0x3008, 0x4064, 0x4f73, 0x5ce4, 0x6874, 0x71e6, 0x790a, 0x7db9, 0x7fdc,
|
||||
0x7f68, 0x7c5e, 0x76d0, 0x6ed9, 0x64a3, 0x5863, 0x4a59, 0x3acc, 0x2a0f, 0x1878, 0x0661, 0xf42a, 0xe230, 0xd0d0, 0xc066, 0xb145,
|
||||
0xa3bd, 0x9813, 0x8e85, 0x8743, 0x8274, 0x8030, 0x8083, 0x836b, 0x88da, 0x90b3, 0x9acd, 0xa6f5, 0xb4ea, 0xc465, 0xd515, 0xe6a3,
|
||||
0xf8b6, 0x0aee, 0x1ced, 0x2e56, 0x3ecf, 0x4e02, 0x5ba1, 0x6764, 0x710e, 0x786f, 0x7d5e, 0x7fc3, 0x7f91, 0x7cc9, 0x777a, 0x6fc0,
|
||||
0x65c1, 0x59b3, 0x4bd3, 0x3c6a, 0x2bc7, 0x1a41, 0x0833, 0xf5fb, 0xe3f6, 0xd283, 0xc1fc, 0xb2b7, 0xa503, 0x9926, 0x8f60, 0x87e1,
|
||||
0x82d2, 0x804c, 0x805d, 0x8303, 0x8833, 0x8fcf, 0x99b2, 0xa5a8, 0xb372, 0xc2c9, 0xd35e, 0xe4da, 0xf6e4, 0x091c, 0x1b26, 0x2ca2,
|
||||
0x3d37, 0x4c8e, 0x5a58, 0x664e, 0x7031, 0x77cd, 0x7cfd, 0x7fa3, 0x7fb4, 0x7d2e, 0x781f, 0x70a0, 0x66da, 0x5afd, 0x4d49, 0x3e04,
|
||||
0x2d7d, 0x1c0a, 0x0a05, 0xf7cd, 0xe5bf, 0xd439, 0xc396, 0xb42d, 0xa64d, 0x9a3f, 0x9040, 0x8886, 0x8337, 0x806f, 0x803d, 0x82a2,
|
||||
0x8791, 0x8ef2, 0x989c, 0xa45f, 0xb1fe, 0xc131, 0xd1aa, 0xe313, 0xf512, 0x074a, 0x195d, 0x2aeb, 0x3b9b, 0x4b16, 0x590b, 0x6533,
|
||||
0x6f4d, 0x7726, 0x7c95, 0x7f7d, 0x7fd0, 0x7d8c, 0x78bd, 0x717b, 0x67ed, 0x5c43, 0x4ebb, 0x3f9a, 0x2f30, 0x1dd0, 0x0bd6, 0xf99f,
|
||||
0xe788, 0xd5f1, 0xc534, 0xb5a7, 0xa79d, 0x9b5d, 0x9127, 0x8930, 0x83a2, 0x8098, 0x8024, 0x8247, 0x86f6, 0x8e1a, 0x978c, 0xa31c,
|
||||
0xb08d, 0xbf9c, 0xcff8, 0xe14d, 0xf341, 0x0578, 0x1792, 0x2932, 0x39fd, 0x499a, 0x57ba, 0x6412, 0x6e64, 0x7678, 0x7c26, 0x7f50,
|
||||
0x7fe6, 0x7de4, 0x7955, 0x7250, 0x68fb, 0x5d84, 0x5029, 0x412e, 0x30e0, 0x1f95, 0x0da7, 0xfb71, 0xe953, 0xd7ab, 0xc6d4, 0xb725,
|
||||
0xa8f1, 0x9c80, 0x9213, 0x89e1, 0x8413, 0x80c9, 0x8012, 0x81f3, 0x8662, 0x8d48, 0x9681, 0xa1dd, 0xaf22, 0xbe0a, 0xce48, 0xdf89,
|
||||
0xf171, 0x03a6, 0x15c7, 0x2777, 0x385b, 0x481a, 0x5664, 0x62ed, 0x6d74, 0x75c4, 0x7bb2, 0x7f1d, 0x7ff5, 0x7e35, 0x79e6, 0x731f,
|
||||
0x6a03, 0x5ec1, 0x5193, 0x42be, 0x328f, 0x2159, 0x0f77, 0xfd44, 0xeb1f, 0xd967, 0xc877, 0xb8a7, 0xaa49, 0x9da8, 0x9305, 0x8a98,
|
||||
0x848b, 0x80ff, 0x8006, 0x81a5, 0x85d3, 0x8c7c, 0x957b, 0xa0a3, 0xadba, 0xbc7b, 0xcc9b, 0xddc6, 0xefa2, 0x01d3, 0x13fa, 0x25ba,
|
||||
0x36b6, 0x4697, 0x5509, 0x61c2, 0x6c80, 0x750b, 0x7b36, 0x7ee3, 0x7ffd, 0x7e7f, 0x7a71, 0x73e8, 0x6b06, 0x5ff8, 0x52f8, 0x444a,
|
||||
0x343a, 0x231b, 0x1146, 0xff17, 0xecec, 0xdb25, 0xca1d, 0xba2c, 0xaba6, 0x9ed6, 0x93fd, 0x8b55, 0x850a, 0x813d, 0x8001, 0x815e,
|
||||
0x854b, 0x8bb5, 0x947b, 0x9f6e, 0xac56, 0xbaf1, 0xcaf1, 0xdc05, 0xedd3
|
||||
};
|
||||
|
||||
static u16 tx_s_cnt = 0;
|
||||
int get_sine_data(u16 *s_cnt, s16 *data, u16 points, u8 ch)
|
||||
{
|
||||
while (points--) {
|
||||
if (*s_cnt >= 441) {
|
||||
*s_cnt = 0;
|
||||
}
|
||||
*data++ = test_sin_441k[*s_cnt];
|
||||
if (ch == 2) {
|
||||
*data++ = test_sin_441k[*s_cnt];
|
||||
}
|
||||
(*s_cnt)++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static u32 sine_send_count = 0;
|
||||
static u8 sine_send_flag = 0;
|
||||
|
||||
static struct __adapter_adc_mic *adapter_adc_mic = NULL;
|
||||
|
||||
#define MY_IO_DEBUG_0(i,x) {JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT &= ~BIT(x);}
|
||||
#define MY_IO_DEBUG_1(i,x) {JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT |= BIT(x);}
|
||||
|
||||
static void adapter_adc_mic_output(void *priv, s16 *data, int len)
|
||||
{
|
||||
if (adapter_adc_mic == NULL || adapter_adc_mic->start == 0) {
|
||||
return ;
|
||||
}
|
||||
int olen;
|
||||
#if (TCFG_WIRELESS_MIC_STEREO_EN)
|
||||
olen = len * 2;
|
||||
#else
|
||||
olen = len;
|
||||
#endif
|
||||
//printf("len = %d,olen = %d\n", len, olen);
|
||||
|
||||
if (adapter_adc_mic->skip_cnt) {
|
||||
adapter_adc_mic->skip_cnt--;
|
||||
memset(data, 0, olen);
|
||||
}
|
||||
//memset(data, 0, olen);
|
||||
//putchar('A');
|
||||
#if 0
|
||||
|
||||
sine_send_count ++;
|
||||
if (sine_send_count >= 200) {
|
||||
sine_send_count = 0;
|
||||
sine_send_flag = !sine_send_flag;
|
||||
}
|
||||
|
||||
if (sine_send_flag) {
|
||||
JL_PORTA->DIR &= ~BIT(4);
|
||||
JL_PORTA->OUT |= BIT(4);
|
||||
get_sine_data(&tx_s_cnt, data, olen / 2, 1);
|
||||
} else {
|
||||
JL_PORTA->DIR &= ~BIT(4);
|
||||
JL_PORTA->OUT &= ~BIT(4);
|
||||
}
|
||||
#else
|
||||
//get_sine_data(&tx_s_cnt, data, olen / 2, 1);
|
||||
#endif
|
||||
|
||||
if (adapter_adc_mic->data_callback) {
|
||||
adapter_adc_mic->data_callback(adapter_adc_mic->data_callback_priv, (u8 *)data, olen);
|
||||
} else {
|
||||
int wlen = cbuf_write(&adapter_adc_mic->cbuf, data, olen);
|
||||
if (wlen != olen) {
|
||||
//putchar('M');
|
||||
}
|
||||
|
||||
if (adapter_adc_mic->resume) {
|
||||
adapter_adc_mic->resume(adapter_adc_mic->resume_priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int adapter_adc_mic_data_read(void *priv, void *data, int len)
|
||||
{
|
||||
if (adapter_adc_mic) {
|
||||
int rlen = adapter_adc_irq_points << 1;
|
||||
return cbuf_read(&adapter_adc_mic->cbuf, data, rlen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int adapter_adc_mic_open(u16 sample_rate, u8 gain, u16 irq_points)
|
||||
{
|
||||
#if (TCFG_WIRELESS_MIC_STEREO_EN)
|
||||
gain = 0;//如果是linein gain只能为0 或 1, 并且前级增益为0db
|
||||
#endif
|
||||
u32 buf_size = BUF_ALIN(sizeof(struct __adapter_adc_mic), 4)
|
||||
+ BUF_ALIN(irq_points * ADAPTER_ADC_MIC_BUF_NUM * ADAPTER_ADC_MIC_ADC_CH * 2, 4)
|
||||
+ BUF_ALIN(irq_points * 2 * 3, 4);
|
||||
u32 offset = 0;
|
||||
u8 *buf = zalloc(buf_size);
|
||||
struct __adapter_adc_mic *hdl = (struct __adapter_adc_mic *)(buf + offset);
|
||||
offset += BUF_ALIN(sizeof(struct __adapter_adc_mic), 4);
|
||||
|
||||
hdl->adc_buf = (s16 *)(buf + offset);
|
||||
offset += BUF_ALIN(irq_points * ADAPTER_ADC_MIC_BUF_NUM * ADAPTER_ADC_MIC_ADC_CH * 2, 4);
|
||||
|
||||
hdl->pcm_buf = (buf + offset);
|
||||
offset += BUF_ALIN(irq_points * 2 * 3, 4);
|
||||
|
||||
if (hdl == NULL) {
|
||||
log_e("adapter_adc_mic zalloc fail\n");
|
||||
return -1;
|
||||
}
|
||||
// 打开mic驱动
|
||||
audio_adc_mic_open(&hdl->mic_ch, AUDIO_ADC_MIC_CH, &adc_hdl);
|
||||
audio_adc_mic_set_gain(&hdl->mic_ch, gain);
|
||||
#if (TCFG_WIRELESS_MIC_STEREO_EN)
|
||||
audio_mic_0dB_en(1);
|
||||
|
||||
audio_adc_mic1_open(&hdl->mic_ch, AUDIO_ADC_MIC_CH, &adc_hdl);
|
||||
audio_adc_mic1_set_gain(&hdl->mic_ch, gain);
|
||||
audio_mic1_0dB_en(1);
|
||||
#endif
|
||||
|
||||
audio_adc_mic_set_sample_rate(&hdl->mic_ch, sample_rate);
|
||||
audio_adc_mic_set_buffs(
|
||||
&hdl->mic_ch,
|
||||
hdl->adc_buf,
|
||||
irq_points * 2,
|
||||
ADAPTER_ADC_MIC_BUF_NUM
|
||||
);
|
||||
hdl->adc_output.priv = NULL;
|
||||
hdl->adc_output.handler = adapter_adc_mic_output;
|
||||
audio_adc_add_output_handler(&adc_hdl, &hdl->adc_output);
|
||||
|
||||
cbuf_init(&hdl->cbuf, hdl->pcm_buf, irq_points * 2 * 3);
|
||||
adapter_adc_irq_points = irq_points;
|
||||
hdl->skip_cnt = 30;
|
||||
hdl->start = 0;
|
||||
|
||||
local_irq_disable();
|
||||
adapter_adc_mic = hdl;
|
||||
local_irq_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adapter_adc_mic_data_output_resume_register(void (*callback)(void *priv), void *priv)
|
||||
{
|
||||
if (adapter_adc_mic) {
|
||||
adapter_adc_mic->resume = callback;
|
||||
adapter_adc_mic->resume_priv = priv;
|
||||
}
|
||||
}
|
||||
|
||||
void adapter_adc_mic_data_callback_register(void (*callback)(void *priv, u8 *data, u16 len), void *priv)
|
||||
{
|
||||
if (adapter_adc_mic) {
|
||||
adapter_adc_mic->data_callback = callback;
|
||||
adapter_adc_mic->data_callback_priv = priv;
|
||||
}
|
||||
}
|
||||
|
||||
void adapter_adc_mic_close(void)
|
||||
{
|
||||
if (adapter_adc_mic) {
|
||||
adapter_adc_mic->start = 0;
|
||||
audio_adc_mic_close(&adapter_adc_mic->mic_ch);
|
||||
audio_adc_del_output_handler(&adc_hdl, &adapter_adc_mic->adc_output);
|
||||
|
||||
local_irq_disable();
|
||||
free(adapter_adc_mic);
|
||||
adapter_adc_mic = NULL;
|
||||
local_irq_enable();
|
||||
}
|
||||
}
|
||||
|
||||
void adapter_adc_mic_start(void)
|
||||
{
|
||||
if (adapter_adc_mic) {
|
||||
adapter_adc_mic->start = 1;
|
||||
audio_adc_mic_start(&adapter_adc_mic->mic_ch);
|
||||
}
|
||||
}
|
||||
|
||||
#endif//TCFG_AUDIO_ADC_ENABLE
|
||||
#endif//TCFG_WIRELESS_MIC_ENABLE
|
||||
|
||||
|
||||
17
apps/earphone/wireless_mic/audio/adapter_adc.h
Normal file
17
apps/earphone/wireless_mic/audio/adapter_adc.h
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
#ifndef __ADAPTER_ADC_H___
|
||||
#define __ADAPTER_ADC_H___
|
||||
|
||||
#include "generic/typedef.h"
|
||||
|
||||
void adapter_adc_init(void);
|
||||
struct audio_adc_hdl *adapter_adc_get_handle(void);
|
||||
int adapter_adc_mic_data_read(void *hdl, void *data, int len);
|
||||
int adapter_adc_mic_open(u16 sample_rate, u8 gain, u16 irq_points);
|
||||
void adapter_adc_mic_data_output_resume_register(void (*callback)(void *priv), void *priv);
|
||||
void adapter_adc_mic_data_callback_register(void (*callback)(void *priv, u8 *data, u16 len), void *priv);
|
||||
void adapter_adc_mic_close(void);
|
||||
void adapter_adc_mic_start(void);
|
||||
|
||||
#endif//__ADAPTER_ADC_H___
|
||||
|
||||
72
apps/earphone/wireless_mic/audio/adapter_media.c
Normal file
72
apps/earphone/wireless_mic/audio/adapter_media.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include "adapter_media.h"
|
||||
#include "adapter_adc.h"
|
||||
#include "adapter_wireless_dec.h"
|
||||
#include "adapter_wireless_enc.h"
|
||||
|
||||
#if (TCFG_WIRELESS_MIC_ENABLE)
|
||||
struct adapter_media g_adapter_media = {0};
|
||||
|
||||
static void adapter_adc_mic_data_callback(void *priv, void *buf, int len)
|
||||
{
|
||||
adapter_wireless_enc_write(buf, len);
|
||||
}
|
||||
|
||||
struct adapter_media *adapter_media_open(void *parm)
|
||||
{
|
||||
memset(&g_adapter_media, 0, sizeof(struct adapter_media));
|
||||
return &g_adapter_media;
|
||||
}
|
||||
|
||||
void adapter_media_close(struct adapter_media *media)
|
||||
{
|
||||
adapter_media_stop(media);
|
||||
}
|
||||
|
||||
void adapter_media_stop(struct adapter_media *media)
|
||||
{
|
||||
printf("adapter_media_stop\n");
|
||||
if (media) {
|
||||
if (media->idev && media->odev) {
|
||||
if (media->status) {
|
||||
if (media->idev->id == ADAPTER_IDEV_MIC && media->odev->id == ADAPTER_ODEV_BT) {
|
||||
printf("adapter_media_stop 1\n");
|
||||
adapter_adc_mic_close();
|
||||
adapter_wireless_enc_close();
|
||||
} else if (media->idev->id == ADAPTER_IDEV_BT && media->odev->id == ADAPTER_ODEV_DAC) {
|
||||
printf("adapter_media_stop 2\n");
|
||||
adapter_wireless_dec_close();
|
||||
}
|
||||
media->status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int adapter_media_start(struct adapter_media *media)
|
||||
{
|
||||
if (media) {
|
||||
if (media->idev && media->odev) {
|
||||
if (media->status) {
|
||||
printf("media start aready\n");
|
||||
return 0;
|
||||
}
|
||||
//start编解码
|
||||
if (media->idev->id == ADAPTER_IDEV_MIC && media->odev->id == ADAPTER_ODEV_BT) {
|
||||
//启动音频编码发射
|
||||
adapter_adc_mic_open(44100, 10, 120);
|
||||
adapter_wireless_enc_open();
|
||||
adapter_adc_mic_data_callback_register(adapter_adc_mic_data_callback, NULL);
|
||||
adapter_adc_mic_start();
|
||||
} else if (media->idev->id == ADAPTER_IDEV_BT && media->odev->id == ADAPTER_ODEV_DAC) {
|
||||
//启动解码输出dac
|
||||
adapter_wireless_dec_open();
|
||||
}
|
||||
media->status = 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif//TCFG_WIRELESS_MIC_ENABLE
|
||||
|
||||
|
||||
|
||||
25
apps/earphone/wireless_mic/audio/adapter_media.h
Normal file
25
apps/earphone/wireless_mic/audio/adapter_media.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef __ADAPTER_MEDIA_H__
|
||||
#define __ADAPTER_MEDIA_H__
|
||||
|
||||
#include "app_config.h"
|
||||
#include "generic/typedef.h"
|
||||
#include "media/includes.h"
|
||||
#include "adapter_idev.h"
|
||||
#include "adapter_odev.h"
|
||||
|
||||
|
||||
struct adapter_media {
|
||||
u8 status;
|
||||
//...
|
||||
struct idev *idev;
|
||||
struct odev *odev;
|
||||
};
|
||||
|
||||
|
||||
struct adapter_media *adapter_media_open(void *parm);
|
||||
void adapter_media_close(struct adapter_media *media);
|
||||
int adapter_media_start(struct adapter_media *media);
|
||||
void adapter_media_stop(struct adapter_media *media);
|
||||
|
||||
#endif//__ADAPTER_MEDIA_H__
|
||||
|
||||
582
apps/earphone/wireless_mic/audio/wireless/adapter_wireless_dec.c
Normal file
582
apps/earphone/wireless_mic/audio/wireless/adapter_wireless_dec.c
Normal file
@ -0,0 +1,582 @@
|
||||
#include "adapter_wireless_dec.h"
|
||||
#include "asm/includes.h"
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
#include "audio_config.h"
|
||||
//#include "adapter_decoder.h"
|
||||
#include "adapter_process.h"
|
||||
|
||||
#if TCFG_WIRELESS_MIC_ENABLE
|
||||
|
||||
//#define WIRELESS_DECODER_SEL AUDIO_CODING_SBC
|
||||
#define WIRELESS_DECODER_SEL AUDIO_CODING_LC3
|
||||
|
||||
#define WIRELESS_PACKET_HEADER_LEN (2)//(2)/*包头Max Length*/
|
||||
#define WIRELESS_DAC_MAX_DELAY (16)
|
||||
#define WIRELESS_DAC_START_DELAY (10)
|
||||
|
||||
struct __adapter_wireless_dec {
|
||||
struct audio_decoder decoder; // 解码器
|
||||
struct audio_res_wait wait; // 资源等待句柄
|
||||
struct audio_mixer_ch mix_ch; // 叠加句柄
|
||||
u8 start; // 解码开始
|
||||
u8 wait_resume;// 需要激活
|
||||
u8 remain; // 解码剩余数据标记
|
||||
int coding_type;// 解码类型
|
||||
};
|
||||
|
||||
|
||||
extern struct audio_decoder_task decode_task;
|
||||
extern struct audio_dac_hdl dac_hdl;
|
||||
extern struct audio_mixer mixer;
|
||||
|
||||
extern const int LC3_SUPPORT_CH;
|
||||
extern const int LC3_DMS_VAL; //单位ms, 【只支持 25,50,100】
|
||||
|
||||
#define ADAPTER_WIRELESS_FRAME_LBUF_SIZE (150*LC3_SUPPORT_CH)
|
||||
|
||||
struct __adapter_wireless_dec *adapter_wireless_dec = NULL;
|
||||
|
||||
int adapter_wireless_media_get_packet(u8 **frame);
|
||||
void adapter_wireless_media_free_packet(void *_packet);
|
||||
void *adapter_wireless_media_fetch_packet(int *len, void *prev_packet);
|
||||
int adapter_wireless_media_get_packet_num(void);
|
||||
int adapter_wireless_dec_close(void);
|
||||
|
||||
|
||||
// 解码获取数据
|
||||
static int adapter_wireless_dec_get_frame(struct audio_decoder *decoder, u8 **frame)
|
||||
{
|
||||
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
|
||||
u8 *packet = NULL;
|
||||
int len = 0;
|
||||
|
||||
// 获取数据
|
||||
len = adapter_wireless_media_get_packet(&packet);
|
||||
if (len < 0) {
|
||||
// 失败
|
||||
putchar('X');
|
||||
return len;
|
||||
}
|
||||
// putchar('g');
|
||||
*frame = packet;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// 解码释放数据空间
|
||||
static void adapter_wireless_dec_put_frame(struct audio_decoder *decoder, u8 *frame)
|
||||
{
|
||||
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
|
||||
|
||||
if (frame) {
|
||||
adapter_wireless_media_free_packet((void *)(frame));
|
||||
}
|
||||
}
|
||||
|
||||
// 解码查询数据
|
||||
static int adapter_wireless_dec_fetch_frame(struct audio_decoder *decoder, u8 **frame)
|
||||
{
|
||||
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
|
||||
u8 *packet = NULL;
|
||||
int len = 0;
|
||||
u32 wait_timeout = 0;
|
||||
|
||||
if (!dec->start) {
|
||||
wait_timeout = jiffies + msecs_to_jiffies(500);
|
||||
}
|
||||
|
||||
__retry_fetch:
|
||||
packet = adapter_wireless_media_fetch_packet(&len, NULL);
|
||||
if (packet) {
|
||||
*frame = packet;
|
||||
} else if (!dec->start) {
|
||||
// 解码启动前获取数据来做格式信息获取等
|
||||
if (time_before(jiffies, wait_timeout)) {
|
||||
os_time_dly(1);
|
||||
goto __retry_fetch;
|
||||
}
|
||||
}
|
||||
printf("adapter_wireless_dec_fetch_frame ok\n");
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct audio_dec_input adapter_wireless_input = {
|
||||
.coding_type = WIRELESS_DECODER_SEL,
|
||||
.data_type = AUDIO_INPUT_FRAME,
|
||||
.ops = {
|
||||
.frame = {
|
||||
.fget = adapter_wireless_dec_get_frame,
|
||||
.fput = adapter_wireless_dec_put_frame,
|
||||
.ffetch = adapter_wireless_dec_fetch_frame,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 解码预处理
|
||||
static int adapter_wireless_dec_probe_handler(struct audio_decoder *decoder)
|
||||
{
|
||||
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
|
||||
|
||||
if (adapter_wireless_media_get_packet_num() < 1) {
|
||||
// 没有数据时返回负数,等有数据时激活解码
|
||||
dec->wait_resume = 1;
|
||||
audio_decoder_suspend(decoder, 0);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 解码后处理
|
||||
static int adapter_wireless_dec_post_handler(struct audio_decoder *decoder)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adapter_wireless_dec_output_handler(struct audio_decoder *decoder, s16 *data, int len, void *priv)
|
||||
{
|
||||
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
|
||||
if (!dec->remain) {
|
||||
/* put_u16hex(len); */
|
||||
}
|
||||
int wlen = 0;
|
||||
do {
|
||||
wlen = audio_mixer_ch_write(&dec->mix_ch, data, len);
|
||||
} while (0);
|
||||
|
||||
int remain_len = len - wlen;
|
||||
|
||||
if (remain_len == 0) {
|
||||
dec->remain = 0;
|
||||
} else {
|
||||
dec->remain = 1;
|
||||
}
|
||||
|
||||
return wlen;
|
||||
}
|
||||
|
||||
static const struct audio_dec_handler adapter_wireless_dec_handler = {
|
||||
.dec_probe = adapter_wireless_dec_probe_handler,
|
||||
.dec_output = adapter_wireless_dec_output_handler,
|
||||
.dec_post = adapter_wireless_dec_post_handler,
|
||||
};
|
||||
|
||||
|
||||
// 解码释放
|
||||
static void adapter_wireless_dec_release(void)
|
||||
{
|
||||
// 删除解码资源等待
|
||||
audio_decoder_task_del_wait(&decode_task, &adapter_wireless_dec->wait);
|
||||
|
||||
|
||||
// 释放空间
|
||||
local_irq_disable();
|
||||
free(adapter_wireless_dec);
|
||||
adapter_wireless_dec = NULL;
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
// 解码关闭
|
||||
static void adapter_wireless_audio_res_close(void)
|
||||
{
|
||||
if (adapter_wireless_dec->start == 0) {
|
||||
printf("adapter_wireless_dec->start == 0");
|
||||
return ;
|
||||
}
|
||||
|
||||
// 关闭数据流节点
|
||||
adapter_wireless_dec->start = 0;
|
||||
audio_decoder_close(&adapter_wireless_dec->decoder);
|
||||
|
||||
audio_mixer_ch_close(&adapter_wireless_dec->mix_ch);
|
||||
|
||||
//adapter_audio_stream_close(&adapter_wireless_dec->stream);
|
||||
|
||||
app_audio_state_exit(APP_AUDIO_STATE_MUSIC);
|
||||
}
|
||||
|
||||
// 解码事件处理
|
||||
static void adapter_wireless_dec_event_handler(struct audio_decoder *decoder, int argc, int *argv)
|
||||
{
|
||||
switch (argv[0]) {
|
||||
case AUDIO_DEC_EVENT_END:
|
||||
printf("AUDIO_DEC_EVENT_END\n");
|
||||
adapter_wireless_dec_close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 解码数据流激活
|
||||
static void adapter_wireless_out_stream_resume(void *p)
|
||||
{
|
||||
struct __adapter_wireless_dec *dec = (struct __adapter_wireless_dec *)p;
|
||||
|
||||
audio_decoder_resume(&dec->decoder);
|
||||
}
|
||||
|
||||
// 收到数据后的处理
|
||||
void adapter_wireless_media_rx_notice_to_decode(void)
|
||||
{
|
||||
if (adapter_wireless_dec && adapter_wireless_dec->start && adapter_wireless_dec->wait_resume) {
|
||||
adapter_wireless_dec->wait_resume = 0;
|
||||
audio_decoder_resume(&adapter_wireless_dec->decoder);
|
||||
}
|
||||
}
|
||||
|
||||
// 解码start
|
||||
static int adapter_wireless_dec_start(void)
|
||||
{
|
||||
int err;
|
||||
struct audio_fmt *fmt;
|
||||
struct __adapter_wireless_dec *dec = adapter_wireless_dec;
|
||||
|
||||
if (!adapter_wireless_dec) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
printf("adapter_wireless_dec_start: in\n");
|
||||
|
||||
// 打开adapter_wireless解码
|
||||
err = audio_decoder_open(&dec->decoder, &adapter_wireless_input, &decode_task);
|
||||
if (err) {
|
||||
goto __err1;
|
||||
}
|
||||
|
||||
// 设置运行句柄
|
||||
audio_decoder_set_handler(&dec->decoder, &adapter_wireless_dec_handler);
|
||||
|
||||
#if (WIRELESS_DECODER_SEL == AUDIO_CODING_SBC)
|
||||
if (dec->coding_type != adapter_wireless_input.coding_type) {
|
||||
struct audio_fmt f = {0};
|
||||
f.coding_type = dec->coding_type;
|
||||
err = audio_decoder_set_fmt(&dec->decoder, &f);
|
||||
if (err) {
|
||||
goto __err2;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取解码格式
|
||||
err = audio_decoder_get_fmt(&dec->decoder, &fmt);
|
||||
if (err) {
|
||||
goto __err2;
|
||||
}
|
||||
#else
|
||||
struct audio_fmt f = {0};
|
||||
f.coding_type = WIRELESS_DECODER_SEL;
|
||||
f.channel = LC3_SUPPORT_CH;
|
||||
f.sample_rate = 44100;
|
||||
f.bit_rate = 64000;
|
||||
f.frame_len = LC3_DMS_VAL;
|
||||
|
||||
dec->decoder.fmt.channel = f.channel;
|
||||
dec->decoder.fmt.sample_rate = f.sample_rate;
|
||||
dec->decoder.fmt.bit_rate = f.bit_rate;
|
||||
dec->decoder.fmt.frame_len = f.frame_len;
|
||||
|
||||
err = audio_decoder_set_fmt(&dec->decoder, &f);
|
||||
if (err) {
|
||||
goto __err2;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 使能事件回调
|
||||
audio_decoder_set_event_handler(&dec->decoder, adapter_wireless_dec_event_handler, 0);
|
||||
|
||||
// 设置输出声道类型
|
||||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
|
||||
audio_decoder_set_output_channel(&dec->decoder, AUDIO_CH_LR);
|
||||
#else
|
||||
audio_decoder_set_output_channel(&dec->decoder, AUDIO_CH_DIFF);
|
||||
#endif
|
||||
|
||||
|
||||
#if TCFG_AUDIO_DAC_ENABLE
|
||||
//设定延时,
|
||||
audio_dac_set_delay_time(&dac_hdl, WIRELESS_DAC_START_DELAY, WIRELESS_DAC_MAX_DELAY);
|
||||
#endif//TCFG_AUDIO_DAC_ENABLE
|
||||
|
||||
// 设置音频输出类型
|
||||
audio_mixer_ch_open(&dec->mix_ch, &mixer);
|
||||
audio_mixer_ch_set_sample_rate(&dec->mix_ch, f.sample_rate);
|
||||
audio_mixer_ch_set_resume_handler(&dec->mix_ch, (void *)&dec->decoder, (void (*)(void *))audio_decoder_resume);
|
||||
app_audio_state_switch(APP_AUDIO_STATE_MUSIC, get_max_sys_vol());
|
||||
|
||||
|
||||
// 开始解码
|
||||
dec->start = 1;
|
||||
err = audio_decoder_start(&dec->decoder);
|
||||
if (err) {
|
||||
goto __err3;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
__err3:
|
||||
__err2:
|
||||
dec->start = 0;
|
||||
audio_decoder_close(&dec->decoder);
|
||||
__err1:
|
||||
adapter_wireless_dec_release();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// 解码资源等待回调
|
||||
static int adapter_wireless_wait_res_handler(struct audio_res_wait *wait, int event)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
y_printf("adapter_wireless_wait_res_handler: %d\n", event);
|
||||
|
||||
if (event == AUDIO_RES_GET) {
|
||||
// 可以开始解码
|
||||
err = adapter_wireless_dec_start();
|
||||
} else if (event == AUDIO_RES_PUT) {
|
||||
// 被打断
|
||||
if (adapter_wireless_dec->start) {
|
||||
adapter_wireless_audio_res_close();
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// 打开解码
|
||||
//int adapter_wireless_dec_open(struct adapter_decoder_fmt *fmt, struct adapter_media_parm *media_parm)
|
||||
int adapter_wireless_dec_open(void)
|
||||
{
|
||||
struct __adapter_wireless_dec *dec;
|
||||
|
||||
if (adapter_wireless_dec) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("adapter_wireless_dec_open \n");
|
||||
|
||||
dec = zalloc(sizeof(*dec));
|
||||
ASSERT(dec);
|
||||
|
||||
|
||||
/* dec->fmt = fmt; */
|
||||
/* dec->media_parm = media_parm; */
|
||||
|
||||
adapter_wireless_dec = dec;
|
||||
dec->coding_type = WIRELESS_DECODER_SEL; // 解码类型
|
||||
dec->wait.priority = 1; // 解码优先级
|
||||
dec->wait.preemption = 0; // 不使能直接抢断解码
|
||||
//dec->wait.snatch_same_prio = 1; // 可抢断同优先级解码
|
||||
dec->wait.handler = adapter_wireless_wait_res_handler;
|
||||
|
||||
adapter_wireless_dec_frame_init();
|
||||
|
||||
audio_decoder_task_add_wait(&decode_task, &dec->wait);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 关闭解码
|
||||
int adapter_wireless_dec_close(void)
|
||||
{
|
||||
|
||||
printf("adapter_wireless_dec_close 1\n");
|
||||
if (!adapter_wireless_dec) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (adapter_wireless_dec->start) {
|
||||
adapter_wireless_audio_res_close();
|
||||
}
|
||||
adapter_wireless_dec_release();
|
||||
|
||||
adapter_wireless_dec_frame_close();
|
||||
|
||||
printf("adapter_wireless_dec_close 2\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* static void adapter_wireless_dec_set_vol(u32 channel, u8 vol) */
|
||||
/* { */
|
||||
/* if (adapter_wireless_dec && adapter_wireless_dec->stream) { */
|
||||
/* adapter_audio_stream_set_vol(adapter_wireless_dec->stream, channel, vol); */
|
||||
/* } */
|
||||
/* } */
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
struct adapter_wireless_media_rx_bulk {
|
||||
struct list_head entry;
|
||||
int data_len;
|
||||
u8 data[0];
|
||||
};
|
||||
|
||||
static u16 adapter_wireless_rx_seqn = 0;
|
||||
static u32 *adapter_wireless_media_buf = NULL;
|
||||
static LIST_HEAD(adapter_wireless_media_head);
|
||||
|
||||
|
||||
|
||||
// 获取frame数据
|
||||
int adapter_wireless_media_get_packet(u8 **frame)
|
||||
{
|
||||
struct adapter_wireless_media_rx_bulk *p;
|
||||
local_irq_disable();
|
||||
if (adapter_wireless_media_head.next != &adapter_wireless_media_head) {
|
||||
p = list_entry((&adapter_wireless_media_head)->next, typeof(*p), entry);
|
||||
__list_del_entry(&p->entry);
|
||||
*frame = p->data;
|
||||
local_irq_enable();
|
||||
return p->data_len;
|
||||
}
|
||||
local_irq_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 释放frame数据
|
||||
void adapter_wireless_media_free_packet(void *data)
|
||||
{
|
||||
struct adapter_wireless_media_rx_bulk *rx = container_of(data, struct adapter_wireless_media_rx_bulk, data);
|
||||
|
||||
local_irq_disable();
|
||||
__list_del_entry(&rx->entry);
|
||||
local_irq_enable();
|
||||
|
||||
lbuf_free(rx);
|
||||
}
|
||||
|
||||
// 检查frame数据
|
||||
void *adapter_wireless_media_fetch_packet(int *len, void *prev_packet)
|
||||
{
|
||||
struct adapter_wireless_media_rx_bulk *p;
|
||||
local_irq_disable();
|
||||
if (adapter_wireless_media_head.next != &adapter_wireless_media_head) {
|
||||
if (prev_packet) {
|
||||
p = container_of(prev_packet, struct adapter_wireless_media_rx_bulk, data);
|
||||
if (p->entry.next != &adapter_wireless_media_head) {
|
||||
p = list_entry(p->entry.next, typeof(*p), entry);
|
||||
*len = p->data_len;
|
||||
local_irq_enable();
|
||||
return p->data;
|
||||
}
|
||||
} else {
|
||||
p = list_entry((&adapter_wireless_media_head)->next, typeof(*p), entry);
|
||||
*len = p->data_len;
|
||||
local_irq_enable();
|
||||
return p->data;
|
||||
}
|
||||
}
|
||||
local_irq_enable();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 获取数据量
|
||||
int adapter_wireless_media_get_packet_num(void)
|
||||
{
|
||||
struct adapter_wireless_media_rx_bulk *p;
|
||||
u32 num = 0;
|
||||
local_irq_disable();
|
||||
list_for_each_entry(p, &adapter_wireless_media_head, entry) {
|
||||
num++;
|
||||
}
|
||||
local_irq_enable();
|
||||
return num;
|
||||
}
|
||||
|
||||
int adapter_wireless_dec_frame_write(void *data, u16 len)
|
||||
{
|
||||
// printf("rx len = %d ", len);
|
||||
struct adapter_wireless_media_rx_bulk *p;
|
||||
local_irq_disable();
|
||||
if (adapter_wireless_media_buf) {
|
||||
if (len < WIRELESS_PACKET_HEADER_LEN) {
|
||||
local_irq_enable();
|
||||
return 0;
|
||||
}
|
||||
u16 rx_seqn = 0;
|
||||
u8 *buf = data;
|
||||
rx_seqn |= (u16)(buf[0] << 8);
|
||||
rx_seqn |= buf[1];
|
||||
if (adapter_wireless_rx_seqn == rx_seqn) {
|
||||
putchar('1');
|
||||
local_irq_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
adapter_wireless_rx_seqn ++;
|
||||
if (rx_seqn != adapter_wireless_rx_seqn) {
|
||||
// putchar('2');
|
||||
adapter_wireless_rx_seqn = rx_seqn;
|
||||
}
|
||||
// putchar('R');
|
||||
|
||||
len -= 2;
|
||||
buf += 2;
|
||||
|
||||
p = lbuf_alloc((struct lbuff_head *)adapter_wireless_media_buf, sizeof(*p) + len);
|
||||
if (p == NULL) {
|
||||
printf("lbuf full !!\n");
|
||||
/* putchar('!'); */
|
||||
local_irq_enable();
|
||||
adapter_wireless_media_rx_notice_to_decode();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//putchar('W');
|
||||
// 填数
|
||||
p->data_len = len;//sizeof(sbc_data);
|
||||
memcpy(p->data, buf, len);
|
||||
list_add_tail(&p->entry, &adapter_wireless_media_head);
|
||||
// 告诉上层有数据
|
||||
adapter_wireless_media_rx_notice_to_decode();
|
||||
local_irq_enable();
|
||||
return 1;
|
||||
}
|
||||
local_irq_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 模拟定时关闭
|
||||
void adapter_wireless_dec_frame_close(void)
|
||||
{
|
||||
y_printf("%s,%d \n", __func__, __LINE__);
|
||||
|
||||
local_irq_disable();
|
||||
__list_del_entry(&adapter_wireless_media_head);
|
||||
if (adapter_wireless_media_buf) {
|
||||
printf("meida_buf free!!!!!!!!!!!!!!!");
|
||||
free(adapter_wireless_media_buf);
|
||||
adapter_wireless_media_buf = NULL;
|
||||
}
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
void adapter_wireless_dec_frame_init(void)
|
||||
{
|
||||
printf("%s,%d \n", __func__, __LINE__);
|
||||
if (adapter_wireless_media_buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 申请空间
|
||||
u32 buf_size = ADAPTER_WIRELESS_FRAME_LBUF_SIZE;
|
||||
void *buf = malloc(buf_size);
|
||||
ASSERT(buf);
|
||||
// 初始化lbuf
|
||||
local_irq_disable();
|
||||
lbuf_init(buf, buf_size, 4, 0);
|
||||
INIT_LIST_HEAD(&adapter_wireless_media_head);
|
||||
local_irq_enable();
|
||||
|
||||
// 启动解码
|
||||
adapter_wireless_media_buf = buf;
|
||||
}
|
||||
|
||||
#endif//TCFG_WIRELESS_MIC_ENABLE
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
#ifndef __ADAPTER_WIRELESS_DEC_H__
|
||||
#define __ADAPTER_WIRELESS_DEC_H__
|
||||
|
||||
#include "generic/typedef.h"
|
||||
#include "media/includes.h"
|
||||
|
||||
void adapter_wireless_dec_frame_init(void);
|
||||
void adapter_wireless_dec_frame_close(void);
|
||||
int adapter_wireless_dec_frame_write(void *data, u16 len);
|
||||
int adapter_wireless_dec_open(void);
|
||||
int adapter_wireless_dec_close(void);
|
||||
|
||||
#endif//__ADAPTER_WIRELESS_DEC_H__
|
||||
368
apps/earphone/wireless_mic/audio/wireless/adapter_wireless_enc.c
Normal file
368
apps/earphone/wireless_mic/audio/wireless/adapter_wireless_enc.c
Normal file
@ -0,0 +1,368 @@
|
||||
#include "adapter_wireless_enc.h"
|
||||
//#include "adapter_encoder.h"
|
||||
#include "media/sbc_enc.h"
|
||||
#include "app_config.h"
|
||||
|
||||
#if TCFG_WIRELESS_MIC_ENABLE
|
||||
|
||||
/* #define WIRELESS_ENCODER_SEL AUDIO_CODING_SBC */
|
||||
#define WIRELESS_ENCODER_SEL AUDIO_CODING_LC3
|
||||
|
||||
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_SBC)
|
||||
#define WIRELESS_ENC_IN_SIZE 512
|
||||
#else
|
||||
#define WIRELESS_ENC_IN_SIZE 480
|
||||
#endif
|
||||
#define WIRELESS_ENC_OUT_SIZE 256
|
||||
#define WIRELESS_FRAME_SUM (1)/*一包多少帧*/
|
||||
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_LC3)
|
||||
#define WIRELESS_PACKET_HEADER_LEN (2)//(2 + 2)//(2)/*包头Max Length*/
|
||||
#else
|
||||
#define WIRELESS_PACKET_HEADER_LEN (2)//(2)/*包头Max Length*/
|
||||
#endif
|
||||
#define WIRELESS_PACKET_REPEAT_SUM (1)/*包重发次数*/
|
||||
#define WIRELESS_ENC_OUT_BUF_SIZE (WIRELESS_ENC_OUT_SIZE * WIRELESS_FRAME_SUM)
|
||||
#define WIRELESS_ENC_PCM_BUF_LEN (WIRELESS_ENC_IN_SIZE * 4)
|
||||
|
||||
struct __adapter_wireless_enc {
|
||||
struct audio_encoder encoder;
|
||||
cbuffer_t cbuf_pcm;
|
||||
s16 pcm_buf[WIRELESS_ENC_PCM_BUF_LEN / 2];
|
||||
s16 output_frame[WIRELESS_ENC_OUT_SIZE / 2]; // 编码输出帧
|
||||
int input_frame[WIRELESS_ENC_IN_SIZE / 4];
|
||||
u8 out_buf[WIRELESS_PACKET_HEADER_LEN + WIRELESS_ENC_OUT_BUF_SIZE]; // sbc帧缓存
|
||||
|
||||
u16 frame_in_size; // 帧输入大小
|
||||
u8 frame_cnt; // 帧打包计数
|
||||
u16 frame_len; // 帧长
|
||||
u16 tx_seqn; // 传输计数
|
||||
volatile u8 start; // 启动标志
|
||||
|
||||
};
|
||||
|
||||
|
||||
static struct audio_encoder_task *wireless_encode_task = NULL;
|
||||
|
||||
|
||||
|
||||
#define MY_IO_DEBUG_0(i,x) {JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT &= ~BIT(x);}
|
||||
#define MY_IO_DEBUG_1(i,x) {JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT |= BIT(x);}
|
||||
|
||||
static int adapter_wireless_enc_push(struct __adapter_wireless_enc *hdl, void *buf, int len)
|
||||
{
|
||||
if (!hdl->start) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// printf("len = %d\n", len);
|
||||
|
||||
int ret = 0;
|
||||
extern int wireless_mic_ble_send(void *priv, u8 * buf, u16 len);
|
||||
for (int i = 0; i < WIRELESS_PACKET_REPEAT_SUM; i++) {
|
||||
ret = wireless_mic_ble_send(NULL, buf, len);
|
||||
if (ret) {
|
||||
// printf("lost ###################\n");
|
||||
putchar('E');
|
||||
} else {
|
||||
// putchar('O');
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int adapter_wireless_enc_write_pcm(struct __adapter_wireless_enc *hdl, void *buf, int len)
|
||||
{
|
||||
if (!hdl->start) {
|
||||
return 0;
|
||||
}
|
||||
//putchar('w');
|
||||
int wlen = cbuf_write(&hdl->cbuf_pcm, buf, len);
|
||||
if (cbuf_get_data_len(&hdl->cbuf_pcm) >= (hdl->frame_in_size)) {
|
||||
audio_encoder_resume(&hdl->encoder);
|
||||
}
|
||||
return wlen;
|
||||
}
|
||||
|
||||
|
||||
static void adapter_wireless_enc_packet_pack(struct __adapter_wireless_enc *hdl, u16 len)
|
||||
{
|
||||
//将包的序列号写到头部
|
||||
hdl->tx_seqn++;
|
||||
#if (WIRELESS_PACKET_HEADER_LEN)
|
||||
hdl->out_buf[0] = hdl->tx_seqn >> 8;
|
||||
hdl->out_buf[1] = hdl->tx_seqn & 0xff;
|
||||
|
||||
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_LC3)
|
||||
//memcpy(&hdl->out_buf[2], &len, 2);
|
||||
#endif//AUDIO_CODING_LC3
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static int adapter_wireless_enc_pcm_get(struct audio_encoder *encoder, s16 **frame, u16 frame_len)
|
||||
{
|
||||
struct __adapter_wireless_enc *hdl = container_of(encoder, struct __adapter_wireless_enc, encoder);
|
||||
int pcm_len = 0;
|
||||
//printf("frame_len = %d ", frame_len);
|
||||
|
||||
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_SBC)
|
||||
frame_len = hdl->frame_in_size;
|
||||
#else
|
||||
if (frame_len > hdl->frame_in_size) {
|
||||
printf("frame_len over limit !!!!, %d\n", frame_len);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
//printf("frame_len = %d\n", frame_len);
|
||||
pcm_len = cbuf_read(&hdl->cbuf_pcm, hdl->input_frame, frame_len);
|
||||
if (pcm_len != frame_len) {
|
||||
/* putchar('L'); */
|
||||
} else {
|
||||
/* put_u16hex(frame_len); */
|
||||
}
|
||||
|
||||
|
||||
*frame = (s16 *)hdl->input_frame;
|
||||
return pcm_len;
|
||||
}
|
||||
|
||||
static void adapter_wireless_enc_pcm_put(struct audio_encoder *encoder, s16 *frame)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct audio_enc_input adapter_wireless_enc_input = {
|
||||
.fget = adapter_wireless_enc_pcm_get,
|
||||
.fput = adapter_wireless_enc_pcm_put,
|
||||
};
|
||||
|
||||
|
||||
static int adapter_wireless_enc_probe_handler(struct audio_encoder *encoder)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adapter_wireless_enc_output_handler(struct audio_encoder *encoder, u8 *frame, int len)
|
||||
{
|
||||
struct __adapter_wireless_enc *enc = container_of(encoder, struct __adapter_wireless_enc, encoder);
|
||||
//检查上次是否还有数据没有发出
|
||||
if (enc->frame_cnt >= WIRELESS_FRAME_SUM) {
|
||||
//putchar('&');
|
||||
int wlen = adapter_wireless_enc_push(enc, enc->out_buf, enc->frame_len);
|
||||
if (wlen != enc->frame_len) {
|
||||
return 0;
|
||||
}
|
||||
enc->frame_cnt = 0;
|
||||
}
|
||||
if (enc->frame_cnt == 0) {
|
||||
//重新打包, 加包头
|
||||
adapter_wireless_enc_packet_pack(enc, len);
|
||||
enc->frame_len = WIRELESS_PACKET_HEADER_LEN;
|
||||
}
|
||||
//拼接数据内容
|
||||
memcpy(&enc->out_buf[enc->frame_len], frame, len);
|
||||
enc->frame_len += len;
|
||||
enc->frame_cnt ++;
|
||||
//检查是否达到发送条件
|
||||
if (enc->frame_cnt >= WIRELESS_FRAME_SUM) {
|
||||
//putchar('@');
|
||||
int wlen = adapter_wireless_enc_push(enc, enc->out_buf, enc->frame_len);
|
||||
if (wlen == enc->frame_len) {
|
||||
enc->frame_cnt = 0;
|
||||
//audio_encoder_resume(&enc->encoder);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
const static struct audio_enc_handler adapter_wireless_enc_handler = {
|
||||
.enc_probe = adapter_wireless_enc_probe_handler,
|
||||
.enc_output = adapter_wireless_enc_output_handler,
|
||||
};
|
||||
|
||||
|
||||
static void adapter_wireless_enc_stop(struct __adapter_wireless_enc *hdl)
|
||||
{
|
||||
if (hdl->start) {
|
||||
hdl->start = 0;
|
||||
audio_encoder_close(&hdl->encoder);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __adapter_wireless_enc *wireless_enc = NULL;
|
||||
void adapter_wireless_enc_close(void)
|
||||
{
|
||||
if (!wireless_enc) {
|
||||
return ;
|
||||
}
|
||||
adapter_wireless_enc_stop(wireless_enc);
|
||||
|
||||
local_irq_disable();
|
||||
free(wireless_enc);
|
||||
wireless_enc = NULL;
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
#if 1
|
||||
int adapter_wireless_enc_open_base(struct audio_fmt *fmt, u16 frame_in_size)
|
||||
{
|
||||
int err = 0;
|
||||
if (fmt == NULL) {
|
||||
log_e("wireless_enc_open parm error\n");
|
||||
return -1;
|
||||
}
|
||||
struct __adapter_wireless_enc *hdl = zalloc(sizeof(struct __adapter_wireless_enc));
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdl->frame_in_size = frame_in_size;
|
||||
|
||||
// 变量初始化
|
||||
cbuf_init(&hdl->cbuf_pcm, hdl->pcm_buf, sizeof(hdl->pcm_buf));
|
||||
|
||||
if (!wireless_encode_task) {
|
||||
///这里不用SDK本身的编码线程因为编码线程成不能高于协议栈线程
|
||||
wireless_encode_task = zalloc(sizeof(struct audio_encoder_task));
|
||||
if (!wireless_encode_task) {
|
||||
printf("wireless_encode_task NULL !!!\n");
|
||||
}
|
||||
printf("wireless_encode_task 1111\n");
|
||||
audio_encoder_task_create(wireless_encode_task, "wl_mic_enc");
|
||||
}
|
||||
|
||||
|
||||
printf("wireless_encode_task 2222\n");
|
||||
audio_encoder_open(&hdl->encoder, &adapter_wireless_enc_input, wireless_encode_task);
|
||||
audio_encoder_set_handler(&hdl->encoder, &adapter_wireless_enc_handler);
|
||||
audio_encoder_set_fmt(&hdl->encoder, fmt);
|
||||
audio_encoder_set_output_buffs(&hdl->encoder, hdl->output_frame, sizeof(hdl->output_frame), 1);
|
||||
|
||||
if (!hdl->encoder.enc_priv) {
|
||||
log_e("encoder err, maybe coding(0x%x) disable \n", fmt.coding_type);
|
||||
err = -EINVAL;
|
||||
goto __err;
|
||||
}
|
||||
|
||||
printf("wireless_encode_task 3333\n");
|
||||
audio_encoder_start(&hdl->encoder);
|
||||
printf("wireless_encode_task 4444\n");
|
||||
|
||||
hdl->start = 1;
|
||||
|
||||
local_irq_disable();
|
||||
wireless_enc = hdl;
|
||||
local_irq_enable();
|
||||
|
||||
return 0;
|
||||
|
||||
__err:
|
||||
audio_encoder_close(&hdl->encoder);
|
||||
local_irq_disable();
|
||||
free(hdl);
|
||||
hdl = NULL;
|
||||
local_irq_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int adapter_wireless_enc_write(void *buf, int len)
|
||||
{
|
||||
if (!wireless_enc) {
|
||||
return 0;
|
||||
}
|
||||
int wlen = adapter_wireless_enc_write_pcm(wireless_enc, buf, len);
|
||||
if (wlen != len) {
|
||||
putchar('L');
|
||||
}
|
||||
return wlen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//static struct audio_stream_entry g_entry; // 音频流入口
|
||||
static sbc_t g_sbc_param = {0};
|
||||
u16 g_sample_rate = 44100;
|
||||
u8 g_channel = 2;
|
||||
|
||||
|
||||
static int adapter_wireless_enc_data_handler(struct audio_stream_entry *entry, struct audio_data_frame *in,
|
||||
struct audio_data_frame *out)
|
||||
{
|
||||
int wlen = adapter_wireless_enc_write(in->data, in->data_len);
|
||||
if (wlen == in->data_len) {
|
||||
//putchar('W');
|
||||
} else {
|
||||
//putchar('M');
|
||||
}
|
||||
return in->data_len;
|
||||
}
|
||||
|
||||
int adapter_wireless_enc_open(void)
|
||||
{
|
||||
struct audio_fmt fmt = {0};
|
||||
u16 frame_in_size = 0;
|
||||
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_SBC)
|
||||
sbc_t *sbc_param = &g_sbc_param;
|
||||
|
||||
sbc_param->frequency = SBC_FREQ_44100;
|
||||
sbc_param->blocks = SBC_BLK_16;
|
||||
sbc_param->subbands = SBC_SB_8;
|
||||
sbc_param->mode = SBC_MODE_STEREO;
|
||||
sbc_param->allocation = 0;
|
||||
sbc_param->endian = SBC_LE;
|
||||
sbc_param->bitpool = 19;//53;
|
||||
|
||||
printf("sbc_param->bitpool ============================ %d\n", sbc_param->bitpool);
|
||||
|
||||
switch (g_sample_rate) {
|
||||
case 16000:
|
||||
sbc_param->frequency = SBC_FREQ_16000;
|
||||
break;
|
||||
case 32000:
|
||||
sbc_param->frequency = SBC_FREQ_32000;
|
||||
break;
|
||||
case 44100:
|
||||
sbc_param->frequency = SBC_FREQ_44100;
|
||||
break;
|
||||
case 48000:
|
||||
sbc_param->frequency = SBC_FREQ_48000;
|
||||
break;
|
||||
}
|
||||
if (g_channel == 1) {
|
||||
sbc_param->mode = SBC_MODE_MONO;
|
||||
frame_in_size = WIRELESS_ENC_IN_SIZE / 2;
|
||||
} else {
|
||||
sbc_param->mode = SBC_MODE_STEREO;
|
||||
frame_in_size = WIRELESS_ENC_IN_SIZE;
|
||||
}
|
||||
|
||||
fmt.coding_type = AUDIO_CODING_SBC;
|
||||
fmt.sample_rate = g_sample_rate;
|
||||
fmt.channel = g_channel;
|
||||
fmt.priv = &g_sbc_param;
|
||||
#else
|
||||
extern const int LC3_DMS_VAL; //单位ms, 【只支持 25,50,100】
|
||||
fmt.coding_type = AUDIO_CODING_LC3;
|
||||
fmt.sample_rate = 44100;//g_sample_rate;
|
||||
#if (TCFG_WIRELESS_MIC_STEREO_EN)
|
||||
fmt.channel = 2;
|
||||
#else
|
||||
fmt.channel = 1;
|
||||
#endif
|
||||
fmt.bit_rate = 64000;//128000;//64000;//128000;
|
||||
fmt.frame_len = LC3_DMS_VAL;//2.5 * 10;
|
||||
if (fmt.channel == 1) {
|
||||
frame_in_size = WIRELESS_ENC_IN_SIZE / 2;
|
||||
} else {
|
||||
frame_in_size = WIRELESS_ENC_IN_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
adapter_wireless_enc_open_base(&fmt, frame_in_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif//TCFG_WIRELESS_MIC_ENABLE
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
#ifndef __ADAPTER_WIRELESS_ENC_H__
|
||||
#define __ADAPTER_WIRELESS_ENC_H__
|
||||
|
||||
#include "asm/includes.h"
|
||||
#include "generic/typedef.h"
|
||||
#include "media/includes.h"
|
||||
|
||||
|
||||
int adapter_wireless_enc_write(void *buf, int len);
|
||||
int adapter_wireless_enc_open(void);
|
||||
void adapter_wireless_enc_close(void);
|
||||
|
||||
#endif//__ADAPTER_WIRELESS_ENC_H__
|
||||
Reference in New Issue
Block a user