ESP32 ADF pipeline切换时遇到问题---音频没有放出

1、问题描述

成功切换的LOG

[2019-03-13 14:48:06.736]# RECV ASCII>
[0;32mI (5181) STAGEFRIGHTMP3_DECODER: MP3 decodig done[0m
[0;32mI (5181) STAGEFRIGHTMP3_DECODER: Closed[0m
[0;32mI (5231) AUDIO_ELEMENT: IN-[i2s] AEL_IO_DONE,-2[0m
[0;33mW (5261) Somnic_music: [ * ] Stop event received[0m
[0;33mW (5271) AUDIO_PIPELINE: create new rb, linked:1, rb:0x3f802bd8, cur_el:bt[0m
[0;32mI (5271) AUDIO_ELEMENT: [bt] Element task created[0m
[0;32mI (5271) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:278, MEM Total:4280908 Bytes, Inter:125296 Bytes, Dram:106384 Byte

[2019-03-13 14:48:06.809]# RECV ASCII>
s

[0m
[0;32mI (5281) AUDIO_PIPELINE: Pipeline started[0m
[0;32mI (5281) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1[0m
[0;32mI (5291) I2S_STREAM: AUDIO_STREAM_WRITER[0m
[0;32mI (5311) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:2[0m


[2019-03-13 14:48:41.994]# RECV ASCII>
[0;31mE (40461) BT_APPL: bta_av_rc_create ACP handle exist for shdl:0[0m
[0;32mI (40501) Somnic_music: [ * ] Receive music info from Bluetooth, sample_rates=44100, bits=16, ch=2[0m
[0;32mI (40521) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_PAUSE[0m
[0;32mI (40521) I2S: APLL: Req RATE: 44100, real rate: 43945.238, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 11249981.000, SCLK: 1406247.625000, diva: 1, divb: 0[0m
[0;33mW (40531) BT_APPL: new conn_srvc id:19, app_id:0[0m
[0;32mI (40531) AUDIO_ELEMENT: [i2s] AEL_M

[2019-03-13 14:48:42.068]# RECV ASCII>
SG_CMD_RESUME,state:3[0m
[0;32mI (40541) I2S_STREAM: AUDIO_STREAM_WRITER[0m
[0;31mE (40551) Somnic_music: [ * ] Action command error: src_type:1048585, source:0x3ffe463c cmd:1, data:0x0, data_len:0[0m
[0;32mI (40561) Somnic_music: [ * ] Bluetooth audio connected

[0m


[2019-03-13 14:48:44.490]# RECV ASCII>
[0;32mI (42991) BT_LOG: bta_av_link_role_ok hndl:x41 role:1 conn_audio:x1 bits:1 features:x824b
[0m
[0;33mW (42991) BT_APPL: new conn_srvc id:19, app_id:1[0m
[0;32mI (42991) Somnic_music: [ * ] Bluetooth audio started

失败的切换LOG

[0;32mI (63011) STAGEFRIGHTMP3_DECODER: MP3 decodig done[0m
[0;32mI (63011) STAGEFRIGHTMP3_DECODER: Closed[0m
[0;32mI (63061) AUDIO_ELEMENT: IN-[i2s] AEL_IO_DONE,-2[0m
[0;33mW (63091) Somnic_music: [ * ] Stop event received[0m
[0;32mI (63091) AUDIO_PIPELINE: found kept rb:0x3f802bd8 kept:1,linked:1, el:0x3f80017c, name:bt[0m
[0;32mI (63101) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:278, MEM Total:4271628 Bytes, Inter:124288 Bytes, Dram:105376 Bytes

[0m
[0;32mI (63111) AUDIO_PIPELINE

[2019-03-13 14:49:04.640]# RECV ASCII>
: Pipeline started[0m
[0;32mI (63111) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1[0m
[0;32mI (63121) I2S_STREAM: AUDIO_STREAM_WRITER[0m
[0;32mI (63141) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:2[0m


[2019-03-13 14:49:12.510]# RECV ASCII>
[0;31mE (70971) BT_APPL: rcb[0].lidx=3, lcb.conn_msk=x1[0m
[0;31mE (70981) BT_APPL: bta_av_rc_create ACP handle exist for shdl:0[0m
[0;32mI (71021) Somnic_music: [ * ] Receive music info from Bluetooth, sample_rates=44100, bits=16, ch=2[0m
[0;33mW (71041) BT_APPL: new conn_srvc id:19, app_id:0[0m
[0;32mI (71041) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_PAUSE[0m
[0;32mI (71051) I2S: APLL: Req RATE: 44100, real rate: 43945.238, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 11249981.000, SCLK: 1406247.625000, div

[2019-03-13 14:49:12.581]# RECV ASCII>
a: 1, divb: 0[0m
[0;31mE (71061) Somnic_music: [ * ] Action command error: src_type:1048585, source:0x3ffe463c cmd:1, data:0x0, data_len:0[0m
[0;32mI (71061) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:3[0m
[0;32mI (71071) Somnic_music: [ * ] Bluetooth audio connected

[0m
[0;32mI (71071) I2S_STREAM: AUDIO_STREAM_WRITER[0m


对比看,没发现有多大不同。

#define AUDIO_MEM_SHOW(x)  audio_mem_print(x, __LINE__, __func__)
void audio_mem_print(const char *tag, int line, const char *func)
{
#ifdef CONFIG_SPIRAM_BOOT_INIT
    ESP_LOGI(tag, "Func:%s, Line:%d, MEM Total:%d Bytes, Inter:%d Bytes, Dram:%d Bytes\r\n", func, line, esp_get_free_heap_size(),
             heap_caps_get_free_size(MALLOC_CAP_INTERNAL), heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
#else
    ESP_LOGI(tag, "Func:%s, Line:%d, MEM Total:%d Bytes\r\n", func, line, esp_get_free_heap_size());
#endif
}

2、原因查找 

static void bt_a2d_sink_data_cb(const uint8_t *data, uint32_t len)
{
	if (g_bt_service->stream) {
		if (audio_element_get_state(g_bt_service->stream) == AEL_STATE_RUNNING) {
			audio_element_output(g_bt_service->stream, (char *)data, len);

		}
	}

}

问题出在data_cb上,由于蓝牙数据流在AEL_STATE_INIT状态,不能把数据传给下一个元素(即I2S数据流)的buffer中去。

因此就需要查看为什么蓝牙数据流没有切换至AEL_STATE_RUNNING。

经过分析

esp_err_t audio_element_resume(audio_element_handle_t el, float wait_for_rb_threshold, TickType_t timeout)
{

    if (!el->task_run) {
        ESP_LOGW(TAG, "[%s] Element has not create when AUDIO_ELEMENT_RESUME", el->tag);
        return ESP_FAIL;
    }

    if ((el->is_running) || (el->state == AEL_STATE_RUNNING)) {
        ESP_LOGD(TAG, "[%s] RESUME: Element is already running, state:%d, task_run:%d", el->tag, el->state, el->task_run);
       // audio_element_force_set_state(el, AEL_STATE_RUNNING);
        return ESP_OK;
    }

    if (el->task_stack <= 0) {
    	ESP_LOGI(TAG,"[%s] FORCE SET RUNNING STATE\r\n",el->tag);
        audio_element_force_set_state(el, AEL_STATE_RUNNING);
        return ESP_OK;
    }

    if (el->state == AEL_STATE_ERROR) {
        ESP_LOGE(TAG, "[%s] RESUME: Element error, state:%d", el->tag, el->state);
        return ESP_FAIL;
    }
    if (el->state == AEL_STATE_FINISHED) {
        ESP_LOGI(TAG, "[%s] RESUME: Element has finished, state:%d", el->tag, el->state);
        return ESP_OK;
    }
    if (wait_for_rb_threshold > 1 || wait_for_rb_threshold < 0) {
        return ESP_FAIL;
    }
    int ret =  ESP_OK;
    audio_element_cmd_send(el, AEL_MSG_CMD_RESUME);
    if (wait_for_rb_threshold != 0 && el->read_type == IO_TYPE_RB) {
        ret = audio_element_wait_for_buffer(el, rb_get_size(el->in.input_rb) * wait_for_rb_threshold, timeout);
    }
    return ret;
}

主要是对于蓝牙数据流el->is_running是true,直接返回,但是其实el->state却是AEL_STATE_INIT,而回调函数判的是state的状态。

解决方法,就是把上述代码// audio_element_force_set_state(el, AEL_STATE_RUNNING);的注释打开。

3、解决问题的方法

首先这是本地播放和蓝牙播放互相切换造成的问题,而本地播放时可以的,蓝牙播放却不行。,根据下图分析,应该是蓝牙数据流到I2S数据流之间的数据有问题,或者蓝牙其他原因。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
引用: 在Ubuntu 20.04.4 LTS操作系统中,我已经安装了ESP-idf开发环境并使用了一段间。现在我想安装esp-adf音频开发框架,但遇到问题。可以在https://***/index.html找到相关文档。 引用: LinkGUI™ Air E32是一个开发平台,基于ESP32 WROVER芯片组,可以实现完美的图形交互体验。它将GUI系统嵌入到乐鑫开源的ESP-ADF/ESP-IDF开发环境中,提供了丰富的UI交互功能。LinkGUI™ Air E32平台由ESP32 WROVER芯片、LCD、按键、T卡插槽、喇叭插槽、麦克风和扩展接口组成。它的SDK以基于ESP-ADF的LinkGUI图形系统为核心,与ESP-ADF开发环境无缝连接,实现了WIFI/BT/音频和高级图形交互的功能。 根据您的问题,您想了解在Ubuntu操作系统上使用esp-adf和lvgl。首先,esp-adf是一个音频开发框架,用于在ESP32芯片上开发音频应用程序。它提供了丰富的音频功能和示例,可以实现音频播放、录制、语音识别等功能。 而lvgl是一个开源的图形库,用于创建嵌入式设备上的用户界面。它提供了丰富的图形元素和交互功能,可以实现按钮、滑块、进度条、列表等常见的UI元素。 在Ubuntu操作系统上,您可以按照ESP-ADF文档中提供的步骤安装和配置esp-adf开发环境。然后,您可以使用lvgl库开发具有图形界面的应用程序。您可以参考lvgl的官方文档和示例来学习如何使用lvgl库进行UI设计和交互。 总结起来,esp-adf是一个音频开发框架,lvgl是一个图形库。您可以在Ubuntu操作系统上使用esp-adf开发音频应用程序,并结合lvgl库创建图形界面。希望这能帮助到您。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Ubuntn环境下安装ESP 音频框架出现Failed to resolve component ‘jsmn‘.问题(已解决)](https://blog.csdn.net/qq_41601311/article/details/124293303)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [基于ESP-ADF的图形系统](https://blog.csdn.net/skdev/article/details/120765588)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值