afe_audio_processor.cc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "afe_audio_processor.h"
  2. #include <esp_log.h>
  3. #define PROCESSOR_RUNNING 0x01
  4. #define TAG "AfeAudioProcessor"
  5. AfeAudioProcessor::AfeAudioProcessor()
  6. : afe_data_(nullptr) {
  7. event_group_ = xEventGroupCreate();
  8. }
  9. void AfeAudioProcessor::Initialize(AudioCodec* codec, int frame_duration_ms) {
  10. codec_ = codec;
  11. frame_samples_ = frame_duration_ms * 16000 / 1000;
  12. // Pre-allocate output buffer capacity
  13. output_buffer_.reserve(frame_samples_);
  14. int ref_num = codec_->input_reference() ? 1 : 0;
  15. std::string input_format;
  16. for (int i = 0; i < codec_->input_channels() - ref_num; i++) {
  17. input_format.push_back('M');
  18. }
  19. for (int i = 0; i < ref_num; i++) {
  20. input_format.push_back('R');
  21. }
  22. srmodel_list_t *models = esp_srmodel_init("model");
  23. char* ns_model_name = esp_srmodel_filter(models, ESP_NSNET_PREFIX, NULL);
  24. char* vad_model_name = esp_srmodel_filter(models, ESP_VADN_PREFIX, NULL);
  25. afe_config_t* afe_config = afe_config_init(input_format.c_str(), NULL, AFE_TYPE_VC, AFE_MODE_HIGH_PERF);
  26. afe_config->aec_mode = AEC_MODE_VOIP_HIGH_PERF;
  27. afe_config->vad_mode = VAD_MODE_0;
  28. afe_config->vad_min_noise_ms = 100;
  29. if (vad_model_name != nullptr) {
  30. afe_config->vad_model_name = vad_model_name;
  31. }
  32. if (ns_model_name != nullptr) {
  33. afe_config->ns_init = true;
  34. afe_config->ns_model_name = ns_model_name;
  35. afe_config->afe_ns_mode = AFE_NS_MODE_NET;
  36. } else {
  37. afe_config->ns_init = false;
  38. }
  39. afe_config->afe_perferred_core = 1;
  40. afe_config->afe_perferred_priority = 1;
  41. afe_config->agc_init = false;
  42. afe_config->memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM;
  43. #ifdef CONFIG_USE_DEVICE_AEC
  44. //改成初始不开启打断
  45. afe_config->aec_init = true;
  46. afe_config->vad_init = false;
  47. // afe_config->aec_init = false;
  48. // afe_config->vad_init = true;
  49. #else
  50. afe_config->aec_init = false;
  51. afe_config->vad_init = true;
  52. #endif
  53. afe_iface_ = esp_afe_handle_from_config(afe_config);
  54. afe_data_ = afe_iface_->create_from_config(afe_config);
  55. xTaskCreate([](void* arg) {
  56. auto this_ = (AfeAudioProcessor*)arg;
  57. this_->AudioProcessorTask();
  58. vTaskDelete(NULL);
  59. }, "audio_communication", 4096, this, 3, NULL);
  60. }
  61. AfeAudioProcessor::~AfeAudioProcessor() {
  62. if (afe_data_ != nullptr) {
  63. afe_iface_->destroy(afe_data_);
  64. }
  65. vEventGroupDelete(event_group_);
  66. }
  67. size_t AfeAudioProcessor::GetFeedSize() {
  68. if (afe_data_ == nullptr) {
  69. return 0;
  70. }
  71. return afe_iface_->get_feed_chunksize(afe_data_) * codec_->input_channels();
  72. }
  73. void AfeAudioProcessor::Feed(std::vector<int16_t>&& data) {
  74. if (afe_data_ == nullptr) {
  75. return;
  76. }
  77. afe_iface_->feed(afe_data_, data.data());
  78. }
  79. void AfeAudioProcessor::Start() {
  80. xEventGroupSetBits(event_group_, PROCESSOR_RUNNING);
  81. }
  82. void AfeAudioProcessor::Stop() {
  83. xEventGroupClearBits(event_group_, PROCESSOR_RUNNING);
  84. if (afe_data_ != nullptr) {
  85. afe_iface_->reset_buffer(afe_data_);
  86. }
  87. }
  88. bool AfeAudioProcessor::IsRunning() {
  89. return xEventGroupGetBits(event_group_) & PROCESSOR_RUNNING;
  90. }
  91. void AfeAudioProcessor::OnOutput(std::function<void(std::vector<int16_t>&& data)> callback) {
  92. output_callback_ = callback;
  93. }
  94. void AfeAudioProcessor::OnVadStateChange(std::function<void(bool speaking)> callback) {
  95. vad_state_change_callback_ = callback;
  96. }
  97. void AfeAudioProcessor::AudioProcessorTask() {
  98. auto fetch_size = afe_iface_->get_fetch_chunksize(afe_data_);
  99. auto feed_size = afe_iface_->get_feed_chunksize(afe_data_);
  100. ESP_LOGI(TAG, "Audio communication task started, feed size: %d fetch size: %d",
  101. feed_size, fetch_size);
  102. while (true) {
  103. xEventGroupWaitBits(event_group_, PROCESSOR_RUNNING, pdFALSE, pdTRUE, portMAX_DELAY);
  104. auto res = afe_iface_->fetch_with_delay(afe_data_, portMAX_DELAY);
  105. if ((xEventGroupGetBits(event_group_) & PROCESSOR_RUNNING) == 0) {
  106. continue;
  107. }
  108. if (res == nullptr || res->ret_value == ESP_FAIL) {
  109. if (res != nullptr) {
  110. ESP_LOGI(TAG, "Error code: %d", res->ret_value);
  111. }
  112. continue;
  113. }
  114. // VAD state change
  115. if (vad_state_change_callback_) {
  116. if (res->vad_state == VAD_SPEECH && !is_speaking_) {
  117. is_speaking_ = true;
  118. vad_state_change_callback_(true);
  119. } else if (res->vad_state == VAD_SILENCE && is_speaking_) {
  120. is_speaking_ = false;
  121. vad_state_change_callback_(false);
  122. }
  123. }
  124. if (output_callback_) {
  125. size_t samples = res->data_size / sizeof(int16_t);
  126. // Add data to buffer
  127. output_buffer_.insert(output_buffer_.end(), res->data, res->data + samples);
  128. // Output complete frames when buffer has enough data
  129. while (output_buffer_.size() >= frame_samples_) {
  130. if (output_buffer_.size() == frame_samples_) {
  131. // If buffer size equals frame size, move the entire buffer
  132. output_callback_(std::move(output_buffer_));
  133. output_buffer_.clear();
  134. output_buffer_.reserve(frame_samples_);
  135. } else {
  136. // If buffer size exceeds frame size, copy one frame and remove it
  137. output_callback_(std::vector<int16_t>(output_buffer_.begin(), output_buffer_.begin() + frame_samples_));
  138. output_buffer_.erase(output_buffer_.begin(), output_buffer_.begin() + frame_samples_);
  139. }
  140. }
  141. }
  142. }
  143. }
  144. void AfeAudioProcessor::EnableDeviceAec(bool enable) {
  145. if (enable) {
  146. if (afe_data_==NULL)
  147. {
  148. ESP_LOGI(TAG, "afe_data_ is NULL");
  149. return;
  150. }
  151. #if CONFIG_USE_DEVICE_AEC
  152. afe_iface_->disable_vad(afe_data_);
  153. afe_iface_->enable_aec(afe_data_);
  154. #else
  155. ESP_LOGE(TAG, "Device AEC is not supported");
  156. #endif
  157. } else {
  158. if (afe_data_==NULL)
  159. {
  160. ESP_LOGI(TAG, "afe_data_ is NULL");
  161. return;
  162. }
  163. afe_iface_->disable_aec(afe_data_);
  164. afe_iface_->enable_vad(afe_data_);
  165. }
  166. }