1
1
mirror of https://github.com/wader/fq.git synced 2024-10-03 23:17:50 +03:00

midi: discarded unknown chunks

This commit is contained in:
twystd 2024-08-25 10:54:46 -07:00
parent e99d9f69ab
commit 4fac4c68a5
4 changed files with 53 additions and 12 deletions

View File

@ -3,7 +3,7 @@
- [x] update forked master branch
- (?) add to probe group
- [ ] discard unknown chunks
- [x] discard unknown chunks
- [x] assert available bytes
- [x] example queries
- [x] fix gaps

View File

@ -5,6 +5,7 @@ package midi
import (
"bytes"
"embed"
"encoding/binary"
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/decode"
@ -34,21 +35,47 @@ func init() {
func decodeMIDI(d *decode.D) any {
d.Endian = decode.BigEndian
decodeMIDIFile(d)
// ... skip to MThd chunk
for d.BitsLeft() > 0 {
if tag, len, err := peekChunk(d); err != nil {
d.Errorf("error reading MIDI file chunk (%v)", err)
} else if tag == "MThd" {
break
} else {
d.SeekRel(8 * int64(len+8))
}
}
// ... read MThd chunk
if d.BitsLeft() < 64 {
d.Errorf("missing MThd header chunk")
} else {
d.FieldStruct("header", decodeMThd)
if d.BitsLeft() < 64 {
d.Errorf("missing MTrk track chunk(s)")
} else {
// ... read MTrk chunks, discarding unexpected chunks
d.FieldArray("tracks", func(d *decode.D) {
for d.BitsLeft() > 0 {
for d.BitsLeft() > 0 {
if tag, len, err := peekChunk(d); err != nil {
d.Errorf("error reading MIDI file chunk (%v)", err)
} else if tag == "MTrk" {
d.FieldStruct("track", decodeMTrk)
break
} else {
d.SeekRel(8 * int64(len+8))
}
}
}
})
}
}
return nil
}
func decodeMIDIFile(d *decode.D) {
d.FieldStruct("header", decodeMThd)
d.FieldArray("tracks", func(d *decode.D) {
for d.BitsLeft() > 0 {
d.FieldStruct("track", decodeMTrk)
}
})
}
func decodeMThd(d *decode.D) {
d.AssertLeastBytesLeft(8)
@ -125,6 +152,20 @@ func decodeEvent(d *decode.D, ctx *context) {
}
}
func peekChunk(d *decode.D) (string, uint32, error) {
if d.BitsLeft() > 64 {
d.AssertLeastBytesLeft(8)
bytes := d.PeekBytes(8)
tag := string(bytes[0:4])
len := binary.BigEndian.Uint32(bytes[4:])
return tag, len, nil
}
return "", 0, nil
}
func peekEvent(d *decode.D) (uint64, uint8, uint8) {
delta := uint64(0)
N := 3

0
format/midi/testdata/empty.mid vendored Normal file
View File

BIN
format/midi/testdata/unknown-chunks.mid vendored Normal file

Binary file not shown.