关于边录边播的问题
Posted: Thu Nov 22, 2018 2:57 pm
刚刚接触esp32,想要实现边录边播,想法是通过两个I2S,分别控制录音和播放。
我的代码实现如下:
公共部分的初始化:
播放部分的初始化
录音部分的初始化
初始化完成后,起两个线程分别捕捉播放及录音的事件通知。
播放事件
录音事件
两个线程单独运行ok,如果同步运行的话,会出现播放卡顿,录音出来的声音是很尖锐的噪音。
请问是不是我的处理思路有问题,或是配置有问题?烦请解答,不胜感激!
我的代码实现如下:
公共部分的初始化:
- esp_log_level_set("*", ESP_LOG_WARN);
- esp_log_level_set(TAG, ESP_LOG_INFO);
- esp_periph_config_t periph_cfg = { 0 };
- esp_periph_init(&periph_cfg);
- periph_sdcard_cfg_t sdcard_cfg = {
- .root = "/sdcard",
- .card_detect_pin = SD_CARD_INTR_GPIO, //GPIO_NUM_34
- };
- esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sdcard_cfg);
- esp_periph_start(sdcard_handle);
- while (!periph_sdcard_is_mounted(sdcard_handle)) {
- vTaskDelay(100 / portTICK_PERIOD_MS);
- }
- periph_touch_cfg_t touch_cfg = {
- .touch_mask = TOUCH_SEL_SET | TOUCH_SEL_PLAY | TOUCH_SEL_VOLUP | TOUCH_SEL_VOLDWN,
- .tap_threshold_percent = 70,
- };
- touch_periph = periph_touch_init(&touch_cfg);
- esp_periph_start(touch_periph);
- audio_hal_codec_config_t audio_hal_codec_cfg = AUDIO_HAL_ES8388_DEFAULT();
- audio_hal_codec_cfg.i2s_iface.samples = AUDIO_HAL_44K_SAMPLES;
- hal = audio_hal_init(&audio_hal_codec_cfg, 0);
- audio_hal_ctrl_codec(hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);
- audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
- pipeline_mp3 = audio_pipeline_init(&pipeline_cfg);
- mem_assert(pipeline_mp3);
- i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
- i2s_cfg.i2s_port = I2S_NUM_0;
- i2s_cfg.type = AUDIO_STREAM_WRITER;
- i2s_stream_writer = i2s_stream_init(&i2s_cfg);
- mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
- mp3_decoder = mp3_decoder_init(&mp3_cfg);
- audio_element_set_read_cb(mp3_decoder, my_sdcard_read_cb, NULL);
- audio_pipeline_register(pipeline_mp3, mp3_decoder, "mp3");
- audio_pipeline_register(pipeline_mp3, i2s_stream_writer, "i2s_mp3");
- ESP_LOGI(TAG, "Link it together [my_sdcard_read_cb]-->mp3_decoder-->i2s_stream-->[codec_chip]");
- audio_pipeline_link(pipeline_mp3, (const char *[]) {"mp3", "i2s_mp3"}, 2);
- audio_event_iface_cfg_t evt_mp3_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
- evt_mp3 = audio_event_iface_init(&evt_mp3_cfg);
- audio_pipeline_set_listener(pipeline_mp3, evt_mp3);
- audio_event_iface_set_listener(esp_periph_get_event_iface(), evt_mp3);
- audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
- pipeline_rec = audio_pipeline_init(&pipeline_cfg);
- mem_assert(pipeline_rec);
- fatfs_stream_cfg_t fatfs_cfg = FATFS_STREAM_CFG_DEFAULT();
- fatfs_cfg.type = AUDIO_STREAM_WRITER;
- fatfs_stream_writer = fatfs_stream_init(&fatfs_cfg);
- i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
- i2s_cfg.i2s_port = I2S_NUM_1;
- i2s_cfg.task_core = 1;
- i2s_cfg.i2s_config.sample_rate = 8000;
- i2s_cfg.i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT;
- i2s_cfg.type = AUDIO_STREAM_READER;
- i2s_stream_reader = i2s_stream_init(&i2s_cfg);
- amrnb_encoder_cfg_t amr_enc_cfg = DEFAULT_AMRNB_ENCODER_CONFIG();
- amr_encoder = amrnb_encoder_init(&amr_enc_cfg);
- audio_pipeline_register(pipeline_rec, i2s_stream_reader, "i2s_rec");
- audio_pipeline_register(pipeline_rec, amr_encoder, "amr");
- audio_pipeline_register(pipeline_rec, fatfs_stream_writer, "file");
- audio_pipeline_link(pipeline_rec, (const char *[]) {"i2s_rec", "amr", "file"}, 3);
- audio_element_set_uri(fatfs_stream_writer, "/sdcard/rec.amr");
- audio_event_iface_cfg_t evt_rec_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
- evt_rec = audio_event_iface_init(&evt_rec_cfg);
- audio_pipeline_set_listener(pipeline_rec, evt_rec);
播放事件
- int player_volume = 50;
- audio_hal_set_volume(hal, player_volume);
- audio_pipeline_run(pipeline_mp3);
- while (1) {
- /* Handle event interface messages from pipeline
- to set music info and to advance to the next song
- */
- audio_event_iface_msg_t msg;
- esp_err_t ret = audio_event_iface_listen(evt_mp3, &msg, portMAX_DELAY);
- if (ret != ESP_OK) {
- ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret);
- continue;
- }
- if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT){
- // Set music info for a new song to be played
- if (msg.source == (void *) mp3_decoder
- && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) {
- audio_element_info_t music_info = {0};
- audio_element_getinfo(mp3_decoder, &music_info);
- ESP_LOGI(TAG, "[ * ] Received music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d",
- music_info.sample_rates, music_info.bits, music_info.channels);
- audio_element_setinfo(i2s_stream_writer, &music_info);
- i2s_stream_set_clk(i2s_stream_writer, music_info.sample_rates, music_info.bits, music_info.channels);
- continue;
- }
- // Advance to the next song when previous finishes
- if (msg.source == (void *) i2s_stream_writer
- && msg.cmd == AEL_MSG_CMD_REPORT_STATUS) {
- audio_element_state_t el_state = audio_element_get_state(i2s_stream_writer);
- if (el_state == AEL_STATE_FINISHED) {
- ESP_LOGI(TAG, "[ * ] Finished, advancing to the next song");
- audio_pipeline_stop(pipeline_mp3);
- audio_pipeline_wait_for_stop(pipeline_mp3);
- get_file(NEXT);
- audio_pipeline_run(pipeline_mp3);
- }
- continue;
- }
- }
- audio_pipeline_run(pipeline_rec);
- int second_recorded = 0;
- while (1) {
- audio_event_iface_msg_t msg;
- if (audio_event_iface_listen(evt_rec, &msg, 1000 / portTICK_RATE_MS) != ESP_OK) {
- second_recorded++;
- ESP_LOGI(TAG, "[ * ] Recording ... %d", second_recorded);
- if (second_recorded >= 5) {
- ESP_LOGI(TAG, "Finishing amr recording");
- break;
- }
- continue;
- }
- /* Stop when the last pipeline element (i2s_stream_reader in this case) receives stop event */
- if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *)i2s_stream_reader && msg.cmd ==
- AEL_MSG_CMD_REPORT_STATUS && (int)msg.data == AEL_STATUS_STATE_STOPPED) {
- ESP_LOGW(TAG, "[ * ] Stop event received");
- break;
- }
- }
请问是不是我的处理思路有问题,或是配置有问题?烦请解答,不胜感激!