蓝牙管道切换的流程问题
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”吗?不清楚什么时候取消注册的
Code: Untitled.c Select all
/******************************
* 文件名称: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();
}