midilib 2.0.5 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +5 -5
  2. data/ChangeLog +2 -1
  3. data/Credits +39 -2
  4. data/README.rdoc +5 -6
  5. data/Rakefile +36 -49
  6. data/TODO.rdoc +13 -2
  7. data/examples/from_scratch.rb +1 -1
  8. data/examples/measures_mbt.rb +11 -11
  9. data/examples/print_program_changes.rb +2 -2
  10. data/examples/reader2text.rb +47 -47
  11. data/examples/seq2text.rb +1 -1
  12. data/examples/split.rb +4 -3
  13. data/examples/strings.rb +4 -4
  14. data/examples/transpose.rb +19 -20
  15. data/install.rb +21 -13
  16. data/lib/midilib/consts.rb +237 -239
  17. data/lib/midilib/event.rb +128 -100
  18. data/lib/midilib/info.rb +3 -5
  19. data/lib/midilib/io/midifile.rb +155 -182
  20. data/lib/midilib/io/seqreader.rb +80 -85
  21. data/lib/midilib/io/seqwriter.rb +93 -88
  22. data/lib/midilib/measure.rb +78 -80
  23. data/lib/midilib/mergesort.rb +39 -0
  24. data/lib/midilib/sequence.rb +40 -32
  25. data/lib/midilib/track.rb +16 -57
  26. data/lib/midilib/utils.rb +4 -7
  27. data/lib/midilib.rb +5 -5
  28. data/test/event_equality.rb +28 -30
  29. data/test/test_event.rb +9 -11
  30. data/test/test_io.rb +83 -3
  31. data/test/test_mergesort.rb +37 -0
  32. data/test/test_midifile.rb +6 -19
  33. data/test/test_sequence.rb +5 -4
  34. data/test/test_track.rb +9 -38
  35. data/test/test_varlen.rb +1 -3
  36. metadata +8 -95
  37. data/html/IO.html +0 -155
  38. data/html/MIDI/ActiveSense.html +0 -206
  39. data/html/MIDI/ChannelEvent.html +0 -231
  40. data/html/MIDI/ChannelPressure.html +0 -265
  41. data/html/MIDI/Clock.html +0 -206
  42. data/html/MIDI/Continue.html +0 -206
  43. data/html/MIDI/Controller.html +0 -280
  44. data/html/MIDI/Event.html +0 -489
  45. data/html/MIDI/IO/MIDIFile.html +0 -2024
  46. data/html/MIDI/IO/SeqReader.html +0 -904
  47. data/html/MIDI/IO/SeqWriter.html +0 -572
  48. data/html/MIDI/IO.html +0 -95
  49. data/html/MIDI/KeySig.html +0 -353
  50. data/html/MIDI/MIDI/MIDI/Array.html +0 -255
  51. data/html/MIDI/MIDI/MIDI.html +0 -95
  52. data/html/MIDI/MIDI.html +0 -95
  53. data/html/MIDI/Marker.html +0 -158
  54. data/html/MIDI/Measure.html +0 -328
  55. data/html/MIDI/Measures.html +0 -285
  56. data/html/MIDI/MetaEvent.html +0 -461
  57. data/html/MIDI/NoteEvent.html +0 -331
  58. data/html/MIDI/NoteOff.html +0 -228
  59. data/html/MIDI/NoteOn.html +0 -228
  60. data/html/MIDI/PitchBend.html +0 -266
  61. data/html/MIDI/PolyPressure.html +0 -277
  62. data/html/MIDI/ProgramChange.html +0 -265
  63. data/html/MIDI/Realtime.html +0 -242
  64. data/html/MIDI/Sequence.html +0 -896
  65. data/html/MIDI/SongPointer.html +0 -266
  66. data/html/MIDI/SongSelect.html +0 -265
  67. data/html/MIDI/Start.html +0 -206
  68. data/html/MIDI/Stop.html +0 -206
  69. data/html/MIDI/SystemCommon.html +0 -158
  70. data/html/MIDI/SystemExclusive.html +0 -268
  71. data/html/MIDI/SystemReset.html +0 -206
  72. data/html/MIDI/Tempo.html +0 -396
  73. data/html/MIDI/TimeSig.html +0 -388
  74. data/html/MIDI/Track.html +0 -695
  75. data/html/MIDI/TuneRequest.html +0 -242
  76. data/html/MIDI/Utils.html +0 -220
  77. data/html/MIDI.html +0 -547
  78. data/html/README_rdoc.html +0 -731
  79. data/html/TODO_rdoc.html +0 -125
  80. data/html/created.rid +0 -14
  81. data/html/css/fonts.css +0 -167
  82. data/html/css/rdoc.css +0 -590
  83. data/html/fonts/Lato-Light.ttf +0 -0
  84. data/html/fonts/Lato-LightItalic.ttf +0 -0
  85. data/html/fonts/Lato-Regular.ttf +0 -0
  86. data/html/fonts/Lato-RegularItalic.ttf +0 -0
  87. data/html/fonts/SourceCodePro-Bold.ttf +0 -0
  88. data/html/fonts/SourceCodePro-Regular.ttf +0 -0
  89. data/html/images/add.png +0 -0
  90. data/html/images/arrow_up.png +0 -0
  91. data/html/images/brick.png +0 -0
  92. data/html/images/brick_link.png +0 -0
  93. data/html/images/bug.png +0 -0
  94. data/html/images/bullet_black.png +0 -0
  95. data/html/images/bullet_toggle_minus.png +0 -0
  96. data/html/images/bullet_toggle_plus.png +0 -0
  97. data/html/images/date.png +0 -0
  98. data/html/images/delete.png +0 -0
  99. data/html/images/find.png +0 -0
  100. data/html/images/loadingAnimation.gif +0 -0
  101. data/html/images/macFFBgHack.png +0 -0
  102. data/html/images/package.png +0 -0
  103. data/html/images/page_green.png +0 -0
  104. data/html/images/page_white_text.png +0 -0
  105. data/html/images/page_white_width.png +0 -0
  106. data/html/images/plugin.png +0 -0
  107. data/html/images/ruby.png +0 -0
  108. data/html/images/tag_blue.png +0 -0
  109. data/html/images/tag_green.png +0 -0
  110. data/html/images/transparent.png +0 -0
  111. data/html/images/wrench.png +0 -0
  112. data/html/images/wrench_orange.png +0 -0
  113. data/html/images/zoom.png +0 -0
  114. data/html/index.html +0 -768
  115. data/html/js/darkfish.js +0 -161
  116. data/html/js/jquery.js +0 -4
  117. data/html/js/navigation.js +0 -142
  118. data/html/js/navigation.js.gz +0 -0
  119. data/html/js/search.js +0 -109
  120. data/html/js/search_index.js +0 -1
  121. data/html/js/search_index.js.gz +0 -0
  122. data/html/js/searcher.js +0 -228
  123. data/html/js/searcher.js.gz +0 -0
  124. data/html/table_of_contents.html +0 -1265
data/lib/midilib/event.rb CHANGED
@@ -1,11 +1,9 @@
1
- require 'midilib/consts'
2
- require 'midilib/utils'
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 # maintained by tracks
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 "subclass responsibility"
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 <=>(an_event)
61
- return @time_from_start <=> an_event.time_from_start
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
- return @print_decimal_numbers ? val.to_s : ('%02x' % val)
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
- return number_to_s(val)
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
- return super << "ch #{channel_to_s(@channel)} "
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(C C# D D# E F F# G G# A A# B)
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=@note)
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
- return @print_note_names ? pch_oct(@note) : number_to_s(@note)
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
- return super <<
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
- return super <<
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
- return @velocity
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
- return super <<
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
- return super << "cntl #{number_to_s(@controller)} #{number_to_s(@value)}"
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
- return super << "prog #{number_to_s(@program)}"
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
- return super << "chan press #{number_to_s(@pressure)}"
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
- return super << "pb #{number_to_s(@value)}"
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
- return super << "sys ex"
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
- return super << "song ptr #{number_to_s(@pointer)}"
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
- return super << "song sel #{number_to_s(@song)}"
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
- return super << "tune req"
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
- return super << "realtime #{number_to_s(@status)}"
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
- return super << "clock"
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
- return super << "start"
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
- return super << "continue"
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
- return super << "stop"
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
- return super << "act sens"
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
- return super << "sys reset"
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
- if RUBY_VERSION >= '1.9'
421
- def self.str_as_bytes(str)
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
- when String
453
- @data = MetaEvent.str_as_bytes(data)
454
- else
455
- @data = data
456
- end
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
- when META_SEQ_NUM
465
- str << "sequence number"
466
- when META_TEXT
467
- str << "text: #{data_as_str}"
468
- when META_COPYRIGHT
469
- str << "copyright: #{data_as_str}"
470
- when META_SEQ_NAME
471
- str << "sequence or track name: #{data_as_str}"
472
- when META_INSTRUMENT
473
- str << "instrument name: #{data_as_str}"
474
- when META_LYRIC
475
- str << "lyric: #{data_as_str}"
476
- when META_MARKER
477
- str << "marker: #{data_as_str}"
478
- when META_CUE
479
- str << "cue point: #{@data}"
480
- when META_TRACK_END
481
- str << "track end"
482
- when META_SMPTE
483
- str << "smpte"
484
- when META_TIME_SIG
485
- str << "time signature"
486
- when META_KEY_SIG
487
- str << "key signature"
488
- when META_SEQ_SPECIF
489
- str << "sequence specific"
490
- else
491
- # Some other possible @meta_type values are handled by subclasses.
492
- str << "(other)"
493
- end
494
- return str
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 Tempo.bpm_to_mpq(bpm)
510
- return MICROSECS_PER_MINUTE / bpm
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 Tempo.mpq_to_bpm(mpq)
515
- return MICROSECS_PER_MINUTE.to_f / mpq.to_f
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
- return @data
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
- majorkeys = ['C flat', 'G flat', 'D flat', 'A flat', 'E flat', 'B flat', 'F',
631
- 'C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#']
632
- minorkeys = ['a flat', 'e flat', 'b flat', 'f', 'c', 'g', 'd',
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 = 5
4
+ VERSION_TWEAK = 1
6
5
  Version = "#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_TWEAK}"
7
- Copyright = 'Copyright (c) 2003-2015 by Jim Menard <jim@jimmenard.com>'
8
-
6
+ Copyright = 'Copyright (c) 2003-2022 by Jim Menard <jim@jimmenard.com>'
9
7
  end