mirror of
https://github.com/wader/fq.git
synced 2024-11-26 10:33:53 +03:00
midi: Decoded MIDIChannelPrefix, MIDIPort and SequencerSpecific metaevents
This commit is contained in:
parent
2a16748391
commit
109719f25d
@ -1,6 +1,6 @@
|
||||
# TODO
|
||||
|
||||
- [ ] update fork from master
|
||||
- [x] update forked master branch
|
||||
- [ ] discard unknown chunks
|
||||
- [ ] tests
|
||||
- [ ] format 0
|
||||
@ -17,25 +17,26 @@
|
||||
- [ ] format 2
|
||||
|
||||
- meta events
|
||||
- [ ] sequence number
|
||||
- [ ] text
|
||||
- [ ] copyright
|
||||
- [x] sequence number
|
||||
- [x] text
|
||||
- [x] copyright
|
||||
- [x] track name
|
||||
- [ ] instrument name
|
||||
- [ ] lyric
|
||||
- [ ] marker
|
||||
- [ ] cue point
|
||||
- [ ] program name
|
||||
- [ ] device name
|
||||
- [ ] MIDI channel prefix
|
||||
- [ ] MIDI port
|
||||
- [ ] end of track
|
||||
- [x] instrument name
|
||||
- [x] lyric
|
||||
- [x] marker
|
||||
- [x] cue point
|
||||
- [x] program name
|
||||
- [x] device name
|
||||
- [x] MIDI channel prefix
|
||||
- [x] MIDI port
|
||||
- [x] end of track
|
||||
- [x] tempo
|
||||
- [ ] SMPTE offset
|
||||
- [x] SMPTE offset
|
||||
- [x] key signature
|
||||
- [ ] check key mappings
|
||||
- [x] time signature
|
||||
- [ ] sequencer specific event
|
||||
- [ ] map manufacturer
|
||||
|
||||
- midi events
|
||||
- [x] note off
|
||||
@ -44,7 +45,7 @@
|
||||
- [ ] map note name
|
||||
- [ ] polyphonic pressure
|
||||
- [x] controller
|
||||
- [ ] program change
|
||||
- [x] program change
|
||||
- [ ] channel pressure
|
||||
- [ ] pitch bend
|
||||
|
||||
|
@ -140,6 +140,14 @@ func decodeMetaEvent(d *decode.D, event uint8) {
|
||||
d.FieldStruct("DeviceName", decodeDeviceName)
|
||||
return
|
||||
|
||||
case TypeMIDIChannelPrefix:
|
||||
d.FieldStruct("TypeMIDIChannelPrefix", decodeMIDIChannelPrefix)
|
||||
return
|
||||
|
||||
case TypeMIDIPort:
|
||||
d.FieldStruct("TypeMIDIPort", decodeMIDIPort)
|
||||
return
|
||||
|
||||
case TypeTempo:
|
||||
d.FieldStruct("Tempo", decodeTempo)
|
||||
return
|
||||
@ -160,9 +168,9 @@ func decodeMetaEvent(d *decode.D, event uint8) {
|
||||
d.FieldStruct("EndOfTrack", decodeEndOfTrack)
|
||||
return
|
||||
|
||||
// TypeMIDIChannelPrefix MetaEventType = 0x20
|
||||
// TypeMIDIPort MetaEventType = 0x21
|
||||
// TypeSequencerSpecificEvent MetaEventType = 0x7f
|
||||
case TypeSequencerSpecificEvent:
|
||||
d.FieldStruct("SequencerSpecificEvent", decodeSequencerSpecificEvent)
|
||||
return
|
||||
}
|
||||
|
||||
// ... unknown event - flush remaining data
|
||||
@ -275,6 +283,40 @@ func decodeDeviceName(d *decode.D) {
|
||||
})
|
||||
}
|
||||
|
||||
func decodeMIDIChannelPrefix(d *decode.D) {
|
||||
d.FieldUintFn("delta", vlq)
|
||||
d.FieldU8("status")
|
||||
d.FieldU8("event")
|
||||
d.FieldUintFn("channel", func(d *decode.D) uint64 {
|
||||
channel := uint64(0)
|
||||
data := vlf(d)
|
||||
|
||||
for _, b := range data {
|
||||
channel <<= 8
|
||||
channel |= uint64(b & 0x00ff)
|
||||
}
|
||||
|
||||
return channel
|
||||
})
|
||||
}
|
||||
|
||||
func decodeMIDIPort(d *decode.D) {
|
||||
d.FieldUintFn("delta", vlq)
|
||||
d.FieldU8("status")
|
||||
d.FieldU8("event")
|
||||
d.FieldUintFn("port", func(d *decode.D) uint64 {
|
||||
channel := uint64(0)
|
||||
data := vlf(d)
|
||||
|
||||
for _, b := range data {
|
||||
channel <<= 8
|
||||
channel |= uint64(b & 0x00ff)
|
||||
}
|
||||
|
||||
return channel
|
||||
})
|
||||
}
|
||||
|
||||
func decodeTempo(d *decode.D) {
|
||||
d.FieldUintFn("delta", vlq)
|
||||
d.FieldU8("status")
|
||||
@ -377,10 +419,10 @@ func decodeKeySignature(d *decode.D) {
|
||||
d.FieldU8("status")
|
||||
d.FieldU8("event")
|
||||
|
||||
bytes := vlf(d)
|
||||
if len(bytes) > 1 {
|
||||
key := (uint64(bytes[0]) << 8) & 0xff00
|
||||
key |= (uint64(bytes[1]) << 0) & 0x00ff
|
||||
data := vlf(d)
|
||||
if len(data) > 1 {
|
||||
key := (uint64(data[0]) << 8) & 0xff00
|
||||
key |= (uint64(data[1]) << 0) & 0x00ff
|
||||
|
||||
d.FieldValueUint("key", key, keys)
|
||||
}
|
||||
@ -393,3 +435,24 @@ func decodeEndOfTrack(d *decode.D) {
|
||||
|
||||
vlf(d)
|
||||
}
|
||||
|
||||
func decodeSequencerSpecificEvent(d *decode.D) {
|
||||
d.FieldUintFn("delta", vlq)
|
||||
d.FieldU8("status")
|
||||
d.FieldU8("event")
|
||||
|
||||
data := vlf(d)
|
||||
if len(data) > 2 && data[0] == 0x00 {
|
||||
d.FieldValueStr("manufacturer", fmt.Sprintf("%02X%02X%02X", data[0], data[1], data[2]))
|
||||
|
||||
if len(data) > 3 {
|
||||
d.FieldValueStr("data", fmt.Sprintf("%v", data[3:]))
|
||||
}
|
||||
|
||||
} else if len(data) > 0 {
|
||||
d.FieldValueStr("manufacturer", fmt.Sprintf("%02x", data[0]))
|
||||
if len(data) > 1 {
|
||||
d.FieldValueStr("data", fmt.Sprintf("%v", data[1:]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ package midi
|
||||
import (
|
||||
"bytes"
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/wader/fq/format"
|
||||
"github.com/wader/fq/pkg/decode"
|
||||
@ -101,8 +100,6 @@ func decodeMTrk(d *decode.D) {
|
||||
func decodeEvent(d *decode.D) {
|
||||
_, status, event := peekEvent(d)
|
||||
|
||||
fmt.Printf(">> status:%02x event:%02x\n", status, event)
|
||||
|
||||
// ... meta event?
|
||||
if status == 0xff {
|
||||
decodeMetaEvent(d, event)
|
||||
|
@ -116,6 +116,10 @@ func decodeMIDIEvent(d *decode.D, status uint8) {
|
||||
d.FieldStruct("NoteOn", decodeNoteOn)
|
||||
return
|
||||
|
||||
case TypePolyphonicPressure:
|
||||
d.FieldStruct("PolyphonicPressure", decodePolyphonicPressure)
|
||||
return
|
||||
|
||||
case TypeController:
|
||||
d.FieldStruct("Controller", decodeController)
|
||||
return
|
||||
@ -124,7 +128,6 @@ func decodeMIDIEvent(d *decode.D, status uint8) {
|
||||
d.FieldStruct("ProgramChange", decodeProgramChange)
|
||||
return
|
||||
|
||||
// TypePolyphonicPressure MidiEventType = 0xa0
|
||||
// TypeProgramChange MidiEventType = 0xc0
|
||||
// TypeChannelPressure MidiEventType = 0xd0
|
||||
// TypePitchBend MidiEventType = 0xe0
|
||||
@ -162,6 +165,17 @@ func decodeNoteOn(d *decode.D) {
|
||||
d.FieldU8("velocity")
|
||||
}
|
||||
|
||||
func decodePolyphonicPressure(d *decode.D) {
|
||||
d.FieldUintFn("delta", vlq)
|
||||
d.FieldUintFn("channel", func(d *decode.D) uint64 {
|
||||
b := d.BytesLen(1)
|
||||
|
||||
return uint64(b[0] & 0x0f)
|
||||
})
|
||||
|
||||
d.FieldU8("pressure")
|
||||
}
|
||||
|
||||
func decodeController(d *decode.D) {
|
||||
d.FieldUintFn("delta", vlq)
|
||||
d.FieldUintFn("channel", func(d *decode.D) uint64 {
|
||||
|
Loading…
Reference in New Issue
Block a user