Skip to content

Commit 17119ff

Browse files
Add SequencerSpecificEvent , and empty!(::MIDITrack) (#173)
* add SequencerSpecificEvent support * add test * update tests * implement `empty!(::MIDITrack)` * add isempty for MIDITrack * fix typo
1 parent 3868e9e commit 17119ff

6 files changed

+50
-8
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7+
# v2.7.0
8+
* New meta event type `SequencerSpecificEvent`.
9+
* Implement `Base.empty!(::MIDITrack)` and `Base.isempty(t::MIDITrack)`.
710
# v2.6.0
811
* New functions `metric_time`.
912
* New functions `duration_metric_time`.

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "MIDI"
22
uuid = "f57c4921-e30c-5f49-b073-3f2f2ada663e"
33
repo = "https://github.com/JuliaMusic/MIDI.jl.git"
4-
version = "2.6.0"
4+
version = "2.7.0"
55

66
[deps]
77
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"

src/events.jl

+24-7
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ const MIDI_EVENTS_DEFS = Dict(
6060
decode = :(Int.(data)),
6161
encode = :(UInt8.([event.semitones, event.scale]))
6262
),
63-
63+
0x7f => (
64+
type = :SequencerSpecificEvent,
65+
fields = ["ssdata::Vector{UInt8}"],
66+
decode = :(data),
67+
encode = :(event.ssdata)
68+
),
6469
# MidiEvents
6570
0x80 => (
6671
type = :NoteOffEvent,
@@ -124,12 +129,14 @@ function define_type(type, fields, decode, encode_, supertype, typebyte)
124129
$(fields...)
125130
end
126131

127-
""" $($type)(dT::Int, typebyte::UInt8, data::Vector{UInt8})
128-
Returns a `$($type)` event from it's byte representation.
129-
The parameter `typebyte::UInt8` is its's $(($type <: MetaEvent) ? "metatype" : "status") byte.
130-
"""
131-
function $type(dT::Int, typebyte::UInt8, data::Vector{UInt8})
132-
$type(dT, typebyte, $decode...)
132+
if !($type.types[end] <: AbstractArray)
133+
""" $($type)(dT::Int, typebyte::UInt8, data::Vector{UInt8})
134+
Returns a `$($type)` event from it's byte representation.
135+
The parameter `typebyte::UInt8` is its's $(($type <: MetaEvent) ? "metatype" : "status") byte.
136+
"""
137+
function $type(dT::Int, typebyte::UInt8, data::Vector{UInt8})
138+
$type(dT, typebyte, $decode...)
139+
end
133140
end
134141

135142
if $type <: MetaEvent
@@ -407,3 +414,13 @@ The `PitchBendEvent` informs a MIDI device to modify the pitch in a specific cha
407414
* `pitch::Int` : Value of the pitch bend.
408415
"""
409416
PitchBendEvent
417+
418+
""" SequencerSpecificEvent <: MetaEvent
419+
The `SequencerSpecificEvent` is used to store vendor-proprietary data in a MIDI file.
420+
421+
## Fields:
422+
* `dT::Int` : Delta time in ticks.
423+
* `metatype::UInt8` : Meta type byte of the event.
424+
* `ssdata::Vector{UInt8}` : Vendor-proprietary data.
425+
"""
426+
SequencerSpecificEvent

src/miditrack.jl

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
Track chunks begin with four bytes spelling out "MTrk", followed by the length
88
(in bytes) of the track (see [`readvariablelength`](@ref)), followed by a sequence
99
of events.
10+
11+
`MIDITrack` implements the `isempty` and `empty!` functions.
1012
"""
1113
mutable struct MIDITrack
1214
events::Vector{TrackEvent}
@@ -21,6 +23,8 @@ function Base.show(io::IO, t::MIDITrack)
2123
print(io, "$(L)-event MIDITrack: $M MIDI, $T Meta, $X Sysex")
2224
end
2325

26+
Base.empty!(t::MIDITrack) = empty!(t.events)
27+
Base.isempty(t::MIDITrack)::Bool = isempty(t.events)
2428

2529
function readtrack(f::IO)
2630

test/SequencerSpecific.mid

36 Bytes
Binary file not shown.

test/metaevent.jl

+18
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,22 @@
3131
@test_throws errtype MIDI.readsysexevent(Int(input[1]), IOBuffer(input[2:length(input)]))
3232
end
3333
end
34+
35+
@testset "SequencerSpecificEvent" begin
36+
midi = load("SequencerSpecific.mid")
37+
sse = midi.tracks[1].events[1]
38+
@test sse isa MIDI.SequencerSpecificEvent
39+
sse.ssdata == [0x11, 0x21, 0x53, 0x1F]
40+
41+
sse = MIDI.SequencerSpecificEvent(0, 0x7f, [0x11, 0x21, 0x53, 0x1F])
42+
@test sse.ssdata == [0x11, 0x21, 0x53, 0x1F]
43+
end
44+
45+
@testset "check empty" begin
46+
midi = load(testmidi())
47+
track = midi.tracks[1]
48+
@test !isempty(track)
49+
empty!(track)
50+
@test isempty(track)
51+
end
3452
end

0 commit comments

Comments
 (0)