diff --git a/docs/about_forth.md b/docs/about_forth.md new file mode 100644 index 0000000..9cbe28a --- /dev/null +++ b/docs/about_forth.md @@ -0,0 +1,112 @@ +# About Forth + +Forth is a stack-based programming language created by Charles H. Moore in the early 1970s. It was designed for simplicity, directness, and interactive exploration. Forth has been used for many years to do scientific work and program embedded systems: controlling telescopes, running on devices used in space missions, etc. Forth quickly evolved into multiple implementations. None of them really reached an incredible popularity. Nonetheless, the ideas behind Forth continue to garner the interest of many different people in very different (often unrelated) fields. Nowadays, Forth languages are sometimes used by hackers and artists for their peculiarities. A Forth implementation is often simple, direct and beautiful. Forth is an elegant and minimal language to learn. It is easy to understand, to extend and to apply to a specific task. The Forth we use in Cagire is specialized in making live music. + +## Why Forth? + +Most programming languages nowadays use a complex syntax made of `variables`, `expressions` and `statements` like `x = 3 + 4`. Forth works differently. It is way more simple than that, has almost no syntax, and performs computations in a quite unique way. You push values onto a `stack` and apply `words` that transform them: + +```forth +3 4 + +``` + +This program leaves the number `7` on the stack. There are no variables, no parentheses, no syntax to remember. You just end up with words and numbers separated by spaces. For live coding music, this directness is quite exciting. All you do is thinking in terms of transformations and adding things to the stack: take a note, shift it up, add reverb, play it. + +## The Stack + +The stack is where values live. When you type a number, it goes on the stack. When you type a word, it usually takes values off and puts new ones back. + +```forth +3 ( stack: 3 ) +4 ( stack: 3 4 ) ++ ( stack: 7 ) +``` + +The stack is `last-in, first-out`. The most recent value is always on top. This means that its often better to read Forth programs from the end to the beginning: from right to left, from the bottom to the top. + +## Words + +Everything in Forth is either a `number` or a `word`. Words are like functions but conceptually simpler. They have no arguments or return values in the traditional sense. They just manipulate the stack directly. + +```forth +dup ( duplicate the top value ) +drop ( discard the top value ) +swap ( swap the top two values ) +``` + +Words compose naturally on the stack. To double a number: + +```forth +3 dup + ( 3 3 +) +``` + +There are a lot of words in a Forth, and thus, Cagire has a `Dictionary` embedded directly into the application. You can also create your own words. They will work just like the already existing words. There are good reasons to create new words on-the-fly: + +- To make synth definitions. +- To abstract _some piece of code_ that you use frequently. +- To share data and processes between different steps. + +## Values + +Four types of values can live on the stack: + +- **Integers**: `42`, `-7`, `0` +- **Floats**: `0.5`, `3.14`, `-1.0` +- **Strings**: `"kick"`, `"hello"` +- **Quotations**: `{ dup + }` (code as data) + +Quotations are special. They let you pass code around as a value. This is how conditionals and loops work. Think nothing of it for now, you will learn more about how to use it later on. + +## Stack Notation + +Documentation uses a notation to show what words do: + +``` +( before -- after ) +``` + +For example, `+` has the signature `( a b -- sum )`. It takes two values and leaves one. + +## The Command Register + +Traditional Forth programs print text to a terminal. Cagire's Forth builds sound commands instead. This happens through an invisible accumulator called the command register. + +The command register has two parts: +- A **sound name** (what instrument to play) +- A list of **parameters** (how to play it) + +Three types of words interact with it: + +```forth +kick sound ;; sets the sound name +0.5 gain ;; adds a parameter +. ;; emits the command and clears the register +``` + +The word `sound` (or its shorthand `s`) sets what sound to play. Parameter words like `gain`, `freq`, `decay`, or `verb` add key-value pairs to the register. Nothing happens until you emit with `.` (dot). At that moment, the register is packaged into a command and sent to the audio engine. + +This design lets you build sounds incrementally: + +```forth +"sine" sound +c4 note +0.5 gain +0.3 decay +0.4 verb +. +``` + +Each line adds something to the register. The final `.` triggers the sound. You can also write it all on one line: + +```forth +"sine" s c4 note 0.5 gain 0.3 decay 0.4 verb . +``` + +The order of parameters does not matter. You can even emit multiple times in a single step: If you need to discard the register without emitting, use `clear`: + +```forth +"kick" s 0.5 gain clear ;; nothing plays, register is emptied +"hat" s . ;; only the hat plays +``` + +This is useful when conditionals might cancel a sound before it emits. diff --git a/docs/dictionary.md b/docs/dictionary.md index d3d9602..9c42b0f 100644 --- a/docs/dictionary.md +++ b/docs/dictionary.md @@ -1,6 +1,6 @@ # The Dictionary -Cagire includes a built-in dictionary of all Forth words. Press `Ctrl+Down` repeatedly to reach the **Dict** view, or navigate directly with `Ctrl+Arrow` keys. +Cagire includes a built-in dictionary of all the internal Forth words. Press `Ctrl+Up` to reach the **Dict** view. ## Using the Dictionary diff --git a/docs/editing.md b/docs/editing.md new file mode 100644 index 0000000..ee9012f --- /dev/null +++ b/docs/editing.md @@ -0,0 +1,62 @@ +# Editing a Step + +Each step in Cagire contains a Forth script. When the sequencer reaches that step, it runs the script to produce sound. This is where you write your music. Press `Enter` when hovering over any step to open the `code editor`. The editor appears as a modal overlay with the step number in the title bar. If the step is a linked step (shown with an arrow like `→05`), pressing `Enter` navigates to the source step instead. + +## Writing Scripts + +Scripts are written in Forth. Type words and numbers separated by spaces. The simplest script that makes sound is: + +```forth +sine sound . +``` + +Add parameters before words to modify them: + +```forth +c4 note 0.75 decay sine sound . +``` + +Writing long lines is not recommended because it can become quite unmanageable. Instead, break them into multiple lines for clarity: + +```forth +c4 note +0.75 decay +sine sound +0.4 verb +. +``` + +## Saving + +- `Esc` - Save and close the editor +- `Ctrl+E` - Save without closing + +When you save, the script is compiled and sent to the sequencer. If there's an error, a message appears briefly at the bottom of the screen. You will also receive visual feedback in the form of a flashing window when saving / evaluating a script. + +## Completion + +As you type, the editor suggests matching Forth words. The completion list shows all built-in words that start with your current input. Press `Tab` to insert the selected suggestion, or `Esc` to dismiss the list. Use arrow keys to navigate between suggestions. + +Completion helps you discover words without memorizing them all. Type a few letters and browse what's available. For example, typing `ver` will suggest `verb` (reverb), typing `fil` will show filter-related words. + +## Debugging + +Press `Ctrl+S` to toggle the stack display. This shows the stack state evaluated up to the cursor line, useful for understanding how values flow through your script. Press `Ctrl+R` to execute the script immediately without waiting for the sequencer to reach the step. + +## Keybindings + +| Key | Action | +|-----|--------| +| `Esc` | Save and close | +| `Ctrl+E` | Save without closing | +| `Ctrl+R` | Execute script once | +| `Ctrl+S` | Toggle stack display | +| `Ctrl+F` | Search | +| `Ctrl+N` | Find next | +| `Ctrl+P` | Find previous | +| `Ctrl+A` | Select all | +| `Ctrl+C` | Copy | +| `Ctrl+X` | Cut | +| `Ctrl+V` | Paste | +| `Shift+Arrows` | Extend selection | +| `Tab` | Accept completion | diff --git a/docs/grid.md b/docs/grid.md index 2fac11c..af322d5 100644 --- a/docs/grid.md +++ b/docs/grid.md @@ -1,16 +1,14 @@ # The Sequencer Grid -The sequencer grid is the heart of Cagire. Each cell represents a step that can contain a Forth script to generate sound. - -## Structure - -- **Steps**: Up to 128 per pattern, displayed 32 at a time -- **Patterns**: Up to 32 per bank -- **Banks**: Up to 32 per project +The sequencer grid is the main view of Cagire. This is the one you see when you open the application. On this view, you can see the step sequencer grid and edit each step using the `code editor`. At the top, you can optionally display an oscilloscope and a spectrum analyzer. ## Navigation -Use arrow keys to move between steps. The grid wraps around at pattern boundaries. +Use arrow keys to move between steps. The grid wraps around at pattern boundaries. You can move in any direction. + +## Preview + +Press `P` to enter preview mode. In preview mode, a view-only code editor opens so that you can see the script of the currently playing step. While in preview mode, you can still move around the grid. Press `Esc` to exit preview mode. ## Selection @@ -18,20 +16,20 @@ Hold `Shift` while pressing arrow keys to select multiple steps. Press `Esc` to ## Editing Steps -- `Enter` - Open the script editor -- `t` - Toggle step active/inactive -- `r` - Rename a step -- `Del` - Delete selected steps +- `Enter` - Open the script editor. +- `t` - Toggle step active/inactive. +- `r` - Rename a step. +- `Del` - Delete selected steps. ## Copy & Paste -- `Ctrl+C` - Copy selected steps -- `Ctrl+V` - Paste as copies -- `Ctrl+B` - Paste as linked steps -- `Ctrl+D` - Duplicate selection -- `Ctrl+H` - Harden links (convert to copies) +- `Ctrl+C` - Copy selected steps. +- `Ctrl+V` - Paste as copies. +- `Ctrl+B` - Paste as linked steps. +- `Ctrl+D` - Duplicate selection. +- `Ctrl+H` - Harden links (convert to copies). -Linked steps share the same script as their source. When you edit the source, all linked steps update automatically. +`Linked steps` share the same script as their source. When you edit the source, all linked steps update automatically. This is an extremely important and powerful feature. It allows you to create complex patterns with minimal effort. `Ctrl+H` is your best friend to manage linked steps and convert them to real steps. ## Pattern Controls @@ -51,4 +49,4 @@ Linked steps share the same script as their source. When you edit the source, al - **Highlighted cell** - Currently playing step - **Colored backgrounds** - Linked steps share colors by source -- **Arrow prefix** (→05) - Step is linked to step 05 +- **Arrow prefix** (`→05`) - Step is linked to step 05 diff --git a/src/views/help_view.rs b/src/views/help_view.rs index ce9426e..903f6fc 100644 --- a/src/views/help_view.rs +++ b/src/views/help_view.rs @@ -33,8 +33,10 @@ const DOCS: &[DocEntry] = &[ ), Topic("Stage / Commit", include_str!("../../docs/staging.md")), Topic("Using the Sequencer", include_str!("../../docs/grid.md")), + Topic("Editing a Step", include_str!("../../docs/editing.md")), // Forth fundamentals Section("Forth"), + Topic("About Forth", include_str!("../../docs/about_forth.md")), Topic("The Dictionary", include_str!("../../docs/dictionary.md")), Topic("The Stack", include_str!("../../docs/stack.md")), Topic("Arithmetic", include_str!("../../docs/arithmetic.md")),