esp-adf icon indicating copy to clipboard operation
esp-adf copied to clipboard

tone_stream.c 中 find_num 缓冲区太小,导致 index 解析错误 (AUD-6553)

Open laodi-chen opened this issue 5 months ago • 6 comments

Bug 描述

tone_stream.c_tone_open() 函数中,解析 URI 的 tone index 使用了长度为 2 的缓冲区 find_num[2],导致超过一位数的 index 被错误解析。

例如:

flash://tone/13_请说.mp3
被解析为:
index = 138  // 错误

建议将 find_num 缓冲区扩大,并使用更安全的 snprintf() 写法替换

laodi-chen avatar Jul 17 '25 09:07 laodi-chen

您好,能否提供一下您的测试代码以及IDF和ADF的仓库版本,我在本地测试的index解析是正确的,我本地的仓库版本为IDF release/v5.5以及ADF master版本。

LiuCodee avatar Jul 29 '25 12:07 LiuCodee

你好 @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 avatar Jul 30 '25 03:07 laodi-chen

你好 @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);
}

LiuCodee avatar Aug 01 '25 04:08 LiuCodee

@laodi-chen 这个问题进展如何,有什么状态可以分享的吗?

jason-mao avatar Aug 13 '25 04:08 jason-mao

我也遇到了 只要存放音频大于10条就有概率出现这个问题 基本上播放一段时间就会有一个index = 138的情况出现 目前把char find_num[2] = { 0 }; 数组长度改为3 暂未复现这个问题

Z3ce avatar Aug 13 '25 10:08 Z3ce

@LiuCodee 异常的触发很神奇,在设备上电后过一些时间再去播放就会产生异常,如果在上电短期内播放则不会出现问题,正如楼上回复所言将长度改为3就不会出现此异常

laodi-chen avatar Aug 15 '25 08:08 laodi-chen