doubao_chat/apps/common/usb/device/uac_stream.c

449 lines
11 KiB
C

#include "app_config.h"
#include "system/includes.h"
#include "usb/usb_config.h"
#include "usb/device/usb_stack.h"
#include "event/device_event.h"
#if TCFG_USB_SLAVE_AUDIO_ENABLE
#include "usb/device/uac_audio.h"
#include "uac_stream.h"
#ifndef APP_AUDIO_STATE_MUSIC
#define APP_AUDIO_STATE_MUSIC 0
#endif
#define LOG_TAG_CONST USB
#define LOG_TAG "[UAC]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#define UAC_DEBUG_ECHO_MODE 0
static u8 speaker_stream_is_open[USB_MAX_HW_NUM];
static spinlock_t uac_lock;
struct uac_speaker_handle {
cbuffer_t cbuf;
volatile u8 need_resume;
u8 channel;
u8 alive;
void *buffer;
};
static void (*uac_rx_handler[USB_MAX_HW_NUM])(void *, void *, int);
static void *uac_rx_priv[USB_MAX_HW_NUM];
#ifndef UAC_BUFFER_SIZE
#if (SOUNDCARD_ENABLE)
#define UAC_BUFFER_SIZE (4 * 1024)
#else
#define UAC_BUFFER_SIZE (2 * 1024)
#endif
#endif
#define UAC_BUFFER_MAX (UAC_BUFFER_SIZE * 50 / 100)
static struct uac_speaker_handle *uac_speaker[USB_MAX_HW_NUM];
#if USB_MALLOC_ENABLE
#else
static struct uac_speaker_handle uac_speaker_handle[USB_MAX_HW_NUM] SEC(.uac_var);
static u8 uac_rx_buffer[USB_MAX_HW_NUM][UAC_BUFFER_SIZE] ALIGNED(4) SEC(.uac_rx);
#endif
#if 0
u32 uac_speaker_stream_length(void)
{
return UAC_BUFFER_SIZE;
}
u32 uac_speaker_stream_size(void)
{
u32 size = 0;
spin_lock(&uac_lock);
if (speaker_stream_is_open && uac_speaker) {
size = cbuf_get_data_size(&uac_speaker->cbuf);
}
spin_unlock(&uac_lock);
return size;
}
u32 uac_speaker_get_alive(void)
{
if (uac_speaker) {
return uac_speaker->alive;
}
return 0;
}
void uac_speaker_set_alive(u8 alive)
{
spin_lock(&uac_lock);
if (uac_speaker) {
uac_speaker->alive = alive;
}
spin_unlock(&uac_lock);
}
void uac_speaker_stream_buf_clear(void)
{
spin_lock(&uac_lock);
if (speaker_stream_is_open) {
cbuf_clear(&uac_speaker->cbuf);
}
spin_unlock(&uac_lock);
}
#endif
void set_uac_speaker_rx_handler(const usb_dev usb_id, void *priv, void (*rx_handler)(void *, void *, int))
{
uac_rx_handler[usb_id] = rx_handler;
uac_rx_priv[usb_id] = priv;
}
int uac_speaker_stream_sample_rate(void)
{
return SPK_AUDIO_RATE;
}
void uac_speaker_stream_write(const usb_dev usb_id, const u8 *obuf, u32 len)
{
if (speaker_stream_is_open[usb_id]) {
//write dac
int wlen = cbuf_write(&uac_speaker[usb_id]->cbuf, (void *)obuf, len);
if (wlen != len) {
//putchar('W');
}
//if (uac_speaker[usb_id]->rx_handler) {
if (uac_rx_handler[usb_id]) {
/* if (uac_speaker[usb_id]->cbuf.data_len >= UAC_BUFFER_MAX) { */
// 马上就要满了,赶紧取走
uac_speaker[usb_id]->need_resume = 1; //2020-12-22注:无需唤醒
/* } */
if (uac_speaker[usb_id]->need_resume) {
uac_speaker[usb_id]->need_resume = 0;
uac_rx_handler[usb_id](uac_rx_priv[usb_id], (void *)obuf, len);
//uac_speaker[usb_id]->rx_handler(0, (void *)obuf, len);
}
}
uac_speaker[usb_id]->alive = 0;
}
}
#if 0
int uac_speaker_read(void *priv, void *data, u32 len)
{
int r_len;
int err = 0;
spin_lock(&uac_lock);
if (!speaker_stream_is_open[usb_id]) {
spin_unlock(&uac_lock);
return 0;
}
r_len = cbuf_get_data_size(&uac_speaker->cbuf);
if (r_len) {
r_len = r_len > len ? len : r_len;
r_len = cbuf_read(&uac_speaker->cbuf, data, r_len);
if (!r_len) {
putchar('U');
}
}
if (r_len == 0) {
uac_speaker->need_resume = 1;
}
spin_unlock(&uac_lock);
return r_len;
}
#endif
void uac_speaker_stream_open(const usb_dev usb_id, u32 samplerate, u32 ch)
{
if (speaker_stream_is_open[usb_id]) {
return;
}
log_info("%s", __func__);
if (!uac_speaker[usb_id]) {
#if USB_MALLOC_ENABLE
uac_speaker[usb_id] = zalloc(sizeof(struct uac_speaker_handle));
if (!uac_speaker[usb_id]) {
return;
}
uac_speaker[usb_id]->buffer = malloc(UAC_BUFFER_SIZE);
if (!uac_speaker[usb_id]->buffer) {
free(uac_speaker[usb_id]);
uac_speaker[usb_id] = NULL;
goto __err;
}
#else
uac_speaker[usb_id] = &uac_speaker_handle[usb_id];
memset(uac_speaker[usb_id], 0, sizeof(struct uac_speaker_handle));
uac_speaker[usb_id]->buffer = uac_rx_buffer[usb_id];
#endif
uac_speaker[usb_id]->channel = ch;
}
//uac_speaker[usb_id]->rx_handler = NULL;
cbuf_init(&uac_speaker[usb_id]->cbuf, uac_speaker[usb_id]->buffer, UAC_BUFFER_SIZE);
struct device_event event = {0};
event.event = USB_AUDIO_PLAY_OPEN;
event.value = (int)((ch << 24) | samplerate);
event.arg = (void *)(int)usb_id;
#if !UAC_DEBUG_ECHO_MODE
device_event_notify(DEVICE_EVENT_FROM_UAC, &event);
#endif
speaker_stream_is_open[usb_id] = 1;
__err:
return;
}
void uac_speaker_stream_close(const usb_dev usb_id)
{
if (speaker_stream_is_open[usb_id] == 0) {
return;
}
log_info("%s", __func__);
spin_lock(&uac_lock);
speaker_stream_is_open[usb_id] = 0;
spin_unlock(&uac_lock);
if (uac_speaker[usb_id]) {
#if USB_MALLOC_ENABLE
if (uac_speaker[usb_id]->buffer) {
free(uac_speaker[usb_id]->buffer);
}
free(uac_speaker[usb_id]);
#endif
uac_speaker[usb_id] = NULL;
}
struct device_event event = {0};
event.event = USB_AUDIO_PLAY_CLOSE;
event.arg = (void *)(int)usb_id;
device_event_notify(DEVICE_EVENT_FROM_UAC, &event);
}
int uac_get_spk_vol(void)
{
extern u8 get_max_sys_vol(void);
extern s8 app_audio_get_volume(u8 state);
int max_vol = get_max_sys_vol();
int vol = app_audio_get_volume(APP_AUDIO_STATE_MUSIC);
if (vol * 100 / max_vol < 100) {
return vol * 100 / max_vol;
} else {
return 99;
}
return 0;
}
static u8 mic_stream_is_open[USB_MAX_HW_NUM];
void uac_mute_volume(const usb_dev usb_id, u32 type, u32 l_vol, u32 r_vol)
{
struct device_event event = {0};
static u32 last_spk_l_vol = (u32) - 1, last_spk_r_vol = (u32) - 1;
static u32 last_mic_vol = (u32) - 1;
switch (type) {
case MIC_FEATURE_UNIT_ID: //MIC
if (mic_stream_is_open[usb_id] == 0) {
return;
}
if (l_vol == last_mic_vol) {
return;
}
last_mic_vol = l_vol;
event.event = USB_AUDIO_SET_MIC_VOL;
break;
case SPK_FEATURE_UNIT_ID: //SPK
if (speaker_stream_is_open[usb_id] == 0) {
return;
}
if (l_vol == last_spk_l_vol && r_vol == last_spk_r_vol) {
return;
}
last_spk_l_vol = l_vol;
last_spk_r_vol = r_vol;
event.event = USB_AUDIO_SET_PLAY_VOL;
break;
default:
break;
}
event.value = (int)(r_vol << 16 | l_vol);
event.arg = (void *)(int)usb_id;
device_event_notify(DEVICE_EVENT_FROM_UAC, &event);
}
static int (*mic_tx_handler[USB_MAX_HW_NUM])(void *, void *, int);
static void *mic_tx_priv[USB_MAX_HW_NUM];
int uac_mic_stream_read(const usb_dev usb_id, u8 *buf, u32 len)
{
if (mic_stream_is_open[usb_id] == 0) {
return 0;
}
#if 0//48K 1ksin
const s16 sin_48k[] = {
0, 2139, 4240, 6270, 8192, 9974, 11585, 12998,
14189, 15137, 15826, 16244, 16384, 16244, 15826, 15137,
14189, 12998, 11585, 9974, 8192, 6270, 4240, 2139,
0, -2139, -4240, -6270, -8192, -9974, -11585, -12998,
-14189, -15137, -15826, -16244, -16384, -16244, -15826, -15137,
-14189, -12998, -11585, -9974, -8192, -6270, -4240, -2139
};
u16 *l_ch = (u16 *)buf;
u16 *r_ch = (u16 *)buf;
r_ch++;
for (int i = 0; i < len / 2; i++) {
*l_ch = sin_48k[i];
*r_ch = sin_48k[i];
l_ch += 1;
r_ch += 1;
}
return len;
#elif UAC_DEBUG_ECHO_MODE
uac_speaker_read(NULL, buf, len);
#if MIC_CHANNEL == 2
const s16 sin_48k[] = {
0, 2139, 4240, 6270, 8192, 9974, 11585, 12998,
14189, 15137, 15826, 16244, 16384, 16244, 15826, 15137,
14189, 12998, 11585, 9974, 8192, 6270, 4240, 2139,
0, -2139, -4240, -6270, -8192, -9974, -11585, -12998,
-14189, -15137, -15826, -16244, -16384, -16244, -15826, -15137,
-14189, -12998, -11585, -9974, -8192, -6270, -4240, -2139
};
u16 *r_ch = (u16 *)buf;
r_ch++;
for (int i = 0; i < len / 4; i++) {
*r_ch = sin_48k[i];
r_ch += 2;
}
#endif
return len;
#else
if (mic_tx_handler[usb_id]) {
#if 1
return mic_tx_handler[usb_id](mic_tx_priv[usb_id], buf, len);
#else
//16bit ---> 24bit
int rlen = mic_tx_handler[usb_id](mic_tx_priv[usb_id], tmp_buf, len / 3 * 2);
rlen /= 2; //sampe point
for (int i = 0 ; i < rlen ; i++) {
buf[i * 3] = 0;
buf[i * 3 + 1] = tmp_buf[i * 2];
buf[i * 3 + 2] = tmp_buf[i * 2 + 1];
}
#endif
} else {
putchar('N');
}
return 0;
#endif
return 0;
}
void set_uac_mic_tx_handler(const usb_dev usb_id, void *priv, int (*tx_handler)(void *, void *, int))
{
mic_tx_handler[usb_id] = tx_handler;
mic_tx_priv[usb_id] = priv;
}
u32 uac_mic_stream_open(const usb_dev usb_id, u32 samplerate, u32 frame_len, u32 ch)
{
if (mic_stream_is_open[usb_id]) {
return 0;
}
log_info("%s", __func__);
struct device_event event = {0};
event.event = USB_AUDIO_MIC_OPEN;
event.value = (int)((ch << 24) | samplerate);
event.arg = (void *)(int)usb_id;
#if !UAC_DEBUG_ECHO_MODE
device_event_notify(DEVICE_EVENT_FROM_UAC, &event);
#endif
mic_stream_is_open[usb_id] = 1;
return 0;
}
void uac_mic_stream_close(const usb_dev usb_id)
{
if (mic_stream_is_open[usb_id] == 0) {
return;
}
log_info("%s", __func__);
struct device_event event = {0};
event.event = USB_AUDIO_MIC_CLOSE;
event.arg = (void *)(int)usb_id;
mic_stream_is_open[usb_id] = 0;
device_event_notify(DEVICE_EVENT_FROM_UAC, &event);
}
_WEAK_
s8 app_audio_get_volume(u8 state)
{
return 88;
}
_WEAK_
void usb_audio_demo_exit(void)
{
}
_WEAK_
int usb_audio_demo_init(void)
{
return 0;
}
_WEAK_
u8 get_max_sys_vol(void)
{
return 100;
}
_WEAK_
void *audio_local_sample_track_open(u8 channel, int sample_rate, int period)
{
return NULL;
}
_WEAK_
int audio_local_sample_track_in_period(void *c, int samples)
{
return 0;
}
_WEAK_
void audio_local_sample_track_close(void *c)
{
}
#endif