Real-time Equalizer
Relevant source files
The following files were used as context for generating this wiki page:
The Real-time Equalizer (EQ) is a core feature of the BT Speaker Studio project, designed to provide users with fine-grained control over audio frequencies. It operates within a distributed architecture where a mobile companion app acts as the control interface, and a Raspberry Pi Zero 2 W acts as the execution and display hub. The system allows for the adjustment of specific frequency bands—bass, mid, and treble—in real-time during audio playback.
The EQ system relies on the shared bt_speaker_core package for data modeling and uses a WebSocket-based communication protocol to synchronize settings between the mobile client and the hardware server. This ensures that changes made on the phone app are immediately reflected in the audio processing and visual feedback on the Pi's HDMI display.
Sources: README.md:1-12, CLAUDE.md:8-13
System Architecture and Data Flow
The Real-time Equalizer follows a unidirectional data flow pattern (in Phase 1) where the phone_app sends configuration updates to the pi_app. The pi_app runs a WebSocket server on port 8080 to receive these updates.
Architecture Overview
The architecture involves three primary components:
- Mobile Client (
phone_app): Provides the UI for adjusting EQ sliders. - Shared Core (
bt_speaker_core): Defines theEqSettingsmodel used by both applications. - Hardware Host (
pi_app): Manages theEqBlocto maintain state and apply settings.
The following diagram illustrates the flow of EQ commands from the user interface to the hardware state management:
Sources: CLAUDE.md:27-32, README.md:21-36
Data Models and Communication
The equalizer utilizes the EqSettings model defined in the bt_speaker_core package. This model is responsible for serializing and deserializing the frequency band values to ensure consistency across the WebSocket bridge.
EqSettings Model
The settings are categorized into three primary frequency ranges. While the specific numerical ranges (dB) are implementation-dependent in the UI, the core data structure maintains these as typed fields.
| Band | Description | Data Type |
|---|---|---|
| Bass | Low-frequency audio adjustments | Double / Numeric |
| Mid | Mid-range frequency audio adjustments | Double / Numeric |
| Treble | High-frequency audio adjustments | Double / Numeric |
Sources: README.md:38-44, CLAUDE.md:11-13
Protocol Specification
EQ updates are sent as JSON objects over WebSocket. These messages are keyed with a type field set to eq to distinguish them from other telemetry or command data such as beat or led.
{
"type": "eq",
"bass": 0.5,
"mid": 0.8,
"treble": 0.3
}
Sources: CLAUDE.md:29-31, README.md:26-30
State Management
The pi_app utilizes the flutter_bloc library to manage the state of the equalizer. The EqBloc is the central component that handles incoming equalizer events and provides the current EQ state to the user interface.
EqBloc Functionality
The EqBloc follows the BLoC-per-feature pattern adopted by the project. It subscribes to the shared WebSocket event stream. When a message of type eq is received, the Pi app parses it into an EqEvent, which is then processed by the EqBloc to update the EqSettings state.
Sources: CLAUDE.md:34-40, README.md:31-40
Interaction with Audio Pipeline
In the broader context of the project, the equalizer settings are intended to influence the audio output and the visualizer. The project uses a Python-based FFT daemon to process audio signals via ALSA loopback.
Frequency Processing
The fft_daemon.py script identifies frequency bins that correspond to the EQ bands. It uses log-spaced frequency bin edges ranging from 60 Hz to 16 kHz to calculate spectrum data, which is then divided into 16 bars for visualization.
# Log-spaced frequency bin edges from 60 Hz to 16 kHz
_FREQ_EDGES = np.logspace(np.log10(60), np.log10(16_000), NUM_BARS + 1)
Sources: apps/pi_app/fft_daemon.py:16-17, README.md:46-51
Project Integration
The Real-time Equalizer is integrated into the Melos-managed monorepo. The phone_app and pi_app both depend on the bt_speaker_core package to access the EQ data structures.
| Package | Role in EQ Feature | Dependency |
|---|---|---|
apps/phone_app | Client UI for EQ control | bt_speaker_core (path) |
apps/pi_app | Server and State Manager | bt_speaker_core (path) |
packages/bt_speaker_core | Shared Models (EqSettings) | N/A |
Sources: apps/phone_app/pubspec.yaml:45-47, apps/pi_app/pubspec.yaml:34-36, pubspec.yaml:8-11
Conclusion
The Real-time Equalizer provides a critical bridge between user preference on the mobile app and high-performance audio visualization on the Raspberry Pi. By utilizing a shared core package and a structured BLoC pattern, the system maintains synchronized state across the network, enabling seamless audio adjustments in an embedded environment.