Closed NeroBlackstone closed 1 month ago
Since the data of this event is variable length, to be honest, I don't know how to define this meta event
What do you mean? MIDI.jl already has the infrastructure to read variable length events, we already do it in the source code for some events. What stops you from using the same code for this new event?
It's a bit complicated, but I'll try to explain the problem clearly.
Since we don't have to decode the data in Sequencer Specific Event raw data (vendor-proprietary data), we just want to move the data intact to the ssdata
field of SequencerSpecificEvent
type.
So the fields of SequencerSpecificEvent
is:
Fields:
dT::Int
: Delta time in ticks.metatype::UInt8
: Meta type byte of the event.ssdata::Vector{UInt8}
: Vendor-proprietary raw data. (# here is the problem)
And if we define (store raw data so no encode and decode, just same):
0x7f => (
type = :SequencerSpecificEvent,
fields = ["ssdata::Vector{UInt8}"],
decode = :(data), # raw data here
encode = :(event.ssdata)
),
We wiil use these codes to generate the Types and Constrctors:
Okay, so when we construct SequencerSpecificEvent
(type(dT, metatype, data)
), we invoke these code to decode the Bytes first (but do nothing here except ...
spread, since we want raw data):
then the invoke:
Since it's variable length events so length(args)
never be same, and a MethodError
will throw, this is problem.
Yes Text is also variable length but it doesn't have this problem, because after decode it will turn to Vector{String}
, after spread it will become normal String.
What if we decode SequencerSpecificEvent
as above Text?:
0x7f => (
type = :SequencerSpecificEvent,
fields = ["ssdata::Vector{UInt8}"],
decode = :([data]), # decode to Vector{Vector{UInt8}}
encode = :(event.ssdata)
),
It's a infinity loop and cause StackOverflowError
, because it repeatly spread
and collect
once and once again.
I have a ugly but work solution:
0x7f => (
type = :SequencerSpecificEvent,
fields = ["ssdata::Vector{Vector{UInt8}}"],
decode = :([[data]]),
encode = :(event.ssdata)
),
And length(ssdata)
is 1, ssdata[1]
is raw MIDI event data
What do you think? I can make a PR to temporarily support SequencerSpecificEvent
until we can come up with a better solution. (At least opening MIDI files won't throw an exception)
Okay I have a better solution and I will post tomorrow.
Is your feature request related to a problem? Please describe. If MIDI file is recorded by a physical device, it will include Sequencer Specific Event.
Currently, MIDI.jl has not defined this event in
MIDI_EVENTS_DEFS
, so any MIDI file opening that contains a Sequencer Specific Event will throw an exception.Describe the solution you'd like Since the data of this event is variable length, to be honest, I don't know how to define this meta event.