A focused Tauri v1 essential showing how live microphone audio can drive raw WebGL graphics without a native Rust audio dependency.
The example captures one microphone through the Web Audio API, calculates a live FFT and waveform, uploads both arrays to the GPU as textures, and supplies reduced frequency bands to a GLSL ES fragment shader.
MediaStreamAudioSourceNode, GainNode, and AnalyserNodeMicrophone
│
▼
MediaStreamAudioSourceNode
│
▼
GainNode ── input gain
│
▼
AnalyserNode
├── getByteFrequencyData() ──► FFT texture ───────┐
├── getByteTimeDomainData() ─► waveform texture ─┤
└── band reduction ──────────► GLSL uniforms ────┤
▼
WebGL fragment shader
│
▼
ping-pong feedback buffers
│
▼
display
The analyser is not connected to AudioContext.destination. The microphone is measured but not monitored through the speakers, which avoids immediate acoustic feedback.
| Value | Frequency range | Primary use |
|---|---|---|
| Sub | 20–60 Hz | Deep kick and low-frequency movement |
| Bass | 60–250 Hz | Beat detection and large-scale deformation |
| Mid | 250–2,000 Hz | Structural movement and visual density |
| High | 2,000–8,000 Hz | Fine detail and brightness |
| Air | 8,000 Hz–Nyquist | Texture, noise, and upper-frequency shimmer |
| RMS | Time-domain energy | Overall loudness response |
| Beat | Adaptive low-band transient | Short visual impulse |
Band values are normalized, multiplied by Sensitivity, then independently smoothed with Band attack and Band release.
All five modes receive the same full spectrum texture, waveform texture, scalar band values, RMS energy, and beat pulse.
13-tauri-v1-audio-reactive-fft/
├── README.md
├── package.json
├── src/
│ ├── index.html controls, meters, monitors, and WebGL stage
│ ├── styles.css fixed-width controls and responsive layout
│ └── app.js Web Audio analysis, beat detection, WebGL renderer
└── src-tauri/
├── Cargo.toml
├── build.rs
├── tauri.conf.json
├── Info.plist macOS microphone usage explanation
├── entitlements.plist
├── icons/
└── src/main.rs
npm install
npm run dev
Press Start microphone. The operating system may ask for microphone permission the first time.
For music playing through speakers in the room:
FFT size 2048
Analyser smooth 0.72
Input gain 1.00×
Sensitivity 1.35×
Band attack 0.62
Band release 0.055
Beat threshold 1.32×
Beat cooldown 180 ms
For a direct, clean source close to the microphone, reduce Sensitivity. For quiet ambient sound, increase Input gain gradually before increasing sensitivity.
| FFT size | Frequency detail | Time response | Frequency bins |
|---|---|---|---|
| 512 | Low | Fastest | 256 |
| 1,024 | Moderate | Fast | 512 |
| 2,048 | Balanced | Balanced | 1,024 |
| 4,096 | High | Slower | 2,048 |
| 8,192 | Highest | Slowest | 4,096 |
A larger FFT does not simply make the visual “better.” It improves frequency resolution while increasing analysis latency and softening fast transients.
Tauri v1 merges src-tauri/Info.plist into the generated macOS application metadata. This example defines NSMicrophoneUsageDescription there and includes the com.apple.security.device.audio-input entitlement for packaged builds.
When permission was denied previously:
During development, macOS may associate permission with the generated debug application or the terminal that launched it. A clean rebuild can occasionally cause the operating system to ask again.
Grant microphone access in the operating-system privacy settings, quit the application completely, and rerun it.
That is intentional. This example analyses the microphone without routing it to the output device.
Increase Threshold, increase Cooldown, or lower Sensitivity.
Lower Threshold slightly, raise Sensitivity, or reduce Analyser smooth so transients remain sharper.
Use a smaller FFT size and raise Band attack. A very large FFT and high analyser smoothing both increase perceived latency.
Press the refresh button, select the desired device again, or stop and restart microphone input. Some operating systems expose a changed device only after the old stream is released.
MediaElementAudioSourceNodeMIT.