forked from xiaozhi/xiaozhi-esp32
fix i2s race condition error
This commit is contained in:
@@ -184,6 +184,7 @@ void BoxAudioCodec::SetOutputVolume(int volume) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BoxAudioCodec::EnableInput(bool enable) {
|
void BoxAudioCodec::EnableInput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == input_enabled_) {
|
if (enable == input_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -207,6 +208,7 @@ void BoxAudioCodec::EnableInput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BoxAudioCodec::EnableOutput(bool enable) {
|
void BoxAudioCodec::EnableOutput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == output_enabled_) {
|
if (enable == output_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -228,6 +230,7 @@ void BoxAudioCodec::EnableOutput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int BoxAudioCodec::Read(int16_t* dest, int samples) {
|
int BoxAudioCodec::Read(int16_t* dest, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (input_enabled_) {
|
if (input_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(input_dev_, (void*)dest, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(input_dev_, (void*)dest, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
@@ -235,6 +238,7 @@ int BoxAudioCodec::Read(int16_t* dest, int samples) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int BoxAudioCodec::Write(const int16_t* data, int samples) {
|
int BoxAudioCodec::Write(const int16_t* data, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (output_enabled_) {
|
if (output_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(output_dev_, (void*)data, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(output_dev_, (void*)data, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include <esp_codec_dev.h>
|
#include <esp_codec_dev.h>
|
||||||
#include <esp_codec_dev_defaults.h>
|
#include <esp_codec_dev_defaults.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
class BoxAudioCodec : public AudioCodec {
|
class BoxAudioCodec : public AudioCodec {
|
||||||
private:
|
private:
|
||||||
@@ -17,6 +19,7 @@ private:
|
|||||||
|
|
||||||
esp_codec_dev_handle_t output_dev_ = nullptr;
|
esp_codec_dev_handle_t output_dev_ = nullptr;
|
||||||
esp_codec_dev_handle_t input_dev_ = nullptr;
|
esp_codec_dev_handle_t input_dev_ = nullptr;
|
||||||
|
std::mutex data_if_mutex_;
|
||||||
|
|
||||||
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
||||||
|
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ void Es8311AudioCodec::SetOutputVolume(int volume) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Es8311AudioCodec::EnableInput(bool enable) {
|
void Es8311AudioCodec::EnableInput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == input_enabled_) {
|
if (enable == input_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -163,6 +164,7 @@ void Es8311AudioCodec::EnableInput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Es8311AudioCodec::EnableOutput(bool enable) {
|
void Es8311AudioCodec::EnableOutput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == output_enabled_) {
|
if (enable == output_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -171,6 +173,7 @@ void Es8311AudioCodec::EnableOutput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Es8311AudioCodec::Read(int16_t* dest, int samples) {
|
int Es8311AudioCodec::Read(int16_t* dest, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (input_enabled_) {
|
if (input_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(dev_, (void*)dest, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(dev_, (void*)dest, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
@@ -178,6 +181,7 @@ int Es8311AudioCodec::Read(int16_t* dest, int samples) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Es8311AudioCodec::Write(const int16_t* data, int samples) {
|
int Es8311AudioCodec::Write(const int16_t* data, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (output_enabled_) {
|
if (output_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(dev_, (void*)data, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(dev_, (void*)data, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <esp_codec_dev.h>
|
#include <esp_codec_dev.h>
|
||||||
#include <esp_codec_dev_defaults.h>
|
#include <esp_codec_dev_defaults.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
class Es8311AudioCodec : public AudioCodec {
|
class Es8311AudioCodec : public AudioCodec {
|
||||||
private:
|
private:
|
||||||
@@ -18,6 +20,7 @@ private:
|
|||||||
esp_codec_dev_handle_t dev_ = nullptr;
|
esp_codec_dev_handle_t dev_ = nullptr;
|
||||||
gpio_num_t pa_pin_ = GPIO_NUM_NC;
|
gpio_num_t pa_pin_ = GPIO_NUM_NC;
|
||||||
bool pa_inverted_ = false;
|
bool pa_inverted_ = false;
|
||||||
|
std::mutex data_if_mutex_;
|
||||||
|
|
||||||
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
||||||
void UpdateDeviceState();
|
void UpdateDeviceState();
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ void Es8374AudioCodec::SetOutputVolume(int volume) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Es8374AudioCodec::EnableInput(bool enable) {
|
void Es8374AudioCodec::EnableInput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == input_enabled_) {
|
if (enable == input_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -153,6 +154,7 @@ void Es8374AudioCodec::EnableInput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Es8374AudioCodec::EnableOutput(bool enable) {
|
void Es8374AudioCodec::EnableOutput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == output_enabled_) {
|
if (enable == output_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -180,6 +182,7 @@ void Es8374AudioCodec::EnableOutput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Es8374AudioCodec::Read(int16_t* dest, int samples) {
|
int Es8374AudioCodec::Read(int16_t* dest, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (input_enabled_) {
|
if (input_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(input_dev_, (void*)dest, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(input_dev_, (void*)dest, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
@@ -187,6 +190,7 @@ int Es8374AudioCodec::Read(int16_t* dest, int samples) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Es8374AudioCodec::Write(const int16_t* data, int samples) {
|
int Es8374AudioCodec::Write(const int16_t* data, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (output_enabled_) {
|
if (output_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(output_dev_, (void*)data, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(output_dev_, (void*)data, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <esp_codec_dev.h>
|
#include <esp_codec_dev.h>
|
||||||
#include <esp_codec_dev_defaults.h>
|
#include <esp_codec_dev_defaults.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
class Es8374AudioCodec : public AudioCodec {
|
class Es8374AudioCodec : public AudioCodec {
|
||||||
private:
|
private:
|
||||||
@@ -18,6 +20,7 @@ private:
|
|||||||
esp_codec_dev_handle_t output_dev_ = nullptr;
|
esp_codec_dev_handle_t output_dev_ = nullptr;
|
||||||
esp_codec_dev_handle_t input_dev_ = nullptr;
|
esp_codec_dev_handle_t input_dev_ = nullptr;
|
||||||
gpio_num_t pa_pin_ = GPIO_NUM_NC;
|
gpio_num_t pa_pin_ = GPIO_NUM_NC;
|
||||||
|
std::mutex data_if_mutex_;
|
||||||
|
|
||||||
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ void Es8388AudioCodec::SetOutputVolume(int volume) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Es8388AudioCodec::EnableInput(bool enable) {
|
void Es8388AudioCodec::EnableInput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == input_enabled_) {
|
if (enable == input_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -157,6 +158,7 @@ void Es8388AudioCodec::EnableInput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Es8388AudioCodec::EnableOutput(bool enable) {
|
void Es8388AudioCodec::EnableOutput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == output_enabled_) {
|
if (enable == output_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -191,6 +193,7 @@ void Es8388AudioCodec::EnableOutput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Es8388AudioCodec::Read(int16_t* dest, int samples) {
|
int Es8388AudioCodec::Read(int16_t* dest, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (input_enabled_) {
|
if (input_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(input_dev_, (void*)dest, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(input_dev_, (void*)dest, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
@@ -198,6 +201,7 @@ int Es8388AudioCodec::Read(int16_t* dest, int samples) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Es8388AudioCodec::Write(const int16_t* data, int samples) {
|
int Es8388AudioCodec::Write(const int16_t* data, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (output_enabled_) {
|
if (output_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(output_dev_, (void*)data, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(output_dev_, (void*)data, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include <driver/i2c_master.h>
|
#include <driver/i2c_master.h>
|
||||||
#include <esp_codec_dev.h>
|
#include <esp_codec_dev.h>
|
||||||
#include <esp_codec_dev_defaults.h>
|
#include <esp_codec_dev_defaults.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
class Es8388AudioCodec : public AudioCodec {
|
class Es8388AudioCodec : public AudioCodec {
|
||||||
private:
|
private:
|
||||||
@@ -17,6 +19,7 @@ private:
|
|||||||
esp_codec_dev_handle_t output_dev_ = nullptr;
|
esp_codec_dev_handle_t output_dev_ = nullptr;
|
||||||
esp_codec_dev_handle_t input_dev_ = nullptr;
|
esp_codec_dev_handle_t input_dev_ = nullptr;
|
||||||
gpio_num_t pa_pin_ = GPIO_NUM_NC;
|
gpio_num_t pa_pin_ = GPIO_NUM_NC;
|
||||||
|
std::mutex data_if_mutex_;
|
||||||
|
|
||||||
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ void Es8389AudioCodec::SetOutputVolume(int volume) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Es8389AudioCodec::EnableInput(bool enable) {
|
void Es8389AudioCodec::EnableInput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == input_enabled_) {
|
if (enable == input_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -160,6 +161,7 @@ void Es8389AudioCodec::EnableInput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Es8389AudioCodec::EnableOutput(bool enable) {
|
void Es8389AudioCodec::EnableOutput(bool enable) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (enable == output_enabled_) {
|
if (enable == output_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -187,6 +189,7 @@ void Es8389AudioCodec::EnableOutput(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Es8389AudioCodec::Read(int16_t* dest, int samples) {
|
int Es8389AudioCodec::Read(int16_t* dest, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (input_enabled_) {
|
if (input_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(input_dev_, (void*)dest, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(input_dev_, (void*)dest, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
@@ -194,6 +197,7 @@ int Es8389AudioCodec::Read(int16_t* dest, int samples) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Es8389AudioCodec::Write(const int16_t* data, int samples) {
|
int Es8389AudioCodec::Write(const int16_t* data, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
if (output_enabled_) {
|
if (output_enabled_) {
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(output_dev_, (void*)data, samples * sizeof(int16_t)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(output_dev_, (void*)data, samples * sizeof(int16_t)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <esp_codec_dev.h>
|
#include <esp_codec_dev.h>
|
||||||
#include <esp_codec_dev_defaults.h>
|
#include <esp_codec_dev_defaults.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class Es8389AudioCodec : public AudioCodec {
|
class Es8389AudioCodec : public AudioCodec {
|
||||||
private:
|
private:
|
||||||
@@ -18,6 +19,7 @@ private:
|
|||||||
esp_codec_dev_handle_t output_dev_ = nullptr;
|
esp_codec_dev_handle_t output_dev_ = nullptr;
|
||||||
esp_codec_dev_handle_t input_dev_ = nullptr;
|
esp_codec_dev_handle_t input_dev_ = nullptr;
|
||||||
gpio_num_t pa_pin_ = GPIO_NUM_NC;
|
gpio_num_t pa_pin_ = GPIO_NUM_NC;
|
||||||
|
std::mutex data_if_mutex_;
|
||||||
|
|
||||||
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
||||||
|
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ NoAudioCodecSimplexPdm::NoAudioCodecSimplexPdm(int input_sample_rate, int output
|
|||||||
}
|
}
|
||||||
|
|
||||||
int NoAudioCodec::Write(const int16_t* data, int samples) {
|
int NoAudioCodec::Write(const int16_t* data, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
std::vector<int32_t> buffer(samples);
|
std::vector<int32_t> buffer(samples);
|
||||||
|
|
||||||
// output_volume_: 0-100
|
// output_volume_: 0-100
|
||||||
@@ -301,6 +302,7 @@ int NoAudioCodec::Write(const int16_t* data, int samples) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int NoAudioCodec::Read(int16_t* dest, int samples) {
|
int NoAudioCodec::Read(int16_t* dest, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
|
|
||||||
std::vector<int32_t> bit32_buffer(samples);
|
std::vector<int32_t> bit32_buffer(samples);
|
||||||
@@ -318,6 +320,7 @@ int NoAudioCodec::Read(int16_t* dest, int samples) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int NoAudioCodecSimplexPdm::Read(int16_t* dest, int samples) {
|
int NoAudioCodecSimplexPdm::Read(int16_t* dest, int samples) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_if_mutex_);
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
|
|
||||||
// PDM 解调后的数据位宽为 16 位,直接读取到目标缓冲区
|
// PDM 解调后的数据位宽为 16 位,直接读取到目标缓冲区
|
||||||
|
|||||||
@@ -5,9 +5,12 @@
|
|||||||
|
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <driver/i2s_pdm.h>
|
#include <driver/i2s_pdm.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class NoAudioCodec : public AudioCodec {
|
class NoAudioCodec : public AudioCodec {
|
||||||
private:
|
protected:
|
||||||
|
std::mutex data_if_mutex_;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user