Skip to content

Commit

Permalink
midi: fixes for PR comments
Browse files Browse the repository at this point in the history
- Reworked event types as snake-case (cf. #1004 (comment))
- Decoded 'alien' chunks (cf. #1004 (comment))
  • Loading branch information
twystd committed Sep 5, 2024
1 parent 9f057b6 commit 87c80f5
Show file tree
Hide file tree
Showing 18 changed files with 206 additions and 144 deletions.
2 changes: 1 addition & 1 deletion format/midi/metaevents.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func decodeMetaEvent(d *decode.D, event uint8, ctx *context) {
}

if fn, ok := metafns[uint64(event)]; ok {
d.FieldStruct("metaevent", func(d *decode.D) {
d.FieldStruct("meta_event", func(d *decode.D) {
d.FieldStruct("time", delta)
d.FieldU8("status")
d.FieldU8("event", metaevents)
Expand Down
12 changes: 11 additions & 1 deletion format/midi/midi.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ func decodeMIDI(d *decode.D) any {
// ... decode tracks
d.FieldArray("tracks", func(d *decode.D) {
for d.BitsLeft() > 0 {
d.FieldStruct("track", decodeMTrk)
if bytes.Equal(d.PeekBytes(4), []byte("MTrk")) {
d.FieldStruct("track", decodeMTrk)
} else {
d.FieldStruct("other", decodeOther)
}
}
})

Expand Down Expand Up @@ -156,6 +160,12 @@ func peekEvent(d *decode.D) (uint64, uint8, uint8) {
}
}

func decodeOther(d *decode.D) {
d.FieldUTF8("tag", 4)
length := d.FieldS32("length")
d.FieldRawLen("data", length*8)
}

// Big endian varint
func vlq(d *decode.D) uint64 {
vlq := uint64(0)
Expand Down
3 changes: 2 additions & 1 deletion format/midi/midi.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ fq -d midi 'grep_by(.event=="note_on") | [.time.tick, .note_on.note] | join(" ")
1. [The Complete MIDI 1.0 Detailed Specification](https://www.midi.org/specifications/item/the-midi-1-0-specification)
2. [Standard MIDI Files](https://midi.org/standard-midi-files)
3. [Standard MIDI File (SMF) Format](http://midi.teragonaudio.com/tech/midifile.htm)
4. [MIDI Files Specification](http://www.somascape.org/midi/tech/mfile.html)
4. [MIDI Files Specification](http://www.somascape.org/midi/tech/mfile.html)
5. [github: test-midi-files](https://github.com/jazz-soft/test-midi-files)
2 changes: 1 addition & 1 deletion format/midi/midievents.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func decodeMIDIEvent(d *decode.D, status uint8, ctx *context) {
}

if fn, ok := midifns[uint64(status&0x00f0)]; ok {
d.FieldStruct("midievent", func(d *decode.D) {
d.FieldStruct("midi_event", func(d *decode.D) {
d.FieldStruct("time", delta)

b := d.PeekBytes(1)
Expand Down
14 changes: 7 additions & 7 deletions format/midi/sysex.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,24 @@ func decodeSysExEvent(d *decode.D, status uint8, ctx *context) {

case status == 0xf0:
if ctx.casio {
d.Errorf("SysExMessage F0 start byte without terminating F7")
d.Errorf("SysEx message F0 start byte without terminating F7")
}

d.FieldStruct("sysex", func(d *decode.D) {
d.FieldStruct("sysex_event", func(d *decode.D) {
d.FieldStruct("time", delta)
d.FieldU8("event", sysex)
decodeSysExMessage(d, ctx)
})

case status == 0xf7 && ctx.casio:
d.FieldStruct("sysex", func(d *decode.D) {
d.FieldStruct("sysex_event", func(d *decode.D) {
d.FieldStruct("time", delta)
d.FieldU8("event", sysex_extensions)
decodeSysExContinuation(d, ctx)
})

case status == 0xf7:
d.FieldStruct("sysex", func(d *decode.D) {
d.FieldStruct("sysex_event", func(d *decode.D) {
d.FieldStruct("time", delta)
d.FieldU8("event", sysex)
decodeSysExEscape(d, ctx)
Expand All @@ -61,7 +61,7 @@ func decodeSysExMessage(d *decode.D, ctx *context) {
d.Fatalf("invalid field length")
}

d.FieldStruct("sysex_message", func(d *decode.D) {
d.FieldStruct("message", func(d *decode.D) {
d.FieldU8("manufacturer", manufacturers)

if length < 1 {
Expand Down Expand Up @@ -95,7 +95,7 @@ func decodeSysExContinuation(d *decode.D, ctx *context) {
d.Fatalf("invalid field length")
}

d.FieldStruct("sysex_continuation", func(d *decode.D) {
d.FieldStruct("continuation", func(d *decode.D) {
if length > 0 {
bytes := d.PeekBytes(int(length))
N := len(bytes)
Expand Down Expand Up @@ -124,7 +124,7 @@ func decodeSysExEscape(d *decode.D, ctx *context) {
d.Fatalf("invalid field length")
}

d.FieldStruct("sysex_escape", func(d *decode.D) {
d.FieldStruct("escape", func(d *decode.D) {
d.FieldRawLen("data", int64(8*length))
})

Expand Down
4 changes: 1 addition & 3 deletions format/midi/testdata/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ run: build
go run . -d midi dv format/midi/testdata/reference.mid

debug: build
go run . -d midi dv format/midi/testdata/midi/invalid-MThd-length.mid
go run . -d midi dv format/midi/testdata/midi/invalid-MTrk-length.mid
go run . -d midi dv format/midi/testdata/events/smpte-offset.mid
go run . -d midi dv format/midi/workdir/test-all-gm-percussion.mid

test: build
go test ./format -run TestFormats/midi
Expand Down
10 changes: 7 additions & 3 deletions format/midi/testdata/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,19 @@ Test file with all supported MIDI key signatures.

Test file with all supported MIDI notes.

8. _invalid-MThd-length.mid_
8. _unknown-chunks.mid_

Test file with 'alien' chunks interleaved with the _MTrk_ track chunks.

9. _invalid-MThd-length.mid_

Test file with invalid _MThd_ chunk length.

9. _invalid-MTrk-length.mid_
10. _invalid-MTrk-length.mid_

Test file with invalid _MTrk_ chunk length.

10. _twinkle.mid_
11. _twinkle.mid_

Sample valid MIDI file for the example queries in the help.

Expand Down
4 changes: 2 additions & 2 deletions format/midi/testdata/format-0.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ $ fq -d midi dv midi/format-0.mid
0x10|72 6b |rk |
0x10| 00 00 00 10 | .... | length: 16 0x12-0x16 (4)
| | | events[0:2]: 0x16-0x26 (16)
| | | [0]{}: metaevent 0x16-0x22 (12)
| | | [0]{}: meta_event 0x16-0x22 (12)
| | | time{}: 0x16-0x17 (1)
0x10| 00 | . | delta: 0 0x16-0x17 (1)
| | | tick: 0
0x10| ff | . | status: 255 0x17-0x18 (1)
0x10| 03 | . | event: "track_name" (3) 0x18-0x19 (1)
0x10| 08 46 6f 72 6d 61 74| .Format| track_name: "Format 0" 0x19-0x22 (9)
0x20|20 30 | 0 |
| | | [1]{}: metaevent 0x22-0x26 (4)
| | | [1]{}: meta_event 0x22-0x26 (4)
| | | time{}: 0x22-0x23 (1)
0x20| 00 | . | delta: 0 0x22-0x23 (1)
| | | tick: 0
Expand Down
8 changes: 4 additions & 4 deletions format/midi/testdata/format-1.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ $ fq -d midi dv midi/format-1.mid
0x10|72 6b |rk |
0x10| 00 00 00 10 | .... | length: 16 0x12-0x16 (4)
| | | events[0:2]: 0x16-0x26 (16)
| | | [0]{}: metaevent 0x16-0x22 (12)
| | | [0]{}: meta_event 0x16-0x22 (12)
| | | time{}: 0x16-0x17 (1)
0x10| 00 | . | delta: 0 0x16-0x17 (1)
| | | tick: 0
0x10| ff | . | status: 255 0x17-0x18 (1)
0x10| 03 | . | event: "track_name" (3) 0x18-0x19 (1)
0x10| 08 46 6f 72 6d 61 74| .Format| track_name: "Format 1" 0x19-0x22 (9)
0x20|20 31 | 1 |
| | | [1]{}: metaevent 0x22-0x26 (4)
| | | [1]{}: meta_event 0x22-0x26 (4)
| | | time{}: 0x22-0x23 (1)
0x20| 00 | . | delta: 0 0x22-0x23 (1)
| | | tick: 0
Expand All @@ -31,15 +31,15 @@ $ fq -d midi dv midi/format-1.mid
0x20| 4d 54 72 6b | MTrk | tag: "MTrk" 0x26-0x2a (4)
0x20| 00 00 00 17 | .... | length: 23 0x2a-0x2e (4)
| | | events[0:2]: 0x2e-0x45 (23)
| | | [0]{}: metaevent 0x2e-0x41 (19)
| | | [0]{}: meta_event 0x2e-0x41 (19)
| | | time{}: 0x2e-0x2f (1)
0x20| 00 | . | delta: 0 0x2e-0x2f (1)
| | | tick: 0
0x20| ff| .| status: 255 0x2f-0x30 (1)
0x30|03 |. | event: "track_name" (3) 0x30-0x31 (1)
0x30| 0f 41 63 6f 75 73 74 69 63 20 47 75 69 74 61| .Acoustic Guita| track_name: "Acoustic Guitar" 0x31-0x41 (16)
0x40|72 |r |
| | | [1]{}: metaevent 0x41-0x45 (4)
| | | [1]{}: meta_event 0x41-0x45 (4)
| | | time{}: 0x41-0x42 (1)
0x40| 00 | . | delta: 0 0x41-0x42 (1)
| | | tick: 0
Expand Down
8 changes: 4 additions & 4 deletions format/midi/testdata/format-2.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ $ fq -d midi dv midi/format-2.mid
0x10|72 6b |rk |
0x10| 00 00 00 12 | .... | length: 18 0x12-0x16 (4)
| | | events[0:2]: 0x16-0x28 (18)
| | | [0]{}: metaevent 0x16-0x24 (14)
| | | [0]{}: meta_event 0x16-0x24 (14)
| | | time{}: 0x16-0x17 (1)
0x10| 00 | . | delta: 0 0x16-0x17 (1)
| | | tick: 0
0x10| ff | . | status: 255 0x17-0x18 (1)
0x10| 03 | . | event: "track_name" (3) 0x18-0x19 (1)
0x10| 0a 4c 65 66 74 20 54| .Left T| track_name: "Left Track" 0x19-0x24 (11)
0x20|72 61 63 6b |rack |
| | | [1]{}: metaevent 0x24-0x28 (4)
| | | [1]{}: meta_event 0x24-0x28 (4)
| | | time{}: 0x24-0x25 (1)
0x20| 00 | . | delta: 0 0x24-0x25 (1)
| | | tick: 0
Expand All @@ -31,14 +31,14 @@ $ fq -d midi dv midi/format-2.mid
0x20| 4d 54 72 6b | MTrk | tag: "MTrk" 0x28-0x2c (4)
0x20| 00 00 00 13| ....| length: 19 0x2c-0x30 (4)
| | | events[0:2]: 0x30-0x43 (19)
| | | [0]{}: metaevent 0x30-0x3f (15)
| | | [0]{}: meta_event 0x30-0x3f (15)
| | | time{}: 0x30-0x31 (1)
0x30|00 |. | delta: 0 0x30-0x31 (1)
| | | tick: 0
0x30| ff | . | status: 255 0x31-0x32 (1)
0x30| 03 | . | event: "track_name" (3) 0x32-0x33 (1)
0x30| 0b 52 69 67 68 74 20 54 72 61 63 6b | .Right Track | track_name: "Right Track" 0x33-0x3f (12)
| | | [1]{}: metaevent 0x3f-0x43 (4)
| | | [1]{}: meta_event 0x3f-0x43 (4)
| | | time{}: 0x3f-0x40 (1)
0x30| 00| .| delta: 0 0x3f-0x40 (1)
| | | tick: 0
Expand Down
1 change: 1 addition & 0 deletions format/midi/testdata/help_midi.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ References
* Standard MIDI Files (https://midi.org/standard-midi-files)
* Standard MIDI File (SMF) Format (http://midi.teragonaudio.com/tech/midifile.htm)
* MIDI Files Specification (http://www.somascape.org/midi/tech/mfile.html)
* github: test-midi-files (https://github.com/jazz-soft/test-midi-files)
Loading

0 comments on commit 87c80f5

Please sign in to comment.