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:
parent
e99d9f69ab
commit
4fac4c68a5
@ -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
|
||||
|
@ -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
0
format/midi/testdata/empty.mid
vendored
Normal file
BIN
format/midi/testdata/unknown-chunks.mid
vendored
Normal file
BIN
format/midi/testdata/unknown-chunks.mid
vendored
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user