audio_service.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. #include "audio_service.h"
  2. #include <esp_log.h>
  3. #if CONFIG_USE_AUDIO_PROCESSOR
  4. #include "processors/afe_audio_processor.h"
  5. #else
  6. #include "processors/no_audio_processor.h"
  7. #endif
  8. #if CONFIG_USE_AFE_WAKE_WORD
  9. #include "wake_words/afe_wake_word.h"
  10. #elif CONFIG_USE_ESP_WAKE_WORD
  11. #include "wake_words/esp_wake_word.h"
  12. #elif CONFIG_USE_CUSTOM_WAKE_WORD
  13. #include "wake_words/custom_wake_word.h"
  14. #endif
  15. #define TAG "AudioService"
  16. AudioService::AudioService() {
  17. event_group_ = xEventGroupCreate();
  18. }
  19. AudioService::~AudioService() {
  20. if (event_group_ != nullptr) {
  21. vEventGroupDelete(event_group_);
  22. }
  23. }
  24. void AudioService::Initialize(AudioCodec* codec) {
  25. codec_ = codec;
  26. codec_->Start();
  27. /* Setup the audio codec */
  28. opus_decoder_ = std::make_unique<OpusDecoderWrapper>(codec->output_sample_rate(), 1, OPUS_FRAME_DURATION_MS);
  29. opus_encoder_ = std::make_unique<OpusEncoderWrapper>(16000, 1, OPUS_FRAME_DURATION_MS);
  30. opus_encoder_->SetComplexity(0);
  31. if (codec->input_sample_rate() != 16000) {
  32. input_resampler_.Configure(codec->input_sample_rate(), 16000);
  33. reference_resampler_.Configure(codec->input_sample_rate(), 16000);
  34. }
  35. #if CONFIG_USE_AUDIO_PROCESSOR
  36. audio_processor_ = std::make_unique<AfeAudioProcessor>();
  37. #else
  38. audio_processor_ = std::make_unique<NoAudioProcessor>();
  39. #endif
  40. #if CONFIG_USE_AFE_WAKE_WORD
  41. wake_word_ = std::make_unique<AfeWakeWord>();
  42. #elif CONFIG_USE_ESP_WAKE_WORD
  43. wake_word_ = std::make_unique<EspWakeWord>();
  44. #elif CONFIG_USE_CUSTOM_WAKE_WORD
  45. wake_word_ = std::make_unique<CustomWakeWord>();
  46. #else
  47. wake_word_ = nullptr;
  48. #endif
  49. audio_processor_->OnOutput([this](std::vector<int16_t>&& data) {
  50. PushTaskToEncodeQueue(kAudioTaskTypeEncodeToSendQueue, std::move(data));
  51. });
  52. audio_processor_->OnVadStateChange([this](bool speaking) {
  53. voice_detected_ = speaking;
  54. if (callbacks_.on_vad_change) {
  55. callbacks_.on_vad_change(speaking);
  56. }
  57. });
  58. if (wake_word_) {
  59. wake_word_->OnWakeWordDetected([this](const std::string& wake_word) {
  60. if (callbacks_.on_wake_word_detected) {
  61. callbacks_.on_wake_word_detected(wake_word);
  62. }
  63. });
  64. }
  65. esp_timer_create_args_t audio_power_timer_args = {
  66. .callback = [](void* arg) {
  67. AudioService* audio_service = (AudioService*)arg;
  68. audio_service->CheckAndUpdateAudioPowerState();
  69. },
  70. .arg = this,
  71. .dispatch_method = ESP_TIMER_TASK,
  72. .name = "audio_power_timer",
  73. .skip_unhandled_events = true,
  74. };
  75. esp_timer_create(&audio_power_timer_args, &audio_power_timer_);
  76. }
  77. void AudioService::Start() {
  78. service_stopped_ = false;
  79. xEventGroupClearBits(event_group_, AS_EVENT_AUDIO_TESTING_RUNNING | AS_EVENT_WAKE_WORD_RUNNING | AS_EVENT_AUDIO_PROCESSOR_RUNNING);
  80. esp_timer_start_periodic(audio_power_timer_, 1000000);
  81. /* Start the audio input task */
  82. #if CONFIG_USE_AUDIO_PROCESSOR
  83. xTaskCreatePinnedToCore([](void* arg) {
  84. AudioService* audio_service = (AudioService*)arg;
  85. audio_service->AudioInputTask();
  86. vTaskDelete(NULL);
  87. }, "audio_input", 2048 * 3, this, 8, &audio_input_task_handle_, 1);
  88. #else
  89. xTaskCreate([](void* arg) {
  90. AudioService* audio_service = (AudioService*)arg;
  91. audio_service->AudioInputTask();
  92. vTaskDelete(NULL);
  93. }, "audio_input", 2048 * 3, this, 8, &audio_input_task_handle_);
  94. #endif
  95. /* Start the audio output task */
  96. xTaskCreate([](void* arg) {
  97. AudioService* audio_service = (AudioService*)arg;
  98. audio_service->AudioOutputTask();
  99. vTaskDelete(NULL);
  100. }, "audio_output", 4096, this, 3, &audio_output_task_handle_);
  101. /* Start the opus codec task */
  102. xTaskCreate([](void* arg) {
  103. AudioService* audio_service = (AudioService*)arg;
  104. audio_service->OpusCodecTask();
  105. vTaskDelete(NULL);
  106. }, "opus_codec", 4096 * 7, this, 2, &opus_codec_task_handle_);
  107. }
  108. void AudioService::Stop() {
  109. esp_timer_stop(audio_power_timer_);
  110. service_stopped_ = true;
  111. xEventGroupSetBits(event_group_, AS_EVENT_AUDIO_TESTING_RUNNING |
  112. AS_EVENT_WAKE_WORD_RUNNING |
  113. AS_EVENT_AUDIO_PROCESSOR_RUNNING);
  114. std::lock_guard<std::mutex> lock(audio_queue_mutex_);
  115. audio_encode_queue_.clear();
  116. audio_decode_queue_.clear();
  117. audio_playback_queue_.clear();
  118. audio_testing_queue_.clear();
  119. audio_queue_cv_.notify_all();
  120. }
  121. bool AudioService::ReadAudioData(std::vector<int16_t>& data, int sample_rate, int samples) {
  122. if (!codec_->input_enabled()) {
  123. codec_->EnableInput(true);
  124. esp_timer_start_periodic(audio_power_timer_, AUDIO_POWER_CHECK_INTERVAL_MS * 1000);
  125. }
  126. if (codec_->input_sample_rate() != sample_rate) {
  127. data.resize(samples * codec_->input_sample_rate() / sample_rate);
  128. if (!codec_->InputData(data)) {
  129. return false;
  130. }
  131. if (codec_->input_channels() == 2) {
  132. auto mic_channel = std::vector<int16_t>(data.size() / 2);
  133. auto reference_channel = std::vector<int16_t>(data.size() / 2);
  134. for (size_t i = 0, j = 0; i < mic_channel.size(); ++i, j += 2) {
  135. mic_channel[i] = data[j];
  136. reference_channel[i] = data[j + 1];
  137. }
  138. auto resampled_mic = std::vector<int16_t>(input_resampler_.GetOutputSamples(mic_channel.size()));
  139. auto resampled_reference = std::vector<int16_t>(reference_resampler_.GetOutputSamples(reference_channel.size()));
  140. input_resampler_.Process(mic_channel.data(), mic_channel.size(), resampled_mic.data());
  141. reference_resampler_.Process(reference_channel.data(), reference_channel.size(), resampled_reference.data());
  142. data.resize(resampled_mic.size() + resampled_reference.size());
  143. for (size_t i = 0, j = 0; i < resampled_mic.size(); ++i, j += 2) {
  144. data[j] = resampled_mic[i];
  145. data[j + 1] = resampled_reference[i];
  146. }
  147. } else {
  148. auto resampled = std::vector<int16_t>(input_resampler_.GetOutputSamples(data.size()));
  149. input_resampler_.Process(data.data(), data.size(), resampled.data());
  150. data = std::move(resampled);
  151. }
  152. } else {
  153. data.resize(samples);
  154. if (!codec_->InputData(data)) {
  155. return false;
  156. }
  157. }
  158. /* Update the last input time */
  159. last_input_time_ = std::chrono::steady_clock::now();
  160. debug_statistics_.input_count++;
  161. #if CONFIG_USE_AUDIO_DEBUGGER
  162. // 音频调试:发送原始音频数据
  163. if (audio_debugger_ == nullptr) {
  164. audio_debugger_ = std::make_unique<AudioDebugger>();
  165. }
  166. audio_debugger_->Feed(data);
  167. #endif
  168. return true;
  169. }
  170. void AudioService::AudioInputTask() {
  171. while (true) {
  172. EventBits_t bits = xEventGroupWaitBits(event_group_, AS_EVENT_AUDIO_TESTING_RUNNING |
  173. AS_EVENT_WAKE_WORD_RUNNING | AS_EVENT_AUDIO_PROCESSOR_RUNNING,
  174. pdFALSE, pdFALSE, portMAX_DELAY);
  175. if (service_stopped_) {
  176. break;
  177. }
  178. if (audio_input_need_warmup_) {
  179. audio_input_need_warmup_ = false;
  180. vTaskDelay(pdMS_TO_TICKS(120));
  181. continue;
  182. }
  183. /* Used for audio testing in NetworkConfiguring mode by clicking the BOOT button */
  184. if (bits & AS_EVENT_AUDIO_TESTING_RUNNING) {
  185. if (audio_testing_queue_.size() >= AUDIO_TESTING_MAX_DURATION_MS / OPUS_FRAME_DURATION_MS) {
  186. ESP_LOGW(TAG, "Audio testing queue is full, stopping audio testing");
  187. EnableAudioTesting(false);
  188. continue;
  189. }
  190. std::vector<int16_t> data;
  191. int samples = OPUS_FRAME_DURATION_MS * 16000 / 1000;
  192. if (ReadAudioData(data, 16000, samples)) {
  193. // If input channels is 2, we need to fetch the left channel data
  194. if (codec_->input_channels() == 2) {
  195. auto mono_data = std::vector<int16_t>(data.size() / 2);
  196. for (size_t i = 0, j = 0; i < mono_data.size(); ++i, j += 2) {
  197. mono_data[i] = data[j];
  198. }
  199. data = std::move(mono_data);
  200. }
  201. PushTaskToEncodeQueue(kAudioTaskTypeEncodeToTestingQueue, std::move(data));
  202. continue;
  203. }
  204. }
  205. /* Feed the wake word */
  206. if (bits & AS_EVENT_WAKE_WORD_RUNNING) {
  207. std::vector<int16_t> data;
  208. int samples = wake_word_->GetFeedSize();
  209. if (samples > 0) {
  210. if (ReadAudioData(data, 16000, samples)) {
  211. wake_word_->Feed(data);
  212. continue;
  213. }
  214. }
  215. }
  216. /* Feed the audio processor */
  217. if (bits & AS_EVENT_AUDIO_PROCESSOR_RUNNING) {
  218. std::vector<int16_t> data;
  219. int samples = audio_processor_->GetFeedSize();
  220. if (samples > 0) {
  221. if (ReadAudioData(data, 16000, samples)) {
  222. audio_processor_->Feed(std::move(data));
  223. continue;
  224. }
  225. }
  226. }
  227. ESP_LOGE(TAG, "Should not be here, bits: %lx", bits);
  228. break;
  229. }
  230. ESP_LOGW(TAG, "Audio input task stopped");
  231. }
  232. void AudioService::AudioOutputTask() {
  233. while (true) {
  234. std::unique_lock<std::mutex> lock(audio_queue_mutex_);
  235. audio_queue_cv_.wait(lock, [this]() { return !audio_playback_queue_.empty() || service_stopped_; });
  236. if (service_stopped_) {
  237. break;
  238. }
  239. auto task = std::move(audio_playback_queue_.front());
  240. audio_playback_queue_.pop_front();
  241. audio_queue_cv_.notify_all();
  242. lock.unlock();
  243. if (!codec_->output_enabled()) {
  244. codec_->EnableOutput(true);
  245. esp_timer_start_periodic(audio_power_timer_, AUDIO_POWER_CHECK_INTERVAL_MS * 1000);
  246. }
  247. codec_->OutputData(task->pcm);
  248. /* Update the last output time */
  249. last_output_time_ = std::chrono::steady_clock::now();
  250. debug_statistics_.playback_count++;
  251. #if CONFIG_USE_SERVER_AEC
  252. /* Record the timestamp for server AEC */
  253. if (task->timestamp > 0) {
  254. lock.lock();
  255. timestamp_queue_.push_back(task->timestamp);
  256. }
  257. #endif
  258. }
  259. ESP_LOGW(TAG, "Audio output task stopped");
  260. }
  261. void AudioService::OpusCodecTask() {
  262. while (true) {
  263. std::unique_lock<std::mutex> lock(audio_queue_mutex_);
  264. audio_queue_cv_.wait(lock, [this]() {
  265. return service_stopped_ ||
  266. (!audio_encode_queue_.empty() && audio_send_queue_.size() < MAX_SEND_PACKETS_IN_QUEUE) ||
  267. (!audio_decode_queue_.empty() && audio_playback_queue_.size() < MAX_PLAYBACK_TASKS_IN_QUEUE);
  268. });
  269. if (service_stopped_) {
  270. break;
  271. }
  272. /* Decode the audio from decode queue */
  273. if (!audio_decode_queue_.empty() && audio_playback_queue_.size() < MAX_PLAYBACK_TASKS_IN_QUEUE) {
  274. auto packet = std::move(audio_decode_queue_.front());
  275. audio_decode_queue_.pop_front();
  276. audio_queue_cv_.notify_all();
  277. lock.unlock();
  278. auto task = std::make_unique<AudioTask>();
  279. task->type = kAudioTaskTypeDecodeToPlaybackQueue;
  280. task->timestamp = packet->timestamp;
  281. SetDecodeSampleRate(packet->sample_rate, packet->frame_duration);
  282. if (opus_decoder_->Decode(std::move(packet->payload), task->pcm)) {
  283. // Resample if the sample rate is different
  284. if (opus_decoder_->sample_rate() != codec_->output_sample_rate()) {
  285. int target_size = output_resampler_.GetOutputSamples(task->pcm.size());
  286. std::vector<int16_t> resampled(target_size);
  287. output_resampler_.Process(task->pcm.data(), task->pcm.size(), resampled.data());
  288. task->pcm = std::move(resampled);
  289. }
  290. lock.lock();
  291. audio_playback_queue_.push_back(std::move(task));
  292. audio_queue_cv_.notify_all();
  293. } else {
  294. ESP_LOGE(TAG, "Failed to decode audio");
  295. lock.lock();
  296. }
  297. debug_statistics_.decode_count++;
  298. }
  299. /* Encode the audio to send queue */
  300. if (!audio_encode_queue_.empty() && audio_send_queue_.size() < MAX_SEND_PACKETS_IN_QUEUE) {
  301. auto task = std::move(audio_encode_queue_.front());
  302. audio_encode_queue_.pop_front();
  303. audio_queue_cv_.notify_all();
  304. lock.unlock();
  305. auto packet = std::make_unique<AudioStreamPacket>();
  306. packet->frame_duration = OPUS_FRAME_DURATION_MS;
  307. packet->sample_rate = 16000;
  308. packet->timestamp = task->timestamp;
  309. if (!opus_encoder_->Encode(std::move(task->pcm), packet->payload)) {
  310. ESP_LOGE(TAG, "Failed to encode audio");
  311. continue;
  312. }
  313. if (task->type == kAudioTaskTypeEncodeToSendQueue) {
  314. {
  315. std::lock_guard<std::mutex> lock(audio_queue_mutex_);
  316. audio_send_queue_.push_back(std::move(packet));
  317. }
  318. if (callbacks_.on_send_queue_available) {
  319. callbacks_.on_send_queue_available();
  320. }
  321. } else if (task->type == kAudioTaskTypeEncodeToTestingQueue) {
  322. std::lock_guard<std::mutex> lock(audio_queue_mutex_);
  323. audio_testing_queue_.push_back(std::move(packet));
  324. }
  325. debug_statistics_.encode_count++;
  326. lock.lock();
  327. }
  328. }
  329. ESP_LOGW(TAG, "Opus codec task stopped");
  330. }
  331. void AudioService::SetDecodeSampleRate(int sample_rate, int frame_duration) {
  332. if (opus_decoder_->sample_rate() == sample_rate && opus_decoder_->duration_ms() == frame_duration) {
  333. return;
  334. }
  335. opus_decoder_.reset();
  336. opus_decoder_ = std::make_unique<OpusDecoderWrapper>(sample_rate, 1, frame_duration);
  337. auto codec = Board::GetInstance().GetAudioCodec();
  338. if (opus_decoder_->sample_rate() != codec->output_sample_rate()) {
  339. ESP_LOGI(TAG, "Resampling audio from %d to %d", opus_decoder_->sample_rate(), codec->output_sample_rate());
  340. output_resampler_.Configure(opus_decoder_->sample_rate(), codec->output_sample_rate());
  341. }
  342. }
  343. void AudioService::PushTaskToEncodeQueue(AudioTaskType type, std::vector<int16_t>&& pcm) {
  344. auto task = std::make_unique<AudioTask>();
  345. task->type = type;
  346. task->pcm = std::move(pcm);
  347. /* Push the task to the encode queue */
  348. std::unique_lock<std::mutex> lock(audio_queue_mutex_);
  349. /* If the task is to send queue, we need to set the timestamp */
  350. if (type == kAudioTaskTypeEncodeToSendQueue && !timestamp_queue_.empty()) {
  351. if (timestamp_queue_.size() <= MAX_TIMESTAMPS_IN_QUEUE) {
  352. task->timestamp = timestamp_queue_.front();
  353. } else {
  354. ESP_LOGW(TAG, "Timestamp queue (%u) is full, dropping timestamp", timestamp_queue_.size());
  355. }
  356. timestamp_queue_.pop_front();
  357. }
  358. audio_queue_cv_.wait(lock, [this]() { return audio_encode_queue_.size() < MAX_ENCODE_TASKS_IN_QUEUE; });
  359. audio_encode_queue_.push_back(std::move(task));
  360. audio_queue_cv_.notify_all();
  361. }
  362. bool AudioService::PushPacketToDecodeQueue(std::unique_ptr<AudioStreamPacket> packet, bool wait) {
  363. std::unique_lock<std::mutex> lock(audio_queue_mutex_);
  364. if (audio_decode_queue_.size() >= MAX_DECODE_PACKETS_IN_QUEUE) {
  365. if (wait) {
  366. audio_queue_cv_.wait(lock, [this]() { return audio_decode_queue_.size() < MAX_DECODE_PACKETS_IN_QUEUE; });
  367. } else {
  368. return false;
  369. }
  370. }
  371. audio_decode_queue_.push_back(std::move(packet));
  372. audio_queue_cv_.notify_all();
  373. return true;
  374. }
  375. std::unique_ptr<AudioStreamPacket> AudioService::PopPacketFromSendQueue() {
  376. std::lock_guard<std::mutex> lock(audio_queue_mutex_);
  377. if (audio_send_queue_.empty()) {
  378. return nullptr;
  379. }
  380. auto packet = std::move(audio_send_queue_.front());
  381. audio_send_queue_.pop_front();
  382. audio_queue_cv_.notify_all();
  383. return packet;
  384. }
  385. void AudioService::EncodeWakeWord() {
  386. if (wake_word_) {
  387. wake_word_->EncodeWakeWordData();
  388. }
  389. }
  390. const std::string& AudioService::GetLastWakeWord() const {
  391. return wake_word_->GetLastDetectedWakeWord();
  392. }
  393. std::unique_ptr<AudioStreamPacket> AudioService::PopWakeWordPacket() {
  394. auto packet = std::make_unique<AudioStreamPacket>();
  395. if (wake_word_->GetWakeWordOpus(packet->payload)) {
  396. return packet;
  397. }
  398. return nullptr;
  399. }
  400. void AudioService::EnableWakeWordDetection(bool enable) {
  401. if (!wake_word_) {
  402. return;
  403. }
  404. ESP_LOGD(TAG, "%s wake word detection", enable ? "Enabling" : "Disabling");
  405. if (enable) {
  406. if (!wake_word_initialized_) {
  407. if (!wake_word_->Initialize(codec_)) {
  408. ESP_LOGE(TAG, "Failed to initialize wake word");
  409. return;
  410. }
  411. wake_word_initialized_ = true;
  412. }
  413. wake_word_->Start();
  414. xEventGroupSetBits(event_group_, AS_EVENT_WAKE_WORD_RUNNING);
  415. } else {
  416. wake_word_->Stop();
  417. xEventGroupClearBits(event_group_, AS_EVENT_WAKE_WORD_RUNNING);
  418. }
  419. }
  420. void AudioService::EnableVoiceProcessing(bool enable) {
  421. ESP_LOGD(TAG, "%s voice processing", enable ? "Enabling" : "Disabling");
  422. if (enable) {
  423. if (!audio_processor_initialized_) {
  424. audio_processor_->Initialize(codec_, OPUS_FRAME_DURATION_MS);
  425. audio_processor_initialized_ = true;
  426. }
  427. /* We should make sure no audio is playing */
  428. ResetDecoder();
  429. audio_input_need_warmup_ = true;
  430. audio_processor_->Start();
  431. xEventGroupSetBits(event_group_, AS_EVENT_AUDIO_PROCESSOR_RUNNING);
  432. } else {
  433. audio_processor_->Stop();
  434. xEventGroupClearBits(event_group_, AS_EVENT_AUDIO_PROCESSOR_RUNNING);
  435. }
  436. }
  437. void AudioService::EnableAudioTesting(bool enable) {
  438. ESP_LOGI(TAG, "%s audio testing", enable ? "Enabling" : "Disabling");
  439. if (enable) {
  440. xEventGroupSetBits(event_group_, AS_EVENT_AUDIO_TESTING_RUNNING);
  441. } else {
  442. xEventGroupClearBits(event_group_, AS_EVENT_AUDIO_TESTING_RUNNING);
  443. /* Copy audio_testing_queue_ to audio_decode_queue_ */
  444. std::lock_guard<std::mutex> lock(audio_queue_mutex_);
  445. audio_decode_queue_ = std::move(audio_testing_queue_);
  446. audio_queue_cv_.notify_all();
  447. }
  448. }
  449. void AudioService::EnableDeviceAec(bool enable) {
  450. ESP_LOGI(TAG, "%s device AEC", enable ? "Enabling" : "Disabling");
  451. audio_processor_->EnableDeviceAec(enable);
  452. }
  453. void AudioService::SetCallbacks(AudioServiceCallbacks& callbacks) {
  454. callbacks_ = callbacks;
  455. }
  456. void AudioService::PlaySound(const std::string_view& sound) {
  457. const char* data = sound.data();
  458. size_t size = sound.size();
  459. for (const char* p = data; p < data + size; ) {
  460. auto p3 = (BinaryProtocol3*)p;
  461. p += sizeof(BinaryProtocol3);
  462. auto payload_size = ntohs(p3->payload_size);
  463. auto packet = std::make_unique<AudioStreamPacket>();
  464. packet->sample_rate = 16000;
  465. packet->frame_duration = 60;
  466. packet->payload.resize(payload_size);
  467. memcpy(packet->payload.data(), p3->payload, payload_size);
  468. p += payload_size;
  469. PushPacketToDecodeQueue(std::move(packet), true);
  470. }
  471. }
  472. bool AudioService::IsIdle() {
  473. std::lock_guard<std::mutex> lock(audio_queue_mutex_);
  474. return audio_encode_queue_.empty() && audio_decode_queue_.empty() && audio_playback_queue_.empty() && audio_testing_queue_.empty();
  475. }
  476. void AudioService::ResetDecoder() {
  477. std::lock_guard<std::mutex> lock(audio_queue_mutex_);
  478. opus_decoder_->ResetState();
  479. timestamp_queue_.clear();
  480. audio_decode_queue_.clear();
  481. audio_playback_queue_.clear();
  482. audio_testing_queue_.clear();
  483. audio_queue_cv_.notify_all();
  484. }
  485. void AudioService::CheckAndUpdateAudioPowerState() {
  486. auto now = std::chrono::steady_clock::now();
  487. auto input_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_input_time_).count();
  488. auto output_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_output_time_).count();
  489. if (input_elapsed > AUDIO_POWER_TIMEOUT_MS && codec_->input_enabled()) {
  490. codec_->EnableInput(false);
  491. }
  492. if (output_elapsed > AUDIO_POWER_TIMEOUT_MS && codec_->output_enabled()) {
  493. codec_->EnableOutput(false);
  494. }
  495. if (!codec_->input_enabled() && !codec_->output_enabled()) {
  496. esp_timer_stop(audio_power_timer_);
  497. }
  498. }