Skip to content

Instantly share code, notes, and snippets.

@autch
Created January 15, 2026 10:31
Show Gist options
  • Select an option

  • Save autch/57f2fe62cb8dbfa071fa062403d49ab1 to your computer and use it in GitHub Desktop.

Select an option

Save autch/57f2fe62cb8dbfa071fa062403d49ab1 to your computer and use it in GitHub Desktop.
Kaitai Struct (https://kaitai.io/) description for P/ECE music sequence file
meta:
id: piece_pmd
file-extension: pmd
endian: le
seq:
- id: hdr
type: header
instances:
part_bodies:
type: part_body(_index, actual_num_parts) # <= pass `_index` into file_body
repeat: expr
repeat-expr: actual_num_parts
title1:
pos: hdr.title1_offset
type: strz
encoding: Shift_JIS
title2:
pos: hdr.title2_offset
type: strz
encoding: Shift_JIS
drum_pattern_offsets:
pos: hdr.drum_offset
type: u2
repeat: eos
if: hdr.drum_offset != 0
drum_pattern_bodies:
type: drum_pattern_body(_index, drum_pattern_offsets.size)
repeat: expr
repeat-expr: drum_pattern_offsets.size
if: hdr.drum_offset != 0
actual_num_parts:
value: "hdr.zero == 0 ? hdr.num_parts : hdr.zero"
types:
header:
seq:
- id: zero
type: u1
valid: 0x00
- id: num_parts
type: u1
if: zero == 0x00
- id: part_offsets
type: u2
repeat: expr
repeat-expr: _root.actual_num_parts
- id: drum_offset
type: u2
- id: title1_offset
type: u2
- id: title2_offset
type: u2
part:
seq:
- id: commands
type: command
repeat: until
repeat-until: |
_.command == ctrlcode::ccd_end or _.command == ctrlcode::ccd_jmp
command:
seq:
- id: command
type: u1
enum: ctrlcode
- id: param
type:
switch-on: command
cases:
"ctrlcode::ccd_lex": lex
"ctrlcode::ccd_gat": gat
"ctrlcode::ccd_jmp": jmp
"ctrlcode::ccd_cal": cal
"ctrlcode::ccd_rpt": rpt
"ctrlcode::ccd_trs": trs
"ctrlcode::ccd_tmp": tmp
"ctrlcode::ccd_ino": ino
"ctrlcode::ccd_vol": vol
"ctrlcode::ccd_env": env
"ctrlcode::ccd_dtn": dtn
"ctrlcode::ccd_not": not
"ctrlcode::ccd_ppa": ppa
"ctrlcode::ccd_tat": tat
"ctrlcode::ccd_vib": vib
"ctrlcode::ccd_mvl": mvl
"ctrlcode::ccd_mfd": mfd
"ctrlcode::ccd_bnd": bnd
"ctrlcode::ccd_exp": exp
"ctrlcode::not_80": note
"ctrlcode::not_81": note
"ctrlcode::not_82": note
"ctrlcode::not_83": note
"ctrlcode::not_84": note
"ctrlcode::not_85": note
"ctrlcode::not_86": note
"ctrlcode::not_87": note
"ctrlcode::not_88": note
"ctrlcode::not_89": note
"ctrlcode::not_8a": note
"ctrlcode::not_8b": note
"ctrlcode::not_8c": note
"ctrlcode::not_8d": note
"ctrlcode::not_8e": note
"ctrlcode::not_8f": note
"ctrlcode::not_90": note
"ctrlcode::not_91": note
"ctrlcode::not_92": note
"ctrlcode::not_93": note
"ctrlcode::not_94": note
"ctrlcode::not_95": note
"ctrlcode::not_96": note
"ctrlcode::not_97": note
"ctrlcode::not_98": note
"ctrlcode::not_99": note
"ctrlcode::not_9a": note
"ctrlcode::not_9b": note
"ctrlcode::not_9c": note
"ctrlcode::not_9d": note
"ctrlcode::not_9e": note
"ctrlcode::not_9f": note
"ctrlcode::not_a0": note
"ctrlcode::not_a1": note
"ctrlcode::not_a2": note
"ctrlcode::not_a3": note
"ctrlcode::not_a4": note
"ctrlcode::not_a5": note
"ctrlcode::not_a6": note
"ctrlcode::not_a7": note
"ctrlcode::not_a8": note
"ctrlcode::not_a9": note
"ctrlcode::not_aa": note
"ctrlcode::not_ab": note
"ctrlcode::not_ac": note
"ctrlcode::not_ad": note
"ctrlcode::not_ae": note
"ctrlcode::not_af": note
"ctrlcode::not_b0": note
"ctrlcode::not_b1": note
"ctrlcode::not_b2": note
"ctrlcode::not_b3": note
"ctrlcode::not_b4": note
"ctrlcode::not_b5": note
"ctrlcode::not_b6": note
"ctrlcode::not_b7": note
"ctrlcode::not_b8": note
"ctrlcode::not_b9": note
"ctrlcode::not_ba": note
"ctrlcode::not_bb": note
"ctrlcode::not_bc": note
"ctrlcode::not_bd": note
"ctrlcode::not_be": note
"ctrlcode::not_bf": note
"ctrlcode::not_c0": note
"ctrlcode::not_c1": note
"ctrlcode::not_c2": note
"ctrlcode::not_c3": note
"ctrlcode::not_c4": note
"ctrlcode::not_c5": note
"ctrlcode::not_c6": note
"ctrlcode::not_c7": note
"ctrlcode::not_c8": note
"ctrlcode::not_c9": note
"ctrlcode::not_ca": note
"ctrlcode::not_cb": note
"ctrlcode::not_cc": note
"ctrlcode::not_cd": note
"ctrlcode::not_ce": note
"ctrlcode::not_cf": note
"ctrlcode::not_d0": note
"ctrlcode::not_d1": note
"ctrlcode::not_d2": note
"ctrlcode::not_d3": note
"ctrlcode::not_d4": note
"ctrlcode::not_d5": note
"ctrlcode::not_d6": note
"ctrlcode::not_d7": note
"ctrlcode::not_d8": note
"ctrlcode::not_d9": note
"ctrlcode::not_da": note
"ctrlcode::not_db": note
"ctrlcode::not_dc": note
"ctrlcode::not_dd": note
"ctrlcode::not_de": note
"ctrlcode::not_df": note
"ctrlcode::ccd_exr": exr
"ctrlcode::len_1": length
"ctrlcode::len_2": length
"ctrlcode::len_3": length
"ctrlcode::len_4": length
"ctrlcode::len_5": length
"ctrlcode::len_6": length
"ctrlcode::len_7": length
"ctrlcode::len_8": length
"ctrlcode::len_9": length
"ctrlcode::len_10": length
"ctrlcode::len_11": length
"ctrlcode::len_12": length
"ctrlcode::len_13": length
"ctrlcode::len_14": length
"ctrlcode::len_15": length
"ctrlcode::len_16": length
"ctrlcode::len_17": length
"ctrlcode::len_18": length
"ctrlcode::len_19": length
"ctrlcode::len_20": length
"ctrlcode::len_21": length
"ctrlcode::len_22": length
"ctrlcode::len_23": length
"ctrlcode::len_24": length
"ctrlcode::len_25": length
"ctrlcode::len_26": length
"ctrlcode::len_27": length
"ctrlcode::len_28": length
"ctrlcode::len_29": length
"ctrlcode::len_30": length
"ctrlcode::len_31": length
"ctrlcode::len_32": length
"ctrlcode::len_33": length
"ctrlcode::len_34": length
"ctrlcode::len_35": length
"ctrlcode::len_36": length
"ctrlcode::len_37": length
"ctrlcode::len_38": length
"ctrlcode::len_39": length
"ctrlcode::len_40": length
"ctrlcode::len_41": length
"ctrlcode::len_42": length
"ctrlcode::len_43": length
"ctrlcode::len_44": length
"ctrlcode::len_45": length
"ctrlcode::len_46": length
"ctrlcode::len_47": length
"ctrlcode::len_48": length
"ctrlcode::len_49": length
"ctrlcode::len_50": length
"ctrlcode::len_51": length
"ctrlcode::len_52": length
"ctrlcode::len_53": length
"ctrlcode::len_54": length
"ctrlcode::len_55": length
"ctrlcode::len_56": length
"ctrlcode::len_57": length
"ctrlcode::len_58": length
"ctrlcode::len_59": length
"ctrlcode::len_60": length
"ctrlcode::len_61": length
"ctrlcode::len_62": length
"ctrlcode::len_63": length
"ctrlcode::len_64": length
"ctrlcode::len_65": length
"ctrlcode::len_66": length
"ctrlcode::len_67": length
"ctrlcode::len_68": length
"ctrlcode::len_69": length
"ctrlcode::len_70": length
"ctrlcode::len_71": length
"ctrlcode::len_72": length
"ctrlcode::len_73": length
"ctrlcode::len_74": length
"ctrlcode::len_75": length
"ctrlcode::len_76": length
"ctrlcode::len_77": length
"ctrlcode::len_78": length
"ctrlcode::len_79": length
"ctrlcode::len_80": length
"ctrlcode::len_81": length
"ctrlcode::len_82": length
"ctrlcode::len_83": length
"ctrlcode::len_84": length
"ctrlcode::len_85": length
"ctrlcode::len_86": length
"ctrlcode::len_87": length
"ctrlcode::len_88": length
"ctrlcode::len_89": length
"ctrlcode::len_90": length
"ctrlcode::len_91": length
"ctrlcode::len_92": length
"ctrlcode::len_93": length
"ctrlcode::len_94": length
"ctrlcode::len_95": length
"ctrlcode::len_96": length
"ctrlcode::len_97": length
"ctrlcode::len_98": length
"ctrlcode::len_99": length
"ctrlcode::len_100": length
"ctrlcode::len_101": length
"ctrlcode::len_102": length
"ctrlcode::len_103": length
"ctrlcode::len_104": length
"ctrlcode::len_105": length
"ctrlcode::len_106": length
"ctrlcode::len_107": length
"ctrlcode::len_108": length
"ctrlcode::len_109": length
"ctrlcode::len_110": length
"ctrlcode::len_111": length
"ctrlcode::len_112": length
"ctrlcode::len_113": length
"ctrlcode::len_114": length
"ctrlcode::len_115": length
"ctrlcode::len_116": length
"ctrlcode::len_117": length
"ctrlcode::len_118": length
"ctrlcode::len_119": length
"ctrlcode::len_120": length
"ctrlcode::len_121": length
"ctrlcode::len_122": length
"ctrlcode::len_123": length
"ctrlcode::len_124": length
"ctrlcode::len_125": length
"ctrlcode::len_126": length
_: nop
nop: {}
part_body:
params:
- id: i
type: u1
- id: s
type: u2
instances:
body:
type: part
pos: _root.hdr.part_offsets[i]
drum_pattern_body:
params:
- id: i
type: u1
- id: s
type: u2
instances:
body:
type: part
pos: _root.drum_pattern_offsets[i]
note: {}
length: {}
# command arguments
lex:
seq:
- id: ext
type: u1
gat:
seq:
- id: gate
type: u1
jmp:
seq:
- id: addr
type: u2
cal:
seq:
- id: addr
type: u2
- id: times
type: u1
rpt:
seq:
- id: times
type: u1
trs:
seq:
- id: value
type: s1
tmp:
seq:
- id: bpm
type: u1
ino:
seq:
- id: inst
type: u1
vol:
seq:
- id: volume
type: u1
env:
seq:
- id: ar
type: u1
- id: dr
type: u1
- id: sl
type: u1
- id: sr
type: u1
dtn:
seq:
- id: detune
type: s1
not:
seq:
- id: note
type: u1
ppa:
seq:
- id: distance
type: s1
- id: speed
type: u1
tat:
seq:
- id: attr
type: u1
vib:
seq:
- id: depth
type: u1
- id: speed
type: u1
- id: delay
type: u1
- id: rate
type: u1
mvl:
seq:
- id: vol
type: u1
mfd:
seq:
- id: fade
type: u2
bnd:
seq:
- id: bend
type: s2
exp:
seq:
- id: exp
type: u1
exr:
seq:
- id: exp
type: s1
enums:
ctrlcode:
# control codes
0x00: ccd_end
0x7f: ccd_lex
0xe0: ccd_rrr
0xe1: ccd_gat
0xe2: ccd_jmp
0xe3: ccd_cal
0xe4: ccd_rpt
0xe5: ccd_nxt
0xe6: ccd_trs
0xe7: ccd_tmp
0xe8: ccd_ino
0xe9: ccd_vol
0xea: ccd_env
0xeb: ccd_dtn
0xec: ccd_not
0xed: ccd_ppa
0xee: ccd_pon
0xef: ccd_pof
0xf0: ccd_tat
0xf1: ccd_vib
0xf2: ccd_mvl
0xf3: ccd_mfd
0xf4: ccd_pfd
0xf5: ccd_bnd
0xf6: ccd_brk
0xf7: ccd_nop
0xf8: ccd_leg
0xf9: ccd_lof
0xfa: ccd_exp
0xfb: ccd_exr
# notes
0x80: not_80
0x81: not_81
0x82: not_82
0x83: not_83
0x84: not_84
0x85: not_85
0x86: not_86
0x87: not_87
0x88: not_88
0x89: not_89
0x8a: not_8a
0x8b: not_8b
0x8c: not_8c
0x8d: not_8d
0x8e: not_8e
0x8f: not_8f
0x90: not_90
0x91: not_91
0x92: not_92
0x93: not_93
0x94: not_94
0x95: not_95
0x96: not_96
0x97: not_97
0x98: not_98
0x99: not_99
0x9a: not_9a
0x9b: not_9b
0x9c: not_9c
0x9d: not_9d
0x9e: not_9e
0x9f: not_9f
0xa0: not_a0
0xa1: not_a1
0xa2: not_a2
0xa3: not_a3
0xa4: not_a4
0xa5: not_a5
0xa6: not_a6
0xa7: not_a7
0xa8: not_a8
0xa9: not_a9
0xaa: not_aa
0xab: not_ab
0xac: not_ac
0xad: not_ad
0xae: not_ae
0xaf: not_af
0xb0: not_b0
0xb1: not_b1
0xb2: not_b2
0xb3: not_b3
0xb4: not_b4
0xb5: not_b5
0xb6: not_b6
0xb7: not_b7
0xb8: not_b8
0xb9: not_b9
0xba: not_ba
0xbb: not_bb
0xbc: not_bc
0xbd: not_bd
0xbe: not_be
0xbf: not_bf
0xc0: not_c0
0xc1: not_c1
0xc2: not_c2
0xc3: not_c3
0xc4: not_c4
0xc5: not_c5
0xc6: not_c6
0xc7: not_c7
0xc8: not_c8
0xc9: not_c9
0xca: not_ca
0xcb: not_cb
0xcc: not_cc
0xcd: not_cd
0xce: not_ce
0xcf: not_cf
0xd0: not_d0
0xd1: not_d1
0xd2: not_d2
0xd3: not_d3
0xd4: not_d4
0xd5: not_d5
0xd6: not_d6
0xd7: not_d7
0xd8: not_d8
0xd9: not_d9
0xda: not_da
0xdb: not_db
0xdc: not_dc
0xdd: not_dd
0xde: not_de
0xdf: not_df
# length specifier
0x01: len_1
0x02: len_2
0x03: len_3
0x04: len_4
0x05: len_5
0x06: len_6
0x07: len_7
0x08: len_8
0x09: len_9
0x0a: len_10
0x0b: len_11
0x0c: len_12
0x0d: len_13
0x0e: len_14
0x0f: len_15
0x10: len_16
0x11: len_17
0x12: len_18
0x13: len_19
0x14: len_20
0x15: len_21
0x16: len_22
0x17: len_23
0x18: len_24
0x19: len_25
0x1a: len_26
0x1b: len_27
0x1c: len_28
0x1d: len_29
0x1e: len_30
0x1f: len_31
0x20: len_32
0x21: len_33
0x22: len_34
0x23: len_35
0x24: len_36
0x25: len_37
0x26: len_38
0x27: len_39
0x28: len_40
0x29: len_41
0x2a: len_42
0x2b: len_43
0x2c: len_44
0x2d: len_45
0x2e: len_46
0x2f: len_47
0x30: len_48
0x31: len_49
0x32: len_50
0x33: len_51
0x34: len_52
0x35: len_53
0x36: len_54
0x37: len_55
0x38: len_56
0x39: len_57
0x3a: len_58
0x3b: len_59
0x3c: len_60
0x3d: len_61
0x3e: len_62
0x3f: len_63
0x40: len_64
0x41: len_65
0x42: len_66
0x43: len_67
0x44: len_68
0x45: len_69
0x46: len_70
0x47: len_71
0x48: len_72
0x49: len_73
0x4a: len_74
0x4b: len_75
0x4c: len_76
0x4d: len_77
0x4e: len_78
0x4f: len_79
0x50: len_80
0x51: len_81
0x52: len_82
0x53: len_83
0x54: len_84
0x55: len_85
0x56: len_86
0x57: len_87
0x58: len_88
0x59: len_89
0x5a: len_90
0x5b: len_91
0x5c: len_92
0x5d: len_93
0x5e: len_94
0x5f: len_95
0x60: len_96
0x61: len_97
0x62: len_98
0x63: len_99
0x64: len_100
0x65: len_101
0x66: len_102
0x67: len_103
0x68: len_104
0x69: len_105
0x6a: len_106
0x6b: len_107
0x6c: len_108
0x6d: len_109
0x6e: len_110
0x6f: len_111
0x70: len_112
0x71: len_113
0x72: len_114
0x73: len_115
0x74: len_116
0x75: len_117
0x76: len_118
0x77: len_119
0x78: len_120
0x79: len_121
0x7a: len_122
0x7b: len_123
0x7c: len_124
0x7d: len_125
0x7e: len_126
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment