Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

39 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Sonica

GPU-accelerated audio visualizer video generator.

Takes an audio file, runs FFT analysis, renders visualizations with GPU shaders, and outputs an MP4 video with the original audio. Any resolution, any aspect ratio โ€” landscape, portrait, square.

Requirements

  • Rust 1.70+
  • ffmpeg (must be in PATH)
  • macOS (Metal) โ€” tested
  • Linux (Vulkan) / Windows (DX12) โ€” should work but untested

Install

cargo install --git https://github.com/rath/sonica

All templates and shaders are embedded in the binary, so no additional files are needed.

With subtitle support

cargo install --git https://github.com/rath/sonica --features subtitles

This adds speech-to-text subtitle overlay via whisper.cpp. Whisper models are automatically downloaded on first use. macOS builds enable Whisper's Metal backend automatically; other platforms use the backend provided by their standard build.

Build from source

git clone https://github.com/rath/sonica
cd sonica
cargo build --release
# Or with subtitle support:
cargo build --release --features subtitles

Usage

# Basic โ€” generates output.mp4 with frequency bars + default effects
sonica audio.wav

# Specify output and template
sonica audio.wav -o visualizer.mp4 -t circular_spectrum

# Cycle through all templates (equal duration each)
sonica audio.wav -t all --effects crt

# CRT retro style
sonica audio.wav --effects crt

# Portrait video for Instagram/TikTok (9:16)
sonica audio.wav -t circular_spectrum --width 1080 --height 1920

# Square video for Instagram feed (1:1)
sonica audio.wav -t particle_burst --width 1080 --height 1080

# 4K 60fps high quality
sonica track.flac -t kaleidoscope --width 3840 --height 2160 --fps 60 --crf 12

# Hardware encoding on macOS
sonica audio.wav --codec h264_videotoolbox --pix-fmt nv12

# Korean title with Google Noto Sans KR
sonica audio.wav --title "์•ˆ๋…•ํ•˜์„ธ์š”, SONICA" --font-url "https://raw.githubusercontent.com/notofonts/noto-cjk/main/Sans/SubsetOTF/KR/NotoSansKR-Regular.otf"

# ์‹ค์ œ ๋™์ž‘๋˜๋Š” Noto Sans KR TTF/OTF URL ์˜ˆ์‹œ
sonica audio.wav --title "์•ˆ๋…•ํ•˜์„ธ์š”" --font-url "https://raw.githubusercontent.com/notofonts/noto-cjk/main/Sans/SubsetOTF/KR/NotoSansKR-Regular.otf"

# ๋กœ์ปฌ ํฐํŠธ ํŒŒ์ผ ๊ฒฝ๋กœ ์˜ˆ์‹œ (macOS)
sonica audio.wav --title "์•ˆ๋…•ํ•˜์„ธ์š”" --font "/System/Library/Fonts/Supplemental/NotoSansCJK-Regular.ttc"

# ์„ค์น˜๋œ ์‹œ์Šคํ…œ ํฐํŠธ๋ฅผ ํŒจ๋ฐ€๋ฆฌ๋ช…์œผ๋กœ ์„ ํƒ
sonica audio.wav --title "์•ˆ๋…•ํ•˜์„ธ์š”" --font-family "BM Dohyeon"

# Speech-to-text subtitles (requires --features subtitles)
sonica audio.wav -o output.mp4 --subtitles

# Subtitles with specific language and model
sonica audio.wav -o output.mp4 --subtitles --whisper-model small --subtitle-lang ko

# Customize subtitle appearance
sonica audio.wav -o output.mp4 --subtitles --subtitle-font-size 64 --subtitle-max-chars 30

# Use a different installed font for subtitles only
sonica audio.wav -o output.mp4 --subtitles --subtitle-font-family "BM Dohyeon"

# High-contrast custom subtitle style without karaoke highlighting
sonica audio.wav -o output.mp4 --subtitles \
  --subtitle-background-opacity 0.7 --subtitle-outline-width 3 \
  --subtitle-text-color "#FFFFFF" --subtitle-highlight-color "#00FFAA" \
  --no-subtitle-karaoke

# Write an editable subtitle draft without rendering video
sonica audio.wav --write-subtitles draft.srt --transcribe-only --subtitle-lang ko

# Render a corrected SRT file
sonica audio.wav -o output.mp4 --subtitle-file corrected.srt

# List available templates
sonica --list-templates

Templates

circular_spectrum

Radial spectrum analyzer with beat-reactive radius

demo-circular_spectrum.mp4

particle_burst

Beat-driven particle system

demo-particle_burst.mp4

waveform_scope

PCM waveform oscilloscope with glow

frequency_bars

Classic equalizer bars with log frequency mapping

kaleidoscope

Audio-reactive fractal kaleidoscope

spectrogram

Scrolling time-frequency heatmap

all

Cycle through all templates, equal duration each.

Effects

Post-processing effects can be combined with --effects:

# Single effect
sonica audio.wav --effects bloom

# Multiple effects
sonica audio.wav --effects bloom,vignette,chromatic_aberration

# CRT preset (scanlines + chromatic aberration + vignette + film grain + color grading)
sonica audio.wav --effects crt

Available effects: bloom, chromatic_aberration, vignette, film_grain, crt_scanlines, color_grading

When --effects is not specified, each template uses its own default effects.

Subtitles

Speech-to-text subtitle overlay using local whisper.cpp inference. Requires building with --features subtitles.

# Auto-detect language, base model (downloaded automatically)
sonica audio.wav --subtitles

# Korean speech with small model for better accuracy
sonica audio.wav --subtitles --whisper-model small --subtitle-lang ko

# Use a local model file
sonica audio.wav --subtitles --whisper-model /path/to/ggml-large-v3-turbo.bin

# Save the generated cues while also rendering them
sonica audio.wav --subtitles --write-subtitles draft.srt

# Transcribe, edit, then render the corrected captions
sonica audio.wav --write-subtitles draft.srt --transcribe-only --subtitle-lang ko
sonica audio.wav --subtitle-file corrected.srt -o output.mp4

Available models: tiny, base, small, medium, large (and .en English-only variants). Models are cached at ~/.cache/sonica/models/ after first download.

On macOS, subtitle-enabled builds use Metal acceleration for Whisper inference automatically.

Subtitles use a high-contrast semi-transparent background and outline at the bottom center of the video. Font size and line wrapping can be adjusted with --subtitle-font-size and --subtitle-max-chars. Use --subtitle-font, --subtitle-font-url, or --subtitle-font-family to override the title font for subtitles only. Background and dim-text opacity, text/highlight/outline colors, outline width, bottom margin, and karaoke highlighting are also configurable.

CLI Reference

sonica [OPTIONS] [INPUT]

Arguments:
  [INPUT]  Input audio file (WAV, MP3, FLAC, OGG, AAC, WebM/Opus, or any FFmpeg-supported format)

Options:
  -o, --output <PATH>        Output video file [default: output.mp4]
  -t, --template <NAME>      Template name, or "all" to cycle [default: frequency_bars]
  -b, --bitrate <RATE>       Video bitrate (e.g. 2400k, 5M), overrides --crf
      --width <PX>           Video width [default: 1920]
      --height <PX>          Video height [default: 1080]
      --fps <N>              Frames per second [default: 30]
      --crf <N>              H.264 quality, 0-51, lower=better [default: 18]
      --effects <LIST>       Post-processing effects, comma-separated (use "none" to disable)
      --smoothing <F>        Audio smoothing factor, 0.0-1.0 [default: 0.85]
      --title <TEXT>         Title text overlay (top right)
      --font <PATH>          Font file for title/time overlay (TTF/OTF)
      --font-url <URL>       Font URL for title/time overlay (TTF/OTF or Google Fonts URL)
      --font-family <NAME>   Installed font family for title/time overlay
      --show-time            Show elapsed time overlay, MM:SS.CC (bottom right)
      --param <KEY=VALUE>    Template parameter overrides, comma-separated
      --config <PATH>        Config file path [default: ./sonica.toml]
      --codec <NAME>         FFmpeg video codec [default: libx264]
      --pix-fmt <FMT>        FFmpeg pixel format [default: yuv420p]
      --list-templates       List available templates and exit
      --subtitles            Enable speech-to-text subtitles (requires --features subtitles)
      --subtitle-file <PATH> Render subtitles from an existing SRT file
      --write-subtitles <PATH>  Save generated subtitles as an editable SRT file
      --transcribe-only      Write subtitles without rendering a video
      --whisper-model <M>    Whisper model name or file path [default: base]
      --subtitle-lang <L>    Subtitle language, ISO 639-1 (e.g. "en", "ko"). Auto-detect if omitted
      --subtitle-font-size <PX>  Subtitle font size [default: 48]
      --subtitle-font <PATH> Font file used only for subtitles
      --subtitle-font-url <URL>  Font URL used only for subtitles
      --subtitle-font-family <NAME>  Installed font family used only for subtitles
      --subtitle-max-chars <N>   Max characters per subtitle line [default: 42]
      --subtitle-background-opacity <N>  Background opacity [default: 0.55]
      --subtitle-dim-opacity <N>  Upcoming karaoke text opacity [default: 0.75]
      --subtitle-text-color <HEX> Subtitle text color [default: #FFFFFF]
      --subtitle-highlight-color <HEX>  Karaoke highlight color [default: #FFFFFF]
      --subtitle-outline-color <HEX>  Outline color [default: #000000]
      --subtitle-outline-width <PX>  Outline width [default: 2]
      --subtitle-margin-bottom <N>  Bottom margin fraction [default: 0.08]
      --no-subtitle-karaoke  Disable word-by-word highlighting
  -h, --help                 Print help

Template Parameters

Each template defines configurable parameters (bar count, colors, etc.) with --param:

# Change bar count and disable mirroring
sonica audio.wav -t frequency_bars --param bar_count=128,mirror=false,gap_ratio=0.1

# Kaleidoscope with 8-fold symmetry
sonica audio.wav -t kaleidoscope --param symmetry=8,zoom=2.0

# More particles
sonica audio.wav -t particle_burst --param particle_count=500

Use --list-templates to see available templates. Check each template's manifest.json for parameter definitions.

Configuration File

Sonica loads config from the first file found in this order:

  1. --config <path> (explicit)
  2. ./sonica.toml (current directory)
  3. ~/.config/sonica/config.toml (global, works on all platforms)
  4. Platform-specific config dir (~/Library/Application Support on macOS)

CLI flags always take priority over config values. See sonica.toml.example for a full annotated example.

[output]
width = 1280
height = 720
fps = 60
crf = 15
codec = "libx264"
pix_fmt = "yuv420p"
font = "/path/to/NotoSansKR-Regular.otf"
font_url = "https://raw.githubusercontent.com/notofonts/noto-cjk/main/Sans/SubsetOTF/KR/NotoSansKR-Regular.otf"

[audio]
smoothing = 0.9

effects = ["bloom", "vignette"]

[subtitle]
whisper_model = "base"
language = "ko"
font_size = 48.0
max_chars_per_line = 42

For Korean text, use a font that includes CJK glyphs (for example NotoSansKR-Regular.otf from Google Fonts) via --font, --font-url, or font / font_url in the config.

Supported Audio Formats

WAV, MP3, FLAC, OGG/Vorbis, and AAC are decoded directly via symphonia. Unsupported codecs and containers, including WebM/Opus, automatically fall back to FFmpeg decoding.

How It Works

  1. Decode audio to mono PCM samples
  2. Transcribe speech to timed subtitles via whisper.cpp (optional)
  3. Analyze in 3 passes:
    • Global stats (peak levels, beat detection, tempo)
    • Per-frame FFT with frequency band extraction (parallelized)
    • Bidirectional smoothing and normalization
  4. Render each frame on GPU via wgpu (Metal/Vulkan) with WGSL shaders
  5. Post-process through a chain of effect shaders
  6. Overlay title, time, and subtitles on CPU
  7. Encode by piping raw RGBA frames to ffmpeg

Performance

On Apple M2 Max, 100 seconds of audio:

Resolution Effects Time Speed
1280x720 none ~8s 12x realtime
1920x1080 CRT (5 passes) ~43s 2.3x realtime

License

MIT

About

GPU-accelerated audio visualizer that renders WGSL shader templates to MP4 via wgpu and ffmpeg.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages