Feat: refactoring by breaking words in multiple files
This commit is contained in:
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
|
||||
### 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.
|
||||
@@ -28,6 +29,7 @@ All notable changes to this project will be documented in this file.
|
||||
- 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] - Unreleased
|
||||
|
||||
|
||||
@@ -186,5 +186,6 @@ impl CmdRegister {
|
||||
pub(super) fn clear(&mut self) {
|
||||
self.sound = None;
|
||||
self.params.clear();
|
||||
self.deltas.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1113,7 +1113,7 @@ fn emit_output(
|
||||
if !out.ends_with('/') {
|
||||
out.push('/');
|
||||
}
|
||||
let _ = write!(&mut out, "dur/{step_duration}");
|
||||
let _ = write!(&mut out, "dur/{}", step_duration * 4.0);
|
||||
}
|
||||
|
||||
if sound.is_some() && delaytime_idx.is_none() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
260
crates/forth/src/words/compile.rs
Normal file
260
crates/forth/src/words/compile.rs
Normal file
@@ -0,0 +1,260 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::ops::Op;
|
||||
use crate::theory;
|
||||
use crate::types::{Dictionary, SourceSpan};
|
||||
|
||||
use super::{lookup_word, WordCompile::*};
|
||||
|
||||
pub(super) fn simple_op(name: &str) -> Option<Op> {
|
||||
Some(match name {
|
||||
"dup" => Op::Dup,
|
||||
"dupn" => Op::Dupn,
|
||||
"drop" => Op::Drop,
|
||||
"swap" => Op::Swap,
|
||||
"over" => Op::Over,
|
||||
"rot" => Op::Rot,
|
||||
"nip" => Op::Nip,
|
||||
"tuck" => Op::Tuck,
|
||||
"2dup" => Op::Dup2,
|
||||
"2drop" => Op::Drop2,
|
||||
"2swap" => Op::Swap2,
|
||||
"2over" => Op::Over2,
|
||||
"+" => Op::Add,
|
||||
"-" => Op::Sub,
|
||||
"*" => Op::Mul,
|
||||
"/" => Op::Div,
|
||||
"mod" => Op::Mod,
|
||||
"neg" => Op::Neg,
|
||||
"abs" => Op::Abs,
|
||||
"floor" => Op::Floor,
|
||||
"ceil" => Op::Ceil,
|
||||
"round" => Op::Round,
|
||||
"min" => Op::Min,
|
||||
"max" => Op::Max,
|
||||
"pow" => Op::Pow,
|
||||
"sqrt" => Op::Sqrt,
|
||||
"sin" => Op::Sin,
|
||||
"cos" => Op::Cos,
|
||||
"log" => Op::Log,
|
||||
"=" => Op::Eq,
|
||||
"!=" => Op::Ne,
|
||||
"lt" => Op::Lt,
|
||||
"gt" => Op::Gt,
|
||||
"<=" => Op::Le,
|
||||
">=" => Op::Ge,
|
||||
"and" => Op::And,
|
||||
"or" => Op::Or,
|
||||
"not" => Op::Not,
|
||||
"xor" => Op::Xor,
|
||||
"nand" => Op::Nand,
|
||||
"nor" => Op::Nor,
|
||||
"ifelse" => Op::IfElse,
|
||||
"pick" => Op::Pick,
|
||||
"sound" => Op::NewCmd,
|
||||
"." => Op::Emit,
|
||||
"rand" => Op::Rand,
|
||||
"exprand" => Op::ExpRand,
|
||||
"logrand" => Op::LogRand,
|
||||
"seed" => Op::Seed,
|
||||
"cycle" => Op::Cycle,
|
||||
"pcycle" => Op::PCycle,
|
||||
"choose" => Op::Choose,
|
||||
"every" => Op::Every,
|
||||
"chance" => Op::ChanceExec,
|
||||
"prob" => Op::ProbExec,
|
||||
"coin" => Op::Coin,
|
||||
"mtof" => Op::Mtof,
|
||||
"ftom" => Op::Ftom,
|
||||
"?" => Op::When,
|
||||
"!?" => Op::Unless,
|
||||
"tempo!" => Op::SetTempo,
|
||||
"speed!" => Op::SetSpeed,
|
||||
"at" => Op::At,
|
||||
"adsr" => Op::Adsr,
|
||||
"ad" => Op::Ad,
|
||||
"apply" => Op::Apply,
|
||||
"ramp" => Op::Ramp,
|
||||
"triangle" => Op::Triangle,
|
||||
"range" => Op::Range,
|
||||
"perlin" => Op::Perlin,
|
||||
"chain" => Op::Chain,
|
||||
"loop" => Op::Loop,
|
||||
"oct" => Op::Oct,
|
||||
"clear" => Op::ClearCmd,
|
||||
".." => Op::IntRange,
|
||||
"gen" => Op::Generate,
|
||||
"geom.." => Op::GeomRange,
|
||||
"times" => Op::Times,
|
||||
"m." => Op::MidiEmit,
|
||||
"ccval" => Op::GetMidiCC,
|
||||
"mclock" => Op::MidiClock,
|
||||
"mstart" => Op::MidiStart,
|
||||
"mstop" => Op::MidiStop,
|
||||
"mcont" => Op::MidiContinue,
|
||||
"forget" => Op::Forget,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_note_name(name: &str) -> Option<i64> {
|
||||
let name = name.to_lowercase();
|
||||
let bytes = name.as_bytes();
|
||||
|
||||
if bytes.len() < 2 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let base = match bytes[0] {
|
||||
b'c' => 0,
|
||||
b'd' => 2,
|
||||
b'e' => 4,
|
||||
b'f' => 5,
|
||||
b'g' => 7,
|
||||
b'a' => 9,
|
||||
b'b' => 11,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let (modifier, octave_start) = match bytes[1] {
|
||||
b'#' | b's' => (1, 2),
|
||||
b'b' if bytes.len() > 2 && bytes[2].is_ascii_digit() => (-1, 2),
|
||||
b'0'..=b'9' => (0, 1),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let octave_str = &name[octave_start..];
|
||||
let octave: i64 = octave_str.parse().ok()?;
|
||||
|
||||
if !(-1..=9).contains(&octave) {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((octave + 1) * 12 + base + modifier)
|
||||
}
|
||||
|
||||
fn parse_interval(name: &str) -> Option<i64> {
|
||||
let simple = match name {
|
||||
"P1" | "unison" => 0,
|
||||
"m2" => 1,
|
||||
"M2" => 2,
|
||||
"m3" => 3,
|
||||
"M3" => 4,
|
||||
"P4" => 5,
|
||||
"aug4" | "dim5" | "tritone" => 6,
|
||||
"P5" => 7,
|
||||
"m6" => 8,
|
||||
"M6" => 9,
|
||||
"m7" => 10,
|
||||
"M7" => 11,
|
||||
"P8" => 12,
|
||||
"m9" => 13,
|
||||
"M9" => 14,
|
||||
"m10" => 15,
|
||||
"M10" => 16,
|
||||
"P11" => 17,
|
||||
"aug11" => 18,
|
||||
"P12" => 19,
|
||||
"m13" => 20,
|
||||
"M13" => 21,
|
||||
"m14" => 22,
|
||||
"M14" => 23,
|
||||
"P15" => 24,
|
||||
_ => return None,
|
||||
};
|
||||
Some(simple)
|
||||
}
|
||||
|
||||
pub(crate) fn compile_word(
|
||||
name: &str,
|
||||
span: Option<SourceSpan>,
|
||||
ops: &mut Vec<Op>,
|
||||
dict: &Dictionary,
|
||||
) -> bool {
|
||||
match name {
|
||||
"linramp" => {
|
||||
ops.push(Op::PushFloat(1.0, span));
|
||||
ops.push(Op::Ramp);
|
||||
return true;
|
||||
}
|
||||
"expramp" => {
|
||||
ops.push(Op::PushFloat(3.0, span));
|
||||
ops.push(Op::Ramp);
|
||||
return true;
|
||||
}
|
||||
"logramp" => {
|
||||
ops.push(Op::PushFloat(0.3, span));
|
||||
ops.push(Op::Ramp);
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(pattern) = theory::lookup(name) {
|
||||
ops.push(Op::Degree(pattern));
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(intervals) = theory::chords::lookup(name) {
|
||||
ops.push(Op::Chord(intervals));
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(word) = lookup_word(name) {
|
||||
match &word.compile {
|
||||
Simple => {
|
||||
if let Some(op) = simple_op(word.name) {
|
||||
ops.push(op);
|
||||
}
|
||||
}
|
||||
Context(ctx) => ops.push(Op::GetContext((*ctx).into())),
|
||||
Param => ops.push(Op::SetParam(word.name.into())),
|
||||
Probability(p) => {
|
||||
ops.push(Op::PushFloat(*p, None));
|
||||
ops.push(Op::ChanceExec);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(var_name) = name.strip_prefix('@') {
|
||||
if !var_name.is_empty() {
|
||||
ops.push(Op::PushStr(Arc::from(var_name), span));
|
||||
ops.push(Op::Get);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(var_name) = name.strip_prefix('!') {
|
||||
if !var_name.is_empty() {
|
||||
ops.push(Op::PushStr(Arc::from(var_name), span));
|
||||
ops.push(Op::Set);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(midi) = parse_note_name(name) {
|
||||
ops.push(Op::PushInt(midi, span));
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(semitones) = parse_interval(name) {
|
||||
ops.push(Op::Dup);
|
||||
ops.push(Op::PushInt(semitones, span));
|
||||
ops.push(Op::Add);
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(op) = simple_op(name) {
|
||||
ops.push(op);
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(body) = dict.lock().get(name) {
|
||||
ops.extend(body.iter().cloned());
|
||||
return true;
|
||||
}
|
||||
|
||||
ops.push(Op::PushStr(Arc::from(name), span));
|
||||
true
|
||||
}
|
||||
532
crates/forth/src/words/core.rs
Normal file
532
crates/forth/src/words/core.rs
Normal file
@@ -0,0 +1,532 @@
|
||||
use super::{Word, WordCompile::*};
|
||||
|
||||
// Stack, Arithmetic, Comparison, Logic, Control, Variables, Definitions
|
||||
pub(super) const WORDS: &[Word] = &[
|
||||
// Stack manipulation
|
||||
Word {
|
||||
name: "dup",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a -- a a)",
|
||||
desc: "Duplicate top of stack",
|
||||
example: "3 dup => 3 3",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "dupn",
|
||||
aliases: &["!"],
|
||||
category: "Stack",
|
||||
stack: "(a n -- a a ... a)",
|
||||
desc: "Duplicate a onto stack n times",
|
||||
example: "2 4 dupn => 2 2 2 2",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "drop",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a --)",
|
||||
desc: "Remove top of stack",
|
||||
example: "1 2 drop => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "swap",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a b -- b a)",
|
||||
desc: "Exchange top two items",
|
||||
example: "1 2 swap => 2 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "over",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a b -- a b a)",
|
||||
desc: "Copy second to top",
|
||||
example: "1 2 over => 1 2 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "rot",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a b c -- b c a)",
|
||||
desc: "Rotate top three",
|
||||
example: "1 2 3 rot => 2 3 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "nip",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a b -- b)",
|
||||
desc: "Remove second item",
|
||||
example: "1 2 nip => 2",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "tuck",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a b -- b a b)",
|
||||
desc: "Copy top under second",
|
||||
example: "1 2 tuck => 2 1 2",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "2dup",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a b -- a b a b)",
|
||||
desc: "Duplicate top two values",
|
||||
example: "1 2 2dup => 1 2 1 2",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "2drop",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a b --)",
|
||||
desc: "Drop top two values",
|
||||
example: "1 2 3 2drop => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "2swap",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a b c d -- c d a b)",
|
||||
desc: "Swap top two pairs",
|
||||
example: "1 2 3 4 2swap => 3 4 1 2",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "2over",
|
||||
aliases: &[],
|
||||
category: "Stack",
|
||||
stack: "(a b c d -- a b c d a b)",
|
||||
desc: "Copy second pair to top",
|
||||
example: "1 2 3 4 2over => 1 2 3 4 1 2",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
// Arithmetic
|
||||
Word {
|
||||
name: "+",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a b -- a+b)",
|
||||
desc: "Add",
|
||||
example: "2 3 + => 5",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "-",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a b -- a-b)",
|
||||
desc: "Subtract",
|
||||
example: "5 3 - => 2",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "*",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a b -- a*b)",
|
||||
desc: "Multiply",
|
||||
example: "3 4 * => 12",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "/",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a b -- a/b)",
|
||||
desc: "Divide",
|
||||
example: "10 2 / => 5",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "mod",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a b -- a%b)",
|
||||
desc: "Modulo",
|
||||
example: "7 3 mod => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "neg",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a -- -a)",
|
||||
desc: "Negate",
|
||||
example: "5 neg => -5",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "abs",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a -- |a|)",
|
||||
desc: "Absolute value",
|
||||
example: "-5 abs => 5",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "floor",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(f -- n)",
|
||||
desc: "Round down to integer",
|
||||
example: "3.7 floor => 3",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "ceil",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(f -- n)",
|
||||
desc: "Round up to integer",
|
||||
example: "3.2 ceil => 4",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "round",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(f -- n)",
|
||||
desc: "Round to nearest integer",
|
||||
example: "3.5 round => 4",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "min",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a b -- min)",
|
||||
desc: "Minimum of two values",
|
||||
example: "3 5 min => 3",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "max",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a b -- max)",
|
||||
desc: "Maximum of two values",
|
||||
example: "3 5 max => 5",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "pow",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a b -- a^b)",
|
||||
desc: "Exponentiation",
|
||||
example: "2 3 pow => 8",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "sqrt",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a -- √a)",
|
||||
desc: "Square root",
|
||||
example: "16 sqrt => 4",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "sin",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a -- sin(a))",
|
||||
desc: "Sine (radians)",
|
||||
example: "3.14159 2 / sin => 1.0",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "cos",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a -- cos(a))",
|
||||
desc: "Cosine (radians)",
|
||||
example: "0 cos => 1.0",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "log",
|
||||
aliases: &[],
|
||||
category: "Arithmetic",
|
||||
stack: "(a -- ln(a))",
|
||||
desc: "Natural logarithm",
|
||||
example: "2.718 log => 1.0",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
// Comparison
|
||||
Word {
|
||||
name: "=",
|
||||
aliases: &[],
|
||||
category: "Comparison",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Equal",
|
||||
example: "3 3 = => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "!=",
|
||||
aliases: &["<>"],
|
||||
category: "Comparison",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Not equal",
|
||||
example: "3 4 != => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lt",
|
||||
aliases: &[],
|
||||
category: "Comparison",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Less than",
|
||||
example: "2 3 lt => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "gt",
|
||||
aliases: &[],
|
||||
category: "Comparison",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Greater than",
|
||||
example: "3 2 gt => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "<=",
|
||||
aliases: &[],
|
||||
category: "Comparison",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Less or equal",
|
||||
example: "3 3 <= => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: ">=",
|
||||
aliases: &[],
|
||||
category: "Comparison",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Greater or equal",
|
||||
example: "3 3 >= => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
// Logic
|
||||
Word {
|
||||
name: "and",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Logical and",
|
||||
example: "1 1 and => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "or",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Logical or",
|
||||
example: "0 1 or => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "not",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(a -- bool)",
|
||||
desc: "Logical not",
|
||||
example: "0 not => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "xor",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Exclusive or",
|
||||
example: "1 0 xor => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "nand",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Not and",
|
||||
example: "1 1 nand => 0",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "nor",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(a b -- bool)",
|
||||
desc: "Not or",
|
||||
example: "0 0 nor => 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "ifelse",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(true-quot false-quot bool --)",
|
||||
desc: "Execute true-quot if true, else false-quot",
|
||||
example: "{ 1 } { 2 } coin ifelse",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "pick",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(..quots n --)",
|
||||
desc: "Execute nth quotation (0-indexed)",
|
||||
example: "{ 1 } { 2 } { 3 } 2 pick => 3",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "?",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(quot bool --)",
|
||||
desc: "Execute quotation if true",
|
||||
example: "{ 2 distort } 0.5 chance ?",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "!?",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(quot bool --)",
|
||||
desc: "Execute quotation if false",
|
||||
example: "{ 1 distort } 0.5 chance !?",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "apply",
|
||||
aliases: &[],
|
||||
category: "Logic",
|
||||
stack: "(quot --)",
|
||||
desc: "Execute quotation unconditionally",
|
||||
example: "{ 2 * } apply",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
// Control
|
||||
Word {
|
||||
name: "times",
|
||||
aliases: &[],
|
||||
category: "Control",
|
||||
stack: "(n quot --)",
|
||||
desc: "Execute quotation n times, @i holds current index",
|
||||
example: "4 { @i . } times => 0 1 2 3",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
// Variables
|
||||
Word {
|
||||
name: "@<var>",
|
||||
aliases: &[],
|
||||
category: "Variables",
|
||||
stack: "( -- val)",
|
||||
desc: "Fetch variable value",
|
||||
example: "@freq => 440",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "!<var>",
|
||||
aliases: &[],
|
||||
category: "Variables",
|
||||
stack: "(val --)",
|
||||
desc: "Store value in variable",
|
||||
example: "440 !freq",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
// Definitions
|
||||
Word {
|
||||
name: ":",
|
||||
aliases: &[],
|
||||
category: "Definitions",
|
||||
stack: "( -- )",
|
||||
desc: "Begin word definition",
|
||||
example: ": kick \"kick\" s emit ;",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: ";",
|
||||
aliases: &[],
|
||||
category: "Definitions",
|
||||
stack: "( -- )",
|
||||
desc: "End word definition",
|
||||
example: ": kick \"kick\" s emit ;",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "forget",
|
||||
aliases: &[],
|
||||
category: "Definitions",
|
||||
stack: "(name --)",
|
||||
desc: "Remove user-defined word from dictionary",
|
||||
example: "\"double\" forget",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
];
|
||||
792
crates/forth/src/words/effects.rs
Normal file
792
crates/forth/src/words/effects.rs
Normal file
@@ -0,0 +1,792 @@
|
||||
use super::{Word, WordCompile::*};
|
||||
|
||||
// Filter, Envelope, Reverb, Delay, Lo-fi, Stereo, Mod FX
|
||||
pub(super) const WORDS: &[Word] = &[
|
||||
// Envelope
|
||||
Word {
|
||||
name: "gain",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set volume (0-1)",
|
||||
example: "0.8 gain",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "postgain",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set post gain",
|
||||
example: "1.2 postgain",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "velocity",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set velocity",
|
||||
example: "100 velocity",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "attack",
|
||||
aliases: &["att"],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set attack time",
|
||||
example: "0.01 attack",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "decay",
|
||||
aliases: &["dec"],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set decay time",
|
||||
example: "0.1 decay",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "sustain",
|
||||
aliases: &["sus"],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set sustain level",
|
||||
example: "0.5 sustain",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "release",
|
||||
aliases: &["rel"],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set release time",
|
||||
example: "0.3 release",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "adsr",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(a d s r --)",
|
||||
desc: "Set attack, decay, sustain, release",
|
||||
example: "0.01 0.1 0.5 0.3 adsr",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "ad",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(a d --)",
|
||||
desc: "Set attack, decay (sustain=0)",
|
||||
example: "0.01 0.1 ad",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "penv",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set pitch envelope",
|
||||
example: "0.5 penv",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "patt",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set pitch attack",
|
||||
example: "0.01 patt",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "pdec",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set pitch decay",
|
||||
example: "0.1 pdec",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "psus",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set pitch sustain",
|
||||
example: "0 psus",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "prel",
|
||||
aliases: &[],
|
||||
category: "Envelope",
|
||||
stack: "(f --)",
|
||||
desc: "Set pitch release",
|
||||
example: "0.1 prel",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// Filter
|
||||
Word {
|
||||
name: "lpf",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set lowpass frequency",
|
||||
example: "2000 lpf",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lpq",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set lowpass resonance",
|
||||
example: "0.5 lpq",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lpe",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set lowpass envelope",
|
||||
example: "0.5 lpe",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lpa",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set lowpass attack",
|
||||
example: "0.01 lpa",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lpd",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set lowpass decay",
|
||||
example: "0.1 lpd",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lps",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set lowpass sustain",
|
||||
example: "0.5 lps",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lpr",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set lowpass release",
|
||||
example: "0.3 lpr",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "hpf",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set highpass frequency",
|
||||
example: "100 hpf",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "hpq",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set highpass resonance",
|
||||
example: "0.5 hpq",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "hpe",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set highpass envelope",
|
||||
example: "0.5 hpe",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "hpa",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set highpass attack",
|
||||
example: "0.01 hpa",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "hpd",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set highpass decay",
|
||||
example: "0.1 hpd",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "hps",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set highpass sustain",
|
||||
example: "0.5 hps",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "hpr",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set highpass release",
|
||||
example: "0.3 hpr",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "bpf",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set bandpass frequency",
|
||||
example: "1000 bpf",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "bpq",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set bandpass resonance",
|
||||
example: "0.5 bpq",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "bpe",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set bandpass envelope",
|
||||
example: "0.5 bpe",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "bpa",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set bandpass attack",
|
||||
example: "0.01 bpa",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "bpd",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set bandpass decay",
|
||||
example: "0.1 bpd",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "bps",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set bandpass sustain",
|
||||
example: "0.5 bps",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "bpr",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set bandpass release",
|
||||
example: "0.3 bpr",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "llpf",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set ladder lowpass frequency",
|
||||
example: "2000 llpf",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "llpq",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set ladder lowpass resonance",
|
||||
example: "0.5 llpq",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lhpf",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set ladder highpass frequency",
|
||||
example: "100 lhpf",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lhpq",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set ladder highpass resonance",
|
||||
example: "0.5 lhpq",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lbpf",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set ladder bandpass frequency",
|
||||
example: "1000 lbpf",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lbpq",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set ladder bandpass resonance",
|
||||
example: "0.5 lbpq",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "ftype",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(n --)",
|
||||
desc: "Set filter type",
|
||||
example: "1 ftype",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "eqlo",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set low shelf gain (dB)",
|
||||
example: "3 eqlo",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "eqmid",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set mid peak gain (dB)",
|
||||
example: "-2 eqmid",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "eqhi",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set high shelf gain (dB)",
|
||||
example: "1 eqhi",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "tilt",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set tilt EQ (-1 dark, 1 bright)",
|
||||
example: "-0.5 tilt",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "comb",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set comb filter mix",
|
||||
example: "0.5 comb",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "combfreq",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set comb frequency",
|
||||
example: "200 combfreq",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "combfeedback",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set comb feedback",
|
||||
example: "0.5 combfeedback",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "combdamp",
|
||||
aliases: &[],
|
||||
category: "Filter",
|
||||
stack: "(f --)",
|
||||
desc: "Set comb damping",
|
||||
example: "0.5 combdamp",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// Reverb
|
||||
Word {
|
||||
name: "verb",
|
||||
aliases: &[],
|
||||
category: "Reverb",
|
||||
stack: "(f --)",
|
||||
desc: "Set reverb mix",
|
||||
example: "0.3 verb",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "verbdecay",
|
||||
aliases: &[],
|
||||
category: "Reverb",
|
||||
stack: "(f --)",
|
||||
desc: "Set reverb decay",
|
||||
example: "2 verbdecay",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "verbdamp",
|
||||
aliases: &[],
|
||||
category: "Reverb",
|
||||
stack: "(f --)",
|
||||
desc: "Set reverb damping",
|
||||
example: "0.5 verbdamp",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "verbpredelay",
|
||||
aliases: &[],
|
||||
category: "Reverb",
|
||||
stack: "(f --)",
|
||||
desc: "Set reverb predelay",
|
||||
example: "0.02 verbpredelay",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "verbdiff",
|
||||
aliases: &[],
|
||||
category: "Reverb",
|
||||
stack: "(f --)",
|
||||
desc: "Set reverb diffusion",
|
||||
example: "0.7 verbdiff",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "size",
|
||||
aliases: &[],
|
||||
category: "Reverb",
|
||||
stack: "(f --)",
|
||||
desc: "Set size",
|
||||
example: "1 size",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// Delay
|
||||
Word {
|
||||
name: "delay",
|
||||
aliases: &[],
|
||||
category: "Delay",
|
||||
stack: "(f --)",
|
||||
desc: "Set delay mix",
|
||||
example: "0.3 delay",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "delaytime",
|
||||
aliases: &[],
|
||||
category: "Delay",
|
||||
stack: "(f --)",
|
||||
desc: "Set delay time",
|
||||
example: "0.25 delaytime",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "delayfeedback",
|
||||
aliases: &[],
|
||||
category: "Delay",
|
||||
stack: "(f --)",
|
||||
desc: "Set delay feedback",
|
||||
example: "0.5 delayfeedback",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "delaytype",
|
||||
aliases: &[],
|
||||
category: "Delay",
|
||||
stack: "(n --)",
|
||||
desc: "Set delay type",
|
||||
example: "1 delaytype",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// Lo-fi
|
||||
Word {
|
||||
name: "crush",
|
||||
aliases: &[],
|
||||
category: "Lo-fi",
|
||||
stack: "(f --)",
|
||||
desc: "Set bit crush",
|
||||
example: "8 crush",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "fold",
|
||||
aliases: &[],
|
||||
category: "Lo-fi",
|
||||
stack: "(f --)",
|
||||
desc: "Set wave fold",
|
||||
example: "2 fold",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "wrap",
|
||||
aliases: &[],
|
||||
category: "Lo-fi",
|
||||
stack: "(f --)",
|
||||
desc: "Set wave wrap",
|
||||
example: "0.5 wrap",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "distort",
|
||||
aliases: &[],
|
||||
category: "Lo-fi",
|
||||
stack: "(f --)",
|
||||
desc: "Set distortion",
|
||||
example: "0.5 distort",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "distortvol",
|
||||
aliases: &[],
|
||||
category: "Lo-fi",
|
||||
stack: "(f --)",
|
||||
desc: "Set distortion volume",
|
||||
example: "0.8 distortvol",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// Stereo
|
||||
Word {
|
||||
name: "pan",
|
||||
aliases: &[],
|
||||
category: "Stereo",
|
||||
stack: "(f --)",
|
||||
desc: "Set pan (-1 to 1)",
|
||||
example: "0.5 pan",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "width",
|
||||
aliases: &[],
|
||||
category: "Stereo",
|
||||
stack: "(f --)",
|
||||
desc: "Set stereo width (0 mono, 1 normal, 2 wide)",
|
||||
example: "0 width",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "haas",
|
||||
aliases: &[],
|
||||
category: "Stereo",
|
||||
stack: "(f --)",
|
||||
desc: "Set Haas delay in ms (spatial placement)",
|
||||
example: "8 haas",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// Mod FX
|
||||
Word {
|
||||
name: "phaser",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set phaser rate",
|
||||
example: "1 phaser",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "phaserdepth",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set phaser depth",
|
||||
example: "0.5 phaserdepth",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "phasersweep",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set phaser sweep",
|
||||
example: "0.5 phasersweep",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "phasercenter",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set phaser center",
|
||||
example: "1000 phasercenter",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "flanger",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set flanger rate",
|
||||
example: "0.5 flanger",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "flangerdepth",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set flanger depth",
|
||||
example: "0.5 flangerdepth",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "flangerfeedback",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set flanger feedback",
|
||||
example: "0.5 flangerfeedback",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "chorus",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set chorus rate",
|
||||
example: "1 chorus",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "chorusdepth",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set chorus depth",
|
||||
example: "0.5 chorusdepth",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "chorusdelay",
|
||||
aliases: &[],
|
||||
category: "Mod FX",
|
||||
stack: "(f --)",
|
||||
desc: "Set chorus delay",
|
||||
example: "0.02 chorusdelay",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
];
|
||||
135
crates/forth/src/words/midi.rs
Normal file
135
crates/forth/src/words/midi.rs
Normal file
@@ -0,0 +1,135 @@
|
||||
use super::{Word, WordCompile::*};
|
||||
|
||||
// MIDI
|
||||
pub(super) const WORDS: &[Word] = &[
|
||||
Word {
|
||||
name: "chan",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(n --)",
|
||||
desc: "Set MIDI channel 1-16",
|
||||
example: "1 chan",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "ccnum",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(n --)",
|
||||
desc: "Set MIDI CC number 0-127",
|
||||
example: "1 ccnum",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "ccout",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(n --)",
|
||||
desc: "Set MIDI CC output value 0-127",
|
||||
example: "64 ccout",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "bend",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(f --)",
|
||||
desc: "Set pitch bend -1.0 to 1.0 (0 = center)",
|
||||
example: "0.5 bend",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "pressure",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(n --)",
|
||||
desc: "Set channel pressure (aftertouch) 0-127",
|
||||
example: "64 pressure",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "program",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(n --)",
|
||||
desc: "Set program change number 0-127",
|
||||
example: "0 program",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "m.",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(--)",
|
||||
desc: "Emit MIDI message from params (note/cc/bend/pressure/program)",
|
||||
example: "60 note 100 velocity 1 chan m.",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "mclock",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(--)",
|
||||
desc: "Send MIDI clock pulse (24 per quarter note)",
|
||||
example: "mclock",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "mstart",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(--)",
|
||||
desc: "Send MIDI start message",
|
||||
example: "mstart",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "mstop",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(--)",
|
||||
desc: "Send MIDI stop message",
|
||||
example: "mstop",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "mcont",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(--)",
|
||||
desc: "Send MIDI continue message",
|
||||
example: "mcont",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "ccval",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(cc chan -- val)",
|
||||
desc: "Read CC value 0-127 from MIDI input (uses dev param for device)",
|
||||
example: "1 1 ccval",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "dev",
|
||||
aliases: &[],
|
||||
category: "MIDI",
|
||||
stack: "(n --)",
|
||||
desc: "Set MIDI device slot 0-3 for output/input",
|
||||
example: "1 dev 60 note m.",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
];
|
||||
58
crates/forth/src/words/mod.rs
Normal file
58
crates/forth/src/words/mod.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
mod compile;
|
||||
mod core;
|
||||
mod effects;
|
||||
mod midi;
|
||||
mod music;
|
||||
mod sequencing;
|
||||
mod sound;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
pub(crate) use compile::compile_word;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum WordCompile {
|
||||
Simple,
|
||||
Context(&'static str),
|
||||
Param,
|
||||
Probability(f64),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Word {
|
||||
pub name: &'static str,
|
||||
pub aliases: &'static [&'static str],
|
||||
pub category: &'static str,
|
||||
pub stack: &'static str,
|
||||
pub desc: &'static str,
|
||||
pub example: &'static str,
|
||||
pub compile: WordCompile,
|
||||
pub varargs: bool,
|
||||
}
|
||||
|
||||
pub static WORDS: LazyLock<Vec<Word>> = LazyLock::new(|| {
|
||||
let mut words = Vec::new();
|
||||
words.extend_from_slice(self::core::WORDS);
|
||||
words.extend_from_slice(sound::WORDS);
|
||||
words.extend_from_slice(effects::WORDS);
|
||||
words.extend_from_slice(sequencing::WORDS);
|
||||
words.extend_from_slice(music::WORDS);
|
||||
words.extend_from_slice(midi::WORDS);
|
||||
words
|
||||
});
|
||||
|
||||
static WORD_MAP: LazyLock<HashMap<&'static str, &'static Word>> = LazyLock::new(|| {
|
||||
let mut map = HashMap::with_capacity(WORDS.len() * 2);
|
||||
for word in WORDS.iter() {
|
||||
map.insert(word.name, word);
|
||||
for alias in word.aliases {
|
||||
map.insert(alias, word);
|
||||
}
|
||||
}
|
||||
map
|
||||
});
|
||||
|
||||
pub fn lookup_word(name: &str) -> Option<&'static Word> {
|
||||
WORD_MAP.get(name).copied()
|
||||
}
|
||||
312
crates/forth/src/words/music.rs
Normal file
312
crates/forth/src/words/music.rs
Normal file
@@ -0,0 +1,312 @@
|
||||
use super::{Word, WordCompile::*};
|
||||
|
||||
// Music, Chord
|
||||
pub(super) const WORDS: &[Word] = &[
|
||||
// Music
|
||||
Word {
|
||||
name: "mtof",
|
||||
aliases: &[],
|
||||
category: "Music",
|
||||
stack: "(midi -- hz)",
|
||||
desc: "MIDI note to frequency",
|
||||
example: "69 mtof => 440.0",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "ftom",
|
||||
aliases: &[],
|
||||
category: "Music",
|
||||
stack: "(hz -- midi)",
|
||||
desc: "Frequency to MIDI note",
|
||||
example: "440 ftom => 69.0",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
// Chords - Triads
|
||||
Word {
|
||||
name: "maj",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth)",
|
||||
desc: "Major triad",
|
||||
example: "c4 maj => 60 64 67",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "m",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth)",
|
||||
desc: "Minor triad",
|
||||
example: "c4 m => 60 63 67",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "dim",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth)",
|
||||
desc: "Diminished triad",
|
||||
example: "c4 dim => 60 63 66",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "aug",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth)",
|
||||
desc: "Augmented triad",
|
||||
example: "c4 aug => 60 64 68",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "sus2",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root second fifth)",
|
||||
desc: "Suspended 2nd",
|
||||
example: "c4 sus2 => 60 62 67",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "sus4",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root fourth fifth)",
|
||||
desc: "Suspended 4th",
|
||||
example: "c4 sus4 => 60 65 67",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
// Chords - Seventh
|
||||
Word {
|
||||
name: "maj7",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh)",
|
||||
desc: "Major 7th",
|
||||
example: "c4 maj7 => 60 64 67 71",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "min7",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh)",
|
||||
desc: "Minor 7th",
|
||||
example: "c4 min7 => 60 63 67 70",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "dom7",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh)",
|
||||
desc: "Dominant 7th",
|
||||
example: "c4 dom7 => 60 64 67 70",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "dim7",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh)",
|
||||
desc: "Diminished 7th",
|
||||
example: "c4 dim7 => 60 63 66 69",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "m7b5",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh)",
|
||||
desc: "Half-diminished (min7b5)",
|
||||
example: "c4 m7b5 => 60 63 66 70",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "minmaj7",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh)",
|
||||
desc: "Minor-major 7th",
|
||||
example: "c4 minmaj7 => 60 63 67 71",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "aug7",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh)",
|
||||
desc: "Augmented 7th",
|
||||
example: "c4 aug7 => 60 64 68 70",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
// Chords - Sixth
|
||||
Word {
|
||||
name: "maj6",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth sixth)",
|
||||
desc: "Major 6th",
|
||||
example: "c4 maj6 => 60 64 67 69",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "min6",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth sixth)",
|
||||
desc: "Minor 6th",
|
||||
example: "c4 min6 => 60 63 67 69",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
// Chords - Extended
|
||||
Word {
|
||||
name: "dom9",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh ninth)",
|
||||
desc: "Dominant 9th",
|
||||
example: "c4 dom9 => 60 64 67 70 74",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "maj9",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh ninth)",
|
||||
desc: "Major 9th",
|
||||
example: "c4 maj9 => 60 64 67 71 74",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "min9",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh ninth)",
|
||||
desc: "Minor 9th",
|
||||
example: "c4 min9 => 60 63 67 70 74",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "dom11",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh ninth eleventh)",
|
||||
desc: "Dominant 11th",
|
||||
example: "c4 dom11 => 60 64 67 70 74 77",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "min11",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh ninth eleventh)",
|
||||
desc: "Minor 11th",
|
||||
example: "c4 min11 => 60 63 67 70 74 77",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "dom13",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh ninth thirteenth)",
|
||||
desc: "Dominant 13th",
|
||||
example: "c4 dom13 => 60 64 67 70 74 81",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
// Chords - Add
|
||||
Word {
|
||||
name: "add9",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth ninth)",
|
||||
desc: "Major add 9",
|
||||
example: "c4 add9 => 60 64 67 74",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "add11",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth eleventh)",
|
||||
desc: "Major add 11",
|
||||
example: "c4 add11 => 60 64 67 77",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "madd9",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth ninth)",
|
||||
desc: "Minor add 9",
|
||||
example: "c4 madd9 => 60 63 67 74",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
// Chords - Altered dominants
|
||||
Word {
|
||||
name: "dom7b9",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh flatninth)",
|
||||
desc: "7th flat 9",
|
||||
example: "c4 dom7b9 => 60 64 67 70 73",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "dom7s9",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third fifth seventh sharpninth)",
|
||||
desc: "7th sharp 9 (Hendrix chord)",
|
||||
example: "c4 dom7s9 => 60 64 67 70 75",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "dom7b5",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third flatfifth seventh)",
|
||||
desc: "7th flat 5",
|
||||
example: "c4 dom7b5 => 60 64 66 70",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "dom7s5",
|
||||
aliases: &[],
|
||||
category: "Chord",
|
||||
stack: "(root -- root third sharpfifth seventh)",
|
||||
desc: "7th sharp 5",
|
||||
example: "c4 dom7s5 => 60 64 68 70",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
];
|
||||
413
crates/forth/src/words/sequencing.rs
Normal file
413
crates/forth/src/words/sequencing.rs
Normal file
@@ -0,0 +1,413 @@
|
||||
use super::{Word, WordCompile::*};
|
||||
|
||||
// Time, Context, Probability, Generator, Desktop
|
||||
pub(super) const WORDS: &[Word] = &[
|
||||
// Probability
|
||||
Word {
|
||||
name: "rand",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(min max -- n|f)",
|
||||
desc: "Random in range. Int if both args are int, float otherwise",
|
||||
example: "1 6 rand => 4 | 0.0 1.0 rand => 0.42",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "exprand",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(lo hi -- f)",
|
||||
desc: "Exponential random biased toward lo. Both args must be positive",
|
||||
example: "1.0 100.0 exprand => 3.7",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "logrand",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(lo hi -- f)",
|
||||
desc: "Exponential random biased toward hi. Both args must be positive",
|
||||
example: "1.0 100.0 logrand => 87.2",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "seed",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(n --)",
|
||||
desc: "Set random seed",
|
||||
example: "12345 seed",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "coin",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(-- bool)",
|
||||
desc: "50/50 random boolean",
|
||||
example: "coin => 0 or 1",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "chance",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(quot prob --)",
|
||||
desc: "Execute quotation with probability (0.0-1.0)",
|
||||
example: "{ 2 distort } 0.75 chance",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "prob",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(quot pct --)",
|
||||
desc: "Execute quotation with probability (0-100)",
|
||||
example: "{ 2 distort } 75 prob",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "choose",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(..n n -- val)",
|
||||
desc: "Random pick from n items",
|
||||
example: "1 2 3 3 choose",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "cycle",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(v1..vn n -- selected)",
|
||||
desc: "Cycle through n items by step runs",
|
||||
example: "60 64 67 3 cycle",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "pcycle",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(v1..vn n -- selected)",
|
||||
desc: "Cycle through n items by pattern iteration",
|
||||
example: "60 64 67 3 pcycle",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "always",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(quot --)",
|
||||
desc: "Always execute quotation",
|
||||
example: "{ 2 distort } always",
|
||||
compile: Probability(1.0),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "never",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(quot --)",
|
||||
desc: "Never execute quotation",
|
||||
example: "{ 2 distort } never",
|
||||
compile: Probability(0.0),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "often",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(quot --)",
|
||||
desc: "Execute quotation 75% of the time",
|
||||
example: "{ 2 distort } often",
|
||||
compile: Probability(0.75),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "sometimes",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(quot --)",
|
||||
desc: "Execute quotation 50% of the time",
|
||||
example: "{ 2 distort } sometimes",
|
||||
compile: Probability(0.5),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "rarely",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(quot --)",
|
||||
desc: "Execute quotation 25% of the time",
|
||||
example: "{ 2 distort } rarely",
|
||||
compile: Probability(0.25),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "almostNever",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(quot --)",
|
||||
desc: "Execute quotation 10% of the time",
|
||||
example: "{ 2 distort } almostNever",
|
||||
compile: Probability(0.1),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "almostAlways",
|
||||
aliases: &[],
|
||||
category: "Probability",
|
||||
stack: "(quot --)",
|
||||
desc: "Execute quotation 90% of the time",
|
||||
example: "{ 2 distort } almostAlways",
|
||||
compile: Probability(0.9),
|
||||
varargs: false,
|
||||
},
|
||||
// Time
|
||||
Word {
|
||||
name: "every",
|
||||
aliases: &[],
|
||||
category: "Time",
|
||||
stack: "(n -- bool)",
|
||||
desc: "True every nth iteration",
|
||||
example: "4 every",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "loop",
|
||||
aliases: &[],
|
||||
category: "Time",
|
||||
stack: "(n --)",
|
||||
desc: "Fit sample to n beats",
|
||||
example: "\"break\" s 4 loop @",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "tempo!",
|
||||
aliases: &[],
|
||||
category: "Time",
|
||||
stack: "(bpm --)",
|
||||
desc: "Set global tempo",
|
||||
example: "140 tempo!",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "speed!",
|
||||
aliases: &[],
|
||||
category: "Time",
|
||||
stack: "(multiplier --)",
|
||||
desc: "Set pattern speed multiplier",
|
||||
example: "2.0 speed!",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "chain",
|
||||
aliases: &[],
|
||||
category: "Time",
|
||||
stack: "(bank pattern --)",
|
||||
desc: "Chain to bank/pattern (1-indexed) when current pattern ends",
|
||||
example: "1 4 chain",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "at",
|
||||
aliases: &[],
|
||||
category: "Time",
|
||||
stack: "(v1..vn --)",
|
||||
desc: "Set delta context for emit timing",
|
||||
example: "0 0.5 at kick s . => emits at 0 and 0.5 of step",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
// Context
|
||||
Word {
|
||||
name: "step",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- n)",
|
||||
desc: "Current step index",
|
||||
example: "step => 0",
|
||||
compile: Context("step"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "beat",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- f)",
|
||||
desc: "Current beat position",
|
||||
example: "beat => 4.5",
|
||||
compile: Context("beat"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "pattern",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- n)",
|
||||
desc: "Current pattern index",
|
||||
example: "pattern => 0",
|
||||
compile: Context("pattern"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "pbank",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- n)",
|
||||
desc: "Current pattern's bank index",
|
||||
example: "pbank => 0",
|
||||
compile: Context("bank"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "tempo",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- f)",
|
||||
desc: "Current BPM",
|
||||
example: "tempo => 120.0",
|
||||
compile: Context("tempo"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "phase",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- f)",
|
||||
desc: "Phase in bar (0-1)",
|
||||
example: "phase => 0.25",
|
||||
compile: Context("phase"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "slot",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- n)",
|
||||
desc: "Current slot number",
|
||||
example: "slot => 0",
|
||||
compile: Context("slot"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "runs",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- n)",
|
||||
desc: "Times this step ran",
|
||||
example: "runs => 3",
|
||||
compile: Context("runs"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "iter",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- n)",
|
||||
desc: "Pattern iteration count",
|
||||
example: "iter => 2",
|
||||
compile: Context("iter"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "stepdur",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- f)",
|
||||
desc: "Step duration in seconds",
|
||||
example: "stepdur => 0.125",
|
||||
compile: Context("stepdur"),
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "fill",
|
||||
aliases: &[],
|
||||
category: "Context",
|
||||
stack: "(-- bool)",
|
||||
desc: "True when fill is on (f key)",
|
||||
example: "\"snare\" s . fill ?",
|
||||
compile: Context("fill"),
|
||||
varargs: false,
|
||||
},
|
||||
// Desktop
|
||||
#[cfg(feature = "desktop")]
|
||||
Word {
|
||||
name: "mx",
|
||||
aliases: &[],
|
||||
category: "Desktop",
|
||||
stack: "(-- x)",
|
||||
desc: "Normalized mouse X position (0-1)",
|
||||
example: "mx 440 880 range freq",
|
||||
compile: Context("mx"),
|
||||
varargs: false,
|
||||
},
|
||||
#[cfg(feature = "desktop")]
|
||||
Word {
|
||||
name: "my",
|
||||
aliases: &[],
|
||||
category: "Desktop",
|
||||
stack: "(-- y)",
|
||||
desc: "Normalized mouse Y position (0-1)",
|
||||
example: "my 0.1 0.9 range gain",
|
||||
compile: Context("my"),
|
||||
varargs: false,
|
||||
},
|
||||
#[cfg(feature = "desktop")]
|
||||
Word {
|
||||
name: "mdown",
|
||||
aliases: &[],
|
||||
category: "Desktop",
|
||||
stack: "(-- bool)",
|
||||
desc: "1 when mouse button held, 0 otherwise",
|
||||
example: "mdown { \"crash\" s . } ?",
|
||||
compile: Context("mdown"),
|
||||
varargs: false,
|
||||
},
|
||||
// Generator
|
||||
Word {
|
||||
name: "..",
|
||||
aliases: &[],
|
||||
category: "Generator",
|
||||
stack: "(start end -- start start+1 ... end)",
|
||||
desc: "Push arithmetic sequence from start to end",
|
||||
example: "1 4 .. => 1 2 3 4",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "gen",
|
||||
aliases: &[],
|
||||
category: "Generator",
|
||||
stack: "(quot n -- results...)",
|
||||
desc: "Execute quotation n times, push all results",
|
||||
example: "{ 1 6 rand } 4 gen => 4 random values",
|
||||
compile: Simple,
|
||||
varargs: true,
|
||||
},
|
||||
Word {
|
||||
name: "geom..",
|
||||
aliases: &[],
|
||||
category: "Generator",
|
||||
stack: "(start ratio count -- start start*r start*r^2 ...)",
|
||||
desc: "Push geometric sequence",
|
||||
example: "1 2 4 geom.. => 1 2 4 8",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
];
|
||||
622
crates/forth/src/words/sound.rs
Normal file
622
crates/forth/src/words/sound.rs
Normal file
@@ -0,0 +1,622 @@
|
||||
use super::{Word, WordCompile::*};
|
||||
|
||||
// Sound, Oscillator, Sample, Wavetable, FM, Modulation, LFO
|
||||
pub(super) const WORDS: &[Word] = &[
|
||||
// Sound
|
||||
Word {
|
||||
name: "sound",
|
||||
aliases: &["s"],
|
||||
category: "Sound",
|
||||
stack: "(name --)",
|
||||
desc: "Begin sound command",
|
||||
example: "\"kick\" sound",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: ".",
|
||||
aliases: &[],
|
||||
category: "Sound",
|
||||
stack: "(--)",
|
||||
desc: "Emit current sound",
|
||||
example: "\"kick\" s . . . .",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "clear",
|
||||
aliases: &[],
|
||||
category: "Sound",
|
||||
stack: "(--)",
|
||||
desc: "Clear sound register (sound and all params)",
|
||||
example: "\"kick\" s 0.5 gain . clear \"hat\" s .",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
// Sample
|
||||
Word {
|
||||
name: "bank",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(str --)",
|
||||
desc: "Set sample bank suffix",
|
||||
example: "\"a\" bank",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "time",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(f --)",
|
||||
desc: "Set time offset",
|
||||
example: "0.1 time",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "repeat",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(n --)",
|
||||
desc: "Set repeat count",
|
||||
example: "4 repeat",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "dur",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(f --)",
|
||||
desc: "Set duration",
|
||||
example: "0.5 dur",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "gate",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(f --)",
|
||||
desc: "Set gate time",
|
||||
example: "0.8 gate",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "speed",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(f --)",
|
||||
desc: "Set playback speed",
|
||||
example: "1.5 speed",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "begin",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(f --)",
|
||||
desc: "Set sample start (0-1)",
|
||||
example: "0.25 begin",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "end",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(f --)",
|
||||
desc: "Set sample end (0-1)",
|
||||
example: "0.75 end",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "voice",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(n --)",
|
||||
desc: "Set voice number",
|
||||
example: "1 voice",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "orbit",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(n --)",
|
||||
desc: "Set orbit/bus",
|
||||
example: "0 orbit",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "n",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(n --)",
|
||||
desc: "Set sample number",
|
||||
example: "0 n",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "cut",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(n --)",
|
||||
desc: "Set cut group",
|
||||
example: "1 cut",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "reset",
|
||||
aliases: &[],
|
||||
category: "Sample",
|
||||
stack: "(n --)",
|
||||
desc: "Reset parameter",
|
||||
example: "1 reset",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// Oscillator
|
||||
Word {
|
||||
name: "freq",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set frequency (Hz)",
|
||||
example: "440 freq",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "detune",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set detune amount",
|
||||
example: "0.01 detune",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "glide",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set glide/portamento",
|
||||
example: "0.1 glide",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "pw",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set pulse width",
|
||||
example: "0.5 pw",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "spread",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set stereo spread",
|
||||
example: "0.5 spread",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "mult",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set multiplier",
|
||||
example: "2 mult",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "warp",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set warp amount",
|
||||
example: "0.5 warp",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "mirror",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set mirror",
|
||||
example: "1 mirror",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "harmonics",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set harmonics (mutable only)",
|
||||
example: "4 harmonics",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "timbre",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set timbre (mutable only)",
|
||||
example: "0.5 timbre",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "morph",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set morph (mutable only)",
|
||||
example: "0.5 morph",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "coarse",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set coarse tune",
|
||||
example: "12 coarse",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "sub",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(f --)",
|
||||
desc: "Set sub oscillator level",
|
||||
example: "0.5 sub",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "suboct",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(n --)",
|
||||
desc: "Set sub oscillator octave",
|
||||
example: "2 suboct",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "subwave",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(n --)",
|
||||
desc: "Set sub oscillator waveform",
|
||||
example: "1 subwave",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "note",
|
||||
aliases: &[],
|
||||
category: "Oscillator",
|
||||
stack: "(n --)",
|
||||
desc: "Set MIDI note",
|
||||
example: "60 note",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// Wavetable
|
||||
Word {
|
||||
name: "scan",
|
||||
aliases: &[],
|
||||
category: "Wavetable",
|
||||
stack: "(f --)",
|
||||
desc: "Set wavetable scan position (0-1)",
|
||||
example: "0.5 scan",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "wtlen",
|
||||
aliases: &[],
|
||||
category: "Wavetable",
|
||||
stack: "(n --)",
|
||||
desc: "Set wavetable cycle length in samples",
|
||||
example: "2048 wtlen",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "scanlfo",
|
||||
aliases: &[],
|
||||
category: "Wavetable",
|
||||
stack: "(f --)",
|
||||
desc: "Set scan LFO rate (Hz)",
|
||||
example: "0.2 scanlfo",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "scandepth",
|
||||
aliases: &[],
|
||||
category: "Wavetable",
|
||||
stack: "(f --)",
|
||||
desc: "Set scan LFO depth (0-1)",
|
||||
example: "0.4 scandepth",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "scanshape",
|
||||
aliases: &[],
|
||||
category: "Wavetable",
|
||||
stack: "(s --)",
|
||||
desc: "Set scan LFO shape (sine/tri/saw/square/sh)",
|
||||
example: "\"tri\" scanshape",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// FM
|
||||
Word {
|
||||
name: "fm",
|
||||
aliases: &[],
|
||||
category: "FM",
|
||||
stack: "(f --)",
|
||||
desc: "Set FM frequency",
|
||||
example: "200 fm",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "fmh",
|
||||
aliases: &[],
|
||||
category: "FM",
|
||||
stack: "(f --)",
|
||||
desc: "Set FM harmonic ratio",
|
||||
example: "2 fmh",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "fmshape",
|
||||
aliases: &[],
|
||||
category: "FM",
|
||||
stack: "(f --)",
|
||||
desc: "Set FM shape",
|
||||
example: "0 fmshape",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "fme",
|
||||
aliases: &[],
|
||||
category: "FM",
|
||||
stack: "(f --)",
|
||||
desc: "Set FM envelope",
|
||||
example: "0.5 fme",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "fma",
|
||||
aliases: &[],
|
||||
category: "FM",
|
||||
stack: "(f --)",
|
||||
desc: "Set FM attack",
|
||||
example: "0.01 fma",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "fmd",
|
||||
aliases: &[],
|
||||
category: "FM",
|
||||
stack: "(f --)",
|
||||
desc: "Set FM decay",
|
||||
example: "0.1 fmd",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "fms",
|
||||
aliases: &[],
|
||||
category: "FM",
|
||||
stack: "(f --)",
|
||||
desc: "Set FM sustain",
|
||||
example: "0.5 fms",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "fmr",
|
||||
aliases: &[],
|
||||
category: "FM",
|
||||
stack: "(f --)",
|
||||
desc: "Set FM release",
|
||||
example: "0.1 fmr",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// Modulation
|
||||
Word {
|
||||
name: "vib",
|
||||
aliases: &[],
|
||||
category: "Modulation",
|
||||
stack: "(f --)",
|
||||
desc: "Set vibrato rate",
|
||||
example: "5 vib",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "vibmod",
|
||||
aliases: &[],
|
||||
category: "Modulation",
|
||||
stack: "(f --)",
|
||||
desc: "Set vibrato depth",
|
||||
example: "0.5 vibmod",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "vibshape",
|
||||
aliases: &[],
|
||||
category: "Modulation",
|
||||
stack: "(f --)",
|
||||
desc: "Set vibrato shape",
|
||||
example: "0 vibshape",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "am",
|
||||
aliases: &[],
|
||||
category: "Modulation",
|
||||
stack: "(f --)",
|
||||
desc: "Set AM frequency",
|
||||
example: "10 am",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "amdepth",
|
||||
aliases: &[],
|
||||
category: "Modulation",
|
||||
stack: "(f --)",
|
||||
desc: "Set AM depth",
|
||||
example: "0.5 amdepth",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "amshape",
|
||||
aliases: &[],
|
||||
category: "Modulation",
|
||||
stack: "(f --)",
|
||||
desc: "Set AM shape",
|
||||
example: "0 amshape",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "rm",
|
||||
aliases: &[],
|
||||
category: "Modulation",
|
||||
stack: "(f --)",
|
||||
desc: "Set RM frequency",
|
||||
example: "100 rm",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "rmdepth",
|
||||
aliases: &[],
|
||||
category: "Modulation",
|
||||
stack: "(f --)",
|
||||
desc: "Set RM depth",
|
||||
example: "0.5 rmdepth",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "rmshape",
|
||||
aliases: &[],
|
||||
category: "Modulation",
|
||||
stack: "(f --)",
|
||||
desc: "Set RM shape",
|
||||
example: "0 rmshape",
|
||||
compile: Param,
|
||||
varargs: false,
|
||||
},
|
||||
// LFO
|
||||
Word {
|
||||
name: "ramp",
|
||||
aliases: &[],
|
||||
category: "LFO",
|
||||
stack: "(freq curve -- val)",
|
||||
desc: "Ramp [0,1]: fract(freq*beat)^curve",
|
||||
example: "0.25 2.0 ramp",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "range",
|
||||
aliases: &[],
|
||||
category: "LFO",
|
||||
stack: "(val min max -- scaled)",
|
||||
desc: "Scale [0,1] to [min,max]",
|
||||
example: "0.5 200 800 range => 500",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "linramp",
|
||||
aliases: &[],
|
||||
category: "LFO",
|
||||
stack: "(freq -- val)",
|
||||
desc: "Linear ramp (curve=1)",
|
||||
example: "1.0 linramp",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "expramp",
|
||||
aliases: &[],
|
||||
category: "LFO",
|
||||
stack: "(freq -- val)",
|
||||
desc: "Exponential ramp (curve=3)",
|
||||
example: "0.25 expramp",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "logramp",
|
||||
aliases: &[],
|
||||
category: "LFO",
|
||||
stack: "(freq -- val)",
|
||||
desc: "Logarithmic ramp (curve=0.3)",
|
||||
example: "2.0 logramp",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "triangle",
|
||||
aliases: &[],
|
||||
category: "LFO",
|
||||
stack: "(freq -- val)",
|
||||
desc: "Triangle wave [0,1]: 0→1→0",
|
||||
example: "0.5 triangle",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "perlin",
|
||||
aliases: &[],
|
||||
category: "LFO",
|
||||
stack: "(freq -- val)",
|
||||
desc: "Perlin noise [0,1] sampled at freq*beat",
|
||||
example: "0.25 perlin",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
];
|
||||
@@ -91,7 +91,7 @@ fn alternating_sounds() {
|
||||
fn dur_is_step_duration() {
|
||||
let outputs = expect_outputs(r#""kick" s ."#, 1);
|
||||
let durs = get_durs(&outputs);
|
||||
assert!(approx_eq(durs[0], 0.125), "dur should be step_duration (0.125), got {}", durs[0]);
|
||||
assert!(approx_eq(durs[0], 0.5), "dur should be 4 * step_duration (0.5), got {}", durs[0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -181,6 +181,15 @@ fn at_reset_with_zero() {
|
||||
assert_eq!(sounds, vec!["kick", "kick", "hat"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clear_resets_at_deltas() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" s . clear "hat" s ."#, 3);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds, vec!["kick", "kick", "hat"]);
|
||||
let deltas = get_deltas(&outputs);
|
||||
assert!(approx_eq(deltas[2], 0.0), "after clear, hat should emit at delta 0, got {}", deltas[2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn at_records_selected_spans() {
|
||||
use cagire::forth::ExecutionTrace;
|
||||
|
||||
Reference in New Issue
Block a user