midilib 2.0.5 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/ChangeLog +2 -1
- data/Credits +39 -2
- data/README.rdoc +5 -6
- data/Rakefile +36 -49
- data/TODO.rdoc +13 -2
- data/examples/from_scratch.rb +1 -1
- data/examples/measures_mbt.rb +11 -11
- data/examples/print_program_changes.rb +2 -2
- data/examples/reader2text.rb +47 -47
- data/examples/seq2text.rb +1 -1
- data/examples/split.rb +4 -3
- data/examples/strings.rb +4 -4
- data/examples/transpose.rb +19 -20
- data/install.rb +21 -13
- data/lib/midilib/consts.rb +237 -239
- data/lib/midilib/event.rb +128 -100
- data/lib/midilib/info.rb +3 -5
- data/lib/midilib/io/midifile.rb +155 -182
- data/lib/midilib/io/seqreader.rb +80 -85
- data/lib/midilib/io/seqwriter.rb +93 -88
- data/lib/midilib/measure.rb +78 -80
- data/lib/midilib/mergesort.rb +39 -0
- data/lib/midilib/sequence.rb +40 -32
- data/lib/midilib/track.rb +16 -57
- data/lib/midilib/utils.rb +4 -7
- data/lib/midilib.rb +5 -5
- data/test/event_equality.rb +28 -30
- data/test/test_event.rb +9 -11
- data/test/test_io.rb +83 -3
- data/test/test_mergesort.rb +37 -0
- data/test/test_midifile.rb +6 -19
- data/test/test_sequence.rb +5 -4
- data/test/test_track.rb +9 -38
- data/test/test_varlen.rb +1 -3
- metadata +8 -95
- data/html/IO.html +0 -155
- data/html/MIDI/ActiveSense.html +0 -206
- data/html/MIDI/ChannelEvent.html +0 -231
- data/html/MIDI/ChannelPressure.html +0 -265
- data/html/MIDI/Clock.html +0 -206
- data/html/MIDI/Continue.html +0 -206
- data/html/MIDI/Controller.html +0 -280
- data/html/MIDI/Event.html +0 -489
- data/html/MIDI/IO/MIDIFile.html +0 -2024
- data/html/MIDI/IO/SeqReader.html +0 -904
- data/html/MIDI/IO/SeqWriter.html +0 -572
- data/html/MIDI/IO.html +0 -95
- data/html/MIDI/KeySig.html +0 -353
- data/html/MIDI/MIDI/MIDI/Array.html +0 -255
- data/html/MIDI/MIDI/MIDI.html +0 -95
- data/html/MIDI/MIDI.html +0 -95
- data/html/MIDI/Marker.html +0 -158
- data/html/MIDI/Measure.html +0 -328
- data/html/MIDI/Measures.html +0 -285
- data/html/MIDI/MetaEvent.html +0 -461
- data/html/MIDI/NoteEvent.html +0 -331
- data/html/MIDI/NoteOff.html +0 -228
- data/html/MIDI/NoteOn.html +0 -228
- data/html/MIDI/PitchBend.html +0 -266
- data/html/MIDI/PolyPressure.html +0 -277
- data/html/MIDI/ProgramChange.html +0 -265
- data/html/MIDI/Realtime.html +0 -242
- data/html/MIDI/Sequence.html +0 -896
- data/html/MIDI/SongPointer.html +0 -266
- data/html/MIDI/SongSelect.html +0 -265
- data/html/MIDI/Start.html +0 -206
- data/html/MIDI/Stop.html +0 -206
- data/html/MIDI/SystemCommon.html +0 -158
- data/html/MIDI/SystemExclusive.html +0 -268
- data/html/MIDI/SystemReset.html +0 -206
- data/html/MIDI/Tempo.html +0 -396
- data/html/MIDI/TimeSig.html +0 -388
- data/html/MIDI/Track.html +0 -695
- data/html/MIDI/TuneRequest.html +0 -242
- data/html/MIDI/Utils.html +0 -220
- data/html/MIDI.html +0 -547
- data/html/README_rdoc.html +0 -731
- data/html/TODO_rdoc.html +0 -125
- data/html/created.rid +0 -14
- data/html/css/fonts.css +0 -167
- data/html/css/rdoc.css +0 -590
- data/html/fonts/Lato-Light.ttf +0 -0
- data/html/fonts/Lato-LightItalic.ttf +0 -0
- data/html/fonts/Lato-Regular.ttf +0 -0
- data/html/fonts/Lato-RegularItalic.ttf +0 -0
- data/html/fonts/SourceCodePro-Bold.ttf +0 -0
- data/html/fonts/SourceCodePro-Regular.ttf +0 -0
- data/html/images/add.png +0 -0
- data/html/images/arrow_up.png +0 -0
- data/html/images/brick.png +0 -0
- data/html/images/brick_link.png +0 -0
- data/html/images/bug.png +0 -0
- data/html/images/bullet_black.png +0 -0
- data/html/images/bullet_toggle_minus.png +0 -0
- data/html/images/bullet_toggle_plus.png +0 -0
- data/html/images/date.png +0 -0
- data/html/images/delete.png +0 -0
- data/html/images/find.png +0 -0
- data/html/images/loadingAnimation.gif +0 -0
- data/html/images/macFFBgHack.png +0 -0
- data/html/images/package.png +0 -0
- data/html/images/page_green.png +0 -0
- data/html/images/page_white_text.png +0 -0
- data/html/images/page_white_width.png +0 -0
- data/html/images/plugin.png +0 -0
- data/html/images/ruby.png +0 -0
- data/html/images/tag_blue.png +0 -0
- data/html/images/tag_green.png +0 -0
- data/html/images/transparent.png +0 -0
- data/html/images/wrench.png +0 -0
- data/html/images/wrench_orange.png +0 -0
- data/html/images/zoom.png +0 -0
- data/html/index.html +0 -768
- data/html/js/darkfish.js +0 -161
- data/html/js/jquery.js +0 -4
- data/html/js/navigation.js +0 -142
- data/html/js/navigation.js.gz +0 -0
- data/html/js/search.js +0 -109
- data/html/js/search_index.js +0 -1
- data/html/js/search_index.js.gz +0 -0
- data/html/js/searcher.js +0 -228
- data/html/js/searcher.js.gz +0 -0
- data/html/table_of_contents.html +0 -1265
data/lib/midilib/event.rb
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
require_relative 'consts'
|
|
2
|
+
require_relative 'utils'
|
|
3
3
|
|
|
4
4
|
module MIDI
|
|
5
|
-
|
|
6
5
|
# The abstract superclass of all MIDI events.
|
|
7
6
|
class Event
|
|
8
|
-
|
|
9
7
|
# Modifying delta_time does not affect time_from_start. You need to call
|
|
10
8
|
# the event's track's +recalc_time+ method.
|
|
11
9
|
attr_accessor :delta_time
|
|
@@ -31,7 +29,10 @@ module MIDI
|
|
|
31
29
|
def initialize(status = 0, delta_time = 0)
|
|
32
30
|
@status = status
|
|
33
31
|
@delta_time = delta_time
|
|
34
|
-
@time_from_start = 0
|
|
32
|
+
@time_from_start = 0 # maintained by tracks
|
|
33
|
+
@print_note_names = false
|
|
34
|
+
@print_decimal_numbers = false
|
|
35
|
+
@print_channel_numbers_from_one = false
|
|
35
36
|
end
|
|
36
37
|
protected :initialize
|
|
37
38
|
|
|
@@ -39,7 +40,7 @@ module MIDI
|
|
|
39
40
|
# MIDI stream. In MIDI::EVENT this raises a "subclass responsibility"
|
|
40
41
|
# exception.
|
|
41
42
|
def data_as_bytes
|
|
42
|
-
raise
|
|
43
|
+
raise 'subclass responsibility'
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
# Quantize this event's time_from_start by moving it to the nearest
|
|
@@ -49,29 +50,27 @@ module MIDI
|
|
|
49
50
|
def quantize_to(boundary)
|
|
50
51
|
diff = @time_from_start % boundary
|
|
51
52
|
@time_from_start -= diff
|
|
52
|
-
if diff >= boundary / 2
|
|
53
|
-
@time_from_start += boundary
|
|
54
|
-
end
|
|
53
|
+
@time_from_start += boundary if diff >= boundary / 2
|
|
55
54
|
end
|
|
56
55
|
|
|
57
56
|
# For sorting. Uses @time_from_start, which is maintained by this event's
|
|
58
57
|
# track. I'm not sure this is necessary, since each track has to
|
|
59
58
|
# maintain its events' time-from-start values anyway.
|
|
60
|
-
def <=>(
|
|
61
|
-
|
|
59
|
+
def <=>(other)
|
|
60
|
+
@time_from_start <=> other.time_from_start
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
# Returns +val+ as a decimal or hex string, depending upon the value of
|
|
65
64
|
# @print_decimal_numbers.
|
|
66
65
|
def number_to_s(val)
|
|
67
|
-
|
|
66
|
+
@print_decimal_numbers ? val.to_s : ('%02x' % val)
|
|
68
67
|
end
|
|
69
68
|
|
|
70
69
|
# Returns +val+ as a decimal or hex string, depending upon the value of
|
|
71
70
|
# @print_decimal_numbers.
|
|
72
71
|
def channel_to_s(val)
|
|
73
72
|
val += 1 if @print_channel_numbers_from_one
|
|
74
|
-
|
|
73
|
+
number_to_s(val)
|
|
75
74
|
end
|
|
76
75
|
|
|
77
76
|
def to_s
|
|
@@ -92,15 +91,15 @@ module MIDI
|
|
|
92
91
|
protected :initialize
|
|
93
92
|
|
|
94
93
|
def to_s
|
|
95
|
-
|
|
94
|
+
super << "ch #{channel_to_s(@channel)} "
|
|
96
95
|
end
|
|
97
|
-
|
|
98
96
|
end
|
|
99
97
|
|
|
100
98
|
# The abstract superclass of all note on, and note off, and polyphonic
|
|
101
99
|
# pressure events.
|
|
102
100
|
class NoteEvent < ChannelEvent
|
|
103
101
|
attr_accessor :note, :velocity
|
|
102
|
+
|
|
104
103
|
def initialize(status, channel, note, velocity, delta_time)
|
|
105
104
|
super(status, channel, delta_time)
|
|
106
105
|
@note = note
|
|
@@ -108,10 +107,10 @@ module MIDI
|
|
|
108
107
|
end
|
|
109
108
|
protected :initialize
|
|
110
109
|
|
|
111
|
-
PITCHES = %w
|
|
110
|
+
PITCHES = %w[C C# D D# E F F# G G# A A# B]
|
|
112
111
|
|
|
113
112
|
# Returns note name as a pitch/octave string like "C4" or "F#6".
|
|
114
|
-
def pch_oct(val
|
|
113
|
+
def pch_oct(val = @note)
|
|
115
114
|
pch = val % 12
|
|
116
115
|
oct = (val / 12) - 1
|
|
117
116
|
"#{PITCHES[pch]}#{oct}"
|
|
@@ -120,7 +119,7 @@ module MIDI
|
|
|
120
119
|
# If @print_note_names is true, returns pch_oct(val) else returns value
|
|
121
120
|
# as a number using number_to_s.
|
|
122
121
|
def note_to_s
|
|
123
|
-
|
|
122
|
+
@print_note_names ? pch_oct(@note) : number_to_s(@note)
|
|
124
123
|
end
|
|
125
124
|
|
|
126
125
|
def data_as_bytes
|
|
@@ -133,12 +132,13 @@ module MIDI
|
|
|
133
132
|
|
|
134
133
|
class NoteOn < NoteEvent
|
|
135
134
|
attr_accessor :off
|
|
135
|
+
|
|
136
136
|
def initialize(channel = 0, note = 64, velocity = 64, delta_time = 0)
|
|
137
137
|
super(NOTE_ON, channel, note, velocity, delta_time)
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
def to_s
|
|
141
|
-
|
|
141
|
+
super <<
|
|
142
142
|
"on #{note_to_s} #{number_to_s(@velocity)}"
|
|
143
143
|
end
|
|
144
144
|
end
|
|
@@ -148,12 +148,13 @@ module MIDI
|
|
|
148
148
|
|
|
149
149
|
class NoteOff < NoteEvent
|
|
150
150
|
attr_accessor :on
|
|
151
|
+
|
|
151
152
|
def initialize(channel = 0, note = 64, velocity = 64, delta_time = 0)
|
|
152
153
|
super(NOTE_OFF, channel, note, velocity, delta_time)
|
|
153
154
|
end
|
|
154
155
|
|
|
155
156
|
def to_s
|
|
156
|
-
|
|
157
|
+
super <<
|
|
157
158
|
"off #{note_to_s} #{number_to_s(@velocity)}"
|
|
158
159
|
end
|
|
159
160
|
end
|
|
@@ -167,13 +168,15 @@ module MIDI
|
|
|
167
168
|
end
|
|
168
169
|
|
|
169
170
|
def pressure
|
|
170
|
-
|
|
171
|
+
@velocity
|
|
171
172
|
end
|
|
173
|
+
|
|
172
174
|
def pressure=(val)
|
|
173
175
|
@velocity = val
|
|
174
176
|
end
|
|
177
|
+
|
|
175
178
|
def to_s
|
|
176
|
-
|
|
179
|
+
super <<
|
|
177
180
|
"poly press #{channel_to_s(@channel)} #{note_to_s} #{number_to_s(@velocity)}"
|
|
178
181
|
end
|
|
179
182
|
end
|
|
@@ -195,7 +198,7 @@ module MIDI
|
|
|
195
198
|
end
|
|
196
199
|
|
|
197
200
|
def to_s
|
|
198
|
-
|
|
201
|
+
super << "cntl #{number_to_s(@controller)} #{number_to_s(@value)}"
|
|
199
202
|
end
|
|
200
203
|
end
|
|
201
204
|
|
|
@@ -214,7 +217,7 @@ module MIDI
|
|
|
214
217
|
end
|
|
215
218
|
|
|
216
219
|
def to_s
|
|
217
|
-
|
|
220
|
+
super << "prog #{number_to_s(@program)}"
|
|
218
221
|
end
|
|
219
222
|
end
|
|
220
223
|
|
|
@@ -233,7 +236,7 @@ module MIDI
|
|
|
233
236
|
end
|
|
234
237
|
|
|
235
238
|
def to_s
|
|
236
|
-
|
|
239
|
+
super << "chan press #{number_to_s(@pressure)}"
|
|
237
240
|
end
|
|
238
241
|
end
|
|
239
242
|
|
|
@@ -253,7 +256,7 @@ module MIDI
|
|
|
253
256
|
end
|
|
254
257
|
|
|
255
258
|
def to_s
|
|
256
|
-
|
|
259
|
+
super << "pb #{number_to_s(@value)}"
|
|
257
260
|
end
|
|
258
261
|
end
|
|
259
262
|
|
|
@@ -281,7 +284,7 @@ module MIDI
|
|
|
281
284
|
end
|
|
282
285
|
|
|
283
286
|
def to_s
|
|
284
|
-
|
|
287
|
+
super << 'sys ex'
|
|
285
288
|
end
|
|
286
289
|
end
|
|
287
290
|
|
|
@@ -301,7 +304,7 @@ module MIDI
|
|
|
301
304
|
end
|
|
302
305
|
|
|
303
306
|
def to_s
|
|
304
|
-
|
|
307
|
+
super << "song ptr #{number_to_s(@pointer)}"
|
|
305
308
|
end
|
|
306
309
|
end
|
|
307
310
|
|
|
@@ -320,7 +323,7 @@ module MIDI
|
|
|
320
323
|
end
|
|
321
324
|
|
|
322
325
|
def to_s
|
|
323
|
-
|
|
326
|
+
super << "song sel #{number_to_s(@song)}"
|
|
324
327
|
end
|
|
325
328
|
end
|
|
326
329
|
|
|
@@ -335,7 +338,7 @@ module MIDI
|
|
|
335
338
|
end
|
|
336
339
|
|
|
337
340
|
def to_s
|
|
338
|
-
|
|
341
|
+
super << 'tune req'
|
|
339
342
|
end
|
|
340
343
|
end
|
|
341
344
|
|
|
@@ -350,7 +353,7 @@ module MIDI
|
|
|
350
353
|
end
|
|
351
354
|
|
|
352
355
|
def to_s
|
|
353
|
-
|
|
356
|
+
super << "realtime #{number_to_s(@status)}"
|
|
354
357
|
end
|
|
355
358
|
end
|
|
356
359
|
|
|
@@ -360,7 +363,7 @@ module MIDI
|
|
|
360
363
|
end
|
|
361
364
|
|
|
362
365
|
def to_s
|
|
363
|
-
|
|
366
|
+
super << 'clock'
|
|
364
367
|
end
|
|
365
368
|
end
|
|
366
369
|
|
|
@@ -368,8 +371,9 @@ module MIDI
|
|
|
368
371
|
def initialize(delta_time = 0)
|
|
369
372
|
super(START, delta_time)
|
|
370
373
|
end
|
|
374
|
+
|
|
371
375
|
def to_s
|
|
372
|
-
|
|
376
|
+
super << 'start'
|
|
373
377
|
end
|
|
374
378
|
end
|
|
375
379
|
|
|
@@ -377,8 +381,9 @@ module MIDI
|
|
|
377
381
|
def initialize(delta_time = 0)
|
|
378
382
|
super(CONTINUE, delta_time)
|
|
379
383
|
end
|
|
384
|
+
|
|
380
385
|
def to_s
|
|
381
|
-
|
|
386
|
+
super << 'continue'
|
|
382
387
|
end
|
|
383
388
|
end
|
|
384
389
|
|
|
@@ -386,8 +391,9 @@ module MIDI
|
|
|
386
391
|
def initialize(delta_time = 0)
|
|
387
392
|
super(STOP, delta_time)
|
|
388
393
|
end
|
|
394
|
+
|
|
389
395
|
def to_s
|
|
390
|
-
|
|
396
|
+
super << 'stop'
|
|
391
397
|
end
|
|
392
398
|
end
|
|
393
399
|
|
|
@@ -395,8 +401,9 @@ module MIDI
|
|
|
395
401
|
def initialize(delta_time = 0)
|
|
396
402
|
super(ACTIVE_SENSE, delta_time)
|
|
397
403
|
end
|
|
404
|
+
|
|
398
405
|
def to_s
|
|
399
|
-
|
|
406
|
+
super << 'act sens'
|
|
400
407
|
end
|
|
401
408
|
end
|
|
402
409
|
|
|
@@ -404,33 +411,27 @@ module MIDI
|
|
|
404
411
|
def initialize(delta_time = 0)
|
|
405
412
|
super(SYSTEM_RESET, delta_time)
|
|
406
413
|
end
|
|
414
|
+
|
|
407
415
|
def to_s
|
|
408
|
-
|
|
416
|
+
super << 'sys reset'
|
|
409
417
|
end
|
|
410
418
|
end
|
|
411
419
|
|
|
412
420
|
class MetaEvent < Event
|
|
413
|
-
attr_reader :meta_type
|
|
414
|
-
attr_reader :data
|
|
421
|
+
attr_reader :meta_type, :data
|
|
415
422
|
|
|
416
423
|
def self.bytes_as_str(bytes)
|
|
417
424
|
bytes ? bytes.collect { |byte| byte.chr }.join : nil
|
|
418
425
|
end
|
|
419
426
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
str.split(//).collect { |chr| chr.ord }
|
|
423
|
-
end
|
|
424
|
-
else
|
|
425
|
-
def self.str_as_bytes(str)
|
|
426
|
-
str.split(//).collect { |chr| chr[0] }
|
|
427
|
-
end
|
|
427
|
+
def self.str_as_bytes(str)
|
|
428
|
+
str.split(//).collect { |chr| chr.ord }
|
|
428
429
|
end
|
|
429
430
|
|
|
430
431
|
def initialize(meta_type, data = nil, delta_time = 0)
|
|
431
432
|
super(META_EVENT, delta_time)
|
|
432
433
|
@meta_type = meta_type
|
|
433
|
-
self.data=(data)
|
|
434
|
+
self.data = (data)
|
|
434
435
|
end
|
|
435
436
|
|
|
436
437
|
def data_as_bytes
|
|
@@ -448,50 +449,50 @@ module MIDI
|
|
|
448
449
|
|
|
449
450
|
# Stores bytes. If data is a string, splits it into an array of bytes.
|
|
450
451
|
def data=(data)
|
|
451
|
-
case data
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
452
|
+
@data = case data
|
|
453
|
+
when String
|
|
454
|
+
MetaEvent.str_as_bytes(data)
|
|
455
|
+
else
|
|
456
|
+
data
|
|
457
|
+
end
|
|
457
458
|
end
|
|
458
459
|
|
|
459
460
|
def to_s
|
|
460
461
|
str = super()
|
|
461
462
|
str << "meta #{number_to_s(@meta_type)} "
|
|
462
463
|
# I know, I know...this isn't OO.
|
|
463
|
-
case @meta_type
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
464
|
+
str << case @meta_type
|
|
465
|
+
when META_SEQ_NUM
|
|
466
|
+
'sequence number'
|
|
467
|
+
when META_TEXT
|
|
468
|
+
"text: #{data_as_str}"
|
|
469
|
+
when META_COPYRIGHT
|
|
470
|
+
"copyright: #{data_as_str}"
|
|
471
|
+
when META_SEQ_NAME
|
|
472
|
+
"sequence or track name: #{data_as_str}"
|
|
473
|
+
when META_INSTRUMENT
|
|
474
|
+
"instrument name: #{data_as_str}"
|
|
475
|
+
when META_LYRIC
|
|
476
|
+
"lyric: #{data_as_str}"
|
|
477
|
+
when META_MARKER
|
|
478
|
+
"marker: #{data_as_str}"
|
|
479
|
+
when META_CUE
|
|
480
|
+
"cue point: #{@data}"
|
|
481
|
+
when META_TRACK_END
|
|
482
|
+
'track end'
|
|
483
|
+
when META_SMPTE
|
|
484
|
+
'smpte'
|
|
485
|
+
when META_TIME_SIG
|
|
486
|
+
'time signature'
|
|
487
|
+
when META_KEY_SIG
|
|
488
|
+
'key signature'
|
|
489
|
+
when META_SEQ_SPECIF
|
|
490
|
+
'sequence specific'
|
|
491
|
+
else
|
|
492
|
+
# Some other possible @meta_type values are handled by subclasses.
|
|
493
|
+
'(other)'
|
|
494
|
+
end
|
|
495
|
+
str
|
|
495
496
|
end
|
|
496
497
|
end
|
|
497
498
|
|
|
@@ -502,17 +503,16 @@ module MIDI
|
|
|
502
503
|
end
|
|
503
504
|
|
|
504
505
|
class Tempo < MetaEvent
|
|
505
|
-
|
|
506
506
|
MICROSECS_PER_MINUTE = 1_000_000 * 60
|
|
507
507
|
|
|
508
508
|
# Translates beats per minute to microseconds per quarter note (beat).
|
|
509
|
-
def
|
|
510
|
-
|
|
509
|
+
def self.bpm_to_mpq(bpm)
|
|
510
|
+
MICROSECS_PER_MINUTE / bpm
|
|
511
511
|
end
|
|
512
512
|
|
|
513
513
|
# Translates microseconds per quarter note (beat) to beats per minute.
|
|
514
|
-
def
|
|
515
|
-
|
|
514
|
+
def self.mpq_to_bpm(mpq)
|
|
515
|
+
MICROSECS_PER_MINUTE.to_f / mpq.to_f
|
|
516
516
|
end
|
|
517
517
|
|
|
518
518
|
def initialize(msecs_per_qnote, delta_time = 0)
|
|
@@ -520,7 +520,7 @@ module MIDI
|
|
|
520
520
|
end
|
|
521
521
|
|
|
522
522
|
def tempo
|
|
523
|
-
|
|
523
|
+
@data
|
|
524
524
|
end
|
|
525
525
|
|
|
526
526
|
def tempo=(val)
|
|
@@ -544,7 +544,6 @@ module MIDI
|
|
|
544
544
|
|
|
545
545
|
# Container for time signature events
|
|
546
546
|
class TimeSig < MetaEvent
|
|
547
|
-
|
|
548
547
|
# Constructor
|
|
549
548
|
def initialize(numer, denom, clocks, qnotes, delta_time = 0)
|
|
550
549
|
super(META_TIME_SIG, [numer, denom, clocks, qnotes], delta_time)
|
|
@@ -593,7 +592,6 @@ module MIDI
|
|
|
593
592
|
|
|
594
593
|
# Container for key signature events
|
|
595
594
|
class KeySig < MetaEvent
|
|
596
|
-
|
|
597
595
|
# Constructor
|
|
598
596
|
def initialize(sharpflat, is_minor, delta_time = 0)
|
|
599
597
|
super(META_KEY_SIG, [sharpflat, is_minor], delta_time)
|
|
@@ -627,13 +625,43 @@ module MIDI
|
|
|
627
625
|
# Returns the key signature as a text string.
|
|
628
626
|
# Example: "key sig A flat major"
|
|
629
627
|
def to_s
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
'a', 'e', 'b', 'f#', 'c#', 'g#', 'd#', 'a#']
|
|
634
|
-
minor_key? ? "key sig #{minorkeys[sharpflat + 7]} minor" :
|
|
628
|
+
if minor_key?
|
|
629
|
+
"key sig #{minorkeys[sharpflat + 7]} minor"
|
|
630
|
+
else
|
|
635
631
|
"key sig #{majorkeys[sharpflat + 7]} major"
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
# Returns the key signature as a code.
|
|
636
|
+
# Example: "Ab" for "key sig A flat major"
|
|
637
|
+
def to_code
|
|
638
|
+
if minor_key?
|
|
639
|
+
minorkey_codes[sharpflat + 7]
|
|
640
|
+
else
|
|
641
|
+
majorkey_codes[sharpflat + 7]
|
|
642
|
+
end
|
|
636
643
|
end
|
|
637
|
-
end
|
|
638
644
|
|
|
645
|
+
private
|
|
646
|
+
|
|
647
|
+
def majorkeys
|
|
648
|
+
@majorkeys ||= ['C flat', 'G flat', 'D flat', 'A flat', 'E flat', 'B flat', 'F',
|
|
649
|
+
'C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#']
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
def minorkeys
|
|
653
|
+
@minorkeys ||= ['a flat', 'e flat', 'b flat', 'f', 'c', 'g', 'd',
|
|
654
|
+
'a', 'e', 'b', 'f#', 'c#', 'g#', 'd#', 'a#']
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
def majorkey_codes
|
|
658
|
+
@majorkeys_codes ||= ['Cb', 'Gb', 'Db', 'Ab', 'Eb', 'Bb', 'F',
|
|
659
|
+
'C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#']
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
def minorkey_codes
|
|
663
|
+
@minorkeys_codes ||= ['Abm', 'Ebm', 'Bbm', 'Fm', 'Cm', 'Gm', 'Dm',
|
|
664
|
+
'Am', 'Em', 'Bm', 'F#m', 'C#m', 'G#m', 'D#m', 'A#m']
|
|
665
|
+
end
|
|
666
|
+
end
|
|
639
667
|
end
|
data/lib/midilib/info.rb
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
module MIDI
|
|
2
|
-
|
|
3
|
-
VERSION_MAJOR = 2
|
|
2
|
+
VERSION_MAJOR = 3
|
|
4
3
|
VERSION_MINOR = 0
|
|
5
|
-
VERSION_TWEAK =
|
|
4
|
+
VERSION_TWEAK = 1
|
|
6
5
|
Version = "#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_TWEAK}"
|
|
7
|
-
Copyright = 'Copyright (c) 2003-
|
|
8
|
-
|
|
6
|
+
Copyright = 'Copyright (c) 2003-2022 by Jim Menard <jim@jimmenard.com>'
|
|
9
7
|
end
|