Real-time voice-driven VRM avatar — a lightweight VTuber application that captures microphone audio, extracts speech features, and drives a 3D VRM model's mouth, eyes, and body with natural idle animations.
- Real-time lip sync — Microphone audio is analyzed via FFT and mapped to Japanese vowel visemes (A/I/U/E/O), driving VRM BlendShape morph targets.
- Natural idle animation — Breathing, head micro-movements, body sway, arm droop, and procedurally generated eye blinks.
- VRM 0.x / 1.0 support — Parses GLB binary extensions to discover BlendShape groups (including Japanese aliases like あ/い/う/え/お and まばたき).
- Transparent window mode — Runs with a transparent background by default for streaming/overlay use.
- Multi-device audio — Supports F32, I16, and U16 sample formats via cpal.
- Frame-rate independent smoothing — Exponential smoothing ensures natural mouth transitions regardless of frame rate.
┌─────────────────────────────────────────────────────────────┐
│ akagicast (bin) │
│ App entry, scene setup, audio polling, DSP scheduling │
├──────────────┬──────────────────┬────────────────────────────┤
│ akagicast- │ akagicast-dsp │ akagicast-avatar │
│ audio │ │ │
│ │ RMS energy │ VRM BlendShape parsing │
│ cpal capture │ Hann-window FFT │ Viseme morph application │
│ Ring buffer │ Spectral centroid│ Idle body animation │
│ Crossbeam TX │ Band energies │ Procedural blink system │
│ │ Viseme mapping │ (Bevy Plugin) │
│ │ Exp. smoothing │ │
├──────────────┴──────────────────┴────────────────────────────┤
│ akagicast-core │
│ Shared types: AudioChunk, VoiceVisemes, DspConfig, Errors │
└─────────────────────────────────────────────────────────────┘
- Rust (edition 2024, stable toolchain)
- Platform audio backend:
- macOS: CoreAudio (built-in)
- Linux: ALSA (
libasound2-devon Debian/Ubuntu,alsa-lib-develon Fedora) - Windows: WASAPI (built-in)
- A VRM model placed in
assets/(tested with VRM 0.x; see assets/ for included sample models)
# Clone the repository
git clone <repo-url>
cd AkagiCast
# Place a .vrm model in assets/ (sample models are already included)
# Build and run
cargo run --bin akagicast --release| Flag | Description |
|---|---|
-d, --debug |
Enable opaque window with debug overlay (shows "Press ESC to quit") |
| Key | Action |
|---|---|
Esc |
Quit the application |
- Drop your
.vrmfile into the assets/ directory. - The application auto-detects VRM files in this priority order:
suzuha.vrm,alicia.vrm,avatar.vrm,catbot.vrm,cool_loops.vrm, then any other*.vrm. - To use a specific model, rename it to one of the priority names or modify the candidate list in main.rs.
# Debug build
cargo build
# Release build (recommended for production — LTO enabled)
cargo build --release
# Run tests
cargo testThe release profile uses thin LTO for optimized binary size and performance.
AkagiCast/
├── Cargo.toml # Workspace manifest
├── assets/ # VRM model files (.vrm)
├── bin/
│ └── akagicast/ # Main binary — application entry point
│ └── src/main.rs
└── crates/
├── akagicast-core/ # Shared types and error definitions
├── akagicast-audio/ # Audio capture (cpal) + lock-free ring buffer
├── akagicast-dsp/ # Digital signal processing — FFT, viseme extraction, smoothing
└── akagicast-avatar/ # VRM loading, BlendShape driving, idle animation (Bevy Plugin)
- akagicast-core (lib.rs) — Defines
AudioChunk,VoiceVisemes,DspConfig, andVtuberError. Has zero Bevy or audio dependencies; usable in any context. - akagicast-audio (lib.rs) — Wraps
cpalto capture mono-mixed microphone audio at 25ms intervals, sends chunks through a bounded ring buffer +crossbeam_channel. Handles F32/I16/U16 sample formats. - akagicast-dsp (lib.rs) — Applies a Hann window, runs rustfft to compute magnitude spectra, extracts spectral centroid and band energies, maps features to A/I/U/E/O viseme weights, and applies exponential smoothing.
- akagicast-avatar (lib.rs) — Bevy
Pluginthat parses GLB JSON to discover morph target indices for viseme presets and blink, then drivesMorphWeightseach frame. Also provides procedural idle body animation (breathing, head sway, natural arm pose, blinking). - akagicast (binary) (main.rs) — Wires everything together: sets up the Bevy app with camera/lighting, starts audio capture, polls audio on each frame, runs DSP, and feeds smoothed visemes into the avatar plugin.
- Capture: cpal captures microphone audio at the device's native sample rate, downmixes to mono, and buffers it in a ring buffer.
- Chunking: A dedicated thread pulls 25ms chunks from the ring buffer and sends them via crossbeam_channel.
- Feature extraction (per frame in Bevy's
Updateschedule):- Compute RMS energy → noise gate → normalized mouth openness.
- Apply Hann window → FFT (1024-point) → magnitude spectrum.
- Compute spectral centroid (brightness) and low/mid/high band energy ratios.
- Map centroid + band energies to A/I/U/E/O vowel weights via Gaussian scoring.
- Smoothing: Exponential interpolation (
lerp_speed = 15.0) prevents jitter; frame-rate independent via1 - exp(-speed * dt). - Application: Smoothed visemes are written to the avatar's
CurrentVisemesresource, which the avatar systems read to set BlendShape weights on the VRM face mesh.
MIT OR Apache-2.0