A real-time audio processing platform for ESP32 using high-quality audio codecs with a professional 5-band parametric equalizer.
- DAC: PCM5102A - 32-bit 384kHz Stereo DAC (Master Clock Generator)
- ADC: WM8782 - 24-bit 192kHz Stereo ADC
- MCU: ESP32-C3 or any ESP32 variant with I2S support
- ✅ Shared I2S Clock Domain - Single I2S peripheral for both input and output
- ✅ Master Clock (MCLK) - 18.432MHz for jitter-free audio (384x sample rate)
- ✅ 24-bit audio at 48kHz sample rate (configurable)
- ✅ Low-latency audio pass-through (~80ms)
- ✅ 5-Band Parametric Equalizer (60Hz, 250Hz, 1kHz, 4kHz, 12kHz)
- ✅ WiFi Connectivity - Remote control via WiFi network
- ✅ MQTT Integration - Control all processors via MQTT protocol
- ✅ Real-time Serial Command Interface for local control
- ✅ Persistent Settings - All settings saved to NVS flash
- ✅ Built-in EQ presets (Flat, Bass, Vocal, Rock, Jazz)
- ✅ Subsonic Filter - DC blocking and subsonic protection
- ✅ Pre-Gain - Adjustable gain stage before EQ
- ✅ True-Peak Limiter - Clipping protection
- ✅ FreeRTOS-based real-time processing
- ✅ Optimized fixed-point biquad IIR filters (Direct Form II Transposed)
- ✅ Modular architecture for easy DSP algorithm integration
-
Hardware Setup: Wire ESP32 to WM8782 and PCM5102A with shared clocks
- See Hardware Setup Guide
- Important: MCLK connects to WM8782 for synchronization
-
Build & Flash:
idf.py -p COM3 build flash monitor- See Build Instructions for details
-
Connect Audio:
- Input: Connect audio source to WM8782
- Output: Connect headphones/speakers to PCM5102A
-
Test: You should hear input audio with EQ processing applied
- Default: Bass boost preset active
- Latency: ~80ms
-
Control via Serial or MQTT:
- Serial: Use serial commands to adjust all processors
- MQTT: Configure WiFi and MQTT for remote control
- See Serial Commands Guide
- See WiFi & MQTT Setup Guide
esp-dsp/
├── main/
│ ├── esp-dsp.cpp # Main application and audio processing task
│ ├── audio_config.h # Audio configuration and pin definitions
│ ├── subsonic.cpp/.h # Subsonic filter / DC blocking
│ ├── pregain.cpp/.h # Pre-gain processor
│ ├── equalizer.cpp/.h # 5-band parametric equalizer
│ ├── limiter.cpp/.h # True-peak limiter
│ ├── wifi_manager.cpp/.h # WiFi connectivity manager
│ ├── mqtt_manager.cpp/.h # MQTT client and topic handling
│ ├── serial_commands.cpp/.h # Serial command interface
│ ├── CMakeLists.txt # Component build configuration
│ └── Kconfig.projbuild # menuconfig options
├── docs/
│ ├── HARDWARE_SETUP.md # Wiring and hardware guide
│ ├── BUILD_INSTRUCTIONS.md # Detailed build instructions
│ ├── WIFI_MQTT_SETUP.md # WiFi and MQTT configuration guide
│ ├── EQUALIZER.md # Equalizer documentation and presets
│ ├── SERIAL_COMMANDS.md # Serial command reference
│ ├── PERSISTENT_SETTINGS.md # NVS flash storage documentation
│ ├── ADDING_EFFECTS.md # Guide for adding custom DSP effects
│ ├── TROUBLESHOOTING.md # Common issues and solutions
│ └── PROJECT_OVERVIEW.md # Architecture and technical details
├── CMakeLists.txt # Top-level CMake configuration
├── sdkconfig.defaults # Default ESP-IDF configuration
├── QUICK_START.md # Quick start guide
└── README.md
Edit main/audio_config.h to match your hardware:
// Shared I2S pins (both ADC and DAC use same clock domain)
#define I2S_MCLK GPIO_NUM_10 // Master clock (18.432MHz @ 48kHz)
#define I2S_DAC_BCLK GPIO_NUM_5 // Bit clock (shared)
#define I2S_DAC_WS GPIO_NUM_6 // Word select (shared)
// DAC (PCM5102A) - Data output
#define I2S_DAC_DOUT GPIO_NUM_7 // Audio data to DAC
// ADC (WM8782) - Data input
#define I2S_ADC_DIN GPIO_NUM_4 // Audio data from ADCNote: Both ADC and DAC share BCLK, WS, and MCLK for perfect synchronization.
Change sample rate in main/audio_config.h:
#define SAMPLE_RATE 48000 // Recommended: 48000 HzAdjust for latency/stability trade-off:
#define DMA_BUFFER_SIZE 480 // Samples per buffer
#define DMA_BUFFER_COUNT 8 // Number of DMA buffersThe system includes a professional 5-band parametric equalizer with persistent settings saved to flash memory.
Control the equalizer in real-time without recompiling:
> eq show # Display current settings
> eq set 0 6.0 # Set 60Hz band to +6dB
> eq preset bass # Load bass boost preset
> eq enable # Enable equalizer
> eq disable # Bypass equalizer
See Serial Commands Guide for complete command reference.
All EQ settings are automatically saved to NVS flash and restored on every boot:
- No need to manually save
- Settings survive power cycles
- See Persistent Settings Guide
Five professionally tuned presets available:
- flat - Neutral reference (all bands at 0dB)
- bass - Enhanced low-end for electronic music
- vocal - Optimized for speech clarity
- rock - V-shaped curve (boosted bass and treble)
- jazz - Natural with slight warmth
Load a preset:
> eq preset bass
See Equalizer Guide for detailed preset specifications.
- Sample Rate: 48 kHz (configurable)
- Bit Depth: 24-bit audio processing
- Latency: ~80ms (configurable via buffer size)
- Equalizer Bands: 5 (60Hz, 250Hz, 1kHz, 4kHz, 12kHz)
- Gain Range: -12dB to +12dB per band
- Filter Type: Biquad peaking (Q=0.707 Butterworth)
- Implementation: Fixed-point Direct Form II Transposed
- Clock Architecture: Shared I2S clock domain with MCLK (18.432MHz)
To add additional DSP effects beyond the equalizer:
- Open
main/esp-dsp.cpp - Find the
audio_task()function - Add your DSP code after the equalizer processing:
// Read from ADC
i2s_channel_read(rx_handle, audio_buffer, sizeof(audio_buffer), &bytes_read, portMAX_DELAY);
// Shift samples for 24-bit processing
for(int i = 0; i < num_samples; i++) {
audio_buffer[i] = audio_buffer[i] >> 8;
}
// Process through equalizer
equalizer_process(&equalizer, audio_buffer, num_samples);
// Add your custom processing here:
// Example: Simple volume control
for (int i = 0; i < num_samples; i++) {
audio_buffer[i] = (audio_buffer[i] * volume) >> 8;
}
// Shift back for output
for(int i = 0; i < num_samples; i++) {
audio_buffer[i] = audio_buffer[i] << 8;
}
// Write to DAC
i2s_channel_write(tx_handle, audio_buffer, bytes_read, &bytes_written, portMAX_DELAY);See Adding Effects Guide for more examples (delay, reverb, compression, etc.)
- Latency: ~80ms at 48kHz with 480 sample buffers (8 buffers)
- CPU Usage: ~5-10% with equalizer enabled
- Sample Rate: Optimized for 48kHz (hardware supports up to 192kHz)
- Memory: ~156KB free heap during operation
This project is provided as-is for educational and development purposes.
Feel free to open issues or submit pull requests for improvements!