我是卓波,很高兴你来看我的博客。

系列文章:

ESP32 LyraT音频开发板试玩(一):搭建开发环境

ESP32 LyraT音频开发板试玩(二):播放音乐

本文延续上一篇博客

将D:\msys32\home\user\esp\esp-adf\examples\get-started目录下的play_mp3工程直接拷贝到esp目录下

看一下代码,代码量也不多,核心是创建一个mp3元素和一个i2s元素,然后将两个元素链接到管道中。

形成了mp3元素拿数据给i2s元素播放的关系。

  1. /* Play mp3 file by audio pipeline
  2.  
  3. This example code is in the Public Domain (or CC0 licensed, at your option.)
  4.  
  5. Unless required by applicable law or agreed to in writing, this
  6. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  7. CONDITIONS OF ANY KIND, either express or implied.
  8. */
  9.  
  10. #include <string.h>
  11. #include "freertos/FreeRTOS.h"
  12. #include "freertos/task.h"
  13.  
  14. #include "esp_log.h"
  15. #include "audio_element.h"
  16. #include "audio_pipeline.h"
  17. #include "audio_event_iface.h"
  18. #include "audio_mem.h"
  19. #include "audio_common.h"
  20. #include "i2s_stream.h"
  21. #include "mp3_decoder.h"
  22. #include "audio_hal.h"
  23.  
  24. static const char *TAG = "PLAY_MP3_FLASH";
  25. /*
  26. To embed it in the app binary, the mp3 file is named
  27. in the component.mk COMPONENT_EMBED_TXTFILES variable.
  28. */
  29. extern const uint8_t adf_music_mp3_start[] asm("_binary_adf_music_mp3_start");
  30. extern const uint8_t adf_music_mp3_end[] asm("_binary_adf_music_mp3_end");
  31.  
  32. int mp3_music_read_cb(audio_element_handle_t el, char *buf, int len, TickType_t wait_time, void *ctx)
  33. {
  34. static int mp3_pos;
  35. int read_size = adf_music_mp3_end - adf_music_mp3_start - mp3_pos;
  36. if (read_size == ) {
  37. return AEL_IO_DONE;
  38. } else if (len < read_size) {
  39. read_size = len;
  40. }
  41. memcpy(buf, adf_music_mp3_start + mp3_pos, read_size);
  42. mp3_pos += read_size;
  43. return read_size;
  44. }
  45.  
  46. void app_main(void)
  47. {
  48. audio_pipeline_handle_t pipeline;
  49. audio_element_handle_t i2s_stream_writer, mp3_decoder;
  50. esp_log_level_set("*", ESP_LOG_WARN);
  51. esp_log_level_set(TAG, ESP_LOG_INFO);
  52.  
  53. ESP_LOGI(TAG, "[ 1 ] Start audio codec chip");
  54. audio_hal_codec_config_t audio_hal_codec_cfg = AUDIO_HAL_ES8388_DEFAULT();
  55. audio_hal_handle_t hal = audio_hal_init(&audio_hal_codec_cfg, );
  56. audio_hal_ctrl_codec(hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START);
  57.  
  58. ESP_LOGI(TAG, "[ 2 ] Create audio pipeline, add all elements to pipeline, and subscribe pipeline event");
  59. audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
  60. pipeline = audio_pipeline_init(&pipeline_cfg);
  61. mem_assert(pipeline);
  62.  
  63. ESP_LOGI(TAG, "[2.1] Create mp3 decoder to decode mp3 file and set custom read callback");
  64. mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
  65. mp3_decoder = mp3_decoder_init(&mp3_cfg);
  66. audio_element_set_read_cb(mp3_decoder, mp3_music_read_cb, NULL);
  67.  
  68. ESP_LOGI(TAG, "[2.2] Create i2s stream to write data to codec chip");
  69. i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
  70. i2s_cfg.type = AUDIO_STREAM_WRITER;
  71. i2s_stream_writer = i2s_stream_init(&i2s_cfg);
  72.  
  73. ESP_LOGI(TAG, "[2.3] Register all elements to audio pipeline");
  74. audio_pipeline_register(pipeline, mp3_decoder, "mp3");
  75. audio_pipeline_register(pipeline, i2s_stream_writer, "i2s");
  76.  
  77. ESP_LOGI(TAG, "[2.4] Link it together [mp3_music_read_cb]-->mp3_decoder-->i2s_stream-->[codec_chip]");
  78. audio_pipeline_link(pipeline, (const char *[]) {"mp3", "i2s"}, );
  79.  
  80. ESP_LOGI(TAG, "[ 3 ] Setup event listener");
  81. audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
  82. audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);
  83.  
  84. ESP_LOGI(TAG, "[3.1] Listening event from all elements of pipeline");
  85. audio_pipeline_set_listener(pipeline, evt);
  86.  
  87. ESP_LOGI(TAG, "[ 4 ] Start audio_pipeline");
  88. audio_pipeline_run(pipeline);
  89.  
  90. while () {
  91. audio_event_iface_msg_t msg;
  92. esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY);
  93. if (ret != ESP_OK) {
  94. ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret);
  95. continue;
  96. }
  97.  
  98. if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) mp3_decoder
  99. && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) {
  100. audio_element_info_t music_info = {};
  101. audio_element_getinfo(mp3_decoder, &music_info);
  102.  
  103. ESP_LOGI(TAG, "[ * ] Receive music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d",
  104. music_info.sample_rates, music_info.bits, music_info.channels);
  105.  
  106. audio_element_setinfo(i2s_stream_writer, &music_info);
  107. i2s_stream_set_clk(i2s_stream_writer, music_info.sample_rates, music_info.bits, music_info.channels);
  108. continue;
  109. }
  110. /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */
  111. if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer
  112. && msg.cmd == AEL_MSG_CMD_REPORT_STATUS && (int) msg.data == AEL_STATUS_STATE_STOPPED) {
  113. break;
  114. }
  115. }
  116.  
  117. ESP_LOGI(TAG, "[ 5 ] Stop audio_pipeline");
  118. audio_pipeline_terminate(pipeline);
  119.  
  120. /* Terminate the pipeline before removing the listener */
  121. audio_pipeline_remove_listener(pipeline);
  122.  
  123. /* Make sure audio_pipeline_remove_listener is called before destroying event_iface */
  124. audio_event_iface_destroy(evt);
  125.  
  126. /* Release all resources */
  127. audio_pipeline_deinit(pipeline);
  128. audio_element_deinit(i2s_stream_writer);
  129. audio_element_deinit(mp3_decoder);
  130. }

然后根据上一篇介绍的方法编译和下载

运行后在串口调试助手输出

  1. ets Jun ::
  2.  
  3. rst:0x1 (POWERON_RESET),boot:0x3f (SPI_FAST_FLASH_BOOT)
  4.  
  5. flash read err,
  6.  
  7. ets_main.c
  8.  
  9. ets Jun ::
  10.  
  11. rst:0x10 (RTCWDT_RTC_RESET),boot:0x3f (SPI_FAST_FLASH_BOOT)
  12.  
  13. configsip: , SPIWP:0xee
  14.  
  15. clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
  16.  
  17. mode:DIO, clock div:
  18.  
  19. load:0x3fff0018,len:
  20.  
  21. load:0x3fff001c,len:
  22.  
  23. load:0x40078000,len:
  24.  
  25. ho tail room
  26.  
  27. load:0x40078000,len:
  28.  
  29. entry 0x40078fb4
  30.  
  31. [;32mI () boot: ESP-IDF v3.0.1 2nd stage bootloader[0m
  32.  
  33. [;32mI () boot: compile time ::[0m
  34.  
  35. [;32mI () boot: Enabling RNG early entropy source...[0m
  36.  
  37. [;32mI () boot: SPI Speed : 40MHz[0m
  38.  
  39. [;32mI () boot: SPI Mode : DIO[0m
  40.  
  41. [;32mI () boot: SPI Flash Size : 4MB[0m
  42.  
  43. [;32mI () boot: Partition Table:[0m
  44.  
  45. [;32mI () boot: ## Label Usage Type ST Offset Length[0m
  46.  
  47. [;32mI () boot: nvs WiFi data [0m
  48.  
  49. [;32mI () boot: phy_init RF data 0000f000 [0m
  50.  
  51. [;32mI () boot: factory factory app [0m
  52.  
  53. [;32mI () boot: End of partition table[0m
  54.  
  55. [;32mI () esp_image: segment : paddr=0x00010020 vaddr=0x3f400020 size=0x1f468 () map[0m
  56.  
  57. [;32mI () esp_image: segment : paddr=0x0002f490 vaddr=0x3ffb0000 size=0x00b80 ( ) load[0m
  58.  
  59. [;32mI () esp_image: segment : paddr=0x00030018 vaddr=0x400d0018 size=0x21604 () map[0m
  60.  
  61. [;32mI () esp_image: segment : paddr=0x00051624 vaddr=0x3ffb0b80 size=0x0169c ( ) load[0m
  62.  
  63. [;32mI () esp_image: segment : paddr=0x00052cc8 vaddr=0x40080000 size=0x00400 ( ) load[0m
  64.  
  65. [;32mI () esp_image: segment : paddr=0x000530d0 vaddr=0x40080400 size=0x09e80 ( ) load[0m
  66.  
  67. [;32mI () esp_image: segment : paddr=0x0005cf58 vaddr=0x400c0000 size=0x00000 ( ) load[0m
  68.  
  69. [;32mI () boot: Loaded app from partition at offset 0x10000[0m
  70.  
  71. [;32mI () boot: Disabling RNG early entropy source...[0m
  72.  
  73. [;32mI () cpu_start: Pro cpu up.[0m
  74.  
  75. [;32mI () cpu_start: Starting app cpu, entry point is 0x40080ee4[0m
  76.  
  77. [;32mI () cpu_start: App cpu up.[0m
  78.  
  79. [;32mI () heap_init: Initializing. RAM available for dynamic allocation:[0m
  80.  
  81. [;32mI () heap_init: At 3FFAE6E0 len ( KiB): DRAM[0m
  82.  
  83. [;32mI () heap_init: At 3FFB2A48 len 0002D5B8 ( KiB): DRAM[0m
  84.  
  85. [;32mI () heap_init: At 3FFE0440 len 00003BC0 ( KiB): D/IRAM[0m
  86.  
  87. [;32mI () heap_init: At 3FFE4350 len 0001BCB0 ( KiB): D/IRAM[0m
  88.  
  89. [;32mI () heap_init: At 4008A280 len 00015D80 ( KiB): IRAM[0m
  90.  
  91. [;32mI () cpu_start: Pro cpu start user code[0m
  92.  
  93. [;32mI () cpu_start: Starting scheduler on PRO CPU.[0m
  94.  
  95. [;32mI () cpu_start: Starting scheduler on APP CPU.[0m
  96.  
  97. [;32mI () PLAY_MP3_FLASH: [ ] Start audio codec chip[0m
  98.  
  99. [;32mI () PLAY_MP3_FLASH: [ ] Create audio pipeline, add all elements to pipeline, and subscribe pipeline event[0m
  100.  
  101. [;32mI () PLAY_MP3_FLASH: [2.1] Create mp3 decoder to decode mp3 file and set custom read callback[0m
  102.  
  103. [;32mI () PLAY_MP3_FLASH: [2.2] Create i2s stream to write data to codec chip[0m
  104.  
  105. [;32mI () PLAY_MP3_FLASH: [2.3] Register all elements to audio pipeline[0m
  106.  
  107. [;32mI () PLAY_MP3_FLASH: [2.4] Link it together [mp3_music_read_cb]-->mp3_decoder-->i2s_stream-->[codec_chip][0m
  108.  
  109. [;32mI () PLAY_MP3_FLASH: [ ] Setup event listener[0m
  110.  
  111. [;32mI () PLAY_MP3_FLASH: [3.1] Listening event from all elements of pipeline[0m
  112.  
  113. [;32mI () PLAY_MP3_FLASH: [ ] Start audio_pipeline[0m
  114.  
  115. [;32mI () PLAY_MP3_FLASH: [ * ] Receive music info from mp3 decoder, sample_rates=, bits=, ch=[0m
  116.  
  117. [;32mI () PLAY_MP3_FLASH: [ ] Stop audio_pipeline[0m
  118.  
  119. [;33mW () AUDIO_PIPELINE: There are no listener registered[0m

接上喇叭,就可以听到音乐

关于idf和adf的api用法,官方有相关教程链接:

IDF: https://docs.espressif.com/projects/esp-idf/en/latest/

ADF: https://docs.espressif.com/projects/esp-adf/en/latest/

最后

本文主要介绍了运行adf的mp3播放例子的方法,在adf的examples文件夹下还有很多例子,亲们可以去研究研究。

版权所有,转载请打赏哟

如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟

ESP32 LyraT音频开发板试玩(二):播放音乐的更多相关文章

  1. ESP32 LyraT音频开发板试玩(一):搭建开发环境

    我是卓波,很高兴你来看我的博客. 系列文章: ESP32 LyraT音频开发板试玩(一):搭建开发环境 ESP32 LyraT音频开发板试玩(二):播放音乐 关于ESP32的开发环境搭建,官方有教程, ...

  2. MicroPython开发板:TPYBoard v102 播放音乐实例

    0x00前言 前段时间看到TPYBoard的技术交流群(群号:157816561,)里有人问关于TPYBoard播放音乐的问题.最近抽空看了一下文档介绍,着手做了个实验.更多MicroPython的教 ...

  3. 【Android开发VR实战】二.播放360&#176;全景视频

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53924006 本文出自[DylanAndroid的博客] [Android开发 ...

  4. ESP32音频开发板ESP32-Korvo V1.1踩坑

    电池供电ESP32-Korvo V1.1开发板供电电压低于3.9V不断复位: 报错->Brownout detector was triggered 断电探测器触发复位 根据同行资料发现,禁用断 ...

  5. QEMU让你无需开发板即可玩溜RT-Thread~

    1.1 本文的目的和背景 嵌入式软件开发离不开开发板,在没有物理开发板的情况下,可以使用QEMU等类似的虚拟机来模拟开发板.QEMU是一个支持跨平台虚拟化的虚拟机,它可以虚拟很多开发板.为了方便大家在 ...

  6. 基于Basys2开发板的简易电子琴和音乐播放器设计

    背景:华中科技大学 电测综合实验 主要功能:Basys2开发板外接一个扬声器(或无源蜂鸣器也可)实现电子琴和音乐播放器的功能.其中由于开发板上只有4个按键,所以电子琴功能只做了4个音调,分别对应于4个 ...

  7. swift开发:试玩 Apple 站点的 playground

    https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_ ...

  8. 用Java开发的【智能语音开发板MEGA ESP32AI】

    有点激动 ~ ~ ~ 新鲜出炉,用视频看看效果哦 我们新研发出世的语音开发板MEGA ESP32AI,来看看吧,有点腻害哦!!!先演示下功能语音控制开关等.播报天气 戳下面链接看视频哦? MEGA E ...

  9. ESP32 ADF windows开发环境搭建 适配ADF到ESP32A1S(转)

    搭建ESP32A1S的ADF开发环境 一,获取IDF和IDF-TOOL adf是乐鑫的音频开发框架,里面有许多乐鑫的音频开发API,同时ADF是基于IDF的.这一部分可以按照官网的教程一步一步来.官网 ...

随机推荐

  1. Liunx网络管理

    本地yum源 yum(Yellow dog Updater, Modified)是一个在 Fedora 和 RedHat 以及CentOS 中的 Shell 前端软件包管理器.基于 RPM 包管理,能 ...

  2. Markdown 使用方法总结

    标题: [#]  表示一级标题 [##] 表示二级标题 [###]表示三级标题 引用块:在引用文本前插入 Tab,具体几个 Tab 根据文本所处的位置不同而不同 列表:[ - ]即一个空格加上一个中划 ...

  3. Oracle10g使用$ORACLE_HOME/rdbms/admin/awrrpt.sql报错

    Enter value for report_name: Using the report name awrrpt_1_591_593.htmlselect output from table(dbm ...

  4. May 23rd 2017 Week 21st Tuesday

    Winners are not those who never fail but those who never quit. 成功者不是从不失败,而是从不放弃. Nothing is impossib ...

  5. C语言 返回指针的函数

    #include <stdio.h> char * test() { return "itcast"; } int main(int argc, const char ...

  6. [BJWC2008]秦腾与教学评估

    嘟嘟嘟 二分好题. 怎么二分呢?反正我是没想出来. 看了题解. 因为只有一个为奇数的点,所以对于一个位置x,求出区间[0, x]的教总和,如果为奇数,说明x取大了:否则x取小了(妙啊). 虽然答案在i ...

  7. AngularJS表格排序

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  8. 复制功能 js

    示例: <input class="herf" type="text" v-model="herfUrl" readonly=&quo ...

  9. 零基础Python知识点回顾(三)

    元组 元组是用圆括号括起来的,其中的元素之间用逗号隔开.(都是英文半角)tuple(元组)跟列表类似是一种序列类型的数据,特点就是其中的元素不能更改 既然是有序的,那么,嘿嘿,不错,它也可以有索引,能 ...

  10. udt通信java再次升级1.1版

    以前完成了udt的java代码测试,功能基本完成,近几天有时间重新梳理了下源码: 对原通信的关闭统一了方法,close定位过时,由shutdown与shutdownNow代替. 将一些主要方法添加了注 ...