# Play Music from Flash
- [中文版](./README_CN.md)
- Basic Example: ⭐
## Example Brief
This example demonstrates reading MP3 and other audio binary data from embedded Flash, decoding with a decoder, applying audio effects, and playing through CODEC_DEV_TX IO.
- Single pipeline: `io_embed_flash` → decoder → audio effects → `io_codec_dev`.
- Supports MP3, WAV, FLAC, AAC, M4A, TS, AMRNB, AMRWB; default is MP3.
### Typical Scenarios
- Boot tones, built-in ringtones, or any playback that does not require external storage.
### Run Flow
- Pipeline: `io_embed_flash` (read from flash) → decoder → audio effects → `io_codec_dev`. Playback URL and format are set by configuration; embedded files are built in via the embed script.
## Environment Setup
### Hardware Required
- **Board**: ESP32-S3-Korvo V3 by default; other ESP audio boards are also supported.
- **Resource requirements**: Audio DAC, speaker.
### Default IDF Branch
This example supports IDF release/v5.4 (>= v5.4.3) and release/v5.5 (>= v5.5.2).
### Prerequisites
The audio files used in this example are in [embedding binary data](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/build-system.html#cmake-embed-data) format; they are compiled with the code and downloaded to flash.
This example provides two test files under `${PROJECT_DIR}/components/music_src/`: `ff-16b-1c-44100hz.mp3` and `alarm.mp3`. The files `esp_embed_tone.h` and `esp_embed_tone.cmake` are generated by `$YOUR_GMF_PATH/elements/gmf_io/mk_flash_embed_tone.py`. To change the audio files, rerun the script to regenerate them:
```
python $YOUR_GMF_PATH/elements/gmf_io/mk_flash_embed_tone.py -p $YOUR_GMF_PATH/gmf_examples/basic_examples/pipeline_play_embed_music/components/music_src
```
## Build and Flash
### Build Preparation
Before building this example, ensure the ESP-IDF environment is set up. If it is already set up, skip this paragraph and go to the project directory and run the pre-build script(s) as follows. If not, run the following in the ESP-IDF root directory to complete the environment setup. For full steps, see the [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/index.html).
```
./install.sh
. ./export.sh
```
Short steps:
- Go to this example's project directory:
```
cd $YOUR_GMF_PATH/gmf_examples/basic_examples/pipeline_play_embed_music
```
- Run the pre-build script: follow the prompts to select the target chip, set up the IDF Action extension, and use `esp_board_manager` to select a supported board. For a custom board, see [Custom board](https://github.com/espressif/esp-gmf/blob/main/packages/esp_board_manager/README.md#custom-board).
On Linux / macOS:
```bash/zsh
source prebuild.sh
```
On Windows:
```powershell
.\prebuild.ps1
```
### Project Configuration
- To adjust audio effect parameters, configure GMF Audio options in menuconfig; default is fine for a quick build.
```bash
idf.py menuconfig
```
In menuconfig:
- `ESP GMF Loader` → `GMF Audio Configurations` → `GMF Audio Effects` → `Channel Convert Destination Channel`
- `ESP GMF Loader` → `GMF Audio Configurations` → `GMF Audio Effects` → `Bit Convert Destination Bits`
- `ESP GMF Loader` → `GMF Audio Configurations` → `GMF Audio Effects` → `Rate Convert Destination Rate`
> Press `s` to save and `Esc` to exit after configuration.
### Build and Flash Commands
- Build the example:
```
idf.py build
```
- Flash the firmware and run the serial monitor (replace PORT with your port name):
```
idf.py -p PORT flash monitor
```
- To exit the monitor, use `Ctrl-]`
## How to Use the Example
### Functionality and Usage
- After power-on the example mounts the SD card and initializes audio, then reads and plays MP3 from the Flash embedded binary; when playback finishes it stops and releases resources.
### Log Output
- Normal run: mount, register elements, create pipeline, set URL, bind task, listen events, start pipeline, wait for finish and destroy resources. Key steps are marked with `[ 1 ]`–`[ 6 ]`.
```c
I (912) main_task: Calling app_main()
I (912) PLAY_EMBED_MUSIC: Func:app_main, Line:85, MEM Total:7253704 Bytes, Inter:334847 Bytes, Dram:334847 Bytes
I (922) PLAY_EMBED_MUSIC: [ 1 ] Mount peripheral
I (927) PERIPH_I2S: I2S[0] TDM, TX, ws: 45, bclk: 9, dout: 8, din: 10
I (933) PERIPH_I2S: I2S[0] initialize success: 0x3c15e744
I (938) DEV_AUDIO_CODEC: DAC is ENABLED
I (942) DEV_AUDIO_CODEC: Init audio_dac, i2s_name: i2s_audio_out, i2s_rx_handle:0x0, i2s_tx_handle:0x3c15e744, data_if: 0x3fcea7f4
I (953) PERIPH_I2C: I2C master bus initialized successfully
I (963) ES8311: Work in Slave mode
I (966) DEV_AUDIO_CODEC: Successfully initialized codec: audio_dac
I (967) DEV_AUDIO_CODEC: Create esp_codec_dev success, dev:0x3fceaa48, chip:es8311
I (975) BOARD_MANAGER: Device audio_dac initialized
I (979) BOARD_DEVICE: Device handle audio_dac found, Handle: 0x3fce9a7c TO: 0x3fce9a7c
I (987) I2S_IF: channel mode 2 bits:16/16 channel:2 mask:3
I (992) I2S_IF: TDM Mode 1 bits:16/16 channel:2 sample_rate:44100 mask:3
I (1013) Adev_Codec: Open codec device OK
I (1013) PLAY_EMBED_MUSIC: [ 2 ] Register all the elements and set audio information to play codec device
I (1015) ESP_GMF_POOL: Registered items on pool:0x3c15efa0, app_main-100
I (1021) ESP_GMF_POOL: IO, Item:0x3c15f0b4, H:0x3c15efb4, TAG:io_codec_dev
I (1028) ESP_GMF_POOL: IO, Item:0x3c15f1c0, H:0x3c15f0c4, TAG:io_embed_flash
I (1035) ESP_GMF_POOL: EL, Item:0x3c15f2f8, H:0x3c15f1d0, TAG:aud_dec
I (1041) ESP_GMF_POOL: EL, Item:0x3c15f3fc, H:0x3c15f308, TAG:aud_alc
I (1047) ESP_GMF_POOL: EL, Item:0x3c15f4e4, H:0x3c15f40c, TAG:aud_ch_cvt
I (1054) ESP_GMF_POOL: EL, Item:0x3c15f5c8, H:0x3c15f4f4, TAG:aud_bit_cvt
I (1060) ESP_GMF_POOL: EL, Item:0x3c15f6b4, H:0x3c15f5d8, TAG:aud_rate_cvt
I (1067) PLAY_EMBED_MUSIC: [ 3 ] Create audio pipeline
I (1072) PLAY_EMBED_MUSIC: [ 3.1 ] Set audio url to play
I (1077) PLAY_EMBED_MUSIC: [ 3.2 ] Create gmf task, bind task to pipeline and load linked element jobs to the bind task
I (1087) ESP_GMF_TASK: Waiting to run... [tsk:pipe_embed-0x3fcebadc, wk:0x0, run:0]
I (1095) ESP_GMF_TASK: Waiting to run... [tsk:pipe_embed-0x3fcebadc, wk:0x3c15ff04, run:0]
I (1102) PLAY_EMBED_MUSIC: [ 3.3 ] Create envent group and listening event from pipeline
I (1110) PLAY_EMBED_MUSIC: [ 4 ] Start audio_pipeline
I (1115) ESP_GMF_EMBED_FLASH: The read item is 1, embed://tone/1
I (1121) PLAY_EMBED_MUSIC: CB: RECV Pipeline EVT: el: NULL-0x3c15f6c4, type: 2000, sub: ESP_GMF_EVENT_STATE_OPENING, payload: 0x0, size: 0, 0x3fcecdd4
I (1134) ESP_GMF_TASK: One times job is complete, del[wk:0x3c15ff04, ctx:0x3c15f708, label:aud_dec_open]
I (1143) ESP_GMF_PORT: ACQ IN, new self payload:0x3c15ff04, port:0x3c15fd34, el:0x3c15f708-aud_dec
I (1152) ESP_ES_PARSER: The verion of es_parser is v1.0.0
W (1158) ESP_GMF_ASMP_DEC: Not enough memory for out, need:2304, old: 1024, new: 2304
I (1166) ESP_GMF_TASK: One times job is complete, del[wk:0x3c15ffb0, ctx:0x3c15f830, label:aud_bit_cvt_open]
I (1174) ESP_GMF_TASK: One times job is complete, del[wk:0x3c160b14, ctx:0x3c15f984, label:aud_rate_cvt_open]
I (1184) PLAY_EMBED_MUSIC: CB: RECV Pipeline EVT: el: aud_ch_cvt-0x3c15fae0, type: 3000, sub: ESP_GMF_EVENT_STATE_INITIALIZED, payload: 0x3fceca20, size: 16, 0x3fcecdd4
I (1198) PLAY_EMBED_MUSIC: CB: RECV Pipeline EVT: el: aud_ch_cvt-0x3c15fae0, type: 2000, sub: ESP_GMF_EVENT_STATE_RUNNING, payload: 0x0, size: 0, 0x3fcecdd4
I (1212) ESP_GMF_TASK: One times job is complete, del[wk:0x3c15ffb0, ctx:0x3c15fae0, label:aud_ch_cvt_open]
I (1223) PLAY_EMBED_MUSIC: [ 5 ] Wait stop event to the pipeline and stop all the pipeline
W (23329) ESP_GMF_EMBED_FLASH: No more data, ret:0, pos: 231725/231725
I (23329) ESP_GMF_TASK: Job is done, [tsk:pipe_embed-0x3fcebadc, wk:0x3c15ff40, job:0x3c15f708-aud_dec_proc]
I (23333) ESP_GMF_TASK: Job is done, [tsk:pipe_embed-0x3fcebadc, wk:0x3c15ffd8, job:0x3c15f830-aud_bit_cvt_proc]
I (23343) ESP_GMF_TASK: Job is done, [tsk:pipe_embed-0x3fcebadc, wk:0x3c160b54, job:0x3c15f984-aud_rate_cvt_proc]
I (23353) ESP_GMF_TASK: Job is done, [tsk:pipe_embed-0x3fcebadc, wk:0x3c160b94, job:0x3c15fae0-aud_ch_cvt_proc]
I (23363) ESP_GMF_TASK: Finish, strategy action: 0, [tsk:0x3fcebadc-pipe_embed]
I (23370) ESP_GMF_EMBED_FLASH: Closed, pos: 231725/231725
I (23375) ESP_GMF_CODEC_DEV: CLose, 0x3c15fd74, pos = 3903364/0
I (23381) ESP_GMF_TASK: One times job is complete, del[wk:0x3c15ffd8, ctx:0x3c15f708, label:aud_dec_close]
I (23390) ESP_GMF_TASK: One times job is complete, del[wk:0x3c15ff3c, ctx:0x3c15f830, label:aud_bit_cvt_close]
I (23400) ESP_GMF_TASK: One times job is complete, del[wk:0x3c160b04, ctx:0x3c15f984, label:aud_rate_cvt_close]
I (23410) ESP_GMF_TASK: One times job is complete, del[wk:0x3c160b2c, ctx:0x3c15fae0, label:aud_ch_cvt_close]
I (23419) PLAY_EMBED_MUSIC: CB: RECV Pipeline EVT: el: NULL-0x3c15f6c4, type: 2000, sub: ESP_GMF_EVENT_STATE_FINISHED, payload: 0x0, size: 0, 0x3fcecdd4
I (23433) ESP_GMF_TASK: Waiting to run... [tsk:pipe_embed-0x3fcebadc, wk:0x0, run:0]
I (23440) ESP_GMF_TASK: Waiting to run... [tsk:pipe_embed-0x3fcebadc, wk:0x0, run:0]
I (23448) PLAY_EMBED_MUSIC: [ 6 ] Destroy all the resources
W (23453) GMF_SETUP_AUD_CODEC: Unregistering default decoder
I (23464) BOARD_DEVICE: Deinit device audio_dac ref_count: 0 device_handle:0x3fce9a7c
I (23471) BOARD_DEVICE: Device audio_dac config found: 0x3c11f6b4 (size: 92)
I (23473) BOARD_PERIPH: Deinit peripheral i2s_audio_out ref_count: 0
E (23479) i2s_common: i2s_channel_disable(1262): the channel has not been enabled yet
W (23486) PERIPH_I2S: Caution: Releasing TX (0x0).
W (23491) PERIPH_I2S: Caution: RX (0x3c15e914) forced to stop.
E (23496) i2s_common: i2s_channel_disable(1262): the channel has not been enabled yet
I (23504) BOARD_PERIPH: Deinit peripheral i2c_master ref_count: 0
I (23510) PERIPH_I2C: I2C master bus deinitialized successfully
I (23515) BOARD_MANAGER: Device audio_dac deinitialized
I (23520) PLAY_EMBED_MUSIC: Func:app_main, Line:151, MEM Total:7253236 Bytes, Inter:334379 Bytes, Dram:334379 Bytes
I (23531) main_task: Returned from app_main()
```
## Troubleshooting
### Audio file not found or cannot play
- Ensure you have run `mk_flash_embed_tone.py` to generate `esp_embed_tone.h` and `esp_embed_tone.cmake`, and that the required audio files (e.g. `ff-16b-1c-44100hz.mp3`, `alarm.mp3`) are present in the `main` directory.
## Technical Support
For technical support, use the links below:
- Technical support: [esp32.com](https://esp32.com/viewforum.php?f=20) forum
- Issue reports and feature requests: [GitHub issue](https://github.com/espressif/esp-gmf/issues)
We will reply as soon as possible.
To create a project from this example, run:
idf.py create-project-from-example "espressif/gmf_examples=0.8.0:pipeline_play_embed_music"