fix: speaker noise. Thanks Junhoo (@1220951120)
This commit is contained in:
+1
-1
@@ -55,7 +55,7 @@ target_include_directories(wdl_resampler PUBLIC
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Opus
|
# Opus
|
||||||
set(OPUS_FIXED_POINT ON)
|
#set(OPUS_FIXED_POINT ON)
|
||||||
add_subdirectory(lib/opus)
|
add_subdirectory(lib/opus)
|
||||||
|
|
||||||
target_compile_options(wdl_resampler PRIVATE -fsigned-char)
|
target_compile_options(wdl_resampler PRIVATE -fsigned-char)
|
||||||
|
|||||||
@@ -15,10 +15,9 @@
|
|||||||
- 开启麦克风静音为禁用静默断连
|
- 开启麦克风静音为禁用静默断连
|
||||||
|
|
||||||
# 当前问题:
|
# 当前问题:
|
||||||
当前无,待反馈
|
- 声音有点小卡顿
|
||||||
|
|
||||||
# 未来计划
|
# 未来计划
|
||||||
~~1. 耳机与扬声器支持~~ (pico 性能不够用于opus编码)
|
|
||||||
|
|
||||||
# 编译
|
# 编译
|
||||||
需要将pico sdk里面的tinyusb版本升级到最新
|
需要将pico sdk里面的tinyusb版本升级到最新
|
||||||
@@ -26,3 +25,4 @@
|
|||||||
# 致谢
|
# 致谢
|
||||||
- [rafaelvaloto/Pico_W-Dualsense](https://github.com/rafaelvaloto/Pico_W-Dualsense) - 灵感来源
|
- [rafaelvaloto/Pico_W-Dualsense](https://github.com/rafaelvaloto/Pico_W-Dualsense) - 灵感来源
|
||||||
- [egormanga/SAxense](https://github.com/egormanga/SAxense) - 震动报文
|
- [egormanga/SAxense](https://github.com/egormanga/SAxense) - 震动报文
|
||||||
|
- [https://controllers.fandom.com/wiki/Sony_DualSense](https://controllers.fandom.com/wiki/Sony_DualSense) 数据报文结构
|
||||||
|
|||||||
+21
-8
@@ -30,13 +30,12 @@ alignas(8) static uint32_t audio_core1_stack[8192];
|
|||||||
queue_t audio_fifo;
|
queue_t audio_fifo;
|
||||||
queue_t opus_fifo;
|
queue_t opus_fifo;
|
||||||
struct audio_raw_element {
|
struct audio_raw_element {
|
||||||
int16_t data[480 * 2];
|
float data[512 * 2];
|
||||||
};
|
};
|
||||||
struct opus_element {
|
struct opus_element {
|
||||||
uint8_t data[200];
|
uint8_t data[200];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void audio_loop() {
|
void audio_loop() {
|
||||||
// 1. 读取 USB 音频数据
|
// 1. 读取 USB 音频数据
|
||||||
if (!tud_audio_available()) return;
|
if (!tud_audio_available()) return;
|
||||||
@@ -48,18 +47,18 @@ void audio_loop() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int16_t audio_buf[480 * 2];
|
static float audio_buf[512 * 2];
|
||||||
static uint audio_buf_pos = 0;
|
static uint audio_buf_pos = 0;
|
||||||
// 2. 从4ch中提取ch3/ch4,转换为float输入重采样器
|
// 2. 从4ch中提取ch3/ch4,转换为float输入重采样器
|
||||||
WDL_ResampleSample *in_buf;
|
WDL_ResampleSample *in_buf;
|
||||||
int nframes = resampler.ResamplePrepare(frames, OUTPUT_CHANNELS, &in_buf);
|
int nframes = resampler.ResamplePrepare(frames, OUTPUT_CHANNELS, &in_buf);
|
||||||
|
|
||||||
for (int i = 0; i < nframes; i++) {
|
for (int i = 0; i < nframes; i++) {
|
||||||
audio_buf[audio_buf_pos++] = raw[i * INPUT_CHANNELS];
|
audio_buf[audio_buf_pos++] = raw[i * INPUT_CHANNELS] / 32768.0f;
|
||||||
audio_buf[audio_buf_pos++] = raw[i * INPUT_CHANNELS + 1];
|
audio_buf[audio_buf_pos++] = raw[i * INPUT_CHANNELS + 1] / 32768.0f;
|
||||||
if (audio_buf_pos == 480 * 2) {
|
if (audio_buf_pos == 512 * 2) {
|
||||||
audio_raw_element element{};
|
audio_raw_element element{};
|
||||||
memcpy(element.data,audio_buf,480 * 2 * 2);
|
memcpy(element.data,audio_buf,512 * 2 * 4);
|
||||||
if (queue_is_full(&audio_fifo)){
|
if (queue_is_full(&audio_fifo)){
|
||||||
queue_try_remove(&audio_fifo,NULL);
|
queue_try_remove(&audio_fifo,NULL);
|
||||||
}
|
}
|
||||||
@@ -115,6 +114,8 @@ void audio_loop() {
|
|||||||
}else {
|
}else {
|
||||||
memcpy(pkt + 79,opus_element.data,200);
|
memcpy(pkt + 79,opus_element.data,200);
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
printf("[Audio] Warning: opus_fifo is empty\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_write(pkt, sizeof(pkt));
|
bt_write(pkt, sizeof(pkt));
|
||||||
@@ -133,6 +134,7 @@ void audio_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static OpusEncoder *encoder;
|
static OpusEncoder *encoder;
|
||||||
|
static WDL_Resampler resampler_audio;
|
||||||
|
|
||||||
void core1_entry() {
|
void core1_entry() {
|
||||||
int error = 0;
|
int error = 0;
|
||||||
@@ -145,12 +147,23 @@ void core1_entry() {
|
|||||||
opus_encoder_ctl(encoder,OPUS_SET_BITRATE(200 * 8 * 100));
|
opus_encoder_ctl(encoder,OPUS_SET_BITRATE(200 * 8 * 100));
|
||||||
opus_encoder_ctl(encoder,OPUS_SET_VBR(false));
|
opus_encoder_ctl(encoder,OPUS_SET_VBR(false));
|
||||||
opus_encoder_ctl(encoder,OPUS_SET_COMPLEXITY(0));
|
opus_encoder_ctl(encoder,OPUS_SET_COMPLEXITY(0));
|
||||||
|
resampler_audio.SetMode(true,0,false);
|
||||||
|
resampler_audio.SetRates(51200,48000);
|
||||||
|
resampler_audio.SetFeedMode(true);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
audio_raw_element audio_element{};
|
audio_raw_element audio_element{};
|
||||||
queue_remove_blocking(&audio_fifo,&audio_element);
|
queue_remove_blocking(&audio_fifo,&audio_element);
|
||||||
|
// 将 512 frames 重采样成 480 frames 以解决噪音问题。感谢 @Junhoo
|
||||||
|
WDL_ResampleSample *in_buf;
|
||||||
|
int nframes = resampler_audio.ResamplePrepare(512, 2, &in_buf);
|
||||||
|
for (int i = 0; i < nframes * 2;i++) {
|
||||||
|
in_buf[i] = audio_element.data[i];
|
||||||
|
}
|
||||||
|
WDL_ResampleSample out_buf[200];
|
||||||
|
resampler_audio.ResampleOut(out_buf,nframes,480,2);
|
||||||
opus_element opus_element{};
|
opus_element opus_element{};
|
||||||
(void)opus_encode(encoder,audio_element.data,480,opus_element.data,200);
|
(void)opus_encode_float(encoder,out_buf,480,opus_element.data,200);
|
||||||
if (queue_is_full(&opus_fifo)) {
|
if (queue_is_full(&opus_fifo)) {
|
||||||
queue_try_remove(&opus_fifo,NULL);
|
queue_try_remove(&opus_fifo,NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user