tone_stream.c 中 find_num 缓冲区太小,导致 index 解析错误 (AUD-6553)
Bug 描述
在 tone_stream.c 的 _tone_open() 函数中,解析 URI 的 tone index 使用了长度为 2 的缓冲区 find_num[2],导致超过一位数的 index 被错误解析。
例如:
flash://tone/13_请说.mp3
被解析为:
index = 138 // 错误
建议将 find_num 缓冲区扩大,并使用更安全的 snprintf() 写法替换
您好,能否提供一下您的测试代码以及IDF和ADF的仓库版本,我在本地测试的index解析是正确的,我本地的仓库版本为IDF release/v5.5以及ADF master版本。
你好 @LiuCodee
idf:4c2820d377d1375e787bcef612f0c32c1427d183/5.4.1 adf:4200c64d4a78b9e9e2297818733aff21c72079a1/master
我已将audio_tone.bin、以及部分代码文件放在附件中。附件.zip
由于我的uri是从nvs读取的我这里使用固定的一条数据。
static void prepare_and_start_playback(tone_request_t *req)
{
// char *tone_url = load_flash_tone_table(req->tone_index);
char *tone_url = "flash://tone/19_19学习次数超过上限.mp3";
ESP_LOGI(TAG, "tone_url:%s", tone_url);
audio_element_set_uri(tone_stream, tone_url);
audio_pipeline_reset_ringbuffer(pipeline);
audio_pipeline_reset_elements(pipeline);
audio_pipeline_run(pipeline);
is_playing = true;
}
在最近的测试中我发现异常与首次播放有某种神奇关联,如果在上电过程播放过一次则不会产生错误。
void app_main(void)
{
// 一些wifi、eth、mqtt、sip等外设的初始化过程
...
init_audio_board();
tone_player_init();
play_tone(0, NULL, NULL, false);
}
I (26813) TONE_PLAYER: tone_url:flash://tone/19_19学习次数超过上限.mp3
I (26813) AUDIO_THREAD: The tone task allocate stack on internal memory
I (26813) AUDIO_ELEMENT: [tone-0x3c1924f0] Element task created
I (26813) AUDIO_THREAD: The mp3 task allocate stack on external memory
I (26823) AUDIO_ELEMENT: [mp3-0x3c192680] Element task created
I (26833) AUDIO_THREAD: The i2s task allocate stack on internal memory
I (26833) AUDIO_ELEMENT: [i2s-0x3c19293c] Element task created
I (26843) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:359, MEM Total:8386552 Bytes, Inter:142687 Bytes, Dram:142687 Bytes, Dram largest free:31744Bytes
I (26853) AUDIO_ELEMENT: [tone] AEL_MSG_CMD_RESUME,state:1
I (26863) AUDIO_ELEMENT: [mp3] AEL_MSG_CMD_RESUME,state:1
I (26863) MP3_DECODER: MP3 opened
I (26873) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1
I (26873) AUDIO_PIPELINE: Pipeline started
I (26883) TONE_PARTITION: tone partition format 1, total 22
I (26883) TONE_STREAM: Tone offset:000530E4, Tone length:24675, pos:19
I (26893) CODEC_ELEMENT_HELPER: The element is 0x3c192680. The reserve data 2 is 0x0.
I (26933) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_PAUSE
I (26933) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:4
W (30173) TONE_STREAM: No more data,ret:0 ,info.byte_pos:24675
I (30173) AUDIO_ELEMENT: IN-[tone] AEL_IO_DONE,0
I (30473) AUDIO_ELEMENT: IN-[mp3] AEL_IO_DONE,-2
I (30833) MP3_DECODER: Closed
I (30923) AUDIO_ELEMENT: IN-[i2s] AEL_IO_DONE,-2
W (30923) AUDIO_ELEMENT: [tone] Element already stopped
W (30923) AUDIO_ELEMENT: [mp3] Element already stopped
W (30923) AUDIO_ELEMENT: [i2s] Element already stopped
main函数中没有播放过,仅当mqtt收到某payload时调用play_tone(0, NULL, NULL, false);函数
I (139913) TONE_PLAYER: tone_url:flash://tone/19_19学习次数超过上限.mp3
I (139913) AUDIO_THREAD: The tone task allocate stack on internal memory
I (139923) AUDIO_ELEMENT: [tone-0x3c1924f0] Element task created
I (139923) AUDIO_THREAD: The mp3 task allocate stack on external memory
I (139933) AUDIO_ELEMENT: [mp3-0x3c192680] Element task created
I (139933) AUDIO_THREAD: The i2s task allocate stack on internal memory
I (139943) AUDIO_ELEMENT: [i2s-0x3c19293c] Element task created
I (139953) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:359, MEM Total:8382440 Bytes, Inter:142679 Bytes, Dram:142679 Bytes, Dram largest free:34816Bytes
I (139963) AUDIO_ELEMENT: [tone] AEL_MSG_CMD_RESUME,state:1
I (139963) AUDIO_ELEMENT: [mp3] AEL_MSG_CMD_RESUME,state:1
I (139973) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1
I (139973) AUDIO_PIPELINE: Pipeline started
I (139973) MP3_DECODER: MP3 opened
I (139983) TONE_PARTITION: tone partition format 1, total 22
E (139993) TONE_PARTITION: Wanted index out of range index[198]
I (139993) TONE_STREAM: Tone offset:00000000, Tone length:0, pos:198
E (140003) TONE_STREAM: Mayebe the flash tone is empty, please ensure the flash's contex
E (140013) AUDIO_ELEMENT: [tone] AEL_STATUS_ERROR_OPEN,-1
W (140013) AUDIO_ELEMENT: [tone] audio_element_on_cmd_error,7
W (140023) AUDIO_ELEMENT: IN-[mp3] AEL_IO_ABORT
E (140023) MP3_DECODER: Failed to read audio data (line 136)
W (140033) AUDIO_ELEMENT: [mp3] AEL_IO_ABORT, -3
I (140033) MP3_DECODER: Closed
W (140143) AUDIO_ELEMENT: IN-[i2s] AEL_IO_ABORT
W (140143) AUDIO_ELEMENT: [tone] Element already stopped
W (140143) AUDIO_ELEMENT: [mp3] Element already stopped
W (140143) AUDIO_ELEMENT: [i2s] Element already stopped
你好 @laodi-chen
使用你的代码和audio_tone.bin在本地测试的结果看起来是正常的,请问你是否尝试过对比load_flash_tone_table(req->tone_index)函数返回的结果以及req->tone_index的值是否符合期望值。
以下是我的测试代码
void play_task(void *arg)
{
play_tone(0, NULL, NULL, false);
vTaskDelay(pdMS_TO_TICKS(1000));
vTaskDelete(NULL);
}
void app_main(void)
{
esp_log_level_set("*", ESP_LOG_WARN);
esp_log_level_set(TAG, ESP_LOG_INFO);
audio_board_handle_t board_handle = audio_board_init();
audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START);
tone_player_init();
// vTaskDelay(pdMS_TO_TICKS(5000));
xTaskCreate(play_task, "Play tone task", 2048, NULL, 5, NULL);
vTaskDelay(pdMS_TO_TICKS(5000));
stop_pipeline();
audio_pipeline_unregister(pipeline, tone_stream);
audio_pipeline_unregister(pipeline, i2s_stream);
audio_pipeline_unregister(pipeline, mp3_decoder);
/* Terminal the pipeline before removing the listener */
audio_pipeline_remove_listener(pipeline);
/* Make sure audio_pipeline_remove_listener & audio_event_iface_remove_listener are called before destroying event_iface */
audio_event_iface_destroy(evt);
/* Release all resources */
audio_pipeline_deinit(pipeline);
audio_element_deinit(tone_stream);
audio_element_deinit(i2s_stream);
audio_element_deinit(mp3_decoder);
}
@laodi-chen 这个问题进展如何,有什么状态可以分享的吗?
我也遇到了 只要存放音频大于10条就有概率出现这个问题 基本上播放一段时间就会有一个index = 138的情况出现 目前把char find_num[2] = { 0 }; 数组长度改为3 暂未复现这个问题
@LiuCodee 异常的触发很神奇,在设备上电后过一些时间再去播放就会产生异常,如果在上电短期内播放则不会出现问题,正如楼上回复所言将长度改为3就不会出现此异常