mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	[i2s_speaker] A few fixes (#6872)
This commit is contained in:
		| @@ -38,15 +38,22 @@ void I2SAudioSpeaker::start() { | |||||||
|     ESP_LOGE(TAG, "Cannot start audio, speaker failed to setup"); |     ESP_LOGE(TAG, "Cannot start audio, speaker failed to setup"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |   if (this->task_created_) { | ||||||
|  |     ESP_LOGW(TAG, "Called start while task has been already created."); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|   this->state_ = speaker::STATE_STARTING; |   this->state_ = speaker::STATE_STARTING; | ||||||
| } | } | ||||||
| void I2SAudioSpeaker::start_() { | void I2SAudioSpeaker::start_() { | ||||||
|  |   if (this->task_created_) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|   if (!this->parent_->try_lock()) { |   if (!this->parent_->try_lock()) { | ||||||
|     return;  // Waiting for another i2s component to return lock |     return;  // Waiting for another i2s component to return lock | ||||||
|   } |   } | ||||||
|   this->state_ = speaker::STATE_RUNNING; |  | ||||||
|  |  | ||||||
|   xTaskCreate(I2SAudioSpeaker::player_task, "speaker_task", 8192, (void *) this, 1, &this->player_task_handle_); |   xTaskCreate(I2SAudioSpeaker::player_task, "speaker_task", 8192, (void *) this, 1, &this->player_task_handle_); | ||||||
|  |   this->task_created_ = true; | ||||||
| } | } | ||||||
|  |  | ||||||
| void I2SAudioSpeaker::player_task(void *params) { | void I2SAudioSpeaker::player_task(void *params) { | ||||||
| @@ -131,7 +138,16 @@ void I2SAudioSpeaker::player_task(void *params) { | |||||||
|                                 (10 / portTICK_PERIOD_MS)); |                                 (10 / portTICK_PERIOD_MS)); | ||||||
|       if (err != ESP_OK) { |       if (err != ESP_OK) { | ||||||
|         event = {.type = TaskEventType::WARNING, .err = err}; |         event = {.type = TaskEventType::WARNING, .err = err}; | ||||||
|         xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY); |         if (xQueueSend(this_speaker->event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) { | ||||||
|  |           ESP_LOGW(TAG, "Failed to send WARNING event"); | ||||||
|  |         } | ||||||
|  |         continue; | ||||||
|  |       } | ||||||
|  |       if (bytes_written != sizeof(sample)) { | ||||||
|  |         event = {.type = TaskEventType::WARNING, .err = ESP_FAIL}; | ||||||
|  |         if (xQueueSend(this_speaker->event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) { | ||||||
|  |           ESP_LOGW(TAG, "Failed to send WARNING event"); | ||||||
|  |         } | ||||||
|         continue; |         continue; | ||||||
|       } |       } | ||||||
|       remaining--; |       remaining--; | ||||||
| @@ -139,18 +155,25 @@ void I2SAudioSpeaker::player_task(void *params) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     event.type = TaskEventType::PLAYING; |     event.type = TaskEventType::PLAYING; | ||||||
|     xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY); |     event.err = current; | ||||||
|  |     if (xQueueSend(this_speaker->event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) { | ||||||
|  |       ESP_LOGW(TAG, "Failed to send PLAYING event"); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   event.type = TaskEventType::STOPPING; | ||||||
|  |   if (xQueueSend(this_speaker->event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) { | ||||||
|  |     ESP_LOGW(TAG, "Failed to send STOPPING event"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   i2s_zero_dma_buffer(this_speaker->parent_->get_port()); |   i2s_zero_dma_buffer(this_speaker->parent_->get_port()); | ||||||
|  |  | ||||||
|   event.type = TaskEventType::STOPPING; |  | ||||||
|   xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY); |  | ||||||
|  |  | ||||||
|   i2s_driver_uninstall(this_speaker->parent_->get_port()); |   i2s_driver_uninstall(this_speaker->parent_->get_port()); | ||||||
|  |  | ||||||
|   event.type = TaskEventType::STOPPED; |   event.type = TaskEventType::STOPPED; | ||||||
|   xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY); |   if (xQueueSend(this_speaker->event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) { | ||||||
|  |     ESP_LOGW(TAG, "Failed to send STOPPED event"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   while (true) { |   while (true) { | ||||||
|     delay(10); |     delay(10); | ||||||
| @@ -181,6 +204,7 @@ void I2SAudioSpeaker::watch_() { | |||||||
|         break; |         break; | ||||||
|       case TaskEventType::STARTED: |       case TaskEventType::STARTED: | ||||||
|         ESP_LOGD(TAG, "Started I2S Audio Speaker"); |         ESP_LOGD(TAG, "Started I2S Audio Speaker"); | ||||||
|  |         this->state_ = speaker::STATE_RUNNING; | ||||||
|         break; |         break; | ||||||
|       case TaskEventType::STOPPING: |       case TaskEventType::STOPPING: | ||||||
|         ESP_LOGD(TAG, "Stopping I2S Audio Speaker"); |         ESP_LOGD(TAG, "Stopping I2S Audio Speaker"); | ||||||
| @@ -191,6 +215,7 @@ void I2SAudioSpeaker::watch_() { | |||||||
|       case TaskEventType::STOPPED: |       case TaskEventType::STOPPED: | ||||||
|         this->state_ = speaker::STATE_STOPPED; |         this->state_ = speaker::STATE_STOPPED; | ||||||
|         vTaskDelete(this->player_task_handle_); |         vTaskDelete(this->player_task_handle_); | ||||||
|  |         this->task_created_ = false; | ||||||
|         this->player_task_handle_ = nullptr; |         this->player_task_handle_ = nullptr; | ||||||
|         this->parent_->unlock(); |         this->parent_->unlock(); | ||||||
|         xQueueReset(this->buffer_queue_); |         xQueueReset(this->buffer_queue_); | ||||||
| @@ -208,7 +233,6 @@ void I2SAudioSpeaker::loop() { | |||||||
|   switch (this->state_) { |   switch (this->state_) { | ||||||
|     case speaker::STATE_STARTING: |     case speaker::STATE_STARTING: | ||||||
|       this->start_(); |       this->start_(); | ||||||
|       break; |  | ||||||
|     case speaker::STATE_RUNNING: |     case speaker::STATE_RUNNING: | ||||||
|     case speaker::STATE_STOPPING: |     case speaker::STATE_STOPPING: | ||||||
|       this->watch_(); |       this->watch_(); | ||||||
|   | |||||||
| @@ -60,7 +60,6 @@ class I2SAudioSpeaker : public Component, public speaker::Speaker, public I2SAud | |||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   void start_(); |   void start_(); | ||||||
|   // void stop_(); |  | ||||||
|   void watch_(); |   void watch_(); | ||||||
|  |  | ||||||
|   static void player_task(void *params); |   static void player_task(void *params); | ||||||
| @@ -70,6 +69,7 @@ class I2SAudioSpeaker : public Component, public speaker::Speaker, public I2SAud | |||||||
|   QueueHandle_t event_queue_; |   QueueHandle_t event_queue_; | ||||||
|  |  | ||||||
|   uint8_t dout_pin_{0}; |   uint8_t dout_pin_{0}; | ||||||
|  |   bool task_created_{false}; | ||||||
|  |  | ||||||
| #if SOC_I2S_SUPPORTS_DAC | #if SOC_I2S_SUPPORTS_DAC | ||||||
|   i2s_dac_mode_t internal_dac_mode_{I2S_DAC_CHANNEL_DISABLE}; |   i2s_dac_mode_t internal_dac_mode_{I2S_DAC_CHANNEL_DISABLE}; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user