---
import fs from 'node:fs';
const cargo = fs.readFileSync('../Cargo.toml', 'utf-8');
const version = cargo.match(/\[workspace\.package\]\s*\nversion\s*=\s*"([^"]+)"/)?.[1];
const DL = 'https://dlcagire.raphaelforment.fr';
---

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cagire - Forth-based live coding sequencer</title>
    <meta name="description" content="Forth-based live coding music sequencer">
    <meta name="author" content="Raphaël Forment">
    <meta name="keywords" content="live coding, forth, sequencer, music, audio, ableton link, synthesizer">
    <link rel="canonical" href="https://cagire.raphaelforment.fr">
    <meta property="og:title" content="Cagire - Forth-based live coding sequencer">
    <meta property="og:description" content="Forth-based live coding music sequencer">
    <meta property="og:type" content="website">
    <meta property="og:url" content="https://cagire.raphaelforment.fr">
    <meta name="twitter:card" content="summary">
    <meta name="twitter:title" content="Cagire - Forth-based live coding sequencer">
    <meta name="twitter:description" content="Forth-based live coding music sequencer">
    <link rel="icon" href="/favicon.ico">
    <meta property="og:image" content="/Cagire.png">
    <link rel="stylesheet" href="/style.css">
</head>
<body>
    <div class="kofi-popup" id="kofi-popup">
        <button class="kofi-close" id="kofi-close" aria-label="Close">&times;</button>
        <p>Consider donating, I need to buy some coffee! Donations help me to rent servers and to secure funding for working on software.</p>
        <a href="https://ko-fi.com/raphaelbubo" target="_blank" rel="noopener">Support on Ko-fi</a>
    </div>
    <header>
        <img class="icon" src="/Cagire.png" alt="Cagire">
        <div>
            <h1>CAGIRE: LIVE CODING IN FORTH</h1>
            <p class="subtitle">AGPL-3.0 · Raphaël Maurice Forment · 2026 · v{version}</p>
        </div>
    </header>

    <div class="examples-grid">
        <div class="example-cell"><img src="/one_pic.webp" alt="Cagire screenshot 1"></div>
        <div class="example-cell"><img src="/second_pic.webp" alt="Cagire screenshot 2"></div>
        <div class="example-cell"><img src="/third_pic.webp" alt="Cagire screenshot 3"></div>
        <div class="example-cell"><img src="/fourth_pic.webp" alt="Cagire screenshot 4"></div>
        <div class="example-cell"><img src="/fifth_pic.webp" alt="Cagire screenshot 5"></div>
        <div class="example-cell"><img src="/sixth_pic.webp" alt="Cagire screenshot 6"></div>
        <div class="example-cell"><img src="/seventh_pic.webp" alt="Cagire screenshot 7"></div>
        <div class="example-cell"><img src="/eight_pic.webp" alt="Cagire screenshot 8"></div>
        <div class="example-cell"><img src="/ninth_pic.webp" alt="Cagire screenshot 9"></div>
    </div>

    <h2>Download</h2>
    <table class="downloads-table">
        <tr>
            <th>Platform</th>
            <th>Desktop</th>
            <th>Terminal</th>
        </tr>
        <tr>
            <td>macOS (Universal)</td>
            <td colspan="2"><a href={`${DL}/cagire-macos-universal.pkg`}>.pkg</a></td>
        </tr>
        <tr>
            <td>macOS (ARM)</td>
            <td><a href={`${DL}/cagire-macos-aarch64-desktop.app.zip`}>.app</a></td>
            <td><a href={`${DL}/cagire-macos-aarch64.tar.gz`}>.tar.gz</a></td>
        </tr>
        <tr>
            <td>macOS (Intel)</td>
            <td><a href={`${DL}/cagire-macos-x86_64-desktop.app.zip`}>.app</a></td>
            <td><a href={`${DL}/cagire-macos-x86_64.tar.gz`}>.tar.gz</a></td>
        </tr>
        <tr>
            <td>Windows</td>
            <td><a href={`${DL}/cagire-windows-x86_64-desktop.exe`}>.exe</a></td>
            <td><a href={`${DL}/cagire-windows-x86_64.zip`}>.zip</a></td>
        </tr>
        <tr>
            <td>Linux</td>
            <td><a href={`${DL}/cagire-linux-x86_64-desktop.deb`}>.deb</a></td>
            <td><a href={`${DL}/cagire-linux-x86_64.tar.gz`}>.tar.gz</a></td>
        </tr>
    </table>
    <p class="note">Source code and issue tracker on <a href="https://github.com/Bubobubobubobubo/cagire">GitHub</a>. You can also compile the software yourself from source!</p>


    <h2>About</h2>
    <p>Cagire is a step sequencer where each step contains a Forth script instead of typical note data. When the sequencer reaches a step, it runs the associated script. Scripts can produce sound, trigger samples, apply effects, or do nothing at all. You are free to define what your scripts will do. Cagire includes a built-in audio engine called <a href="https://doux.livecoding.fr">Doux</a>. No external software is needed to make sound. It comes with oscillators, sample players, filters, reverb, delay, distortion, and more.</p>

    <h2>Features (click to learn more!)</h2>
    <div class="features">
        <div class="feature-tags">
            <button data-desc="Powered by an audio engine crafted specifically for live coding. Classic waveforms (aliased and non-aliased). Noise generators. Mutable Instruments Plaits modes (modal, virtual analog, waveshaping, FM, granular, additive, etc). Small but fun FM synth with 2 operators, multiple algorithms and feedback control. Wavetable scanning with LFO control: bring your own wavetables. Sub-oscillators with independent waveform and octave. Sample playback with slicing, time-stretching and gating. Live microphone input. Configurable polyphony (default 32 voices). 8 independent effect buses (orbits).">Synthesis</button>
            <button data-desc="Two reverb algorithms, Four delay types: standard, ping-pong, tape and multitap. Feedback, chorus, phaser and flanger with configurable depth, sweep and feedback. Distortion, bitcrusher, wave folding and wave wrapping. Comb filter with tunable frequency, feedback and damping. Audio-rate modulation for the final touch. ">Effects</button>
            <button data-desc="Multimode filter with lowpass, highpass and bandpass modes, each with its own ADSR envelope, frequency and resonance. Selectable filter slope (12, 24 or 48 dB/oct). Ladder filter variants (lowpass, highpass, bandpass) if you like that! 3-band parametric EQ (lo/mid/hi) and a tilt EQ for broad tonal shaping.">Filters</button>
            <button data-desc="4 MIDI inputs and 4 MIDI outputs. Send and receive CC messages, pitch bend, channel aftertouch and program changes. MIDI clock output (clock, start, stop, continue). Read incoming CC values in real-time from any device. Full channel selection per voice.">MIDI</button>
            <button data-desc="Write notes by name (c4, d#5), build chords and scales from a rich built-in library. Convert between MIDI and frequency on the fly. Express musical ideas directly in code.">Theory</button>
            <button data-desc="Conditional execution and probability branching built into the language. Weighted random choices, coin flips, euclidean rhythms with rotation. Multiple random distributions, Perlin noise, seeded randomness. Cagire is designed to be generative and fun.">Probability</button>
            <button data-desc="Everything moves. Audio-rate LFOs, slides, ramps, envelopes, jitter, drunk walks, vibrato, ring modulation — all available as simple words you drop into any script. Shape any parameter over time with multiple curve types. Add controlled randomness or smooth motion at your heart's content.">Modulation</button>
            <button data-desc="Tempo sync with any Ableton Link-enabled app or hardware on the same network. Shared tempo and phase across all connected devices. You can jam with your friends!">Ableton Link</button>
            <button data-desc="32 banks * 32 patterns * 1024 steps per project. That's ~1.048.000 scripts per project, way too much! Play as much patterns as you want simultaneously.">Projects</button>
                <button data-desc="Forth is concatenative, minimal and radically extensible. No syntax to learn — just words separated by spaces. You build your own vocabulary on top of the language, growing it toward your musical ideas. Expressions are terse and compositional: small words combine into larger ones. Forth rewards exploration and improvisation, making it a natural fit for live coding.">Forth</button>
            <button data-desc="Per-pattern speed control, sync modes (loop, play-once, trigger) and launch quantization (bar, beat, step or immediate). Pattern chaining for longer sequences. Scripts are time-aware: they know their beat position, phase, iteration count and tempo.">Sequencer</button>
            <button data-desc="Play multiple patterns simultaneously. Mute and solo staging with quantized execution. Fill mode for live key input. Stage pattern starts and stops to land on the beat. Built for improvisation on stage.">Play Live</button>
            <button data-desc="Works in the terminal for minimal setups. Desktop mode (egui) with mouse support if you feel fancy. Runs on macOS (ARM and Intel), Windows and Linux.">Cross-platform</button>
            <button data-desc="Many built-in color themes to match your taste. Hue rotation for themes can help you to get that special wonky look.">Themes</button>
            <button data-desc="Every built-in word is documented with stack effect notation, description and usage example. A full help system covering everything from basics to advanced techniques. Browse the dictionary and help pages without leaving the app. Inline help to learn Forth and Cagire.">Dictionary</button>
        </div>
        <div class="feature-desc" id="feature-desc"></div>
    </div>

    <h2>Live Coding</h2>
    <p>Live coding is a technique where a programmer writes code in real-time in front of an audience. It is a way to experiment with code, to share openly, to express yourself through code. It can be technical, poetical, weird, preferably all at once. Live coding can be used to create music, visual art, and other forms of media. Live coding is an autotelic activity: doing it is its own reward. There are no errors, only fun. Learn more at <a href="https://toplap.org">TOPLAP</a> or <a href="https://livecoding.fr">livecoding.fr</a>.</p>

    <video src="/mono_cagire.mp4" autoplay muted loop playsinline></video>

    <p class="colophon">
        <a href="https://raphaelforment.fr">BuboBubo</a> · Audio engine: <a href="https://doux.livecoding.fr">Doux</a> · <a href="https://github.com/Bubobubobubobubo/cagire">GitHub</a> · AGPL-3.0    </p>

    <script is:inline src="/script.js"></script>
</body>
</html>
