Skip to content

Commit 40cb926

Browse files
committed
Merge branch 'feature/add_esp_audio_seek' into 'master'
ADD seek APIs See merge request adf/esp-adf-internal!401
2 parents 30403e2 + e9c4faf commit 40cb926

25 files changed

+194
-81
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ As a general, the ESP-ADF features will be supported as shown below:
2222

2323
### Quick Start
2424

25-
You need [version 3.2.3 of ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/v3.2.3/versions.html) to provide the toolchain, the ESP32-LyraT board and headphone connected.
25+
You need [version 3.3.1 of ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/v3.3.1/versions.html) to provide the toolchain, the ESP32-LyraT board and headphone connected.
2626

27-
**Note:** If this is your first exposure to ESP32 and ESP-IDF, proceed to [Getting Started](https://docs.espressif.com/projects/esp-idf/en/v3.2.3/get-started/index.html) documentation.
27+
**Note:** If this is your first exposure to ESP32 and ESP-IDF, proceed to [Getting Started](https://docs.espressif.com/projects/esp-idf/en/v3.3.1/get-started/index.html) documentation.
2828

2929
Clone the ESP-ADF repository, set up `ADF_PATH`, and then compile, flash and monitor applications in the same way as when working with ESP-IDF.
3030

components/audio_hal/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ set(COMPONENT_SRCS ./audio_hal.c
3030

3131
register_component()
3232

33-
target_link_libraries(${COMPONENT_NAME} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/driver/zl38063/firmware")
34-
target_link_libraries(${COMPONENT_NAME} INTERFACE firmware)
33+
target_link_libraries(${COMPONENT_TARGET} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/driver/zl38063/firmware")
34+
target_link_libraries(${COMPONENT_TARGET} INTERFACE firmware)

components/audio_hal/driver/es8388/headphone_detect.c

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ static void IRAM_ATTR headphone_gpio_intr_handler(void *arg)
7171
void headphone_detect_deinit()
7272
{
7373
xTimerDelete(timer_headphone, HP_DELAY_TIME_MS / portTICK_RATE_MS);
74+
gpio_uninstall_isr_service();
7475
timer_headphone = NULL;
7576
}
7677

components/audio_pipeline/audio_element.c

+16-7
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,9 @@
2929
#include "freertos/semphr.h"
3030
#include "freertos/task.h"
3131
#include "freertos/event_groups.h"
32-
#include "freertos/ringbuf.h"
3332

34-
#include "rom/queue.h"
3533
#include "esp_log.h"
36-
#include "audio_event_iface.h"
37-
3834
#include "audio_element.h"
39-
#include "audio_common.h"
4035
#include "audio_mem.h"
4136
#include "audio_mutex.h"
4237
#include "audio_error.h"
@@ -78,7 +73,7 @@ typedef enum {
7873
struct audio_element {
7974
/* Functions/RingBuffers */
8075
io_func open;
81-
io_func seek;
76+
ctrl_func seek;
8277
process_func process;
8378
io_func close;
8479
io_func destroy;
@@ -285,7 +280,7 @@ static esp_err_t audio_element_on_cmd(audio_event_iface_msg_t *msg, void *contex
285280
static esp_err_t audio_element_process_running(audio_element_handle_t el)
286281
{
287282
int process_len = -1;
288-
if (el->state < AEL_STATE_RUNNING || !el->is_open) {
283+
if (el->state < AEL_STATE_RUNNING || !el->is_running) {
289284
return ESP_ERR_INVALID_STATE;
290285
}
291286
process_len = el->process(el, el->buf, el->buf_size);
@@ -881,6 +876,7 @@ audio_element_handle_t audio_element_init(audio_element_cfg_t *config)
881876
el->process = config->process;
882877
el->close = config->close;
883878
el->destroy = config->destroy;
879+
el->seek = config->seek;
884880
el->multi_in.max_rb_num = config->multi_in_rb_num;
885881
el->multi_out.max_rb_num = config->multi_out_rb_num;
886882
if (el->multi_in.max_rb_num > 0) {
@@ -1053,6 +1049,7 @@ esp_err_t audio_element_pause(audio_element_handle_t el)
10531049
return ESP_FAIL;
10541050
}
10551051
if ((el->state >= AEL_STATE_PAUSED)) {
1052+
audio_element_force_set_state(el, AEL_STATE_PAUSED);
10561053
ESP_LOGD(TAG, "[%s] Element already paused, state:%d", el->tag, el->state);
10571054
return ESP_OK;
10581055
}
@@ -1132,6 +1129,7 @@ esp_err_t audio_element_stop(audio_element_handle_t el)
11321129
}
11331130
if (el->is_running == false) {
11341131
xEventGroupSetBits(el->state_event, STOPPED_BIT);
1132+
audio_element_report_status(el, AEL_STATUS_STATE_STOPPED);
11351133
ESP_LOGW(TAG, "[%s] Element already stopped", el->tag);
11361134
return ESP_OK;
11371135
}
@@ -1223,3 +1221,14 @@ ringbuf_handle_t audio_element_get_multi_output_ringbuf(audio_element_handle_t e
12231221
}
12241222
return NULL;
12251223
}
1224+
1225+
esp_err_t audio_element_seek(audio_element_handle_t el, void *in_data, int in_size, void *out_data, int *out_size)
1226+
{
1227+
esp_err_t ret = ESP_OK;
1228+
if (el && el->seek) {
1229+
ret = el->seek(el, in_data, in_size, out_data, out_size);
1230+
} else {
1231+
ret = ESP_ERR_NOT_SUPPORTED;
1232+
}
1233+
return ret;
1234+
}

components/audio_pipeline/audio_event_iface.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424

2525
#include "freertos/xtensa_api.h"
2626
#include "freertos/FreeRTOS.h"
27-
#include "freertos/ringbuf.h"
2827
#include "freertos/semphr.h"
2928
#include "freertos/task.h"
3029
#include "freertos/FreeRTOSConfig.h"
3130

31+
#include "rom/queue.h"
3232
#include "esp_log.h"
3333
#include "audio_event_iface.h"
3434
#include "audio_error.h"

components/audio_pipeline/audio_pipeline.c

+45-5
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,12 @@
2828
#include "freertos/task.h"
2929
#include "freertos/event_groups.h"
3030

31+
#include "rom/queue.h"
3132
#include "esp_log.h"
3233
#include "audio_element.h"
33-
34-
#include "rom/queue.h"
3534
#include "audio_pipeline.h"
3635
#include "audio_event_iface.h"
3736
#include "audio_mem.h"
38-
#include "audio_common.h"
3937
#include "audio_mutex.h"
4038
#include "ringbuf.h"
4139
#include "audio_error.h"
@@ -403,6 +401,17 @@ esp_err_t audio_pipeline_stop(audio_pipeline_handle_t pipeline)
403401
break;
404402
}
405403
}
404+
// Fix the in stream has been finished while calling PAUSE function, then call audio_pipeline_stop.
405+
// There are AEL_STATUS_STATE_FINISHED and AEL_STATUS_STATE_PAUSED status in linked elements,
406+
// use audio_element_set_ringbuf_done easy to cause block.
407+
STAILQ_FOREACH(el_item, &pipeline->el_list, next) {
408+
if (el_item->linked
409+
&& el_item->el_state == AEL_STATUS_STATE_PAUSED) {
410+
type = false;
411+
ESP_LOGW(TAG, "audio_element_stop has paused element");
412+
break;
413+
}
414+
}
406415
STAILQ_FOREACH(el_item, &pipeline->el_list, next) {
407416
if (el_item->linked) {
408417
if (type) {
@@ -412,7 +421,6 @@ esp_err_t audio_pipeline_stop(audio_pipeline_handle_t pipeline)
412421
}
413422
}
414423
}
415-
audio_pipeline_change_state(pipeline, AEL_STATE_INIT);
416424
return ESP_OK;
417425
}
418426

@@ -642,8 +650,40 @@ esp_err_t audio_pipeline_check_items_state(audio_pipeline_handle_t pipeline, aud
642650
el_cnt ++;
643651
ESP_LOGV(TAG, "pipeline state check, pl:%p, el:%p, tag:%16s, state:%d, status:%d", pipeline, item->el,
644652
audio_element_get_tag(item->el), item->el_state, status);
645-
if ((AEL_STATUS_NONE != item->el_state) && (status == item->el_state)) {
653+
if (item->el_state == AEL_STATUS_NONE) {
654+
continue;
655+
}
656+
if (status == item->el_state) {
646657
el_sta_cnt++;
658+
} else if ((status == AEL_STATUS_STATE_RUNNING)) {
659+
if ((item->el_state > AEL_STATUS_NONE) && (item->el_state < AEL_STATUS_INPUT_DONE)) {
660+
el_sta_cnt++;
661+
ESP_LOGW(TAG, "Check AEL RUNNING, pl:%p, el:%p, tag:%16s, state:%d, wanted:%d", pipeline, item->el,
662+
audio_element_get_tag(item->el), item->el_state, status);
663+
}
664+
} else if (status == AEL_STATUS_STATE_PAUSED) {
665+
if ((item->el_state == AEL_STATUS_STATE_FINISHED)
666+
|| ((item->el_state > AEL_STATUS_NONE) && (item->el_state < AEL_STATUS_INPUT_DONE))) {
667+
el_sta_cnt++;
668+
ESP_LOGW(TAG, "Check AEL PAUSED, pl:%p, el:%p, tag:%16s, state:%d, wanted:%d", pipeline, item->el,
669+
audio_element_get_tag(item->el), item->el_state, status);
670+
}
671+
} else if (status == AEL_STATUS_STATE_STOPPED) {
672+
if ((item->el_state == AEL_STATUS_STATE_FINISHED)
673+
|| ((item->el_state > AEL_STATUS_NONE) && (item->el_state < AEL_STATUS_INPUT_DONE))) {
674+
el_sta_cnt++;
675+
ESP_LOGW(TAG, "Check AEL STOPPED, pl:%p, el:%p, tag:%16s, state:%d, wanted:%d", pipeline, item->el,
676+
audio_element_get_tag(item->el), item->el_state, status);
677+
}
678+
} else if (status == AEL_STATUS_STATE_FINISHED) {
679+
if ((item->el_state == AEL_STATUS_STATE_FINISHED)
680+
|| ((item->el_state > AEL_STATUS_NONE) && (item->el_state < AEL_STATUS_INPUT_DONE))) {
681+
el_sta_cnt++;
682+
ESP_LOGW(TAG, "Check AEL FINISHED, pl:%p, el:%p, tag:%16s, state:%d, wanted:%d", pipeline, item->el,
683+
audio_element_get_tag(item->el), item->el_state, status);
684+
}
685+
} else {
686+
// TODO nothing
647687
}
648688
}
649689
if (el_cnt && (el_sta_cnt == el_cnt)) {

components/audio_pipeline/include/audio_common.h

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ typedef enum {
6262
AUDIO_CODEC_M4A,
6363
AUDIO_CODEC_TS,
6464
AUDIO_CODEC_AMR,
65+
AUDIO_CODEC_OGG,
66+
AUDIO_CODEC_FLAC,
6567
AUDIO_PLAYLIST
6668
} audio_codec_t;
6769

components/audio_pipeline/include/audio_element.h

+24-5
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@
2525
#ifndef _AUDIO_ELEMENT_H_
2626
#define _AUDIO_ELEMENT_H_
2727

28-
#include "freertos/FreeRTOS.h"
29-
30-
#include "rom/queue.h"
3128
#include "esp_err.h"
3229
#include "audio_event_iface.h"
3330
#include "ringbuf.h"
@@ -109,6 +106,9 @@ typedef struct audio_element *audio_element_handle_t;
109106
typedef struct {
110107
int user_data_0; /*!< user data 0 */
111108
int user_data_1; /*!< user data 1 */
109+
int user_data_2; /*!< user data 2 */
110+
int user_data_3; /*!< user data 3 */
111+
int user_data_4; /*!< user data 4 */
112112
} audio_element_reserve_data_t;
113113

114114
/**
@@ -118,8 +118,10 @@ typedef struct {
118118
int sample_rates; /*!< Sample rates in Hz */
119119
int channels; /*!< Number of audio channel, mono is 1, stereo is 2 */
120120
int bits; /*!< Bit wide (8, 16, 24, 32 bits) */
121+
int bps; /*!< Bit per second */
121122
int64_t byte_pos; /*!< The current position (in bytes) being processed for an element */
122123
int64_t total_bytes; /*!< The total bytes for an element */
124+
int duration; /*!< The duration for an element (optional) */
123125
char *uri; /*!< URI (optional) */
124126
audio_codec_t codec_fmt; /*!< Music format (optional) */
125127
audio_element_reserve_data_t reserve_data; /*!< This value is reserved for user use (optional) */
@@ -137,6 +139,7 @@ typedef audio_element_err_t (*process_func)(audio_element_handle_t self, char *e
137139
typedef audio_element_err_t (*stream_func)(audio_element_handle_t self, char *buffer, int len, TickType_t ticks_to_wait,
138140
void *context);
139141
typedef esp_err_t (*event_cb_func)(audio_element_handle_t el, audio_event_iface_msg_t *event, void *ctx);
142+
typedef esp_err_t (*ctrl_func)(audio_element_handle_t self, void *in_data, int in_size, void *out_data, int *out_size);
140143

141144
/**
142145
* @brief Audio Element configurations.
@@ -147,7 +150,7 @@ typedef esp_err_t (*event_cb_func)(audio_element_handle_t el, audio_event_iface_
147150
*/
148151
typedef struct {
149152
io_func open; /*!< Open callback function */
150-
io_func seek; /*!< Seek callback function */
153+
ctrl_func seek; /*!< Seek callback function */
151154
process_func process; /*!< Process callback function */
152155
io_func close; /*!< Close callback function */
153156
io_func destroy; /*!< Destroy callback function */
@@ -835,7 +838,7 @@ ringbuf_handle_t audio_element_get_multi_output_ringbuf(audio_element_handle_t e
835838
esp_err_t audio_element_process_init(audio_element_handle_t el);
836839

837840
/**
838-
* @brief Provides a way to call elements's `close`
841+
* @brief Provides a way to call element's `close`
839842
*
840843
* @param[in] el The audio element handle
841844
*
@@ -845,6 +848,22 @@ esp_err_t audio_element_process_init(audio_element_handle_t el);
845848
*/
846849
esp_err_t audio_element_process_deinit(audio_element_handle_t el);
847850

851+
/**
852+
* @brief Call element's `seek`
853+
*
854+
* @param[in] el The audio element handle
855+
* @param[in] in_data A pointer to in data
856+
* @param[in] in_size The size of the `in_data`
857+
* @param[out] out_data A pointer to the out data
858+
* @param[out] out_size The size of the `out_data`
859+
*
860+
* @return
861+
* - ESP_OK
862+
* - ESP_FAIL
863+
* - ESP_ERR_NOT_SUPPORTED
864+
*/
865+
esp_err_t audio_element_seek(audio_element_handle_t el, void *in_data, int in_size, void *out_data, int *out_size);
866+
848867
#ifdef __cplusplus
849868
}
850869
#endif

components/audio_pipeline/include/audio_event_iface.h

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
#include "freertos/FreeRTOS.h"
2929
#include "freertos/queue.h"
30-
#include "rom/queue.h"
3130

3231
#ifdef __cplusplus
3332
extern "C" {

components/audio_pipeline/include/audio_pipeline.h

-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
#ifndef _AUDIO_PIPELINE_H_
2626
#define _AUDIO_PIPELINE_H_
2727

28-
#include "rom/queue.h"
29-
#include "esp_err.h"
3028
#include "audio_element.h"
3129

3230
#ifdef __cplusplus

components/audio_stream/http_stream.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@
3030
#include "freertos/ringbuf.h"
3131
#include "freertos/semphr.h"
3232
#include "freertos/task.h"
33+
#include "rom/queue.h"
3334

3435
#include "esp_log.h"
3536
#include "errno.h"
3637
#include "http_stream.h"
37-
#include "audio_common.h"
3838
#include "audio_mem.h"
3939
#include "audio_element.h"
4040
#include "esp_system.h"

components/audio_stream/i2s_stream.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ static int _i2s_write(audio_element_handle_t self, char *buffer, int len, TickTy
214214
i2s_dac_data_scale(info.bits, (uint8_t *)buffer, len);
215215
}
216216
i2s_write(i2s->config.i2s_port, buffer, len, &bytes_written, ticks_to_wait);
217+
audio_element_getinfo(self, &info);
217218
info.byte_pos += bytes_written;
218219
audio_element_setinfo(self, &info);
219220
return bytes_written;
@@ -348,8 +349,7 @@ audio_element_handle_t i2s_stream_init(i2s_stream_cfg_t *config)
348349
});
349350
audio_element_setdata(el, i2s);
350351

351-
audio_element_info_t info;
352-
audio_element_getinfo(el, &info);
352+
audio_element_info_t info = {0};
353353
info.sample_rates = config->i2s_config.sample_rate;
354354
info.channels = config->i2s_config.channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? 2 : 1;
355355
info.bits = config->i2s_config.bits_per_sample;

components/audio_stream/include/i2s_stream.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ typedef struct {
7272
.dma_buf_len = 300, \
7373
.use_apll = 1, \
7474
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, \
75+
.tx_desc_auto_clear = true, \
7576
}, \
7677
.i2s_port = 0, \
7778
.use_alc = false, \
@@ -95,6 +96,7 @@ typedef struct {
9596
.dma_buf_count = 3, \
9697
.dma_buf_len = 300, \
9798
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, \
99+
.tx_desc_auto_clear = true, \
98100
}, \
99101
.i2s_port = 0, \
100102
.use_alc = false, \
@@ -133,7 +135,7 @@ esp_err_t i2s_stream_set_clk(audio_element_handle_t i2s_stream, int rate, int bi
133135
*
134136
* @param[in] i2s_stream The i2s element handle
135137
* @param[in] volume The volume of stream will be set.
136-
*
138+
*
137139
* @return
138140
* - ESP_OK
139141
* - ESP_FAIL
@@ -147,8 +149,8 @@ esp_err_t i2s_alc_volume_set(audio_element_handle_t i2s_stream, int volume);
147149
* @param[in] volume The volume of stream
148150
*
149151
* @return
150-
* - ESP_OK
151-
* - ESP_FAIL
152+
* - ESP_OK
153+
* - ESP_FAIL
152154
*/
153155
esp_err_t i2s_alc_volume_get(audio_element_handle_t i2s_stream, int* volume);
154156

components/clouds/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ set(COMPONENT_SRCS )
66

77
register_component()
88

9-
target_link_libraries(${COMPONENT_NAME} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/dueros/lightduer")
10-
target_link_libraries(${COMPONENT_NAME} INTERFACE duer-device)
9+
target_link_libraries(${COMPONENT_TARGET} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/dueros/lightduer")
10+
target_link_libraries(${COMPONENT_TARGET} INTERFACE duer-device)
1111

components/esp_peripherals/esp_peripherals.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ esp_periph_set_handle_t esp_periph_set_init(esp_periph_config_t *config)
142142

143143
//TODO: Should we uninstall gpio isr service??
144144
//TODO: Because gpio need for sdcard and gpio, then install isr here
145-
// gpio_uninstall_isr_service();
145+
146146
gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1);
147147

148148
periph_sets->run = false;
@@ -185,7 +185,6 @@ esp_err_t esp_periph_set_destroy(esp_periph_set_handle_t periph_set_handle)
185185
}
186186
periph_set_handle->run = false;
187187
esp_periph_wait_for_stop(periph_set_handle, portMAX_DELAY);
188-
189188
esp_periph_handle_t item, tmp;
190189
STAILQ_FOREACH_SAFE(item, &periph_set_handle->periph_list, entries, tmp) {
191190
STAILQ_REMOVE(&periph_set_handle->periph_list, item, esp_periph, entries);

0 commit comments

Comments
 (0)