Take management should be per clip instance — deleting a take from one half of a comped split shouldn't pull it out from under the other half. That's cleanest if the takes themselves live on the instance rather than the clip, so they do now. AudioClipType::TakeFolder is gone entirely. A clip is plain Sampled/Midi content again, and an instance with a non-empty `takes` list simply OVERRIDES it with whichever take is active. Splitting already clones the instance, so each half gets its own take list for free — no index remapping across instances, no copy-on-write, no shared-state surprise — and comping still works, because the halves can still each select a different take. It collapsed machinery too: resolve() moved from the clip to the instance, and owns_audio_pool_index went back to a one-liner. Management (DeleteTakeAction, DeleteUnusedTakesAction, RenameTakeAction): - Right-click a clip with more than one take: `Delete "<active take>"` and "Delete Unused Takes". Deletion is named after the take that's PLAYING rather than being a generic entry, so you pick the victim by selecting it — one clear act instead of hunting a small trash icon in a list (which is where this started, and it was fiddly). - Double-click a take in the dropdown to rename it in place. - What happens to the selection on delete is the subtle part, and there's a test per case: deleting a take BELOW the active one shifts the selection down so you keep hearing the same take; deleting the ACTIVE take lands on whatever slid into its place (not silently back to take 1); deleting the LAST take steps back one. The only take can't be deleted at all — the menu item isn't offered. - Deleted takes' audio stays in the pool: undo has to put it back, and the other half of a split may still be playing it. Fixes: - A recording that stopped before the loop came round wasn't joining an existing take list — it landed as a separate overlapping clip. Trigger- on-wrap is right for the FIRST recording, but once takes exist there, a further run is plainly another take however short. The engine can't know that (it's document state), so the editor passes `force_takes` with the start-recording command and the run is cut and padded to the region even with zero wraps. This forced cycle_loop_len and `wrapped` apart on the MIDI side: the region length has to be known from the start, but the clip should only pin to full-region length AFTER a pass completes, or the bar jumps to full width the moment you hit record. - Recording a second take left BOTH sounding. append_cycle_takes tore down the recording's backend clip by looking it up in clip_instance_to_backend_map — but on the audio path the recording instance isn't in that map yet; it's only added during promotion, which the append path skips. The event already carries the engine's clip id, so it's handed over explicitly now. - The take badge is hidden when there's only one take — no choice to make. |
||
|---|---|---|
| .github/workflows | ||
| daw-backend | ||
| docs | ||
| ffmpeg-blob-io | ||
| lightningbeam-core | ||
| lightningbeam-ui | ||
| nam-ffi | ||
| packaging | ||
| screenshots | ||
| scripts | ||
| src | ||
| tests | ||
| vendor | ||
| .gitignore | ||
| .gitmodules | ||
| ARCHITECTURE.md | ||
| BEAM_FILE_FORMAT.md | ||
| CONTRIBUTING.md | ||
| Changelog.md | ||
| LICENSE | ||
| README.md | ||
| beam_inspector.py | ||
| beam_inspector_README.md | ||
| create_release.sh | ||
| package.json | ||
| phone-ui-sketches.html | ||
| pnpm-lock.yaml | ||
README.md
Lightningbeam
A free and open-source 2D multimedia editor combining vector animation, audio production, and video editing in a single application.
Screenshots
Features
Vector Animation
- GPU-accelerated vector rendering with Vello
- Draw and animate vector shapes with keyframe-based timeline
- Non-destructive editing workflow
- Paint bucket tool for automatic fill detection
Audio Production
- Real-time multi-track audio recording and playback
- Node graph-based effects processing
- MIDI sequencing with synthesizers and samplers
- Comprehensive effects library (reverb, delay, EQ, compression, distortion, etc.)
- Custom audio engine with lock-free design for glitch-free playback
Video Editing
- Video timeline and editing with FFmpeg-based decoding
- GPU-accelerated waveform rendering with mipmaps
- Audio integration from video soundtracks
Technical Stack
Current Implementation (Rust UI)
- UI Framework: egui (immediate-mode GUI)
- GPU Rendering: Vello + wgpu (Vulkan/Metal/DirectX 12)
- Audio Engine: Custom real-time engine (
daw-backend)- cpal for cross-platform audio I/O
- symphonia for audio decoding
- dasp for node graph processing
- Video: FFmpeg 8 for encode/decode
- Platform: Cross-platform (Linux, macOS, Windows)
Legacy Implementation (Deprecated)
- Frontend: Vanilla JavaScript
- Backend: Rust (Tauri framework)
Project Status
Lightningbeam is developed on the main branch. The project has been rewritten from a Tauri/JavaScript prototype to a pure Rust application to eliminate IPC bottlenecks and achieve better performance for real-time video and audio processing.
Current Status:
- ✅ Core UI panes (Stage, Timeline, Asset Library, Info Panel, Toolbar)
- ✅ Drawing tools (Select, Draw, Rectangle, Ellipse, Paint Bucket, Transform)
- ✅ Undo/redo system
- ✅ GPU-accelerated vector rendering
- ✅ Audio engine with node graph processing
- ✅ GPU waveform rendering with mipmaps
- ✅ Video decoding integration
- ✅ Export system (video, image, audio, animated GIF, SVG)
- ✅ Node editor UI
- 🚧 Piano roll editor (in progress)
Getting Started
Download a prebuilt release
If you don't want to build from source, prebuilt binaries for each release are on the GitHub releases page. Download the build for your platform and run it directly.
Building from source
Prerequisites
- Rust (stable toolchain via rustup)
- System dependencies:
- Linux: ALSA development files, FFmpeg 8
- macOS: FFmpeg (via Homebrew)
- Windows: FFmpeg 8, Visual Studio with C++ tools
See docs/BUILDING.md for detailed setup instructions.
Building and Running
# Clone the repository
git clone https://github.com/skykooler/lightningbeam.git
# Or from Gitea
git clone https://git.skyler.io/skyler/lightningbeam.git
cd lightningbeam/lightningbeam-ui
# Build and run
cargo run
# Or build optimized release version
cargo build --release
Documentation
- CONTRIBUTING.md - Development setup and contribution guidelines
- ARCHITECTURE.md - System architecture overview
- docs/BUILDING.md - Detailed build instructions and troubleshooting
- docs/AUDIO_SYSTEM.md - Audio engine architecture and development
- docs/UI_SYSTEM.md - UI pane system and tool development
- docs/RENDERING.md - GPU rendering pipeline and shaders
Project History
Lightningbeam evolved from earlier multimedia editing projects I've worked on since 2010, including the FreeJam DAW. The JavaScript/Tauri prototype began in November 2023, and the Rust UI rewrite started in late 2024 to eliminate performance bottlenecks and provide a more integrated native experience.
Goals
Create a comprehensive FOSS alternative for 2D-focused multimedia work, integrating animation, audio, and video editing in a unified workflow. Lightningbeam aims to be:
- Fast: GPU-accelerated rendering and real-time audio processing
- Flexible: Node graph-based audio routing and modular synthesis
- Integrated: Seamless workflow across animation, audio, and video
- Open: Free and open-source, built on open standards
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
License
[License information to be added]


