Auditor's Guide
This document is the entry point for a code, security, or technical due-diligence review of Buffle Audio Visualize. It states the scope, provenance, dependencies, security posture, real-time characteristics, and validation methodology, and points to where each claim can be verified in the source.
Everything here is meant to be checkable. Where a claim can be reproduced with a command, the command is given.
1. What this software is (and is not)
- It is an analysis-only audio plugin (VST3 + macOS Standalone). It visualizes audio; it does not modify it.
- The audio output is a bit-for-bit pass-through of
the input with zero added latency. Verify in
WaveformVisualizer/Source/PluginProcessor.cpp→processBlock(samples are read by the engines, never written), andgetTailLengthSeconds()returns0. - There are no sound-altering parameters.
2. Provenance & reproducibility
- First-party source:
WaveformVisualizer/Source/(~7,700 lines of C++ across 26 files),Installer/build_installer.sh, and the documentation. Licensed MIT. - Framework dependency: JUCE 8.0.7, vendored at
./JUCE(not authored here). - The build is deterministic given the pinned JUCE tree; no packages are fetched at build time. Reproduce with the commands in the README (Building from source).
- Version is single-sourced in
WaveformVisualizer/Source/PluginVersion.hand mirrored in the.jucer; the installer reads it from the header.
3. Dependencies & licensing
| Component | Version | Role | License |
|---|---|---|---|
| This project | 4.0.1 | Plugin source, installer, docs | MIT (see LICENSE) |
| JUCE | 8.0.7 | Application/audio framework | Dual: JUCE personal/commercial or AGPLv3 |
Licensing note for the auditor: the project's own
code is MIT, but it links JUCE, which is dual-licensed. Any party
building or redistributing binaries must satisfy the
JUCE license terms that apply to them (JUCE's own personal/ commercial
terms, or AGPLv3). This is a compliance item for the distributor, not a
defect in the source. See THIRD_PARTY_NOTICES.md. No other
third-party code is vendored in
WaveformVisualizer/Source/.
4. Security posture
| Concern | Status | How to verify |
|---|---|---|
| Network access | None | grep -rniE "URL|Socket|http|WebBrowser|curl" WaveformVisualizer/Source/
→ no matches |
| Telemetry / analytics | None | Same as above; no analytics SDKs are linked |
| Data collection | None | No user data is read, stored, or transmitted |
| Filesystem writes | User-initiated only | Only the HTML mix report, to a path the user picks via a save dialog
(TimelineComponent::exportReport) |
| Filesystem reads | User-initiated only | Only a reference audio file the user picks
(SpectrumComponent::chooseReferenceFile) |
| Process launch | The exported report only | File::startAsProcess() opens the report the user just
saved |
| Credential / secret handling | None | No secrets in the repo; nothing is entered or stored |
| Plugin state persistence | Settings only, in-project | getStateInformation / setStateInformation
(de)serialize a juce::ValueTree — UI/analysis settings
(waveform window, vectorscope view, spectrum averaging/hold, Translation
Lens, Masking Radar toggle) and the tone-match reference library. No
audio, no filesystem paths beyond what the DAW itself already persists,
no network — the data lives entirely inside the host's own project
file. |
| Cross-instance data sharing (v4.0.0+) | In-process only, metrics only | InstanceRegistry.h uses
juce::SharedResourcePointer so instances loaded in the same
OS process can read each other's name and metrics (LUFS/true
peak/correlation) for the session panel. No shared memory, sockets, or
files — it is a plain C++ object shared within one process's address
space, and it holds no audio and no user data beyond those three numbers
and a display name. |
| Code signing | Ad-hoc / unsigned | The installer is not Developer-ID signed or notarized |
Net: the plugin's only I/O beyond audio is two explicit, user-driven file operations. It does not phone home.
5. Real-time safety
Audio plugins must avoid unbounded work, blocking, and allocation on the audio thread. This project's characteristics are described honestly in ARCHITECTURE.md § Threading & synchronization model. Summary for the reviewer:
- Engine buffers are pre-sized in
prepare(); the steady-state spectrum, loudness, and band-split paths do not allocate. - The audio path takes short, bounded critical sections (not lock-free) to publish arrays to the GUI. This is a deliberate, conventional trade-off.
- Two bounded, amortized allocations remain (vectorscope point vector and loudness gating-block history) and are explicitly capped.
- The 4096-point FFT runs on the audio thread within a critical section on each 75 %-overlap hop — bounded O(n log n), not deferred.
None of these are defects; they are the points a real-time reviewer should weigh, and they are surfaced deliberately.
6. Validation methodology
Every release is validated with:
pluginval at strictness level 10 — the strictest setting. It open/closes the editor repeatedly, processes audio across sample rates (44.1–96 kHz) and block sizes (64–1024), enumerates and toggles bus layouts, round-trips plugin state, and fuzzes parameters. Every release since v3.0.0, including the current v4.0.1, returns
SUCCESS.pluginval --strictness-level 10 --validate \ ~/Library/Audio/Plug-Ins/VST3/buffleaudio_visualize.vst3Standalone launch smoke test — the app is launched, confirmed alive for several seconds, checked for crash reports, and quit cleanly.
Clean Release build — zero compiler warnings in first-party source (JUCE's own SDK warnings are out of scope).
There is not yet an automated unit-test suite; validation relies on pluginval's behavioral coverage plus the smoke test. Adding first-party unit tests for the DSP (e.g. LUFS against reference tones, K-weighting coefficients, true-peak on known signals) is a recommended next step and is noted in the roadmap.
7. Suggested review path
PluginProcessor.cpp— confirm the audio pass-through and engine wiring.- The four engines (
*Analyzer.{h,cpp},WaveformBuffer.{h,cpp}) — DSP and the atomic/lock publication pattern. PluginEditor.{h,cpp}— the 10 Hz health/recorder tick and the metric snapshot.HealthMonitor.h,SessionRecorder.h,TimelineComponent.cpp— message-thread logic; noteSessionRecorder::exportReportbuilds HTML by string concatenation (report content is derived from numeric metrics, not user free-text).SpectrumComponent.cpp— the largest file; references, Translation Lens, and Masking Radar. The file/threading touch-points arechooseReferenceFile(open dialog + background analysis) and nothing else external.
8. Known limitations & areas of attention
- Masking Radar is a beta heuristic — perceptually motivated, not yet tuned against listening tests; labelled beta in the UI. The spectral SHARP readout is likewise an approximation (labelled as such); TILT is a real calibrated measurement.
- Multi-instance session panel is in-process only (v4.0.0+) — instances see each other only when the host loads them in the same OS process; some hosts sandbox each plugin/instance into its own process, and this cannot be detected from inside the plugin, so it isn't surfaced in the UI.
- No automated unit tests — see §6.
- Windows/Linux exporters are present but unvalidated
(since v3.6.0) — the
.jucergenerates working VS2022/Linux Makefile project files, but this repository is maintained on macOS only and they have never been compiled or pluginval-tested on real hardware. - Unsigned installer — no Apple Developer ID signing
or notarization. The signing pipeline
(
Installer/sign_and_notarize.sh) is written and ready but blocked on the project owner obtaining a paid Apple Developer account and certificates; seeRELEASING.md.
9. Points of contact
Issues and questions: the project's GitHub issue
tracker. Security reports: see SECURITY.md.