Skip to content

Commit

Permalink
Merge branch 'bugfix/pwm_io_done_early' into 'master'
Browse files Browse the repository at this point in the history
audio_stream: Fix pwm_stream IO_DONE early cause sound lost

See merge request adf/esp-adf-internal!1272
  • Loading branch information
jason-mao committed Feb 6, 2024
2 parents 77faee1 + 09987f4 commit f1cd5b6
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions components/audio_stream/pwm_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ static esp_err_t pwm_data_list_wait_semaphore(pwm_data_handle_t data, TickType_t
return ESP_FAIL;
}

static esp_err_t pwm_data_list_wait_flushed(pwm_data_handle_t data, TickType_t ticks_to_wait)
{
data->is_give = 2;
if (xSemaphoreTake(data->semaphore, ticks_to_wait) == pdTRUE) {
return ESP_OK;
}
return ESP_FAIL;
}

static inline void ledc_set_left_duty_fast(uint32_t duty_val)
{
*g_ledc_left_duty_val = (duty_val) << 4;
Expand Down Expand Up @@ -307,9 +316,10 @@ static void IRAM_ATTR timer_group_isr(void *para)
}
}

if (0 == handle->data->is_give && pwm_data_list_get_free(handle->data) > BUFFER_MIN_SIZE) {
if ((0 == handle->data->is_give && pwm_data_list_get_free(handle->data) > BUFFER_MIN_SIZE) ||
(2 == handle->data->is_give && pwm_data_list_get_count(handle->data) == 0)) {
handle->data->is_give = 1;
BaseType_t xHigherPriorityTaskWoken;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(handle->data->semaphore, &xHigherPriorityTaskWoken);
if (pdFALSE != xHigherPriorityTaskWoken) {
portYIELD_FROM_ISR();
Expand Down Expand Up @@ -529,6 +539,26 @@ static esp_err_t pwm_data_convert(pwm_data_handle_t data, uint8_t *inbuf, int32_
return ESP_OK;
}

static uint32_t pwm_get_data_duration(uint32_t data_size)
{
audio_pwm_handle_t handle = g_audio_pwm_handle;
uint32_t sample_bytes = (handle->config.duty_resolution) > 8 ? 2: 1;
uint32_t byte_rate = sample_bytes * handle->channel_set_num * handle->framerate;
if (byte_rate == 0) {
return 0;
}
// Add extra 20ms
return (data_size * 1000 / byte_rate) + 20;
}

static void pwm_wait_flush(void)
{
audio_pwm_handle_t handle = g_audio_pwm_handle;
uint32_t data_size = pwm_data_list_get_count(handle->data);
if (handle->status == AUDIO_PWM_STATUS_BUSY && data_size > 0) {
pwm_data_list_wait_flushed(handle->data, pwm_get_data_duration(data_size) / portTICK_RATE_MS);
}
}

esp_err_t audio_pwm_write(uint8_t *inbuf, size_t inbuf_len, size_t *bytes_written, TickType_t ticks_to_wait)
{
Expand Down Expand Up @@ -666,6 +696,9 @@ static int _pwm_process(audio_element_handle_t self, char *in_buffer, int in_len
} else {
w_size = r_size;
}
if (w_size == 0 || w_size == AEL_IO_DONE) {
pwm_wait_flush();
}
return w_size;
}

Expand Down

0 comments on commit f1cd5b6

Please sign in to comment.