Alias System API Reference¶
Table of Contents¶
- Syntax Overview
- Alias Definition
- Parameter Specification
- Parameter Types
- Computed Values
- Conditional Logic
- Alias Invocation
- Import System
- Error Handling
- Grammar Reference
Syntax Overview¶
The alias system uses a declarative syntax inspired by Markdown and YAML:
@alias name {param1} {param2} "Description"
{computed_var = expression}
@if {param} == value
- command template
@end
@end
Keywords¶
@alias- Begin alias definition@end- End alias definition or conditional block@if- Begin conditional branch@elif- Else-if branch@else- Else branch@import- Import device library (Stage 8)
Alias Definition¶
Basic Syntax¶
Components¶
alias_name (required)
- Type: Identifier
- Pattern: [a-zA-Z_][a-zA-Z0-9_]*
- Convention: device_function (lowercase with underscores)
- Example: cortex_scene, helix_snapshot
parameters (optional)
- Zero or more parameter specifications
- Format: {param_name} or {param_name:type} or {param_name=default}
- Must be unique within alias
- Order matters for invocation
description (required)
- Type: String (single or double quotes)
- Purpose: Human-readable description
- Displayed in help/documentation
- Should explain what (not how)
command_templates (required)
- One or more command lines starting with -
- Can reference parameters: {param_name}
- Can reference computed values: {var_name}
- Can invoke other aliases
- Can include conditional blocks
Examples¶
# Simple alias
@alias preset_change {ch} {preset} "Change preset"
- pc {ch}.{preset}
@end
# Multi-command alias
@alias scene_with_fx {ch} {scene} {fx_level} "Scene with effects"
- cc {ch}.34.{scene}
- cc {ch}.91.{fx_level}
@end
# Alias calling another alias
@alias quick_scene_a {ch} "Quick scene A"
- cortex_scene {ch} 0
@end
Parameter Specification¶
Parameter Syntax¶
Parameters are enclosed in braces: {parameter_spec}
{name} # Generic parameter
{name:type} # Typed parameter
{name:min-max} # Range parameter
{name=default} # Default value
{name:type=default} # Type + default
{name=opt1:val1,opt2:val2} # Enum parameter
Parameter Components¶
Name
- Required
- Must be valid identifier: [a-zA-Z_][a-zA-Z0-9_]*
- Case-sensitive
- Should be descriptive: preset, scene, velocity
Type (optional)
- Specifies parameter type and validation
- See Parameter Types for full list
- Format: :type or :min-max
Default Value (optional)
- Provides default if argument omitted
- Format: =value
- Must be valid for parameter type
- Allows optional parameters
Enum Values (optional)
- Named options mapping to numbers
- Format: =name1:value1,name2:value2,...
- Names must be identifiers
- Values must be integers
Parameter Examples¶
# Generic (0-127)
{channel}
{value}
# Range constrained
{scene:0-7}
{bpm:40-300}
{velocity:1-127}
# Typed
{note:note} # Note name or number
{level:percent} # 0-100 → 0-127
{enabled:bool} # true/false, on/off, etc.
{channel:channel} # 1-16
# Default values
{channel=1} # Channel defaults to 1
{velocity=100} # Velocity defaults to 100
# Enum
{mode=clean:0,crunch:1,lead:2}
{device=cortex:0,helix:1,kemper:2}
# Combined
{bpm:40-300=120} # Range with default
{level:percent=50} # Type with default
Parameter Types¶
Generic (default)¶
Type: generic (implicit)
Range: 0-127
Input: Integer
Output: Integer (0-127)
Range¶
Type: :min-max
Range: Custom (specified)
Input: Integer in range
Output: Integer (validated)
Note¶
Type: :note
Range: 0-127 (MIDI note numbers)
Input: Note name (C4, D#5, Bb3) or MIDI number
Output: MIDI note number (0-127)
Note Name Format:
- Base note: A-G
- Accidental: # (sharp) or b (flat)
- Octave: 0-9 (MIDI octaves, C4 = middle C = 60)
Examples:
- C4 → 60
- C#4 → 61
- Db4 → 61
- A0 → 21
- G9 → 127
Percent¶
Type: :percent
Range: 0-100
Input: Percentage (0-100)
Output: MIDI value (0-127)
Conversion: midi_value = round(percent * 127 / 100)
Examples:
- 0% → 0
- 50% → 64
- 100% → 127
Bool¶
Type: :bool
Range: 0 or 127
Input: Boolean value
Output: 0 (false) or 127 (true)
Accepted Values:
- True: true, on, yes, 1, 127
- False: false, off, no, 0
Output: - True → 127 - False → 0
Channel¶
Type: :channel
Range: 1-16
Input: MIDI channel (1-16)
Output: Channel number (1-16)
Velocity¶
Type: :velocity
Range: 1-127 (0 reserved for note-off)
Input: Velocity (1-127)
Output: Velocity (1-127)
Enum¶
Type: Implicit (defined by options) Range: Defined by enum values Input: Name or value Output: Corresponding integer value
Invocation:
- By name: device_mode 1 clean → 0
- By value: device_mode 1 0 → 0
Computed Values¶
Status: ✅ Complete (Phase 6)
Computed values allow defining variables with calculated values based on parameters.
Syntax¶
Expressions¶
Variables: Reference parameters with ${param_name}
Operators:
- Arithmetic: +, -, *, /, %, ** (power)
- Parentheses: (, )
Functions:
- int(x) - Convert to integer
- round(x) - Round to nearest integer
- floor(x) - Round down
- ceil(x) - Round up
- abs(x) - Absolute value
- min(a, b) - Minimum
- max(a, b) - Maximum
- clamp(x, min, max) - Constrain value
Example¶
@alias bpm_to_midi {ch} {bpm:40-300} "Convert BPM to MIDI"
{midi_val = int((${bpm} - 40) * 127 / 260)}
- cc {ch}.81.{midi_val}
@end
Evaluation Order¶
- Parameter binding
- Computed value evaluation (in definition order)
- Conditional branch selection
- Command expansion
Conditional Logic¶
Status: Stage 7 (Complete)
Conditionals allow different command sequences based on parameter values.
Syntax¶
@alias name {params} "description"
@if condition
- commands
@elif condition
- commands
@else
- commands
@end
@end
Condition Syntax¶
Operators:
- == - Equal
- != - Not equal
- < - Less than
- > - Greater than
- <= - Less than or equal
- >= - Greater than or equal
Values:
- Numbers: 0, 127, 42
- Strings: "text" (for future string params)
- Parameter references: {other_param}
Rules¶
- At least one
@ifbranch required - Zero or more
@elifbranches - Zero or one
@elsebranch - Conditions evaluated in order (first match wins)
@elsematches if no other branch matches- Conditional block closed with
@endbefore alias@end
Examples¶
# Simple conditional
@alias device_load {ch} {preset} {device=cortex:0,helix:1} "Device-aware load"
@if {device} == 0
- pc {ch}.{preset}
@elif {device} == 1
- cc {ch}.69.{preset}
@end
@end
# With else
@alias smart_velocity {ch} {note:note} {level:0-2} "Dynamic velocity"
@if {level} == 0
- note {ch}.{note}.50 500ms
@elif {level} == 1
- note {ch}.{note}.80 500ms
@else
- note {ch}.{note}.127 500ms
@end
@end
# Multiple conditions
@alias scene_selector {ch} {scene} {mode} "Scene with mode check"
@if {mode} == 0
- cc {ch}.34.{scene}
@elif {mode} == 1
- cc {ch}.69.{scene}
@else
- pc {ch}.{scene}
@end
@end
Alias Invocation¶
Syntax¶
Argument Passing¶
Positional Arguments: - Arguments matched to parameters by position - Must provide arguments for all required parameters - Optional parameters (with defaults) can be omitted - Excess arguments cause error
Examples:
@alias test {a} {b=10} {c=20} "Test defaults"
- cc {a}.{b}.{c}
@end
# Valid invocations:
- test 1 # a=1, b=10, c=20
- test 1 5 # a=1, b=5, c=20
- test 1 5 15 # a=1, b=5, c=15
# Invalid:
- test # Error: missing required 'a'
- test 1 2 3 4 # Error: too many arguments
Expansion Process¶
- Parse: Parse alias call and arguments
- Resolve: Look up alias definition
- Bind: Match arguments to parameters
- Validate: Check types and ranges
- Compute: Evaluate computed values (if any)
- Select: Choose conditional branch (if any)
- Expand: Replace parameter placeholders
- Recurse: Expand nested alias calls
- Generate: Create MIDI events
Timing¶
Alias invocations use the same timing as MIDI commands:
[00:00.000] # Absolute time
- alias_name args
[1.1.0] # Musical time
- alias_name args
[+500ms] # Relative time
- alias_name args
[@] # Simultaneous
- alias_name args
All commands expanded from an alias inherit the timing of the alias call.
Import System¶
Status: ✅ Complete
The import system allows loading aliases from external files.
Syntax¶
Path Resolution¶
- Relative to current file
- Searched in
devices/directory .mmdextension optional
Examples¶
@import "devices/quad_cortex.mmd"
@import "quad_cortex" # .mmd assumed
@import "../shared/common_aliases.mmd"
Import Behavior¶
- Aliases merged into current namespace
- Name conflicts cause error
- Circular imports detected and prevented
- Imports processed before alias definitions
Error Handling¶
Compile-Time Errors¶
Undefined Alias:
Wrong Argument Count:
Error: Alias 'cortex_load' expects 4 arguments, got 3 at line 15
Usage: cortex_load {ch} {setlist} {group} {preset}
Parameter Out of Range:
Invalid Parameter Type:
Error: Invalid note name 'H4' for parameter 'note' in alias 'play_note' at line 25
Valid note names: A-G with optional # or b, plus octave 0-9
Invalid Enum Value:
Error: Invalid value 'lead' for enum parameter 'mode' in alias 'amp_channel'
Valid options: clean, crunch, rhythm
Circular Dependency:
Max Depth Exceeded:
Error: Alias expansion max depth (10) exceeded in 'recursive_alias'
Call chain: recursive_alias → recursive_alias → ...
Runtime Errors¶
Computation Error:
No Conditional Match:
Error: No conditional branch matched in alias 'device_load' at line 30
Parameter values: {device: 5}
Grammar Reference¶
Complete Alias Grammar (Lark)¶
// Alias definition
macro_alias: "@alias" IDENTIFIER alias_params STRING _NL*
(computed_value _NL*)*
alias_body
"@end"
// Parameters
alias_params: param_ref*
param_ref: "{" param_spec "}"
param_spec: IDENTIFIER // Simple
| IDENTIFIER param_type // Typed
| IDENTIFIER param_default // Default
| IDENTIFIER param_enum // Enum
| IDENTIFIER param_type param_default // Type + default
param_type: ":" INT "-" INT // Range
| ":" PARAM_TYPE_NAME // Named type
param_default: "=" (INT | IDENTIFIER)
param_enum: "=" enum_option ("," enum_option)*
enum_option: IDENTIFIER ":" INT
PARAM_TYPE_NAME: "note" | "channel" | "bool" | "percent" | "velocity"
// Computed values (Stage 6)
computed_value: "{" IDENTIFIER "=" expression "}"
// Alias body - commands or conditionals
alias_body: (command_template _NL*)+ // Non-conditional
| alias_conditional_stmt // Conditional
// Conditionals (Stage 7)
alias_conditional_stmt: alias_if_clause
alias_elif_clause*
alias_else_clause?
"@end" _NL*
alias_if_clause: "@if" alias_condition _NL*
(command_template _NL*)+
alias_elif_clause: "@elif" alias_condition _NL*
(command_template _NL*)+
alias_else_clause: "@else" _NL*
(command_template _NL*)+
alias_condition: param_ref COMPARE_OP alias_cond_value
| IDENTIFIER COMPARE_OP alias_cond_value
alias_cond_value: STRING | NUMBER | param_ref | IDENTIFIER
COMPARE_OP: "==" | "!=" | "<=" | ">=" | "<" | ">"
// Command template
command_template: "-" /[^\n]+/
// Alias invocation
alias_call: IDENTIFIER (INT | FLOAT | STRING | IDENTIFIER)*
Type Hierarchy¶
Parameter Types:
├── generic (0-127)
├── range (min-max)
├── note (note names or 0-127)
├── percent (0-100 → 0-127)
├── bool (true/false → 0/127)
├── channel (1-16)
├── velocity (1-127)
└── enum (named → integer)
Expression Types:
├── number (int or float)
├── variable (parameter reference)
├── binary_op (arithmetic)
├── unary_op (negation)
├── function_call
└── parenthesized
Versioning¶
The alias system follows semantic versioning:
Current: v1.0.0 (Stage 7 complete)
Version History: - v0.1.0: Basic aliases (Stage 1) - v0.2.0: Enhanced parameters (Stage 2) - v0.3.0: Nested aliases (Stage 5) - v0.6.0: Computed values (Stage 6, in progress) - v0.7.0: Conditional logic (Stage 7, complete) - v0.9.0: Integration (Stage 9, complete) - v1.0.0: Full release
See Also¶
- Alias System User Guide - Tutorials and examples
- Device Library Creation Guide - Library authoring
- MML Specification - Complete language spec
- Examples - Working code samples