diff --git a/CLAUDE.md b/CLAUDE.md index 9c56b8c..1dfb673 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,162 +2,98 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +Halo is a 2-deck DJ app for macOS with an integrated lighting console (Art-Net output driven by per-track cues +and a live programmer). `ROADMAP.md` is the authoritative description of the architecture and feature plan — +read it before designing anything non-trivial. + ## Common Commands -### Building and Running - **Build**: `cargo build --release` -- **Run with Art-Net broadcast**: `cargo run --release -- --source-ip ` -- **Run with unicast and MIDI**: `cargo run --release -- --source-ip 192.168.1.100 --dest-ip 192.168.1.200 --enable-midi` -- **Run with multi-destination setup**: `cargo run --release -- --source-ip 192.168.1.100 --lighting-dest-ip 192.168.1.200 --pixel-dest-ip 192.168.1.201` -- **Load a show file**: `cargo run --release -- --source-ip --show-file shows/Jasons40th.json` - -### CLI Arguments -- `--source-ip ` - Art-Net source IP address (required) -- `--dest-ip ` - Single destination IP (legacy, optional) -- `--lighting-dest-ip ` - Lighting fixtures destination IP (multi-destination) -- `--pixel-dest-ip ` - Pixel fixtures destination IP (multi-destination) -- `--lighting-universe ` - Universe for lighting fixtures (default: 1) -- `--pixel-start-universe ` - Starting universe for pixel fixtures (default: 2) -- `--artnet-port ` - Art-Net port (default: 6454) -- `--broadcast` - Force broadcast mode -- `--enable-midi` - Enable MIDI support -- `--show-file ` - Path to show JSON file - -See `docs/multi-destination-artnet.md` for detailed multi-destination Art-Net setup. - -### Development Tools +- **Run**: `cargo run --release` (optionally pass an audio file path as the only positional arg to load it on launch) - **Check compilation**: `cargo check --workspace --all-targets` -- **Format code**: `cargo +nightly fmt --all` (requires nightly toolchain for unstable formatting options) -- **Lint**: `cargo clippy --workspace --all-targets --all-features -- -D warnings` +- **Format code**: `cargo +nightly fmt --all` (nightly required — `rustfmt.toml` uses unstable options) - **Test**: `cargo test --workspace` -- **Install nightly toolchain**: `rustup toolchain install nightly` (required for formatting only) +- **Lint**: `cargo clippy --workspace --all-targets` (currently not enforced in CI) +- **macOS app bundle**: `cargo bundle --release` (requires `cargo-bundle`) + +There are no CLI flags. Art-Net destination, audio device, and other settings are configured in-app and +persisted (see Persistence below). Logging is controlled with `RUST_LOG`. + +### Toolchain -### Toolchain Requirements -- **Stable Rust**: Used for building, testing, and linting (MSRV: 1.90.0) -- **Nightly Rust**: Required only for formatting due to unstable options in `rustfmt.toml` +- **Stable Rust** for building/testing (CI pins 1.90.0); **nightly** only for formatting. +- The `timestretch` crate is a **path dependency on a sibling clone**: `../timestretch-rs` next to this repo + (from `crates/halo`, `path = "../../../timestretch-rs"`). CI checks out `robmorgan/timestretch-rs` to that + location. Builds fail without it. ## Architecture Overview -Halo is a real-time lighting console built with Rust, designed for solo performers. It uses a multi-crate workspace architecture with async/tokio runtime: - -### Core Crates -- **`halo-core`**: Core lighting engine with async module system, DMX output, cue system, effects engine, pixel engine, and MIDI integration -- **`halo-fixtures`**: Fixture library and management system -- **`halo-ui`**: egui-based UI components and interface -- **`halo`**: CLI application and main entry point (uses `#[tokio::main]` async runtime) - -### Key Systems - -#### Lighting Console (`halo-core/src/console.rs`) -- Central `LightingConsole` struct manages all lighting operations -- Uses async `ModuleManager` to coordinate separate modules (`DmxModule`, `AudioModule`, `MidiModule`, `SmpteModule`) -- Channel-based communication using `ConsoleCommand` and `ConsoleEvent` via tokio `mpsc` -- Handles fixture patching, cue management, and MIDI integration -- Supports multi-destination Art-Net routing for different fixture types - -#### Cue System (`halo-core/src/cue/`) -- `CueManager` handles playback state and timecode synchronization -- Supports both internal and external SMPTE timecode -- `CueList` contains sequences of `Cue` objects with static values and effects -- Audio playback synchronization with Ableton Link - -#### Effect Engine (`halo-core/src/effect/`) -- Mathematical effect generators: sine, sawtooth, square waves -- Beat-synchronized effects using rhythm detection -- Effect distribution across multiple fixtures with customizable parameters - -#### MIDI Integration (`halo-core/src/midi/`) -- MPK49 controller support for live performance -- `MidiOverride` system for real-time control during shows -- Actions include static values and cue triggering - -#### Module System (`halo-core/src/modules/`) -- `ModuleManager` coordinates all async modules in separate tokio tasks -- Each module implements `AsyncModule` trait with `initialize()`, `run()`, and `shutdown()` methods -- Inter-module communication via `ModuleEvent` (DMX output, audio commands, timecode sync, MIDI input) -- Status/error reporting via `ModuleMessage` back to manager -- **DmxModule**: Real-time DMX output at 44Hz with multi-destination Art-Net routing -- **AudioModule**: Audio file playback in dedicated OS thread (not tokio task) using `rodio` and `symphonia` -- **MidiModule**: MIDI input handling and event forwarding -- **SmpteModule**: SMPTE timecode synchronization for external timecode sources - -#### Pixel Engine (`halo-core/src/pixel/`) -- `PixelEngine` manages all pixel bar fixtures with per-universe routing -- Pixel effects: `Chase`, `Wave`, `Strobe`, `ColorCycle` -- `PixelEffectScope` controls effect application: `Bar` (uniform) or `Individual` (per-pixel) -- Beat-synchronized effects using rhythm detection -- Supports effect distribution across multiple fixtures (All, Step, Wave) -- Renders RGB data per universe for pixel bar fixtures - -#### Configuration System (`halo-core/src/config.rs`) -- `ConfigManager` handles persistent configuration in `config.json` (repository root) -- `Settings` structure stores audio device, MIDI device, DMX settings, and fixture library preferences -- Configuration loaded at startup; CLI arguments override saved settings -- Settings UI panel allows runtime configuration changes -- Version-aware configuration with migration support - -#### UI Architecture (`halo-ui/src/`) -- `HaloApp` is the main egui application with tabbed interface -- Separate panels: Dashboard, Programmer, Cue Editor, Patch Panel, Show Manager -- Real-time fixture grid visualization and control -- Timeline view for cue sequencing - -### Network Configuration -- Multi-destination Art-Net architecture via `NetworkConfig` (`artnet/network_config.rs`) -- Multiple `ArtNetDestination` entries with independent broadcast/unicast modes -- Universe routing via `HashMap` maps universes to destination indices -- Common setup: Universe 1 for lighting fixtures, Universes 2+ for pixel fixtures -- CLI supports separate `--lighting-dest-ip` and `--pixel-dest-ip` for easy multi-destination setup -- Legacy `--dest-ip` still supported for single-destination backward compatibility -- Art-Net output on port 6454 (configurable via `--artnet-port`) - -### Show File Format -- JSON-based show files in `shows/` directory -- Contains cue lists with timing, effects, pixel effects, and fixture assignments -- Includes audio file paths for synchronized playback -- Loadable at runtime via `--show-file` parameter -- Managed through UI Show Manager with save/load functionality - -## Development Notes - -### Repository Conventions - -#### Rust Crates -- Crate names are prefixed with `halo-`. For example, the `core` folder's crate is named `halo-core` -- When using `format!` and you can inline variables into `{}`, always do that -- Never use `unsafe` blocks or functions in any code - -#### Code Formatting -After making any changes to Rust code, always run: -```bash -cargo +nightly fmt --all -``` - -### macOS Platform Requirement -- Development and execution require macOS due to system-specific audio and MIDI dependencies -- Uses Core Audio frameworks through `rodio` and `midir` crates - -### Async Architecture -- Built on tokio async runtime with async/await throughout the codebase -- Module system uses async tasks for concurrent operation -- Channel-based communication between UI and console (`tokio::sync::mpsc`) -- AudioModule uses dedicated OS thread (not async task) for real-time audio playback - -### Configuration Management -- `config.json` file in repository root stores persistent settings -- Auto-created with defaults on first run if not present -- CLI arguments override configuration file settings -- Editable through Settings panel in UI - -### Fixture Patching -- Fixtures are defined in the fixture library with channel layouts -- Traditional lighting fixtures typically on Universe 1 -- Pixel bar fixtures on Universes 2+ with per-universe routing -- DMX addressing starts from specified universe and channel - -### Performance Considerations -- DMX module outputs at 44Hz for smooth lighting output -- Async module architecture allows concurrent operation of DMX, audio, MIDI, and timecode -- UI runs on main thread with egui's native event loop and repaint system -- Channel-based communication between UI and console for thread-safe operation -- Audio playback in dedicated OS thread for consistent timing \ No newline at end of file +Two workspace crates: + +- **`crates/halo`** — the application: UI (egui/eframe, wgpu backend), audio engine, decks, mixer DSP, track + library, analysis workers, and the DMX engine thread. +- **`crates/halo-light`** — UI-free, audio-free lighting domain library: fixtures, cues, programmer resolution, + DMX rendering, Art-Net transport. + +### Threading model (no tokio) + +Plain threads + channels/atomics, mirroring the `timestretch` controller/processor/source split: + +- **UI thread** — egui at ~30 fps while playing. Talks to audio via atomics and the engine's wait-free control + mailbox; a mutex only guards cold UI state. +- **Feed/control thread per deck** — keeps the engine's source ring fed, handles warm-start seeks and gapless + loop wraps (`JumpMap` re-anchor), publishes the playhead. +- **Audio callback thread (cpal)** — owns both `EngineProcessor`s and the whole mixer chain + (engine → trim → EQ → filter → fader → crossfader → master → limiter). Must stay **allocation-free and + lock-free**; parameters arrive via atomics and are smoothed per block. +- **Worker threads** (`std::thread` + `mpsc`, drained per frame by the UI) — library import, track analysis. +- **DMX engine thread** — 44 Hz tick: reads deck playheads from atomics, `resolve()` → `render()` → Art-Net send. + +### Key modules — `crates/halo/src` + +- `main.rs` — eframe/wgpu entry point; positional file arg; `env_logger`. +- `app.rs` — `HaloApp`: views (Prepare/Perform), deck UI, mixer UI, rig ownership, PATCH tab, settings window. +- `deck.rs` — `Deck`: one `timestretch::Engine` per deck, feed thread, seeks, loops, EOF, playhead. +- `audio.rs` — cpal stream setup and the audio callback owning the mixer chain. +- `dsp.rs` — `IsolatorEq` (LR4 crossover, full-kill), `DjFilter` (RBJ biquad LP/HP), `Limiter`. +- `state.rs` — shared atomics (`DeckShared`, `MixerShared`), scrub state, meters, CPU load. +- `scrub.rs` — audible scrub: varispeed voice with momentum glide/settle, engine↔voice crossfade. +- `waveform/` — 3-band RGB peaks pyramid, overview strip, zoomed beat-grid view, trigger-lane strips + cue editor. +- `decoder.rs` — symphonia decode (mp3/flac/ogg/wav) to interleaved stereo `f32`. +- `worker.rs` — background import/analysis workers (own DB connections). +- `library.rs` — SQLite (rusqlite, bundled): `tracks`, `playlists`, `playlist_tracks`, `lighting_cues`, `settings`. +- `dmx.rs` — `spawn_dmx_engine`, the 44 Hz Art-Net output thread (has an end-to-end UDP test). +- `programmer_ui.rs` — lighting programmer surface (fixture grid, five parameter views, effect panels). +- `show.rs` — `simulate_show()`: deterministic demo cue generator, not real authored content. +- `fader.rs` / `knob.rs` — custom egui widgets. + +### Key modules — `crates/halo-light/src` + +- `fixture.rs` — `Rig`, grid/selection types, `default_rig()`. +- `fixture_library.rs` — `FixtureProfile`/`Channel`/`ChannelType`, hardcoded profile registry, patching. +- `cues.rs` — `CueSet` (runtime, non-overlapping per lane) + `CueFile` (persisted JSON, seconds). +- `programmer.rs` — `resolve()`: **the single merge point** (programmer override > track cues > off). +- `output.rs` — pure `render()`: resolved lanes + params → per-universe `[u8; 512]` DMX frames. +- `artnet.rs` — synchronous Art-Net over `std::net::UdpSocket` (broadcast/unicast, multi-destination). + +### Persistence + +- **eframe persistence** (`PERSIST_KEY = "halo"`) — UI/mixer state: trims, keylock, pitch range, quantize, + gated mode, audition volume, device/buffer, sort order. +- **Library DB `settings` table** — Art-Net config and rig patch. +- There is no config file; `config.json` in old branches/history is from the pre-pivot console. + +## Conventions + +- Crate names are prefixed with `halo-` (the `halo-light` crate lives in `crates/halo-light`). +- **Never use `unsafe`** blocks or functions in any code. +- When using `format!` (and friends) and a variable can be inlined into `{}`, always inline it. +- **No tokio** — concurrency is plain threads + `mpsc` + atomics. Don't reintroduce async scaffolding. +- The audio callback must never allocate, lock, or panic. +- `programmer::resolve()` stays the single merge point for lighting state; `output::render()` stays pure. +- After changing Rust code, always run `cargo +nightly fmt --all`. + +## CI + +`.github/workflows/rust.yml` runs on macOS arm64 and Linux x86_64: checks out `timestretch-rs` as a sibling, +then `cargo +nightly fmt --check`, `cargo build`, `cargo test` on stable 1.90.0. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1195e20..f9c32f6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,13 +7,18 @@ ## ⏩ Quick‑Start ### 1. Fork, clone & branch + +Halo depends on the [`timestretch`](https://github.com/robmorgan/timestretch-rs) crate by local path, so clone +`timestretch-rs` alongside your halo clone: + ```bash git clone https://github.com//halo.git +git clone https://github.com/robmorgan/timestretch-rs.git cd halo git checkout -b feat/ ``` -### 2. Compile fast (uses stable toolchain from rust-toolchain.toml) +### 2. Compile fast (uses stable toolchain) ```bash cargo check --workspace --all-targets ``` @@ -49,21 +54,21 @@ git push origin feat/ ## Project Layout -| Crate | Role | -| ------------------- | -------------------------------------------------------- | -| **`halo-core`** | Core lighting engine. | -| **`halo-fixtures`** | Fixture library and management. | -| **`halo`** | CLI and main entrypoint | -| **`halo-ui`** | UI Components and Interface. | +| Crate | Role | +| ----------------- | ----------------------------------------------------------------------------------------- | +| **`halo`** | The application: UI, decks, audio engine, mixer DSP, track library, DMX engine thread. | +| **`halo-light`** | UI-free lighting domain library: fixtures, cues, programmer resolution, Art-Net output. | -All crates live in one Cargo **workspace**, so `cargo ` from the repo root affects everything. +All crates live in one Cargo **workspace**, so `cargo ` from the repo root affects everything. The +[`timestretch`](https://github.com/robmorgan/timestretch-rs) engine is a path dependency expected at +`../timestretch-rs`, next to this repository. ----- ## Dev Environment * **Platform**: Development and execution require **macOS**. - * **Rust (Build/Test)**: **Stable** toolchain, MSRV pinned in `rust-toolchain.toml` (currently *1.90.0*). Install via [rustup.rs][rustup.rs]. This is used by default for `cargo build`, `cargo check`, `cargo test`, etc. + * **Rust (Build/Test)**: **Stable** toolchain (CI runs *1.90.0*). Install via [rustup.rs][rustup.rs]. This is used by default for `cargo build`, `cargo check`, `cargo test`, etc. * **Rust (Format)**: **Nightly** toolchain is required *only* for formatting (`cargo fmt`) due to unstable options used in our `rustfmt.toml` configuration. * Install via: `rustup toolchain install nightly` * **Rust Components**: `rustfmt`, `clippy` – install via `rustup component add rustfmt clippy`. Make sure these components are available for *both* your default stable toolchain and the nightly toolchain. @@ -107,7 +112,7 @@ All crates live in one Cargo **workspace**, so `cargo ` from the repo root 1. Sync with `main`; rebase preferred. 2. Ensure your code is formatted correctly with `cargo +nightly fmt --all`. -3. Ensure CI is green (build, fmt check, clippy, tests on macOS using appropriate toolchains). +3. Ensure CI is green (fmt check, build, and tests on macOS arm64 and Linux x86_64). 4. Fill out the PR template; explain *why* + *how*. 5. Respond to review comments promptly – we’re friendly, promise! 6. Maintainers will *Squash & Merge* (unless history is already clean). diff --git a/README.md b/README.md index 48b224a..5f4b67c 100644 --- a/README.md +++ b/README.md @@ -6,114 +6,113 @@

- Lighting console bringing advanced features to solo performances. + A two-deck DJ app with a built-in lighting console.

## About -⭕️ Halo is a real-time lighting console, designed to bring modern, immersive experiences into the hands of solo -performers. Traditional consoles are typically deployed at front of house (FOH) and require a dedicated lighting -designer. On the other hand, software designed for solo performers is often limited in features and is difficult to -operate during a live show. Halo bridges this gap through a combination of pre-defined cues, beat-synchronized -effects, and live improvisation through MIDI overrides. This enables performers to elevate their shows with immersive -lighting that responds to their performance. +**⭕️ Halo is a DJ app with a built-in lighting console, designed for solo performers who want to deliver immersive +live shows.** + +Mix across two decks while Halo drives the lighting rig in sync with your set. Lighting cues can be prepared per track, +then shaped and overridden live from a console-style programmer—so one performer can control the music, the lights, and +the energy of the room from a single app, without relying on a dedicated lighting operator. + +Halo is designed to integrate seamlessly with the Ableton Push 2, providing hands-on real-time control and visual +feedback without forcing you to perform through a mouse and keyboard. + +Built for macOS in Rust, Halo uses the [`timestretch`](https://github.com/robmorgan/timestretch-rs) engine for +real-time tempo and pitch control.

- Halo Screenshot + Halo Screenshot

> [!WARNING] > This project is still in heavy development and unsuitable for production use (even though I'm using it for shows). - ## Features -* **Intuitive UI.** Featuring a Dashboard, Programmer, Cue Editor, Patch Panel, Show Manager, and Settings panels. -* **Show File System.** Save and load complete shows with cues, effects, and fixture assignments. -* **Programmer.** Control lighting fixtures using a professional programmer interface with real-time feedback. -* **Cue System.** Create, save, and recall lighting scenes using cue lists with timecode synchronization. -* **Effect Engine.** Beat synchronized effects engine with sine, sawtooth and square patterns plus customizable parameters. -* **Pixel Engine.** Dedicated pixel engine for displaying various effects and colors on pixel bar fixtures. -* **Multi-destination Art-Net.** Route different fixture types (traditional lighting, pixels) to separate Art-Net nodes. -* **Audio Playback.** Integrated audio file playback synchronized with cues and Ableton Link. -* **SMPTE Timecode.** Both internal and external timecode synchronization for precise show timing and automation. -* **MIDI Integration.** Control your show with MIDI devices (currently supports Akai MPK49) with override system. -* **Configuration System.** Persistent settings with UI-based configuration panel for audio, MIDI, and DMX preferences. -* **Fixture Library.** Built-in support for various lighting fixtures with extensible fixture definitions. -* **Async Module Architecture.** Separate modules for DMX (44Hz output), Audio, MIDI, and Timecode running concurrently. +### DJ + +* **Dual decks** powered by one `timestretch` engine each: warm-start seeks, gapless loop wrap, and keylocked + tempo control. +* **Full mixer chain** per deck: trim → 3-band isolator EQ (full-kill) → resonant LP/HP filter → channel fader, + into a constant-power crossfader, master fader, and soft limiter. +* **CDJ-style transport**: play/pause and cue (set while paused, hold to preview, release to return). +* **Hot cues** — 8 per deck, with Normal and Gated modes and optional quantize to the beat grid. +* **Loops** — manual in/out, 4-beat quantized autoloop, and halve/double controls from 1/16 up to 16 beats. +* **Tempo & sync** — tempo slider with ±8/±16/±50% ranges, keylock, pitch-bend nudges, and one-button sync that + locks BPM and beat phase to a master deck. +* **Audible scrub** with momentum — grab the waveform and hear it, like dragging a platter. +* **Rich waveforms** — 3-band RGB overview strip and a zoomed, centered-playhead view with beat/bar marks, + rendered from background track analysis. +* **Track library** — SQLite-backed browser with playlists, search, sortable columns (BPM, key, duration, …), + folder import, and background analysis. BPM comes from analysis; musical key is read from file tags. +* **Prepare & Perform views** — audition tracks on an independent third channel and edit cues in Prepare, then + play the show in Perform. +* **Meters everywhere** — per-deck and master levels plus an audio-callback CPU meter. + +### Lighting + +* **Per-track cue lanes** (Lighting / Pixels / FX) under the waveforms, edited directly and persisted in the + library alongside the track. +* **Console-style programmer** — fixture grid, group selects, and Intensity/Color/Position/Beam/Pixel FX views + with beat-synced effects; latch or flash overrides sit above track cues, with STORE-from-live. +* **Real fixture engine** — a default rig patched from real fixture profiles, editable live in the PATCH tab + (profile, universe, address, grid position) and persisted to the library. +* **Art-Net output** — a dedicated 44 Hz engine thread resolves cues + programmer state into per-universe DMX + frames and sends them over Art-Net (broadcast or unicast to a node), independent of the UI. + +See [ROADMAP.md](ROADMAP.md) for the full feature arc and what's next. ## Requirements -* **macOS** (required for Core Audio and MIDI dependencies) -* **Rust toolchain** (cargo, rustc) - MSRV: 1.90.0 -* **Network interface for Art-Net output** (e.g., [Enttec ODE MK2](https://support.enttec.com/support/solutions/articles/101000438016-ode-mk2-70405-70406-)) -* **Optional:** MIDI controller (e.g., Akai MPK49, Novation Launch Control XL) -* **Optional:** Ableton Link compatible device/software for beat synchronization +* **macOS 12+** (Core Audio via cpal; the UI uses the wgpu backend) +* **Rust toolchain** (stable for building/testing; nightly only for `cargo +nightly fmt`) +* **[`timestretch-rs`](https://github.com/robmorgan/timestretch-rs)** cloned alongside this repo (path dependency) +* **Optional:** an Art-Net node and DMX fixtures for the lighting rig ## Installation +Halo depends on the `timestretch` crate by local path, so clone the two repos side by side: + ```bash git clone https://github.com/robmorgan/halo.git +git clone https://github.com/robmorgan/timestretch-rs.git cd halo cargo build --release ``` -## Usage - -### Basic Usage - -Start with Art-Net broadcast mode: +To build a macOS app bundle (`Halo.app`): ```bash -cargo run --release -- --source-ip +cargo install cargo-bundle +cargo bundle --release ``` -Load a show file: +## Usage ```bash -cargo run --release -- --source-ip --show-file shows/myshow.json +cargo run --release ``` -### Multi-Destination Setup - -Route lighting and pixel fixtures to separate Art-Net nodes: +Load tracks through the in-app library or file dialog, or pass a file directly to load it on launch: ```bash -cargo run --release -- --source-ip 192.168.1.100 \ - --lighting-dest-ip 192.168.1.200 \ - --pixel-dest-ip 192.168.1.201 \ - --enable-midi +cargo run --release -- path/to/track.mp3 ``` -See [docs/multi-destination-artnet.md](docs/multi-destination-artnet.md) for detailed multi-destination configuration. - -### Command Line Options - -```bash -USAGE: - halo [OPTIONS] - -OPTIONS: - --source-ip Art-Net source IP address (required) - --dest-ip Single destination IP (legacy, optional) - --lighting-dest-ip Lighting fixtures destination IP - --pixel-dest-ip Pixel fixtures destination IP - --lighting-universe Universe for lighting fixtures (default: 1) - --pixel-start-universe Starting universe for pixel fixtures (default: 2) - --artnet-port Art-Net port (default: 6454) - --broadcast Force broadcast mode - -m, --enable-midi Enable MIDI support - --show-file Path to show JSON file -``` +* **Prepare view** — import folders into the library, build playlists, audition tracks, and edit per-track + lighting cues. +* **Perform view** — two decks, mixer, and the lighting programmer. +* **Art-Net** — configure broadcast or unicast-to-node output in the in-app settings window; the choice is + persisted with the library. +* **Logs** — set `RUST_LOG=debug` (or another filter) when launching from a terminal. ## Documentation -For detailed documentation, see the [docs/](docs/) directory: - -* [Architecture Overview](docs/architecture.md) - System design and component structure -* [CLI Reference](docs/cli-reference.md) - Complete command-line interface documentation -* [Multi-Destination Art-Net](docs/multi-destination-artnet.md) - Setting up multiple Art-Net destinations -* [Troubleshooting Guide](docs/troubleshooting.md) - Common issues and solutions +* [ROADMAP.md](ROADMAP.md) — architecture overview, phased feature plan, and current status. ## License diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 189ddb1..0000000 --- a/TODO.md +++ /dev/null @@ -1,22 +0,0 @@ -# TODO - -## Input - -- [x] Use [crossterm](https://github.com/crossterm-rs/crossterm) for instant keyboard input. -- [ ] OSC - -## UI - -- [ ] Programmer - - [ ] Audio Playback - -## Engine - -- [ ] Cues - - [ ] Cue Master - - [ ] Cue Lists -- [ ] Presets (gobos, position, color) -- [ ] Color - - [ ] Interpolated Fades (note: your cheap PARs cant blend colors) -- [ ] Fixtures - - [ ] Groups diff --git a/_docs/screenshot.png b/_docs/screenshot.png new file mode 100644 index 0000000..abe7105 Binary files /dev/null and b/_docs/screenshot.png differ diff --git a/config.json b/config.json deleted file mode 100644 index 7146a83..0000000 --- a/config.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": "0.1.0", - "settings": { - "target_fps": 60, - "enable_autosave": false, - "autosave_interval_secs": 300, - "audio_device": "Default", - "audio_buffer_size": 512, - "audio_sample_rate": 48000, - "midi_enabled": false, - "midi_device": "None", - "midi_channel": 1, - "dmx_enabled": true, - "dmx_broadcast": false, - "dmx_source_ip": "192.168.1.100", - "dmx_dest_ip": "192.168.1.200", - "dmx_port": 6454, - "wled_enabled": false, - "wled_ip": "192.168.1.50", - "pixel_engine_enabled": true, - "pixel_engine_fps": 44.0, - "pixel_universe_mapping": {}, - "enable_pan_tilt_limits": true - }, - "created_at": "2025-10-13T02:53:54.682044+00:00", - "modified_at": "2025-10-13T02:53:54.682105+00:00" -} diff --git a/config.template.json b/config.template.json deleted file mode 100644 index 3973c21..0000000 --- a/config.template.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "version": "0.1.0", - "settings": { - "target_fps": 60, - "enable_autosave": false, - "autosave_interval_secs": 300, - "audio_device": "Default", - "audio_buffer_size": 512, - "audio_sample_rate": 48000, - "midi_enabled": false, - "midi_device": "None", - "midi_channel": 1, - "dmx_enabled": true, - "dmx_broadcast": false, - "dmx_source_ip": "192.168.1.100", - "dmx_dest_ip": "192.168.1.200", - "dmx_port": 6454, - "wled_enabled": false, - "wled_ip": "192.168.1.50" - }, - "created_at": "2025-01-13T10:00:00Z", - "modified_at": "2025-01-13T10:00:00Z" -} \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 5d40c07..3cca57f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,32 +1,8 @@ # Halo Documentation -This directory contains comprehensive documentation for the Halo lighting console. +Current documentation lives in [ROADMAP.md](../ROADMAP.md) at the repository root — it covers the architecture, +the phased feature plan, and current status. See the top-level [README](../README.md) for build and usage +instructions. -## Table of Contents - -- [Multi-Destination Art-Net Setup](multi-destination-artnet.md) - Configure separate outputs for lighting and pixel fixtures -- [CLI Reference](cli-reference.md) - Complete command-line interface documentation -- [Architecture](architecture.md) - Technical architecture and implementation details -- [Examples](examples.md) - Common usage scenarios and configurations -- [Troubleshooting](troubleshooting.md) - Common issues and solutions - -## Quick Start - -For the most common use case of separating lighting and pixel outputs: - -```bash -cargo run --release -- \ - --source-ip 192.168.1.100 \ - --lighting-dest-ip 192.168.1.200 \ - --pixel-dest-ip 192.168.1.201 -``` - -This sends: -- **Lighting fixtures** (universe 1) → `192.168.1.200` (e.g., Enttec Ode MK2) -- **Pixel fixtures** (universes 2+) → `192.168.1.201` (e.g., Enttec Octo MK2) - -## Getting Help - -- Run `halo --help` for CLI usage -- Check [troubleshooting.md](troubleshooting.md) for common issues -- See [CLAUDE.md](../CLAUDE.md) for development commands and architecture overview \ No newline at end of file +The [legacy/](legacy/) directory contains documentation for the pre-pivot Halo lighting console (the old +tokio-based Art-Net console). It no longer describes this codebase and is kept for reference only. diff --git a/docs/legacy/README.md b/docs/legacy/README.md new file mode 100644 index 0000000..5d40c07 --- /dev/null +++ b/docs/legacy/README.md @@ -0,0 +1,32 @@ +# Halo Documentation + +This directory contains comprehensive documentation for the Halo lighting console. + +## Table of Contents + +- [Multi-Destination Art-Net Setup](multi-destination-artnet.md) - Configure separate outputs for lighting and pixel fixtures +- [CLI Reference](cli-reference.md) - Complete command-line interface documentation +- [Architecture](architecture.md) - Technical architecture and implementation details +- [Examples](examples.md) - Common usage scenarios and configurations +- [Troubleshooting](troubleshooting.md) - Common issues and solutions + +## Quick Start + +For the most common use case of separating lighting and pixel outputs: + +```bash +cargo run --release -- \ + --source-ip 192.168.1.100 \ + --lighting-dest-ip 192.168.1.200 \ + --pixel-dest-ip 192.168.1.201 +``` + +This sends: +- **Lighting fixtures** (universe 1) → `192.168.1.200` (e.g., Enttec Ode MK2) +- **Pixel fixtures** (universes 2+) → `192.168.1.201` (e.g., Enttec Octo MK2) + +## Getting Help + +- Run `halo --help` for CLI usage +- Check [troubleshooting.md](troubleshooting.md) for common issues +- See [CLAUDE.md](../CLAUDE.md) for development commands and architecture overview \ No newline at end of file diff --git a/docs/architecture.md b/docs/legacy/architecture.md similarity index 100% rename from docs/architecture.md rename to docs/legacy/architecture.md diff --git a/docs/cli-reference.md b/docs/legacy/cli-reference.md similarity index 100% rename from docs/cli-reference.md rename to docs/legacy/cli-reference.md diff --git a/docs/examples.md b/docs/legacy/examples.md similarity index 100% rename from docs/examples.md rename to docs/legacy/examples.md diff --git a/docs/multi-destination-artnet.md b/docs/legacy/multi-destination-artnet.md similarity index 100% rename from docs/multi-destination-artnet.md rename to docs/legacy/multi-destination-artnet.md diff --git a/docs/presets.md b/docs/legacy/presets.md similarity index 100% rename from docs/presets.md rename to docs/legacy/presets.md diff --git a/docs/troubleshooting.md b/docs/legacy/troubleshooting.md similarity index 100% rename from docs/troubleshooting.md rename to docs/legacy/troubleshooting.md diff --git a/start-capture.sh b/start-capture.sh deleted file mode 100755 index fc4f027..0000000 --- a/start-capture.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -echo "Starting Halo for Capture..." -#cargo run --release -- --source-ip 127.0.0.1 --lighting-dest-ip 127.0.0.1 --pixel-dest-ip 127.0.0.1 --show-file shows/Guys40th.json -cargo run -- --source-ip 127.0.0.1 --lighting-dest-ip 127.0.0.1 --pixel-dest-ip 127.0.0.1 --broadcast --show-file shows/Jasons40th.json diff --git a/start.sh b/start.sh deleted file mode 100755 index a1f5f0b..0000000 --- a/start.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -echo "Starting Halo..." -#cargo run -- --source-ip 10.143.62.113 --show-file shows/Guys40th.json -#cargo run -- --source-ip 127.0.0.1 --dest-ip 10.8.45.80 --show-file shows/Guys40th.json -#cargo run -- --source-ip 127.0.0.1 --dest-ip 10.8.45.80 --show-file shows/Guys40th.json -# - -# doesn't work when capture is running so use this (for broadcast): -#cargo run -- --source-ip 10.8.45.1 --show-file shows/Guys40th.json - -# unicast - using local IP address -#cargo run -- --source-ip 192.168.1.131 --dest-ip 192.168.1.131 --show-file shows/Guys40th.json - -#cargo run -- --source-ip 192.168.1.131 --dest-ip 192.168.1.131 --show-file shows/Guys40th.json -#cargo run -- --source-ip 10.8.45.1 --dest-ip 10.8.45.80 --show-file shows/Guys40th.json - -cargo run -- --source-ip 10.8.45.1 --lighting-dest-ip 10.8.45.80 --pixel-dest-ip 10.8.45.90 --pixel-start-universe 1 --show-file shows/Jasons40th.json