# Changelog All notable changes to this project will be documented in this file. ## [0.1.1] ### Forth Language - `map` word: apply a quotation to each stack element (`1 2 3 ( 10 * ) map => 10 20 30`). - `loop` fix: now operates in steps instead of beats, uses `step_duration()` for correct timing. ### Fixed - Crash on missing sample directories: sample path scanning now validates directories exist before scanning. - Audio channel minimum enforced to 2, preventing crash on devices reporting fewer channels. - Audio device disconnect: automatic stream restart when device is lost (terminal and desktop). - Live keys (e.g. `f` for fill) no longer trigger while searching in dictionary or help views. - Side panel always uses horizontal layout (removed broken vertical fallback for narrow terminals). ### Changed - Runtime highlight enabled by default. ### Packaging - Modular CI: split monolithic release workflow into per-platform builds (Linux, macOS, Windows, cross-compilation). - Separate CI workflows for CLAP/VST plugin builds (Linux, macOS, Windows, Raspberry Pi). - Windows MSI installer workflow fixes. - Website download matrix updated. ## [0.1.0] ### Breaking - **Quotation syntax changed from `{ }` to `( )`** — all deferred code blocks now use parentheses. ### Forth Language **Syntax:** - `[ v1 v2 v3 ]` bracket lists with implicit count. - `( ... )` quotation syntax (replaces `{ }`). - `,varname` assignment syntax (SetKeep): assign without consuming. - `case/of/endof/endcase` control flow. - `print` — debug word, outputs top-of-stack as text. - Arithmetic and unary ops now lift over ArpList and CycleList element-wise. **New words:** - `index` — select item at explicit index (wraps with modulo). - `slice` / `pick` — sample slicing: divide a sample into N equal parts and select which slice to play. - `wave` / `waveform` — set drum synthesis waveform (0=sine, 0.5=triangle, 1=saw). - `pbounce` — ping-pong cycle keyed by pattern iteration. - `except` — inverse of `every`. - `every+` / `except+` — phase-offset variants. - `bjork` / `pbjork` — euclidean rhythm gates using quotations. - `arp` — arpeggio list type (spreads notes across time). - `all` / `noall` — apply params globally to all emitted sounds. - `linmap` / `expmap` — linear and exponential range mapping. - `rec` / `overdub` (`dub`) — record/overdub master audio to a named sample. - `orec` / `odub` — record/overdub a single orbit. **Harmony and voicing:** - `key!` — set tonal center. - `triad` / `seventh` — diatonic chord from scale degree. - `inv` / `dinv` — chord inversion / down inversion. - `drop2` / `drop3` — drop voicings. - `tp` — transpose all ints on stack by N semitones. **New chord types:** - `pwr`, `augmaj7`, `7sus4`, `9sus4`, `maj69`, `min69`, `maj11`, `maj13`, `min13`, `dom7s11`. **Effect parameters:** - Ducking compressor: `comp`, `compattack`/`cattack`, `comprelease`/`crelease`, `comporbit`/`corbit`. - Smear effect: `smear`, `smearfreq`, `smearfb`. - Reverb: `verbtype`, `verbchorus`, `verbchorusfreq`, `verbprelow`, `verbprehigh`, `verblowcut`, `verbhighcut`, `verblowgain`. **Behavior changes:** - All parameter words now accept varargs (100+ words updated to consume the full stack). - `every` reworked to accept quotations. - Removed `chain` word (replaced by pattern-level Follow Up setting). ### Engine - SF2 soundfont support: auto-scans sample directories for `.sf2` files. - Follow-up actions: patterns have configurable follow-up (Loop, Stop, Chain). Replaces the `chain` word with a declarative UI setting (`e` key). - Delta-time MIDI scheduling for tighter timing. - Audio stream errors surfaced as flash messages. - Prelude script evaluated on application startup (not only on play). - Global periodic script: a hidden script page runs alongside all patterns at its own speed/length. - RestartAll command: reset all active patterns to step 0 and clear state. - Tempo and current beat exposed in sequencer snapshot. - Spectrum analyzer rescaling. ### UI / UX - **Engine page redesign**: responsive narrow/wide layout, Link/MIDI/device settings moved here from Options. - **Patterns view redesign**: banks column with pattern counts, expandable detail rows, bottom preview strip with mini step grid. - **Mouse support**: click navigation on header/grid/panels/modals, text selection in code editor (click+drag), double-click on scope/spectrum/lissajous to cycle display modes. - Smooth playback progress bar interpolated between steps. - Dynamic step grid sizing adapts to terminal height. - Lissajous XY scope with Braille rendering and thermal trail mode. - Gain boost (1x–16x) and normalize toggle for scope/lissajous/spectrum. - Pattern description field: editable via `d`, shown in pattern list and properties. - Bank/pattern import and export via clipboard (base64 serialization for sharing). - Mute/solo on main page now apply immediately (no staging). - Step name automatically cleared when deleting a step. - F1–F6 page navigation across the 3×2 page grid. - Collapsible help sections with code block copy. - Onboarding system for first-time users. - Show/hide preview pane toggle and zoom factor setting. - Reduced UI lag: sequencer snapshot moved after render call. - 10 bundled demo projects loaded on fresh startup (togglable in Options). - Options page: each option shows a description line below when focused. - Dictionary page: word list uses full page height (removed description box). ### Themes - 5 new themes: Iceberg, Everforest, Fauve, Tropicalia, Jaipur. - Palette-based generation: all 18 themes derived from a 14-field Palette via Oklab color space (definitions reduced from ~300 to ~20 lines each). ### Desktop (egui) - Fixed Alt/Option key on macOS (dead-key composition now works). - Fixed multi-character text paste. - Extended function key support (F13–F20). - No console window on Windows desktop build. ### Packaging - macOS: `.dmg` disk image with `.app` bundle (Intel + Apple Silicon fat binaries via `lipo`). - Windows: `.msi` installer via WiX. - Linux: improved AppImage build scripts and Docker cross-compilation. ### CLAP Plugin (experimental) - Early CLAP plugin support via nih-plug, baseview, and egui. Feature-gated builds separate CLI from plugin targets. ### Documentation - Complete reorganization into `docs/` subdirectories. - 10 getting-started guides, 5 interactive tutorials. - New tutorials: Recording, Soundfonts, Sharing (import/export). - New topics: control flow, generators, harmony, randomness, variables, timing, bracket syntax. - Crate-level READMEs for forth, markdown, project, ratatui. ### Fixed - CycleList + ArpList index collision: arp uses timing index, cycle uses polyphony slot. - Scope widget not drawing completely in some terminal sizes. ### Codebase - `src/app.rs` split into 10 focused modules. - `src/input.rs` split into 8 page-specific handlers. - Undo/redo system with scope-based tracking. - Feature-gated CLI vs plugin builds. - New reusable widgets: CategoryList, HintBar, PropsForm, ScrollIndicators, SearchBar, SectionHeader. ## [0.0.9] ### Website - Compressed screenshot images: resized to 1600px and converted PNG to WebP (8MB → 538KB). - Version number displayed in subtitle, read automatically from `Cargo.toml` at build time. ### Added - `arp` word for arpeggios: wraps stack values into an arpeggio list that spreads notes across time positions instead of playing them all simultaneously. With explicit `at` deltas, arp items zip with deltas (cycling the shorter list); without `at`, the step is auto-subdivided evenly. Example: `sine s c4 e4 g4 b4 arp note .` plays a 4-note arpeggio across the step. - Resolved value annotations: nondeterministic words (`rand`, `choose`, `cycle`, `bounce`, `wchoose`, `coin`, `chance`, `prob`, `exprand`, `logrand`) now display their resolved value inline (e.g., `choose [sine]`, `rand [7]`, `chance [yes]`) during playback in both Preview and Editor modals. - Inline sample finder in the editor: press `Ctrl+B` to open a fuzzy-search popup of all sample folder names. Type to filter, `Ctrl+N`/`Ctrl+P` to navigate, `Tab`/`Enter` to insert the folder name at cursor, `Esc` to dismiss. Mutually exclusive with word completion. - Sample browser now displays the 0-based file index next to each sample name, making it easy to reference samples by index in Forth scripts (e.g., `"drums" bank 0 n`). ### Improved - Header bar stats block (CPU/voices/Link peers) is now centered like all other header sections. - CPU percentage changes color when load is high: accent color at 50%+, error color at 80%+. - Extracted 6 reusable TUI components into `cagire-ratatui`: `CategoryList`, `render_scroll_indicators`, `render_search_bar`, `render_section_header`, `render_props_form`, `hint_line`. Reduces duplication across views. ### Fixed - Soundless emits (e.g., `1 gain .`) no longer stack infinite voices. All emitted commands now receive a default duration of one beat unless the user explicitly sets `dur`. Use `0 dur` for intentionally infinite voices. ## [0.0.8] - 2026-02-07 ### Fixed - macOS `.pkg` installer bundle relocation: disabled `BundleIsRelocatable` so `Cagire.app` always installs to `/Applications/` instead of being redirected to an existing bundle location. ### Added - Syntax highlighting for user-defined Forth words: words created with `: name ... ;` now render with a distinct color in both the editor and step preview, instead of dimmed gray. - Multi-selection in Patterns view: Shift+Up/Down selects adjacent ranges of banks or patterns using anchor-based selection. Works with copy/paste (Ctrl+C/V), reset (Delete), toggle play (`p`), mute (`m`), and solo (`x`). Selection is column-scoped and clears on plain arrows, column switch, or Esc. Single-only actions (rename, pattern props, enter) are disabled during multi-selection. - Audio-rate modulation DSL: LFO words (`lfo`, `tlfo`, `wlfo`, `qlfo` for sine/triangle/sawtooth/square), transition envelopes (`slide`, `expslide`, `sslide` for linear/exponential/smooth), random modulation (`jit`, `sjit`, `drunk` for random hold/smooth random/drunk walk), and multi-segment envelope (`env`). These produce modulation strings consumed by parameter words for continuous audio-rate control. - Feedback delay FX words: `feedback`/`fb` (level), `fbtime`/`fbt` (delay time), `fbdamp`/`fbd` (damping), `fblfo` (LFO rate), `fblfodepth` (LFO depth), `fblfoshape` (LFO shape). - `bounce` word: ping-pong cycle through n items by step runs (e.g., `60 64 67 72 4 bounce` → 60 64 67 72 67 64 60 64...). - `wchoose` word: weighted random selection from n value/weight pairs (e.g., `60 0.6 64 0.3 67 0.1 3 wchoose`). Supports quotations. - New themes: **Eden** (dark forest — green-only palette on black), **Georges** (Commodore 64 palette on black), **Ember** (warm dark tones), **Letz Light** (light theme). - Proper desktop app icon and metadata across all platforms: moved icon to `assets/Cagire.png`, added Windows `.exe` icon and file properties embedding via `winres` build script, added PNG to cargo-bundle icon list for Linux `.deb` packaging. - Universal macOS `.pkg` installer in CI: combines Intel and Apple Silicon builds into fat binaries via `lipo`, then packages `Cagire.app` and CLI into a single `.pkg` installer. - Waveform rendering widget in the TUI. ### Improved - Sample library browser: search now shows folder names only (no files) while typing, sorted by fuzzy match score. After confirming search with Enter, folders can be expanded and collapsed normally. Esc clears the search filter before closing the panel. Left arrow on a file collapses the parent folder. Cursor and scroll position stay valid after expand/collapse operations. - RAM optimizations saving ~5 MB at startup plus smaller enums and fewer hot-path allocations: - Removed dead `Step::command` field (~3.1 MB) - Narrowed `Step::source` from `Option` to `Option` (~1.8 MB) - `Op::SetParam` and `Op::GetContext` now use `&'static str` instead of `String` - `SourceSpan` fields narrowed from `usize` to `u32` - Dirty pattern tracking uses fixed `[[bool; 32]; 32]` array instead of `HashSet` - Boxed `FileBrowserState` in `Modal` enum to shrink all variants - `StepContext::cc_access` borrows instead of cloning `Arc` - Removed unnecessary `Arc` wrapper from `Stack` type - Variable key cache computes on-demand with reusable buffers instead of pre-allocating 2048 Strings - Render pipeline: background fill uses `Clear` widget instead of generating blank paragraph lines. ### Fixed - Sequencer sync: auto-loaded patterns now use PhaseLock instead of Reset, so they align to the global beat grid and stay in sync with manually-started patterns. - PhaseLock off-by-one: start step calculation now uses the frontier beat instead of the lookahead end, eliminating a systematic 1-step offset. - Stale pattern cache on load: dirty patterns are now flushed before queued start/stop changes, ensuring pattern data arrives before activation. - Loading while paused no longer drops auto-started patterns; pending starts are preserved and activate on resume. ### Changed - Header bar is now always 3 lines tall with vertically centered content and full-height background colors, replacing the previous 1-or-2-line width-dependent layout. - Help view Welcome page: BigText title is now gated behind `cfg(not(feature = "desktop"))`, falling back to a plain text title in the desktop build (same strategy as the splash screen). - Space now toggles play/pause on all views, including the Patterns page where it previously toggled pattern play. Pattern play on the Patterns page is now bound to `p`. ## [0.0.7] - 2026-05-02 ### Added - 3-operator FM synthesis words: `fm2` (operator 2 depth), `fm2h` (operator 2 harmonic ratio), `fmalgo` (algorithm: 0=cascade, 1=parallel, 2=branch), `fmfb` (feedback amount). Extends the existing 2-OP FM engine to a full 3-OP architecture with configurable routing and operator feedback. - Background head-preload for sample libraries. At startup, a background thread decodes the first 4096 frames (~93ms) of every sample into RAM. Short samples (most percussion/drums) are fully captured and play instantly on first trigger. Eliminates first-hit misses for live performance. - Most changes are on doux side. It makes sense to recompile and release now to ship a version that comes with these improvements. ### Fixed - Code editor now scrolls vertically to keep the cursor visible. Previously, lines beyond the visible area were clipped and the cursor could move off-screen. ## [0.0.6] - 2026-05-02 ### Added - TachyonFX based animations - Prelude: project-level Forth script for persistent word definitions. Press `d` to edit, `D` to re-evaluate. Runs automatically on playback start and project load. - Varargs stack words: `rev`, `shuffle`, `sort` (ascending), `rsort` (descending), `sum`, `prod`. All take a count and operate on the top n items. - Euclidean rhythm words: `euclid` (k n -- hits) distributes k hits across n steps, `euclidrot` (k n r -- hits) adds rotation offset. - Shorthand float syntax: `.25` parses as `0.25`, `-.5` parses as `-0.5`. ### Changed - Split `words.rs` (3,078 lines) into a `words/` directory module with category-based files: `core.rs`, `sound.rs`, `effects.rs`, `sequencing.rs`, `music.rs`, `midi.rs`, plus `compile.rs` and `mod.rs`. - Renamed `tri` Forth word to `triangle`. - Sequencer rewritten with prospective lookahead scheduling. Instead of sleeping until a substep, waking late, and detecting past events, the sequencer now pre-computes all events within a ~20ms forward window. Events arrive at doux with positive time deltas, scheduled before they need to fire. Sleep+spin-wait replaced by `recv_timeout(3ms)` on the command channel. Timing no longer depends on OS sleep precision. - `audio_sample_pos` updated at buffer start instead of end, so `engine_time` reflects current playback position. - Doux grace period increased from 1ms to 50ms as a safety net (events should never be late with lookahead). - Flattened model re-export indirection; `script.rs` now exports only `ScriptEngine`. - Hue rotation step size increased from 1° to 5° for faster adjustment. - Moved catalog data (DOCS, CATEGORIES) from views to `src/model/`, eliminating state-to-view layer inversion. - Extracted shared initialization into `src/init.rs`, deduplicating ~140 lines between terminal and desktop binaries. - Split App dispatch into focused service modules (`help_nav`, `dict_nav`, `euclidean`, `clipboard`, extended `pattern_editor`), reducing `app.rs` by ~310 lines. - Moved stack preview computation from render path to input time, making editor rendering pure. - Decoupled script runtime state between UI and sequencer threads, eliminating shared mutexes on the RT path. ### Fixed - Prelude content no longer leaks into step editor. Closing the prelude editor now restores the current step's content to the buffer. - Desktop binary now loads color theme and connects MIDI devices on startup (was missing). - Audio commands no longer silently dropped when channel is full; switched to unbounded channel matching MIDI dispatch pattern. - PatternProps and EuclideanDistribution modals now use the global theme background instead of the terminal default. - Changing pattern properties is now a stage/commit operation. - Changing pattern speed only happens at pattern boundaries. - `mlockall` warning no longer appears on macOS; memory locking is now Linux-only. - `clear` now resets `at` deltas, so subsequent emits default to a single emit at position 0. ## [0.0.5] - 2026-04-02 ### Added - Mute/solo for patterns: stage with `m`/`x`, commit with `c`. Solo mutes all other patterns. Clear with `M`/`X`. - Lookahead scheduling: scripts are pre-evaluated ahead of time and audio commands are scheduled at precise beat positions, improving timing accuracy under CPU load. - Realtime thread scheduling (`SCHED_FIFO`) for sequencer thread on Unix systems, improving timing reliability. - Deep into the Linux hellscape: trying to get reliable performance, better stability, etc. ### Fixed - Editor completion popup no longer steals arrow keys. Arrow keys always move the cursor; use Ctrl+N/Ctrl+P to navigate the completion list. ## [0.0.4] - 2026-02-02 ### Added - Double-stack words: `2dup`, `2drop`, `2swap`, `2over`. - `forget` word to remove user-defined words from the dictionary. - Active patterns panel showing playing patterns with bank, pattern, iteration count, and step position. - Configurable visualization layout (Top/Bottom/Left/Right) for scope and spectrum placement. - Euclidean distribution modal to spread a step's script across the pattern using Euclidean rhythms. - Fairyfloss theme (pastel candy colors by sailorhg). - Hot Dog Stand theme (classic Windows 3.1 red/yellow). - Hue rotation option in Options menu to shift all theme colors (0-360°). ### Changed - Title view now adapts to smaller terminal sizes gracefully. ### Fixed - Scope/spectrum ratio asymmetry in Left/Right layout modes. - Updated `cpal` dependency from 0.15 to 0.17 to fix type mismatch with `doux` audio backend. - Copy/paste (Ctrl+C/V/X) not working in desktop version due to egui intercepting clipboard shortcuts. ## [0.0.3] - 2026-02-02 ### Added - Polyphonic parameters: param words (`note`, `freq`, `gain`, etc.) and sound words now consume the entire stack, enabling polyphony (e.g., `60 64 67 note sine s .` emits 3 voices). - New random distribution words: `exprand` (exponential) and `logrand` (logarithmic). - Music theory chord words: `maj`, `m`, `dim`, `aug`, `sus2`, `sus4`, `maj7`, `min7`, `dom7`, `dim7`, `m7b5`, `minmaj7`, `aug7`, `maj6`, `min6`, `dom9`, `maj9`, `min9`, `dom11`, `min11`, `dom13`, `add9`, `add11`, `madd9`, `dom7b9`, `dom7s9`, `dom7b5`, `dom7s5`. - Playing patterns are now saved with the project and restored on load. ### Changed - `at` now consumes the entire stack for time offsets; polyphony multiplies with deltas (2 notes × 2 times = 4 voices). - Iterator (`iter`) now resets when a pattern restarts. - Project loading now properly resets state: stops all patterns, clears user variables/dictionary, and clears queued changes. ### Removed - `tcycle` word (replaced by polyphonic parameter behavior). ## [0.0.2] - 2026-02-01 - CI testing and codebase cleanup ## [0.0.1] - Initial Release - CI testing