A MP3 player built in C for Raspberry Pi Zero 2W with the Waveshare 1.3" LCD HAT and InnoMaker/HiFiBerry-compatible I2S DAC.
- Raspberry Pi Zero 2W (or compatible)
- Waveshare 1.3" 240x240 IPS LCD HAT
- InnoMaker DAC Mini HAT (PCM5122) or HiFiBerry DAC+ compatible
- MicroSD card with Raspberry Pi OS
sudo apt-get update
sudo apt-get install -y build-essential cmake mpv gitNote: WiringPi is required for GPIO control and SPI communication with the LCD display and is included as a git submodule.
mp3_pi_player/
├── scripts/ # Build and utility scripts
│ ├── setup.sh # One-time project setup
│ ├── build.sh # Multi-build system
│ ├── clean.sh # Smart cleaning utility
│ ├── run.sh # Run different build types
│ └── dev.sh # Quick dev cycle (build+run)
├── src/ # Main application source
└── external/ # External dependencies (git submodules)
├── 1.3-inch-LCD-HAT/ # Waveshare LCD driver library
└── WiringPi/ # GPIO library
The LCD HAT and I2S audio DAC share GPIO pins, which creates a conflict:
I2S Audio Pins (used by DAC):
- GPIO 18 (Pin 12) - PCM_CLK - I2S Bit Clock
- GPIO 19 (Pin 35) - PCM_FS - I2S Frame Sync
- GPIO 20 (Pin 38) - PCM_DIN - I2S Data In
- GPIO 21 (Pin 40) - PCM_DOUT - I2S Data Out
LCD HAT Button Pins (conflicting):
- GPIO 19 - KEY_DOWN button
- GPIO 20 - KEY2 button
- GPIO 21 - KEY1 button
Available (non-conflicting) buttons:
- GPIO 6 - KEY_UP
- GPIO 5 - KEY_LEFT
- GPIO 26 - KEY_RIGHT
- GPIO 13 - KEY_PRESS
- GPIO 16 - KEY3
The code permanently disables GPIO 19, 20, 21 as button inputs in the external LCD library to preserve I2S audio functionality. These pins are never initialized, leaving them in ALT0 mode for audio.
Trade-off: You lose 3 buttons (KEY_DOWN, KEY1, KEY2) but maintain full audio functionality.
Edit the boot config:
sudo nano /boot/firmware/config.txtAdd/modify these settings:
# Audio Configuration - CRITICAL SETTINGS
dtoverlay=hifiberry-dacplus,slave
dtparam=audio=off
dtparam=spi=on
# Display
dtoverlay=vc4-kms-v3d
max_framebuffers=2
# Other settings
camera_auto_detect=1
display_auto_detect=1
auto_initramfs=1
disable_fw_kms_setup=1
arm_64bit=1
disable_overscan=1
arm_boost=1
[cm4]
otg_mode=1
[cm5]
dtoverlay=dwc2,dr_mode=host
[all]Key Audio Settings Explained:
dtoverlay=hifiberry-dacplus,slave- Uses HiFiBerry driver with I2S in slave mode (Pi is master)dtparam=audio=off- CRITICAL: Disables built-in audio to prevent I2S conflicts- The
,slaveparameter was the final fix for correct audio playback speed/pitch
If these files exist, they contain outdated parameters that cause issues:
# Backup and remove if they exist
sudo mv /etc/modprobe.d/bcm2835-i2s.conf /etc/modprobe.d/bcm2835-i2s.conf.bak 2>/dev/null
sudo mv /etc/modprobe.d/bcm2835.conf /etc/modprobe.d/bcm2835.conf.bak 2>/dev/nullThese files contained obsolete force_slave=1 parameters that are no longer supported in modern kernels.
sudo rebootAfter reboot, verify audio is working:
# Check audio devices
aplay -l
# Test audio output
speaker-test -D hw:1,0 -c 2 -r 48000
# Test with MPV
mpv --no-video --ao=alsa --audio-device=alsa:hw=1,0 ~/Music/test.mp3You should see:
card 1: sndrpihifiberry [snd_rpi_hifiberry_dacplus], device 0: ...
# 1. Clone repository
cd ~/Documents/projects
git clone <your-repo-url> mp3_pi_player
cd mp3_pi_player
# 2. Run setup script (one-time)
./scripts/setup.sh
# 3. Add music
cp ~/path/to/music/*.mp3 ~/Music/
# 4. Build and run
./scripts/build.sh
./scripts/run.shIf you prefer manual setup:
# 1. Clone with submodules
git clone --recursive <your-repo-url> mp3_pi_player
cd mp3_pi_player
# 2. Install dependencies
sudo apt-get update
sudo apt-get install -y build-essential cmake mpv git
# 3. Build WiringPi
cd external/WiringPi
./build
cd ../..
# 4. Create directories
mkdir -p bin ~/Music
# 5. Make scripts executable
chmod +x scripts/*.sh
# 6. Build project
./scripts/build.sh
# 7. Run
./scripts/run.shInitializes the project after cloning. Run this once after cloning the repository.
Build Types:
| Type | Flag |
|---|---|
| Release | |
| Debug | -D |
| RelWithDebInfo | -W |
Options:
-D, --debug- Debug build (no optimization, full symbols, verbose logging)-W, --with-debug- RelWithDebInfo (optimized with debug symbols)-R, --release- Release build (explicit, usually not needed)-c, --clean- Clean before building-m, --makefile- Use Makefile instead of CMake-v, --verbose- Show detailed build output-l, --list- List all available builds-h, --help- Show help message
Options:
-a, --all- Clean all builds (release, debug, relwithdebinfo)-r, --release- Clean release build only-d, --debug- Clean debug build only-w, --relwithdebinfo- Clean relwithdebinfo build only-c, --cmake- Clean stray CMake files from project root-y, --yes- Skip confirmation prompts (batch mode)-h, --help- Show help message
Options:
-D, --debug- Run debug build-W, --with-debug- Run relwithdebinfo build-h, --help- Show help message,- Run Release when no arguments
Music Browser:
- UP (GPIO 6) - Open Menu
- LEFT (GPIO 5) - Select Previous song
- RIGHT (GPIO 26) - Select Next Song
- PRESS (GPIO 13) - Play/pause toggle
- KEY3 (GPIO 16) - Play selected song
Music Player:
- Large PLAY/STOP button appears on screen (press center button)
- PRESS (GPIO 13) - Toggle play/pause
- UP (GPIO 6) - Next song (auto-advances when song finishes)
- RIGHT (GPIO 26) - Fast-forward (hold button)
- KEY3 (GPIO 16) - Return to browser or exit
Cause: I2S clock misconfiguration
Solution: Ensure /boot/firmware/config.txt has:
dtoverlay=hifiberry-dacplus,slave
dtparam=audio=offThe ,slave parameter is critical - it configures the I2S interface correctly.
Cause: Audio overlay not loading or conflicting with built-in audio
Solutions:
- Verify
dtparam=audio=offin config.txt - Check
dmesg | grep -i "hifiberry\|pcm512x"for errors - Verify overlay loaded:
aplay -lshould show card 1
Fixed - Integer underflow when drawing images to the screen (or simply exceeding it's length).
Expected: GPIO 19, 20, 21 buttons (KEY_DOWN, KEY1, KEY2) are intentionally disabled for audio compatibility.
Available buttons: KEY_UP (6), KEY_LEFT (5), KEY_RIGHT (26), KEY_PRESS (13), KEY3 (16)
- Waveshare for the 1.3" LCD HAT hardware and demo code
- WiringPi library for GPIO control
- HiFiBerry for device tree overlay compatibility
Based on Waveshare demo code. Modifications for audio integration and MP3 player functionality.