显示 HN:MTXT – 音乐文本格式
Show HN: MTXT – Music Text Format

原始链接: https://github.com/Daninet/mtxt

## MTXT:一种便于阅读的音乐格式 MTXT是一种新的基于文本的音乐数据格式,旨在方便创建、编辑和操作,而无需专业工具。它基于节拍,使用十进制表示法来表示小节拍(例如,在4/4拍中,3.25表示3个四分音符加一个十六分音符)。每个事件占用一行,简化了使用任何文本编辑器进行编辑,并支持乐谱符号,如`C4`、`D#3`,或自定义别名,如`kick`或`Cmaj7`。 主要特性包括内置的参数平滑过渡支持(如音量或速度),具有可定制的曲线,实时流式传输,以及使用美分表示的微调音记号(例如`C4+50`)。文件具有灵活性,允许事件以任何顺序排列,并且通过转换工具与MIDI完全兼容。 值得注意的是,MTXT被设计为易于被语言模型(LLM)处理,并且具有前瞻性,支持大量的通道和自定义元数据。一个Rust库和一个CLI工具可用于解析、写入和转换MTXT文件,包括移调、量化和通道过滤等选项。该格式优先考虑人类可读性和表现力,同时保持精确性和兼容性。

Hacker News 新闻 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Show HN: MTXT – 音乐文本格式 (github.com/daninet) 9 分,daninet 发表于 2 小时前 | 隐藏 | 过去 | 收藏 | 1 条评论 yaoke259 发表于 0 分钟前 [–] 很酷!回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

MTXT is a human-editable, text-based representation of music information.
It aims to simplify the process of writing, reading, and editing musical data without requiring specialized binary tools.

  • Beat-based: Events are placed on fractional beats using simple decimal notation (e.g., in a 4/4 time signature, 1 beat = 1 quarter note, so 3.25 represents 3 quarter notes plus 1 sixteenth note).
  • One event per line: Easy to search and modify with any text editor.
  • Human-friendly: Use of musical note names (C4, D#3, etc.) and custom note aliases (e.g. kick or Cmaj7). Hand-crafted files are practical and expressive.
  • Transitions: Built-in support for gliding continuous parameters (CC, tempo) with customizable curves and timing.
  • Real-time ready: Supports streaming musical events and real-time data transfer with transitions and flexible timing.
  • Microtonal support: Built-in cents notation for notes (e.g. C4+50, D4-25) and global tuning commands for alternate tuning systems and just intonation.
  • Flexible organization: Events can be written in any order in the file, with the parser handling chronological sorting.
  • MIDI compatible: Reference implementation includes MIDI to MTXT and MTXT to MIDI conversion.
  • LLM compatible: Can be easily generated and manipulated by language models.
  • Future-proof: Supports up to 65535 channels, arbitrary CC parameters with custom string keys and custom metadata.
mtxt 1.0
meta global title Sunrise Melody
meta global author Jane Composer

// Define aliases for drums and chords
alias kick C1
alias Cmaj7 C4,E4,G4,B4

// Global tempo and time signature
0.0 tempo 100
0.0 timesig 4/4

// Set defaults for channel, duration, and velocity
ch=0
dur=1.0
vel=0.8

// Set voice. "John's bright grand" has precedence, but it falls back to a more generic "piano" if not found.
0.0 voice piano, John's bright grand

// Start silently
0.0 cc volume 0.0

// Fade in volume over 3.0 beats, ending at beat 4.0
4.0 cc volume 1.0 transition_time=3.0 transition_curve=0.5

// Play melody (uses default duration and velocity from above, unless overridden)
0.0 note C4
1.0 note E4 
2.0 note G4 vel=0.5
2.0 note G4 vel=0.5

// Chords can also be played (defined above as an alias for C4,E4,G4,B4 notes)
1.0 note Cmaj7 dur=2.0 vel=0.2

// Tempo ramp
8.0 tempo 120 transition_time=4.0

// Microtonal note (12TET equal temperament C4 + 50 cents)
3.0 note C4+50

Rust Library and CLI Tool

This repository includes a reference implementation in Rust that provides:

  • Library (mtxt): Rust crate for parsing and writing MTXT files, with MIDI conversion features.
  • CLI tool: Command-line utility for converting between MIDI and MTXT formats with built-in transforms. Builds can be downloaded from releases.
mid2mtxt input.mid output.mtxt
mid2mtxt input.mtxt output.mid

The CLI supports various transforms that can be applied during conversion:

Musical Transforms:

  • --transpose <SEMITONES> - Transpose all notes by semitones (e.g., --transpose +2 or --transpose -12)
  • -q, --quantize <GRID> - Quantize timing to a grid (e.g., 4 for quarter notes, 16 for 16th notes)
  • --swing <AMOUNT> - Apply swing feel (0.0 to 1.0)
  • --humanize <AMOUNT> - Add timing randomization for humanization (0.0 to 1.0)

Channel Filtering:

  • --include-channels <CHANNELS> - Include only specific channels (comma-separated, e.g., 1,2,10)
  • --exclude-channels <CHANNELS> - Exclude specific channels (comma-separated, e.g., 1,2,10)

File Organization:

  • --apply-directives - Apply global directives to events (inline parameters)
  • --extract-directives - Extract common inline parameters into global directives
  • --sort - Sort events by time

  • First line must declare version:
  • Lines beginning with // are comments and ignored by the parser.
  • A file consists of:
    1. Version line
    2. Global metadata (optional)
    3. Events (can be in any timestamp order)
  • All times are in beats specified as fractional numbers. e.g. in a 4/4 time signature, 1 beat = 1 quarter note, so 3.25 represents 3 quarter notes plus 1 sixteenth note.
  • This allows changing the tempo and time signature without affecting the timing of events.
  • Events may appear in any order in the file; the parser will sort them before playback
  • Precision is limited to 5 decimal places (5 microseconds at 120 BPM).
  • Declares the file format version in the major.minor format (e.g., mtxt 1.0).
  • Must be the first non-comment line.
// global meta (applies to the entire file and all channels)
meta global <type> <value>
// channel meta (applies to a single channel), starting from the specified time
[<time>] meta [ch=<0..65535>] <type> <value>
  • Adds metadata (e.g., title, author, copyright, trackname, custom types).
  • Value extends from the type to the end of the line (or until inline comment).
  • Channel is optional, if not specified it inherits the channel from the previous ch command.
  • Time is optional, defaults to 0.0.
  • See Standard Meta Types for a list of standard types.
  • Newline characters in need to be escaped to avoid breaking the syntax.
Type Description Example
title Song title meta global title My Song
author Composer/author meta global author John Doe
copyright Copyright notice meta global copyright © 2024 Music Corp
composer Composer name meta global composer John Doe
name Channel name meta ch=1 name Lead Guitar
instrument Instrument name meta ch=2 instrument Steinway Grand
smpte SMPTE offset meta global smpte 00:00:00:00
keysignature Key signature 4.0 meta ch=3 keysignature C major
text General text meta text Verse 1
lyric Lyrics 5.0 meta lyric Hello world
marker Marker/cue point 6.0 meta marker Chorus
cue Cue point 7.0 meta cue Solo begins
program Program name meta global program Piano Ballad
device Device name meta global device OpenPiano 1000
key Key signature meta global key C major
date Creation date meta global date 2024-01-01
genre Musical genre meta global genre Rock
album Album name meta global album Greatest Hits
url Related URL meta global url https://example.com
artist Performer name meta global artist The Band
license Usage license meta global license CC-BY-4.0
generator Software tool meta global generator MySequencer v1.0
  • Sets the default MIDI channel for subsequent events.
  • Inline ch=<N> on events overrides the default for that event only.
  • Required before channel-dependent events that omit inline ch.
  • Defines a named alias for a note pitch or a chord.
  • <name>: Alphanumeric identifier (e.g., snare, Cmaj7).
  • <value>: Target note(s), comma-separated if multiple.
  • No timestamp. Applies to all subsequent events in the file until overridden.
  • Example:
    alias snare C2
    alias Cmaj7 C4,E4,G4,B4  // chord alias
    0.0 note snare
    1.0 note Cmaj7          // plays all 4 notes
    

vel (default note-on velocity)

  • Sets the default note-on velocity.
  • Inline vel=<N> on note/on overrides for that event.

offvel (default note-off velocity)

  • Sets the default note-off velocity.
  • Inline offvel=<N> on note/off overrides for that event.
  • Defaults to 1.0 if not set.

dur (default note duration)

  • Sets the default note duration in beats.
  • Inline dur=<N> on note overrides for that event.
  • Defaults to 1.0 if not set.
transition_curve=<float>
transition_interval=<float>
  • Sets default transition parameters for cc and tempo.
  • transition_time must be specified per event (default 0.0).
  • See Transitions section for details.
  • Defaults: curve=0.0, interval=1.0.
<time> note <NOTE> [dur=<float>] [vel=<0..1>] [offvel=<0..1>] [ch=<0..65535>]
  • Emits note-on at <time> and note-off at <time + dur>.
  • Uses defaults from dur, vel, offvel, and ch unless overridden.
  • <time> is absolute beat BEAT.SUB (0-based). Example: 3.5.
  • <NOTE> can be a standard note name or an alias.
  • Standard names support C..B with #/b, octave required (e.g., C4).
    • Allowed: C, C#, Db, D, D#, Eb, E, F, F#, Gb, G, G#, Ab, A, A#, Bb, B
    • Case insensitive: Both uppercase and lowercase are accepted (C4, c4, Bb2, bb2, F#3, f#3)
    • Double accidentals not allowed.
    • Microtonal: +N/-N cents (range -99..+99), applied via pitch bend. Examples: C4+50 (50 cents sharp), D4-25 (25 cents flat), bb2+10.5 (10.5 cents sharp). Positive values require +.
<time> on <NOTE> [vel=<0..1>] [ch=<0..65535>]
  • Emits a note-on only; useful for streaming.
  • Uses default vel and ch unless overridden.
<time> off <NOTE> [offvel=<0..1>] [ch=<0..65535>]
  • Emits a note-off only; useful for streaming.
  • Uses default offvel and ch unless overridden.
<time> cc [note] <controller> <value> [ch=<0..65535>] [transition_curve=<float>] [transition_time=<float>] [transition_interval=<float>]
  • Sends a control change. <controller> identifies the parameter.
  • <value> is [0.0..1.0]. Uses default ch unless overridden.
  • Uses global transition defaults unless overridden inline.
  • Optional note to apply CC to a specific note. If a note is specified, it applies to that note only.
  • When a note is not specified, it applies to all notes within a channel.
  • Arbitrary string keys can be used for custom parameters (e.g., cc my_param 0.5).
Name Range Description
pitch -12.0..12.0 Pitch bend in semitones. 0=none, 1 = one semitone up, -0.005 = half cent down
aftertouch 0.0..1.0 Channel or Polyphonic Aftertouch
vibrato 0.0..1.0 Vibrato depth (Modulation Wheel)
vibrato_rate 0.0..1024.0 Vibrato rate in Hz
breath 0.0..1.0 Breath controller pressure
foot 0.0..1.0 Foot controller pedal position
portamento 0.0..1.0 Portamento glide time
volume 0.0..1.0 Channel volume level
balance -1.0..1.0 Stereo balance (left < 0, right > 0)
pan -1.0..1.0 Stereo panning position (left < 0, right > 0)
expression 0.0..1.0 Expression (secondary volume, relative to main)
sustain 0.0..1.0 Sustain pedal (damper) on/off (> 0.5 is on)
portamento_switch 0.0..1.0 Portamento on/off switch (> 0.5 is on)
sostenuto 0.0..1.0 Sostenuto pedal on/off (> 0.5 is on)
soft 0.0..1.0 Soft pedal (una corda) on/off (> 0.5 is on)
legato 0.0..1.0 Legato footswitch on/off (> 0.5 is on)
sound_variation 0.0..1.0 Sound variation
timbre 0.0..1.0 Timbre/harmonic intensity
resonance 0.0..1.0 Resonance/Harmonic Content
attack 0.0..1.0 Attack time
decay 0.0..1.0 Decay time
hold 0.0..1.0 Hold time
sustain_level 0.0..1.0 Sustain level (envelope)
release 0.0..1.0 Release time
cutoff 0.0..1.0 Filter cutoff frequency (Brightness)
reverb 0.0..1.0 Reverb send level
tremolo 0.0..1.0 Tremolo depth
tremolo_rate 0.0..1024.0 Tremolo rate in Hz
chorus 0.0..1.0 Chorus send level
detune 0.0..1.0 Detune depth
phaser 0.0..1.0 Phaser depth
distortion 0.0..1.0 Distortion/Drive amount
compression 0.0..1.0 Compression amount
local_control 0.0..1.0 Local control on/off (> 0.5 is on)
polyphony 1.0..1024.0 Polyphony count (rounded to int). 1=mono

voice (instrument selection)

<time> voice [ch=<0..65535>] <voice_list>
  • Sets the instrument voice for the channel.
  • <voice_list> is a comma-separated list of voice names (e.g., piano, acoustic piano, john's super piano).
  • The synthesizer should use the last voice in the list that it supports.
  • It is recommended to use a standard voice from instruments.md as the first item for compatibility.
<time> tempo <bpm> [transition_curve=<float>] [transition_time=<float>] [transition_interval=<float>]
  • Sets tempo in BPM at <time>.
  • Uses global transition defaults unless overridden inline.
  • By default, tempo is at 120 BPM at the start of the file.
<time> timesig <NUM>/<DEN>
  • Sets time signature; affects beat interpretation after <time>.
  • By default, time signature is 4/4 at the start of the file.
<time> tuning <target> <cents>
  • By default, notes are defined with equal temperament tuning (12TET).
  • Sets the global tuning offset for a note or pitch class.
  • <target> can be a pitch class (e.g., C, F#) or a specific note (e.g., C4).
  • <cents> is in range [-100.0..+100.0]. Positive values must use +.
  • Tuning is additive: Final Pitch = Standard Pitch + Tuning + Note Offset.
  • Changes are instantaneous (no interpolation).
  • Specific note tuning overrides pitch class tuning.
  • Example:
    0.0 tuning E -13.7   // Flatten all Es
    0.0 tuning G +3.5    // Sharpen all Gs
    0.0 tuning E4 0.0    // Exception: E4 is standard tuning (overrides previous line)
    
  • Resets state variables to defaults.
  • <target> options:
    • all (default): All notes off, all controllers reset, tuning cleared on all channels.
    • ch=<N>: Resets controllers and turns off notes on specific channel.
    • tuning: Clears all global tuning definitions.
  • Example:
    10.0 reset all
    12.0 reset ch=1
    14.0 reset tuning
    
  • Sends raw SysEx bytes (space-separated hex, including F0/F7 as needed).
  • Example: 12.0 sysex F0 7E 7F 09 01 F7
  • Lines beginning with // are ignored by the parser.

Use transitions to glide a continuous parameter to a target value by a specific beat, with a chosen feel.

  • Supported on: cc, tempo.
  • Fields:
    • transition_curve=<alpha> controls the feel of the glide:
      • 0.0 (linear): steady change from start to finish (default)
      • > 0 (gentle start → speeds up): musical "ease-in", swells late.
      • < 0 (fast start → settles): musical "ease-out", arrives smoothly.
    • transition_time=<duration> (τ) is the glide length in beats. Defaults to 0.0 (instant jump). The change begins at T − τ and reaches the target at command time T.
    • transition_interval=<duration> is the minimum time between each value update in milliseconds. Defaults to 1.0 (as fast as possible).

Examples:

  • 0.0 cc pitch 0.0 — pitch is 0.0 at 0.0.
  • 1.0 cc pitch 0.5 transition_time=0.2 — pitch glides to 0.5 value between beats 0.8 and 1.0.
  • 5.0 cc pitch 0.95 transition_curve=0.5 transition_time=1.5 — starts at 3.5, accelerates toward 0.95 near 5.0.
  • 7.0 cc volume 0.2 transition_curve=-0.4 transition_time=2.0 — begins at 5.0, moves quickly then coasts into 0.2 at 7.0.

Curve definition:

  • value(t) = V0 + (V1 − V0) * ( s + max(α,0) * (s^4 − s) − max(−α,0) * ((1 − (1 − s)^4) − s) )
  • s = (t − (T − τ)) / τ; if τ = 0, the change is instant at T.

Notes:

  • Each transition needs a defined value before its end time T to establish the start (V0 at T − τ). If no prior value exists, this is an error.
  • Overlapping transitions on the same parameter/channel: the new transition immediately aborts the previous at the current value and takes over. When segments conflict, the one with the later end beat (T) has precedence.

Copyright © 2025 Dani Biró

Licensed under the MIT License.

联系我们 contact @ memedata.com