A small Windows desktop audio visualizer using NumPy, PyQt6, and SoundCard/WASAPI.
cd C:\Users\Sopht\coding\sound_visualizer
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
python main.pyThe first run uses the Windows default speaker loopback. To use a microphone, edit the JSON file at:
%APPDATA%\SoundVisualizer\config.json
Create it from the defaults with:
python config.pySet audio.source to input for the default microphone, or set audio.device to a device id printed by:
python audio_capture.pyThe configuration exposes independent output/input sources, FFT sizes, shared frequency bounds and smoothing, bar count, colors, opacity, frame rate, visualization mode, line style, and data overlays.
visual.mode:barsorlinevisual.orientation:flatorcirclevisual.line_style:traceororganicvisual.radius_ratio: circle radius as a fraction of the smaller window dimensionvisual.left_colorandvisual.right_color: independent stereo colorsgeneral.frequency_minandgeneral.frequency_max: shared frequency range for both streamsgeneral.smoothingandgeneral.decay: shared FFT response controlsgeneral.binning_method:defaultpreserves the existing grouping;logarithmicuses expanding high-frequency binsdata.marker_startanddata.marker_end: marker span from 0 to 1data.marker_opacity,data.marker_color,data.data_opacity,data.data_font, anddata.data_size_factor: overlay stylingdata.show_output_frequency,data.show_output_bpm,data.show_input_frequency, anddata.show_input_bpm: independent stream readouts
The tray icon is shown in the Windows notification area. Its Settings action opens a separate live configuration window with color pickers and expandable input/output device selectors. Changes are saved immediately. When click-through is disabled, drag anywhere to move the visualizer and drag the lower-right grip to resize it.
Output and input have independent capture and magnitude controls:
analysis.output_magnitude_mode:normalizedorscaledanalysis.output_magnitude_scale: used byscaledanalysis.input_magnitude_mode:normalizedorscaledanalysis.input_magnitude_scale: used byscaled
Each device selector has Default and None (disabled). Selecting None removes that stream's visualization and data readouts. Existing configurations are migrated when loaded.
Startup registration is available from Python:
python -c "from startup import set_startup; set_startup(True)"Disable it with set_startup(False). This uses the current user's Run key and does not require administrator rights.
Run python capture_probe.py to enumerate input and loopback devices and confirm that audio blocks are arriving. If the selected device is unavailable, the visualizer remains open and renders a silent state while the tray can be used to quit or reload configuration.
The desktop layer is currently a Windows-compatible fallback mode for a non-topmost transparent widget. Reliable attachment behind desktop icons will be implemented as a separate Windows shell integration step.
The default capture is stereo for both output loopback and input. Left and right channels are analyzed independently and drawn on top of each other. In flat orientation output grows upward and input grows downward; in circle orientation output grows outward and input grows inward. A few inactive frequency channels can be normal when an FFT bin does not land inside a narrow logarithmic band; the analyzer now samples the spectrum at logarithmic frequency centers instead, which keeps those bands continuous. The lowest and highest bands can still be quiet when they fall outside the useful audio/device range.