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