fixbug: audio input stutters

This commit is contained in:
Terrence
2025-01-11 01:52:33 +08:00
parent 6bb9ee3441
commit b3e39b6a22
9 changed files with 49 additions and 35 deletions

View File

@@ -96,8 +96,8 @@ void BoxAudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_
i2s_chan_config_t chan_cfg = { i2s_chan_config_t chan_cfg = {
.id = I2S_NUM_0, .id = I2S_NUM_0,
.role = I2S_ROLE_MASTER, .role = I2S_ROLE_MASTER,
.dma_desc_num = 2, .dma_desc_num = 6,
.dma_frame_num = 240 * 3, .dma_frame_num = 240,
.auto_clear_after_cb = true, .auto_clear_after_cb = true,
.auto_clear_before_cb = false, .auto_clear_before_cb = false,
.intr_priority = 0, .intr_priority = 0,

View File

@@ -99,8 +99,8 @@ void CoreS3AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gp
i2s_chan_config_t chan_cfg = { i2s_chan_config_t chan_cfg = {
.id = I2S_NUM_0, .id = I2S_NUM_0,
.role = I2S_ROLE_MASTER, .role = I2S_ROLE_MASTER,
.dma_desc_num = 2, .dma_desc_num = 6,
.dma_frame_num = 240 * 3, .dma_frame_num = 240,
.auto_clear_after_cb = true, .auto_clear_after_cb = true,
.auto_clear_before_cb = false, .auto_clear_before_cb = false,
.intr_priority = 0, .intr_priority = 0,

View File

@@ -79,8 +79,8 @@ void Es8311AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gp
i2s_chan_config_t chan_cfg = { i2s_chan_config_t chan_cfg = {
.id = I2S_NUM_0, .id = I2S_NUM_0,
.role = I2S_ROLE_MASTER, .role = I2S_ROLE_MASTER,
.dma_desc_num = 2, .dma_desc_num = 6,
.dma_frame_num = 240 * 3, .dma_frame_num = 240,
.auto_clear_after_cb = true, .auto_clear_after_cb = true,
.auto_clear_before_cb = false, .auto_clear_before_cb = false,
.intr_priority = 0, .intr_priority = 0,

View File

@@ -15,7 +15,7 @@ NoAudioCodec::~NoAudioCodec() {
} }
NoAudioCodec::NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din) { NoAudioCodecDuplex::NoAudioCodecDuplex(int input_sample_rate, int output_sample_rate, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din) {
duplex_ = true; duplex_ = true;
input_sample_rate_ = input_sample_rate; input_sample_rate_ = input_sample_rate;
output_sample_rate_ = output_sample_rate; output_sample_rate_ = output_sample_rate;
@@ -23,8 +23,8 @@ NoAudioCodec::NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_n
i2s_chan_config_t chan_cfg = { i2s_chan_config_t chan_cfg = {
.id = I2S_NUM_0, .id = I2S_NUM_0,
.role = I2S_ROLE_MASTER, .role = I2S_ROLE_MASTER,
.dma_desc_num = 2, .dma_desc_num = 6,
.dma_frame_num = 240 * 3, .dma_frame_num = 240,
.auto_clear_after_cb = false, .auto_clear_after_cb = false,
.auto_clear_before_cb = false, .auto_clear_before_cb = false,
.intr_priority = 0, .intr_priority = 0,
@@ -68,7 +68,7 @@ NoAudioCodec::NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_n
ESP_LOGI(TAG, "Duplex channels created"); ESP_LOGI(TAG, "Duplex channels created");
} }
NoAudioCodec::NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_ws, gpio_num_t mic_din) { NoAudioCodecSimplex::NoAudioCodecSimplex(int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_ws, gpio_num_t mic_din) {
duplex_ = false; duplex_ = false;
input_sample_rate_ = input_sample_rate; input_sample_rate_ = input_sample_rate;
output_sample_rate_ = output_sample_rate; output_sample_rate_ = output_sample_rate;
@@ -77,8 +77,8 @@ NoAudioCodec::NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_n
i2s_chan_config_t chan_cfg = { i2s_chan_config_t chan_cfg = {
.id = (i2s_port_t)0, .id = (i2s_port_t)0,
.role = I2S_ROLE_MASTER, .role = I2S_ROLE_MASTER,
.dma_desc_num = 2, .dma_desc_num = 6,
.dma_frame_num = 240 * 3, .dma_frame_num = 240,
.auto_clear_after_cb = true, .auto_clear_after_cb = true,
.auto_clear_before_cb = false, .auto_clear_before_cb = false,
.intr_priority = 0, .intr_priority = 0,
@@ -131,15 +131,15 @@ NoAudioCodec::NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_n
ESP_LOGI(TAG, "Simplex channels created"); ESP_LOGI(TAG, "Simplex channels created");
} }
NoAudioCodec::NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_din) { NoAudioCodecSimplexPdm::NoAudioCodecSimplexPdm(int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_din) {
duplex_ = false; duplex_ = false;
input_sample_rate_ = input_sample_rate; input_sample_rate_ = input_sample_rate;
output_sample_rate_ = output_sample_rate; output_sample_rate_ = output_sample_rate;
// Create a new channel for speaker // Create a new channel for speaker
i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG((i2s_port_t)1, I2S_ROLE_MASTER); i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG((i2s_port_t)1, I2S_ROLE_MASTER);
tx_chan_cfg.dma_desc_num = 2; tx_chan_cfg.dma_desc_num = 6;
tx_chan_cfg.dma_frame_num = 240 * 3; tx_chan_cfg.dma_frame_num = 240;
tx_chan_cfg.auto_clear_after_cb = true; tx_chan_cfg.auto_clear_after_cb = true;
tx_chan_cfg.auto_clear_before_cb = false; tx_chan_cfg.auto_clear_before_cb = false;
tx_chan_cfg.intr_priority = 0; tx_chan_cfg.intr_priority = 0;

View File

@@ -5,19 +5,29 @@
#include <driver/gpio.h> #include <driver/gpio.h>
#include <driver/i2s_pdm.h> #include <driver/i2s_pdm.h>
class NoAudioCodec : public AudioCodec { class NoAudioCodec : public AudioCodec {
private: private:
virtual int Write(const int16_t* data, int samples) override; virtual int Write(const int16_t* data, int samples) override;
virtual int Read(int16_t* dest, int samples) override; virtual int Read(int16_t* dest, int samples) override;
public: public:
// Duplex
NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
// Simplex
NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_ws, gpio_num_t mic_din);
// Simplex_PDM
NoAudioCodec(int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_din);
virtual ~NoAudioCodec(); virtual ~NoAudioCodec();
}; };
class NoAudioCodecDuplex : public NoAudioCodec {
public:
NoAudioCodecDuplex(int input_sample_rate, int output_sample_rate, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
};
class NoAudioCodecSimplex : public NoAudioCodec {
public:
NoAudioCodecSimplex(int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_ws, gpio_num_t mic_din);
};
class NoAudioCodecSimplexPdm : public NoAudioCodec {
public:
NoAudioCodecSimplexPdm(int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_din);
};
#endif // _NO_AUDIO_CODEC_H #endif // _NO_AUDIO_CODEC_H

View File

@@ -66,11 +66,11 @@ AudioProcessor::~AudioProcessor() {
void AudioProcessor::Input(const std::vector<int16_t>& data) { void AudioProcessor::Input(const std::vector<int16_t>& data) {
input_buffer_.insert(input_buffer_.end(), data.begin(), data.end()); input_buffer_.insert(input_buffer_.end(), data.begin(), data.end());
auto chunk_size = esp_afe_vc_v1.get_feed_chunksize(afe_communication_data_) * channels_; auto feed_size = esp_afe_vc_v1.get_feed_chunksize(afe_communication_data_) * channels_;
while (input_buffer_.size() >= chunk_size) { while (input_buffer_.size() >= feed_size) {
auto chunk = input_buffer_.data(); auto chunk = input_buffer_.data();
esp_afe_vc_v1.feed(afe_communication_data_, chunk); esp_afe_vc_v1.feed(afe_communication_data_, chunk);
input_buffer_.erase(input_buffer_.begin(), input_buffer_.begin() + chunk_size); input_buffer_.erase(input_buffer_.begin(), input_buffer_.begin() + feed_size);
} }
} }
@@ -91,8 +91,10 @@ void AudioProcessor::OnOutput(std::function<void(std::vector<int16_t>&& data)> c
} }
void AudioProcessor::AudioProcessorTask() { void AudioProcessor::AudioProcessorTask() {
int chunk_size = esp_afe_vc_v1.get_fetch_chunksize(afe_communication_data_); auto fetch_size = esp_afe_sr_v1.get_fetch_chunksize(afe_communication_data_);
ESP_LOGI(TAG, "Audio communication task started, chunk size: %d", chunk_size); auto feed_size = esp_afe_sr_v1.get_feed_chunksize(afe_communication_data_);
ESP_LOGI(TAG, "Audio communication task started, feed size: %d fetch size: %d",
feed_size, fetch_size);
while (true) { while (true) {
xEventGroupWaitBits(event_group_, PROCESSOR_RUNNING, pdFALSE, pdTRUE, portMAX_DELAY); xEventGroupWaitBits(event_group_, PROCESSOR_RUNNING, pdFALSE, pdTRUE, portMAX_DELAY);

View File

@@ -114,16 +114,18 @@ bool WakeWordDetect::IsDetectionRunning() {
void WakeWordDetect::Feed(const std::vector<int16_t>& data) { void WakeWordDetect::Feed(const std::vector<int16_t>& data) {
input_buffer_.insert(input_buffer_.end(), data.begin(), data.end()); input_buffer_.insert(input_buffer_.end(), data.begin(), data.end());
auto chunk_size = esp_afe_sr_v1.get_feed_chunksize(afe_detection_data_) * channels_; auto feed_size = esp_afe_sr_v1.get_feed_chunksize(afe_detection_data_) * channels_;
while (input_buffer_.size() >= chunk_size) { while (input_buffer_.size() >= feed_size) {
esp_afe_sr_v1.feed(afe_detection_data_, input_buffer_.data()); esp_afe_sr_v1.feed(afe_detection_data_, input_buffer_.data());
input_buffer_.erase(input_buffer_.begin(), input_buffer_.begin() + chunk_size); input_buffer_.erase(input_buffer_.begin(), input_buffer_.begin() + feed_size);
} }
} }
void WakeWordDetect::AudioDetectionTask() { void WakeWordDetect::AudioDetectionTask() {
auto chunk_size = esp_afe_sr_v1.get_fetch_chunksize(afe_detection_data_); auto fetch_size = esp_afe_sr_v1.get_fetch_chunksize(afe_detection_data_);
ESP_LOGI(TAG, "Audio detection task started, chunk size: %d", chunk_size); auto feed_size = esp_afe_sr_v1.get_feed_chunksize(afe_detection_data_);
ESP_LOGI(TAG, "Audio detection task started, feed size: %d fetch size: %d",
feed_size, fetch_size);
while (true) { while (true) {
xEventGroupWaitBits(event_group_, DETECTION_RUNNING_EVENT, pdFALSE, pdTRUE, portMAX_DELAY); xEventGroupWaitBits(event_group_, DETECTION_RUNNING_EVENT, pdFALSE, pdTRUE, portMAX_DELAY);

View File

@@ -109,10 +109,10 @@ public:
virtual AudioCodec* GetAudioCodec() override { virtual AudioCodec* GetAudioCodec() override {
#ifdef AUDIO_I2S_METHOD_SIMPLEX #ifdef AUDIO_I2S_METHOD_SIMPLEX
static NoAudioCodec audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, static NoAudioCodecSimplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK, AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK, AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN); AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK, AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK, AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN);
#else #else
static NoAudioCodec audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, static NoAudioCodecDuplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN); AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN);
#endif #endif
return &audio_codec; return &audio_codec;

View File

@@ -114,10 +114,10 @@ public:
virtual AudioCodec* GetAudioCodec() override { virtual AudioCodec* GetAudioCodec() override {
#ifdef AUDIO_I2S_METHOD_SIMPLEX #ifdef AUDIO_I2S_METHOD_SIMPLEX
static NoAudioCodec audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, static NoAudioCodecSimplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK, AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK, AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN); AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK, AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK, AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN);
#else #else
static NoAudioCodec audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, static NoAudioCodecDuplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN); AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN);
#endif #endif
return &audio_codec; return &audio_codec;