Inspiration
Sound is made of layers — bass, mids, highs, air — yet most audio tools treat it as a single undivided signal. We wanted to build something that lets anyone visually explore and physically separate those layers, making the invisible structure of audio tangible.
What it does
FourierWaveAnalyser is a Flutter mobile app that decomposes any WAV audio file into its constituent frequency bands using FFT. Upload a WAV, and the app splits it into five bands — Sub-bass (0–300 Hz), Bass (300–400 Hz), Mids (400–500 Hz), Highs (500–600 Hz), and Air (600–10000 Hz) — each exported as a standalone WAV file. Users can preview each band directly in-app, select bands to merge back together, and manage multiple tracks in a session with adjustable time offsets for layering. A real-time spectrum visualizer shows the frequency content of the loaded file.
How we built it
The core is a hand-rolled radix-2 Cooley-Tukey FFT implemented in pure Dart — no external signal processing library. Band separation uses an overlap-add method with a Hann window (4096-point FFT, 1024-sample hop) applied as a bandpass filter in the frequency domain. The inverse FFT reconstructs filtered audio, which is then encoded as 16-bit PCM WAV entirely on-device. The UI is built in Flutter with custom CustomPainter widgets for the spectrum and spectrogram visualizations. Audio preview is handled via just_audio, and the session system allows saving extracted bands and merging them with sample-accurate offsets.
Challenges we ran into
Implementing the FFT and inverse FFT from scratch in Dart required careful attention to bit-reversal permutation and twiddle factor computation. Getting the overlap-add reconstruction artifact-free took several iterations of windowing. On the Android build side, we hit a significant compatibility issue where a stale GeneratedPluginRegistrant.java from an older version of file_picker conflicted with the newer v11 API, requiring us to downgrade the Android Gradle Plugin to resolve dependency resolution failures across all plugins.
Accomplishments that we're proud of
The entire signal processing pipeline — FFT, bandpass filtering, IFFT, WAV encoding and decoding — is written in pure Dart with no native code or external DSP library. All processing happens fully on-device with no data leaving the phone. The session mixer with per-track time offsets allows basic multitrack-style composition from extracted bands.
What we learned
Implementing FFT from scratch deepened our understanding of the Cooley-Tukey algorithm, the importance of windowing to reduce spectral leakage, and the overlap-add method for block-based filtering. We also learned a lot about Flutter's cross-platform build system, particularly the friction points between Android Gradle Plugin versions and pub package plugin metadata.
Log in or sign up for Devpost to join the conversation.