Claude Code Plugins

Community-maintained marketplace

Feedback

mmd-device-library

@cjgdev/midi-markdown
0
0

Create custom MIDI device libraries for MIDI Markdown with aliases, parameters, and documentation. Use when the user wants to create device-specific aliases for hardware (guitar processors, synthesizers, effects units), document MIDI implementations, or build reusable command libraries.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name mmd-device-library
description Create custom MIDI device libraries for MIDI Markdown with aliases, parameters, and documentation. Use when the user wants to create device-specific aliases for hardware (guitar processors, synthesizers, effects units), document MIDI implementations, or build reusable command libraries.

Device Library Creation Skill

Overview

This skill guides you through creating custom device libraries for MIDI Markdown. Device libraries provide high-level aliases for MIDI hardware, making automation code more readable and maintainable.

What is a Device Library?

A device library is an MMD file containing:

  • Device metadata (name, manufacturer, MIDI channel)
  • Alias definitions for device-specific commands
  • Documentation for each alias
  • Optional computed values and conditionals

Example usage:

@import "devices/my_device.mmd"

[00:00.000]
- my_device_preset 1.5      # Instead of: cc 1.32.0; pc 1.5

Quick Start

Minimal Device Library

---
device: "My Device Name"
manufacturer: "Company Name"
version: 1.0.0
default_channel: 1
---

@alias device_preset pc.{ch}.{preset} "Load preset (0-127)"

Save as devices/my_device.mmd and import:

@import "devices/my_device.mmd"

[00:00.000]
- device_preset 1.42

Step-by-Step Creation

Step 1: Gather MIDI Implementation

You need:

  1. MIDI Implementation Chart (from device manual)
  2. CC numbers for device functions
  3. PC behavior (how program changes work)
  4. SysEx messages (if applicable)
  5. Channel assignment (default MIDI channel)

Where to find:

  • Device user manual (appendix)
  • Manufacturer website (downloads section)
  • MIDI implementation PDF/chart

Step 2: Create Library File

Create devices/my_device.mmd:

---
device: "Device Name"
manufacturer: "Company"
version: 1.0.0
default_channel: 1
documentation: "https://example.com/midi-docs"
midi_channels: [1]
capabilities:
  - program_change
  - control_change
  - sysex
---

# ==============================================
# Device Name MIDI Library
# ==============================================

# MIDI Implementation Overview:
# - Channel: 1 (default)
# - Program Change: 0-127
# - Control Change: See sections below
# - SysEx: F0 00 01 02 ... F7

# ==============================================
# Section 1: Preset Management
# ==============================================

@alias device_preset pc.{ch}.{preset:0-127} "Load preset (0-127)"

# Add more aliases...

Step 3: Document Your Aliases

Each alias needs a description:

@alias device_volume cc.{ch}.7.{value:0-127} "Set master volume (0-127)"

Description guidelines:

  • What it does
  • Parameter ranges
  • Special notes (if any)

Step 4: Test the Library

Create test file:

---
title: "Device Library Test"
ppq: 480
---

@import "devices/my_device.mmd"

[00:00.000]
- device_preset 1.0
- device_volume 1.100

Validate:

mmdc validate test.mmd
mmdc inspect test.mmd

Alias Patterns

Simple Aliases

Map device functions to CC or PC:

@alias device_function cc.{ch}.{cc_number}.{value} "Description"

Examples:

@alias amp_gain cc.{ch}.1.{value:0-127} "Amp gain (0-127)"
@alias delay_time cc.{ch}.12.{value:0-127} "Delay time (0-127)"
@alias reverb_mix cc.{ch}.91.{value:0-127} "Reverb mix (0-127)"

Multi-Command Aliases

Combine multiple MIDI commands:

@alias device_load {ch}.{bank}.{preset} "Load bank and preset"
  - cc {ch}.32.{bank}      # Bank select LSB
  - cc {ch}.0.0            # Bank select MSB
  - pc {ch}.{preset}       # Program change
@end

Aliases with Defaults

Provide default values for optional parameters:

@alias device_volume {ch}.{value=100} "Set volume (default: 100)"
  - cc {ch}.7.{value}
@end

# Usage
- device_volume 1          # Uses default 100
- device_volume 1.75       # Uses 75

Enum Parameters

Named values for parameters:

@alias device_routing {ch}.{mode=series:0,parallel:1,a_only:2,b_only:3} "Set routing mode"
  - cc {ch}.85.{mode}
@end

# Usage
- device_routing 1.parallel    # Sends value 1
- device_routing 1.a_only      # Sends value 2

Computed Values

Transform parameters before sending:

@alias device_tempo {ch} {bpm:40-300} "Set tempo (40-300 BPM)"
  {midi_val = int((${bpm} - 40) * 127 / 260)}
  - cc {ch}.14.{midi_val}
@end

# BPM 120 → MIDI value 39

Common Device Patterns

Guitar Processor (Quad Cortex, Helix, Kemper)

# Preset loading
@alias cortex_load {ch}.{setlist}.{scene}.{preset} "Load complete preset"
  - cc {ch}.32.{setlist}   # Setlist
  - cc {ch}.0.{scene}      # Scene/group
  - pc {ch}.{preset}       # Preset
@end

# Scene switching
@alias cortex_scene pc.{ch}.{scene:0-7} "Switch scene (A-H = 0-7)"

# Expression pedals
@alias cortex_exp1 cc.{ch}.11.{value:0-127} "Expression pedal 1"
@alias cortex_exp2 cc.{ch}.12.{value:0-127} "Expression pedal 2"

# Stomp switches
@alias cortex_stomp_a cc.{ch}.81.{state:0-127} "Stomp A (0=off, 127=on)"
@alias cortex_stomp_a_on cc.{ch}.81.127 "Stomp A on"
@alias cortex_stomp_a_off cc.{ch}.81.0 "Stomp A off"

# Tap tempo
@alias cortex_tap_tempo cc.{ch}.80.127 "Tap tempo"

# Tuner
@alias cortex_tuner cc.{ch}.68.{state:0-127} "Tuner (0=off, 127=on)"

Multi-FX Unit (Eventide, Strymon)

# Preset selection
@alias h90_preset pc.{ch}.{preset:0-127} "Load preset"

# Algorithm selection
@alias h90_algo_a cc.{ch}.82.{algo:0-52} "Algorithm for path A"
@alias h90_algo_b cc.{ch}.83.{algo:0-52} "Algorithm for path B"

# Mix control
@alias h90_mix cc.{ch}.84.{percent:0-100} "A/B mix (0=A, 100=B)"

# Routing
@alias h90_routing cc.{ch}.85.{mode=series:0,parallel:1} "Routing mode"

# Performance controls
@alias h90_bypass cc.{ch}.102.{state=active:127,bypassed:0} "Bypass"
@alias h90_infinity cc.{ch}.90.127 "Infinity (freeze)"
@alias h90_hotswitch cc.{ch}.91.127 "HotSwitch"

Synthesizer

# Oscillator controls
@alias synth_osc1_wave cc.{ch}.70.{wave=saw:0,square:32,tri:64,sine:96} "OSC1 waveform"
@alias synth_osc1_detune cc.{ch}.71.{value:0-127} "OSC1 detune"

# Filter controls
@alias synth_filter_cutoff cc.{ch}.74.{value:0-127} "Filter cutoff"
@alias synth_filter_resonance cc.{ch}.71.{value:0-127} "Filter resonance"

# Envelope
@alias synth_env_attack cc.{ch}.73.{value:0-127} "Envelope attack"
@alias synth_env_decay cc.{ch}.75.{value:0-127} "Envelope decay"
@alias synth_env_sustain cc.{ch}.76.{value:0-127} "Envelope sustain"
@alias synth_env_release cc.{ch}.77.{value:0-127} "Envelope release"

# LFO
@alias synth_lfo_rate cc.{ch}.78.{value:0-127} "LFO rate"
@alias synth_lfo_depth cc.{ch}.79.{value:0-127} "LFO depth"

Organization Best Practices

Section Headers

Organize aliases by function:

# ==============================================
# Preset Management
# ==============================================

@alias device_preset ...
@alias device_bank ...

# ==============================================
# Effects Controls
# ==============================================

@alias device_reverb ...
@alias device_delay ...

# ==============================================
# Expression Pedals
# ==============================================

@alias device_exp1 ...
@alias device_exp2 ...

Naming Conventions

Prefix with device name:

@alias cortex_preset ...   # ✓ Clear
@alias preset ...           # ✗ Too generic

Use descriptive names:

@alias amp_gain ...            # ✓ Descriptive
@alias ag ...                  # ✗ Unclear

Group related functions:

@alias stomp_a_on ...
@alias stomp_a_off ...
@alias stomp_a_toggle ...

Parameter Naming

Use meaningful names:

{ch}           # Channel
{preset}       # Preset number
{value}        # Generic value
{percent}      # Percentage (0-100)
{state}        # On/off state
{mode}         # Mode selection

Include ranges in descriptions:

@alias device_tempo {ch} {bpm:40-300} "Set tempo (40-300 BPM)"

Advanced Features

Conditional Aliases

Different behavior based on parameters:

@alias smart_load {ch}.{preset}.{device_type} "Device-aware preset load"
  @if {device_type} == "a"
    - cc {ch}.32.0
    - pc {ch}.{preset}
  @elif {device_type} == "b"
    - cc {ch}.71.{preset}
  @end
@end

SysEx Support

Include SysEx messages:

@alias device_patch_dump "Request patch dump"
  - sysex F0 00 01 06 02 F7
@end

Macros for Common Sequences

@alias scene_change_smooth {ch}.{old_scene}.{new_scene} "Smooth scene transition"
  # Fade out old scene
  - cc {ch}.7.curve(100, 0, ease-in)

  # Switch scene
  [+500ms]
  - pc {ch}.{new_scene}

  # Fade in new scene
  [@]
  - cc {ch}.7.curve(0, 100, ease-out)
@end

Validation and Testing

Validate Library Structure

mmdc validate devices/my_device.mmd

Test Each Alias

Create comprehensive test file:

---
title: "Device Library Test Suite"
ppq: 480
---

@import "devices/my_device.mmd"

# Test all aliases
[00:00.000]
- device_preset 1.0
- device_volume 1.100
- device_function1 1.50
# ... test each alias

# Test edge cases
[00:10.000]
- device_preset 1.127     # Max value
- device_volume 1.0       # Min value
- device_function1 1.127  # Max value

Verify MIDI Output

# Inspect generated events
mmdc inspect test.mmd

# Compile and check MIDI
mmdc compile test.mmd -o test.mid

# Play back to verify
mmdc play test.mmd --port 0

Documentation Template

Complete library template:

---
device: "Device Full Name"
manufacturer: "Company Name"
version: 1.0.0
default_channel: 1
documentation: "https://example.com/midi-implementation"
midi_channels: [1]
date_created: "2025-01-15"
date_modified: "2025-01-15"
author: "Your Name"
capabilities:
  - program_change
  - control_change
  - sysex
notes: "Additional notes about this device"
---

# ==============================================
# Device Name MIDI Library
# ==============================================

/**
 * MIDI Implementation Summary
 *
 * Channels: 1 (default), supports 1-16
 * Program Change: 0-127 (presets)
 * Control Change: See sections below
 * SysEx: See SysEx section
 *
 * Quick Start:
 *   @import "devices/device_name.mmd"
 *   - device_preset 1.0
 *
 * Documentation: https://example.com/docs
 */

# ==============================================
# Preset Management
# ==============================================

@alias device_preset pc.{ch}.{preset:0-127} "Load preset (0-127)"

@alias device_bank_preset {ch}.{bank:0-7}.{preset:0-127} "Load bank and preset"
  - cc {ch}.32.{bank}
  - pc {ch}.{preset}
@end

# ==============================================
# Effects Controls
# ==============================================

@alias device_reverb cc.{ch}.91.{value:0-127} "Reverb mix (0-127)"
@alias device_delay cc.{ch}.92.{value:0-127} "Delay mix (0-127)"

# ... Add more sections as needed

Real-World Examples

Study existing device libraries:

# View Quad Cortex implementation
cat devices/quad_cortex.mmd

# View Eventide H90 implementation
cat devices/eventide_h90.mmd

# View Helix implementation
cat devices/helix.mmd

These provide patterns for:

  • Complex preset loading sequences
  • Expression pedal mapping
  • Stomp switch control
  • Tempo synchronization
  • Scene management

Publishing Your Library

1. Test Thoroughly

# Validate
mmdc validate devices/my_device.mmd

# Test all aliases
mmdc validate test_suite.mmd

# Test with actual device
mmdc play test_suite.mmd --port "Device Name"

2. Document Usage

Add README or examples:

/**
 * Usage Examples
 *
 * Basic preset load:
 *   - device_preset 1.42
 *
 * Bank select:
 *   - device_bank_preset 1.2.5
 *
 * Effects control:
 *   - device_reverb 1.75
 */

3. Share with Community

  • Add to project devices/ directory
  • Create pull request
  • Include test files
  • Document MIDI implementation source

Troubleshooting

Alias Not Working

# Check import
grep "@import" your_file.mmd

# Verify alias definition
grep "@alias device_name" devices/my_device.mmd

# Test with raw MIDI
- cc 1.XX.YY  # Instead of alias

Parameter Count Mismatch

# Check parameter count
@alias name {p1}.{p2} "..."

# Usage must match
- name 1.2      # ✓ Correct
- name 1        # ✗ Missing parameter

Value Out of Range

# Add range constraints
@alias func {ch}.{value:0-100} "..."

# Or use computed values
{clamped = min(127, max(0, ${value}))}

Related Skills and Resources

Skills:

  • mmd-writing - MMD syntax reference
  • mmd-debugging - Troubleshooting aliases
  • mmd-cli - Testing and validation

Resources:

  • devices/ - Existing device libraries (6 examples)
  • examples/04_device_libraries/ - Usage examples
  • docs/user-guide/alias-system.md - Alias documentation
  • spec.md - Complete alias syntax reference

Quick Reference

Alias Syntax

# Simple alias
@alias name command.{param} "Description"

# Multi-command alias
@alias name {p1}.{p2} "Description"
  - command1
  - command2
@end

# With defaults
@alias name {param=default} "Description"

# With enums
@alias name {param=opt1:val1,opt2:val2} "Description"

# With computed values
@alias name {param} "Description"
  {computed = expression}
  - command ${computed}
@end

Testing Workflow

1. mmdc validate devices/my_device.mmd
2. mmdc validate test_file.mmd
3. mmdc inspect test_file.mmd
4. mmdc play test_file.mmd --port 0

For complete device library examples, see the devices/ directory in the project.