蓝牙管道切换的流程问题
Posted: Fri Mar 15, 2019 8:11 am
我根据了“flexible_pipeline”例程的逻辑重新改了代码,如下。
发现几个问题
1、audio_pipeline_pause得换成audio_pipeline_stop+audio_pipeline_wait_for_stop才可用
2、得重新注册i2s_stream_writer——audio_pipeline_register(pipeline, i2s_stream_writer, "i2sw");
但是audio_pipeline_stop注释不是说了“The link state of the elements in the pipeline is kept”吗?不清楚什么时候取消注册的
发现几个问题
1、audio_pipeline_pause得换成audio_pipeline_stop+audio_pipeline_wait_for_stop才可用
2、得重新注册i2s_stream_writer——audio_pipeline_register(pipeline, i2s_stream_writer, "i2sw");
但是audio_pipeline_stop注释不是说了“The link state of the elements in the pipeline is kept”吗?不清楚什么时候取消注册的
- /******************************
- * 文件名称:play_bt_music_example.c
- * 作 者:Kyle
- * 日 期:20190319
- * 描 述:bt与aux_in音频切换
- ******************************/
- /* 头文件 --------------------------------------------------------------------*/
- #include <string.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "esp_log.h"
- #include "nvs_flash.h"
- #include "audio_element.h"
- #include "audio_pipeline.h"
- #include "audio_event_iface.h"
- #include "audio_common.h"
- #include "i2s_stream.h"
- #include "esp_peripherals.h"
- #include "periph_button.h"
- #include "audio_hal.h"
- #include "board.h"
- #include "bluetooth_service.h"
- /* 宏定义 --------------------------------------------------------------------*/
- static const char *TAG = "BLUETOOTH_EXAMPLE";
- /* 变量 ----------------------------------------------------------------------*/
- //状态切换
- bool ex_audio_status = false;
- audio_pipeline_handle_t pipeline;
- audio_element_handle_t bt_stream_reader, i2s_stream_reader, i2s_stream_writer;
- /* 函数定义 ------------------------------------------------------------------*/
- /******************************
- * 函数名称:app_main
- * 作 者:Kyle
- * 日 期:20190319
- * 描 述:主函数
- * 输入参数:无
- * 返 回 值:无
- ******************************/
- void app_main(void)
- {
- //nvs flash初始化
- esp_err_t err = nvs_flash_init();
- if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
- // NVS partition was truncated and needs to be erased
- // Retry nvs_flash_init
- ESP_ERROR_CHECK(nvs_flash_erase());
- err = nvs_flash_init();
- }
- esp_log_level_set("*", ESP_LOG_INFO);
- esp_log_level_set(TAG, ESP_LOG_DEBUG);
- //1.创建蓝牙服务
- ESP_LOGI(TAG, "[ 1 ] Create Bluetooth service");
- bluetooth_service_cfg_t bt_cfg = {
- .device_name = "ESP-ADF-SPEAKER",
- .mode = BLUETOOTH_A2DP_SINK,
- };
- bluetooth_service_start(&bt_cfg);
- //2.启动编解码器芯片
- ESP_LOGI(TAG, "[ 2 ] Start codec chip");
- audio_hal_codec_config_t audio_hal_codec_cfg = AUDIO_HAL_ES8388_DEFAULT();
- audio_hal_codec_cfg.i2s_iface.samples = AUDIO_HAL_44K_SAMPLES;
- audio_hal_codec_cfg.adc_input = AUDIO_HAL_ADC_INPUT_LINE2;
- audio_hal_handle_t hal = audio_hal_init(&audio_hal_codec_cfg, 0);
- audio_hal_ctrl_codec(hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START);
- //3.创建音频管道以进行播放
- ESP_LOGI(TAG, "[ 3 ] Create audio pipeline for playback");
- audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
- pipeline = audio_pipeline_init(&pipeline_cfg);
- //3.1.创建i2s流以将数据从编解码器芯片读取
- ESP_LOGI(TAG, "[3.1] Create i2s stream to read data to codec chip");
- i2s_stream_cfg_t i2sr_cfg = I2S_STREAM_CFG_DEFAULT();
- i2sr_cfg.type = AUDIO_STREAM_READER;
- i2s_stream_reader = i2s_stream_init(&i2sr_cfg);
- //3.2.创建i2s流以将数据写入编解码器芯片
- ESP_LOGI(TAG, "[3.1] Create i2s stream to write data to codec chip");
- i2s_stream_cfg_t i2sw_cfg = I2S_STREAM_CFG_DEFAULT();
- i2sw_cfg.type = AUDIO_STREAM_WRITER;
- i2s_stream_writer = i2s_stream_init(&i2sw_cfg);
- //3.3.获取蓝牙流
- ESP_LOGI(TAG, "[3.2] Get Bluetooth stream");
- bt_stream_reader = bluetooth_service_create_stream();
- //3.2.将所有元素注册到音频管道
- ESP_LOGI(TAG, "[3.2] Register all elements to audio pipeline");
- audio_pipeline_register(pipeline, i2s_stream_reader, "i2sr");
- audio_pipeline_register(pipeline, i2s_stream_writer, "i2sw");
- audio_pipeline_register(pipeline, bt_stream_reader, "bt");
- //3.3.把它链接在一起
- ESP_LOGI(TAG, "[3.3] Link it together [Bluetooth]-->bt_stream_reader-->i2s_stream_writer-->[codec_chip]");
- audio_pipeline_link(pipeline, (const char *[]) {"i2sr", "i2sw"}, 2);
- //4.初始化外围设备
- ESP_LOGI(TAG, "[ 4 ] Initialize peripherals");
- esp_periph_config_t periph_cfg = { 0 };
- esp_periph_init(&periph_cfg);
- //4.1.初始化button外围设备
- ESP_LOGI(TAG, "[4.1] Initialize button peripheral");
- periph_button_cfg_t btn_cfg = {
- .gpio_mask = GPIO_SEL_36 | GPIO_SEL_39, // REC BTN & MODE BTN
- };
- esp_periph_handle_t button_periph = periph_button_init(&btn_cfg);
- //4.2.创建蓝牙外设
- ESP_LOGI(TAG, "[4.2] Create Bluetooth peripheral");
- esp_periph_handle_t bt_periph = bluetooth_service_create_periph();
- //4.2.启动所有外围设备
- ESP_LOGI(TAG, "[4.2] Start all peripherals");
- esp_periph_start(button_periph);
- esp_periph_start(bt_periph);
- //5.设置事件监听器
- ESP_LOGI(TAG, "[ 5 ] Setup event listener");
- audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
- audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);
- //5.1.来自管道的所有元素的监听事件
- ESP_LOGI(TAG, "[5.1] Listening event from all elements of pipeline");
- audio_pipeline_set_listener(pipeline, evt);
- //5.2.外围设备的监听事件
- ESP_LOGI(TAG, "[5.2] Listening event from peripherals");
- audio_event_iface_set_listener(esp_periph_get_event_iface(), evt);
- //6.启动audio_pipeline
- ESP_LOGI(TAG, "[ 6 ] Start audio_pipeline");
- audio_pipeline_run(pipeline);
- //7.监听所有管道事件
- ESP_LOGI(TAG, "[ 7 ] Listen for all pipeline events");
- while (1) {
- audio_event_iface_msg_t msg;
- esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY);
- if (ret != ESP_OK) {
- ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret);
- continue;
- }
- if (msg.source_type != PERIPH_ID_BUTTON) {
- // audio_element_handle_t el = (audio_element_handle_t)msg.source;
- // ESP_LOGI(TAG, "Element tag:[%s],src_type:%x, cmd:%d, data_len:%d, data:%p",
- // audio_element_get_tag(el), msg.source_type, msg.cmd, msg.data_len, msg.data);
- continue;
- }
- if (((int)msg.data == GPIO_MODE) && (msg.cmd == PERIPH_BUTTON_PRESSED)){
- ex_audio_status = !ex_audio_status;
- if (!ex_audio_status) {
- periph_bluetooth_pause(bt_periph);
- }
- audio_pipeline_stop(pipeline);
- audio_pipeline_wait_for_stop(pipeline);
- ESP_LOGE(TAG, "Changing music to %s", ex_audio_status ? "bt" : "i2sr");
- if (ex_audio_status) {
- audio_pipeline_breakup_elements(pipeline, i2s_stream_reader);
- //蓝牙
- audio_pipeline_register(pipeline, i2s_stream_writer, "i2sw");
- audio_pipeline_relink(pipeline, (const char *[]) {"bt", "i2sw"}, 2);
- audio_pipeline_set_listener(pipeline, evt);
- } else {
- audio_pipeline_breakup_elements(pipeline, bt_stream_reader);
- //外部
- audio_pipeline_register(pipeline, i2s_stream_writer, "i2sw");
- audio_pipeline_relink(pipeline, (const char *[]) {"i2sr", "i2sw"}, 2);
- audio_pipeline_set_listener(pipeline, evt);
- }
- audio_pipeline_run(pipeline);
- audio_pipeline_resume(pipeline);
- if (ex_audio_status) {
- periph_bluetooth_play(bt_periph);
- }
- }
- }
- //8.停止audio_pipeline
- ESP_LOGI(TAG, "[ 8 ] Stop audio_pipeline");
- audio_pipeline_terminate(pipeline);
- audio_pipeline_unregister(pipeline, bt_stream_reader);
- audio_pipeline_unregister(pipeline, i2s_stream_reader);
- audio_pipeline_unregister(pipeline, i2s_stream_writer);
- //在删除侦听器之前终止管道
- /* Terminate the pipeline before removing the listener */
- audio_pipeline_remove_listener(pipeline);
- //在删除侦听器之前停止所有外围设备
- /* Stop all peripherals before removing the listener */
- esp_periph_stop_all();
- audio_event_iface_remove_listener(esp_periph_get_event_iface(), evt);
- //确保在销毁event_iface之前调用audio_pipeline_remove_listener和audio_event_iface_remove_listener
- /* 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(bt_stream_reader);
- audio_element_deinit(i2s_stream_reader);
- audio_element_deinit(i2s_stream_writer);
- esp_periph_destroy();
- bluetooth_service_destroy();
- }