smf 0.15.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/MANUAL +172 -0
  2. data/MANUAL.en +135 -0
  3. data/MANUAL.en.html +150 -0
  4. data/MANUAL.en.rd +144 -0
  5. data/MANUAL.html +201 -0
  6. data/MANUAL.rd +179 -0
  7. data/README +33 -0
  8. data/README.en +33 -0
  9. data/lib/smf.rb +736 -0
  10. data/lib/smf/divert.rb +21 -0
  11. data/lib/smf/io.rb +1278 -0
  12. data/lib/smf/toy/beatmap.rb +73 -0
  13. data/lib/smf/toy/gm.rb +327 -0
  14. data/lib/smf/toy/groove.rb +34 -0
  15. data/lib/smf/toy/macro.rb +282 -0
  16. data/lib/smf/toy/macro/mml.rb +34 -0
  17. data/lib/smf/toy/macro/mml/parser.rb +545 -0
  18. data/lib/smf/toy/macro/mml/parser.ry +239 -0
  19. data/lib/smf/toy/macro/stt.rb +33 -0
  20. data/lib/smf/toy/morse.rb +126 -0
  21. data/lib/smf/toy/quantize.rb +32 -0
  22. data/lib/smf/toy/rmi.rb +29 -0
  23. data/lib/smf/toy/searchsegment.rb +24 -0
  24. data/lib/smf/toy/shuffle.rb +39 -0
  25. data/lib/smf/toy/tempomap.rb +75 -0
  26. data/lib/smf/toy/text.rb +369 -0
  27. data/lib/smf/toy/velcomp.rb +42 -0
  28. data/lib/smf/toy/virtual.rb +118 -0
  29. data/lib/smf/toy/xml.rb +377 -0
  30. data/sample/Makefile +58 -0
  31. data/sample/bwv772.mid +0 -0
  32. data/sample/bwv772.mml +94 -0
  33. data/sample/bwv775.mid +0 -0
  34. data/sample/bwv775.mml +157 -0
  35. data/sample/bwv787.mid +0 -0
  36. data/sample/bwv787.mml +129 -0
  37. data/sample/groove.grv +33 -0
  38. data/sample/groove.rb +45 -0
  39. data/sample/ltvddpd2.mid +0 -0
  40. data/sample/ltvddpd2.stt +60 -0
  41. data/sample/merge.rb +38 -0
  42. data/sample/mml-samp.rb +19 -0
  43. data/sample/mml.rb +36 -0
  44. data/sample/morse-samp.rb +11 -0
  45. data/sample/morse.rb +31 -0
  46. data/sample/play-oss.rb +215 -0
  47. data/sample/play-oss2.rb +253 -0
  48. data/sample/play-oss3.rb +150 -0
  49. data/sample/play-spkr.rb +97 -0
  50. data/sample/play-win.rb +195 -0
  51. data/sample/quantize.rb +41 -0
  52. data/sample/rand1.rb +21 -0
  53. data/sample/rand2.rb +24 -0
  54. data/sample/rmi2smf.rb +26 -0
  55. data/sample/shuffle.rb +43 -0
  56. data/sample/smf2rmi.rb +26 -0
  57. data/sample/smf2smf.rb +26 -0
  58. data/sample/smf2text.rb +27 -0
  59. data/sample/smf2wav.rb +123 -0
  60. data/sample/smf2xml.rb +27 -0
  61. data/sample/split.rb +40 -0
  62. data/sample/stt-samp.rb +19 -0
  63. data/sample/stt.rb +36 -0
  64. data/sample/text2smf.rb +28 -0
  65. data/sample/velcomp.rb +45 -0
  66. data/sample/virtual-samp.rb +19 -0
  67. data/sample/xml2smf.rb +28 -0
  68. metadata +128 -0
data/README ADDED
@@ -0,0 +1,33 @@
1
+ SMF �⥸�塼��
2
+ ==============
3
+
4
+ SMF �ϥ��֥������Ȼظ�������ץȸ��� Ruby �Τ���Ρ��֥����������MIDI��
5
+ ������ץ⥸�塼��Ǥ���
6
+
7
+
8
+ ���󥹥ȡ���
9
+ ------------
10
+
11
+ ������ץ� "install.rb" ��Ĥ����ޤ���
12
+
13
+ $ ruby install.rb config
14
+ $ ruby install.rb setup
15
+ ($ su)
16
+ # ruby install.rb install
17
+
18
+ ���路���ϡ�"ruby install.rb --help" �Ȥ��Ƥ���������
19
+
20
+
21
+ ����ʸ��
22
+ --------
23
+
24
+ MIDI ���ʶ��IJ��MIDI 1.0 ���ʡץ�åȡ��ߥ塼���å� 1989
25
+
26
+ �����Żһ��ȶ����MIDI 1.0 ���ʽ�ץ�åȡ��ߥ塼���å� 1998
27
+
28
+ JIS X 6054-1,2:1999 �Żҳڴ�ǥ������륤�󥿡��ե����� (MIDI)
29
+
30
+
31
+ ������� (�դʤФ����褷)
32
+ mailto:tadf@funaba.org
33
+ http://www.funaba.org/
@@ -0,0 +1,33 @@
1
+ An "SMF" module
2
+ ==============
3
+
4
+ SMF is a "Standard MIDI File" module for an object‐oriented
5
+ scripting language Ruby.
6
+
7
+
8
+ Install
9
+ ‐‐‐‐‐‐‐
10
+
11
+ Use the script "install.rb".
12
+
13
+ $ ruby install.rb config
14
+ $ ruby install.rb setup
15
+ ($ su)
16
+ # ruby install.rb install
17
+
18
+ For more information, type "ruby install.rb ‐‐help".
19
+
20
+
21
+ References
22
+ ‐‐‐‐‐‐‐‐‐‐
23
+
24
+ MIDI kikaku kyogi‐kai, MIDI 1.0 kikaku, rittor music 1989
25
+
26
+ ongaku denshi jigyo kyokai, MIDI 1.0 kikaku‐sho, rittor music 1998
27
+
28
+ JIS X 6054‐1,2:1999 Musical Instrument Digital Interface (MIDI)
29
+
30
+
31
+ Tadayoshi Funaba
32
+ mailto:tadf@funaba.org
33
+ http://www.funaba.org/en/
@@ -0,0 +1,736 @@
1
+ # smf.rb: Written by Tadayoshi Funaba 1998-2006,2008
2
+ # $Id: smf.rb,v 1.39 2008-07-06 00:00:43+09 tadf Exp $
3
+
4
+ require 'smf/io'
5
+ require 'forwardable'
6
+
7
+ module SMF
8
+
9
+ class Sequence
10
+
11
+ def initialize(format=1, division=96, tc=nil)
12
+ # format:0/2
13
+ # division:1/2**15-1(if tc=nil):1/2**8-1(otherwise)
14
+ # tc:nil,24,25,29,30
15
+ @format, @division, @tc, @arr = format, division, tc, []
16
+ end
17
+
18
+ attr_accessor :format, :division, :tc
19
+
20
+ def smpte()
21
+ warn('smpte is deprecated; use tc') if $VERBOSE
22
+ self.tc
23
+ end
24
+
25
+ def smpte=(v)
26
+ warn('smpte= is deprecated; use tc=') if $VERBOSE
27
+ self.tc = v
28
+ end
29
+
30
+ if [].respond_to?(:count)
31
+
32
+ def ntrks() @arr.count{|x| x} end
33
+
34
+ else
35
+
36
+ def ntrks() @arr.nitems end
37
+
38
+ end
39
+
40
+ def hash() @format.hash ^ @division.hash ^ @arr.hash end
41
+ def eql? (other) self == other end
42
+
43
+ def == (other)
44
+ self.class == other.class &&
45
+ format == other.format &&
46
+ division == other.division &&
47
+ tc == other.tc &&
48
+ to_a == other.to_a
49
+ end
50
+
51
+ def calc_set(a, b)
52
+ sq = self.class.new(format, division, tc)
53
+ a, b = a.to_a, b.to_a
54
+ n = yield(a, b)
55
+ sq.replace(n)
56
+ sq
57
+ end
58
+
59
+ private :calc_set
60
+
61
+ def + (other) calc_set(self, other){|a, b| a + b} end
62
+ def - (other) calc_set(self, other){|a, b| a - b} end
63
+ def & (other) calc_set(self, other){|a, b| a & b} end
64
+ def | (other) calc_set(self, other){|a, b| a | b} end
65
+
66
+ def * (times)
67
+ sq = self.class.new(format, division, tc)
68
+ sq.replace(self.to_a * times)
69
+ sq
70
+ end
71
+
72
+ def << (tr)
73
+ @arr << tr
74
+ self
75
+ end
76
+
77
+ def >> (tr)
78
+ @arr.reject!{|x| x.object_id == tr.object_id}
79
+ self
80
+ end
81
+
82
+ def concat(other) replace(self + other) end
83
+
84
+ def each
85
+ @arr.compact.each do |tr|
86
+ yield tr
87
+ end
88
+ self
89
+ end
90
+
91
+ def join
92
+ sq = self.class.new(format, division, tc)
93
+ tr = Track.new
94
+ sq << @arr.inject(tr){|t, x| t + x}
95
+ sq
96
+ end
97
+
98
+ def join!
99
+ @arr.replace(join)
100
+ self
101
+ end
102
+
103
+ def replace(another)
104
+ if Sequence === another
105
+ @format = another.format
106
+ @division = another.division
107
+ @tc = another.tc
108
+ end
109
+ @arr.replace(another.to_a)
110
+ self
111
+ end
112
+
113
+ extend Forwardable
114
+ include Enumerable
115
+
116
+ de = (Array.instance_methods - self.instance_methods)
117
+ de -= %w(assoc flatten flatten! pack rassoc transpose)
118
+ de += %w(include? sort to_a)
119
+
120
+ def_delegators(:@arr, *de)
121
+
122
+ undef_method :zip
123
+
124
+ end
125
+
126
+ class Track
127
+
128
+ def initialize() @arr = [] end
129
+
130
+ if [].respond_to?(:count)
131
+
132
+ def nevts() @arr.count{|x| x} end
133
+
134
+ else
135
+
136
+ def nevts() @arr.nitems end
137
+
138
+ end
139
+
140
+ def hash() @arr.hash end
141
+ def eql? (other) self == other end
142
+
143
+ def == (other)
144
+ self.class == other.class &&
145
+ to_a == other.to_a
146
+ end
147
+
148
+ def calc_set_sub(a, b, e)
149
+ tr = self.class.new
150
+ n = yield(a, b).reject{|x| EndOfTrack === x}
151
+ eot = e.select{|x| EndOfTrack === x}
152
+ n << eot.max unless eot.empty?
153
+ tr.replace(n)
154
+ tr
155
+ end
156
+
157
+ def calc_set_maxsize(a, b, &block)
158
+ a, b = a.to_a, b.to_a
159
+ calc_set_sub(a, b, a + b, &block)
160
+ end
161
+
162
+ def calc_set_selfsize(a, b, &block)
163
+ a, b = a.to_a, b.to_a
164
+ calc_set_sub(a, b, a, &block)
165
+ end
166
+
167
+ private :calc_set_sub, :calc_set_maxsize, :calc_set_selfsize
168
+
169
+ def + (other) calc_set_maxsize(self, other){|a, b| a + b} end
170
+ def - (other) calc_set_selfsize(self, other){|a, b| a - b} end
171
+ def & (other) calc_set_selfsize(self, other){|a, b| a & b} end
172
+ def | (other) calc_set_maxsize(self, other){|a, b| a | b} end
173
+
174
+ def * (times)
175
+ tr = self.class.new
176
+ size = self[-1].offset
177
+ eot, orig = partition{|x| EndOfTrack === x}
178
+ times.times do |i|
179
+ tr += orig.collect{|ev| ev = ev.dup; ev.offset += size * i; ev}
180
+ end
181
+ unless eot.empty?
182
+ x = eot.max
183
+ x.offset += size * times
184
+ tr << x
185
+ end
186
+ tr
187
+ end
188
+
189
+ def << (ev)
190
+ @arr << ev
191
+ self
192
+ end
193
+
194
+ def >> (ev)
195
+ @arr.reject!{|x| x.object_id == ev.object_id}
196
+ self
197
+ end
198
+
199
+ def concat!(other) replace(self + other) end
200
+
201
+ def each
202
+ i = 0
203
+ @arr.compact.sort_by{|x| [x, i += 1]}.
204
+ each do |ev|
205
+ yield ev
206
+ end
207
+ self
208
+ end
209
+
210
+ def _merge(a, b, &block)
211
+ c = []
212
+ until a.empty? || b.empty?
213
+ c << if yield(a[0], b[0]) <= 0 then a.shift else b.shift end
214
+ end
215
+ c + a + b
216
+ end
217
+
218
+ def _sort(xs, &block)
219
+ mid = (xs.size / 2).truncate
220
+ if mid < 1
221
+ xs
222
+ else
223
+ _merge(_sort(xs[0...mid], &block), _sort(xs[mid..-1], &block), &block)
224
+ end
225
+ end
226
+
227
+ def _sort_by(xs)
228
+ _sort(xs.collect{|x| [x, yield(x)]}){|a, b| a[1] <=> b[1]}.
229
+ collect!{|x| x[0]}
230
+ end
231
+
232
+ private :_merge, :_sort, :_sort_by
233
+
234
+ def sort(&block)
235
+ block ||= proc{|a, b| a <=> b}
236
+ _sort(@arr, &block)
237
+ end
238
+
239
+ def sort!(&block)
240
+ replace(sort(&block))
241
+ self
242
+ end
243
+
244
+ def sort_by(&block)
245
+ _sort_by(@arr, &block)
246
+ end
247
+
248
+ def replace(another)
249
+ @arr.replace(another.to_a)
250
+ self
251
+ end
252
+
253
+ extend Forwardable
254
+ include Enumerable
255
+
256
+ de = (Array.instance_methods - self.instance_methods)
257
+ de -= %w(assoc flatten flatten! pack rassoc transpose)
258
+ de += %w(include? to_a)
259
+
260
+ def_delegators(:@arr, *de)
261
+
262
+ undef_method :zip
263
+
264
+ end
265
+
266
+ class Event
267
+
268
+ include Comparable
269
+
270
+ def initialize(offset)
271
+ # offset:0/oo
272
+ @offset = offset
273
+ end
274
+
275
+ attr_accessor :offset
276
+
277
+ def <=>(other) self.offset <=> other.offset end
278
+
279
+ def hash() @offset.hash end
280
+ def eql? (other) self == other end
281
+
282
+ def == (other)
283
+ self.class == other.class &&
284
+ offset == other.offset
285
+ end
286
+
287
+ end
288
+
289
+ class MIDIMessage < Event; end
290
+
291
+ class ChannelMessage < MIDIMessage
292
+
293
+ def initialize(offset, ch)
294
+ # ch:0/2**4-1
295
+ super(offset)
296
+ @ch = ch
297
+ end
298
+
299
+ attr_accessor :ch
300
+
301
+ alias_method :channel, :ch
302
+ alias_method :channel=, :ch=
303
+
304
+ def == (other)
305
+ super && ch == other.ch
306
+ end
307
+
308
+ end
309
+
310
+ class VoiceMessage < ChannelMessage; end
311
+
312
+ class NoteOff < VoiceMessage
313
+
314
+ def initialize(offset, ch, note, vel)
315
+ # note:0/2**7-1, vel:0/2**7-1
316
+ super(offset, ch)
317
+ @note, @vel = note, vel
318
+ end
319
+
320
+ attr_accessor :note
321
+
322
+ def vel() @vel || 64 end
323
+ def vel=(vel) @vel = vel end
324
+ def fake?() @vel.nil? end
325
+
326
+ alias_method :velocity, :vel
327
+ alias_method :velocity=, :vel=
328
+
329
+ def == (other)
330
+ super && note == other.note && vel == other.vel
331
+ end
332
+
333
+ end
334
+
335
+ class NoteOn < VoiceMessage
336
+
337
+ def initialize(offset, ch, note, vel)
338
+ # note:0/2**7-1, vel:0/2**7-1
339
+ super(offset, ch)
340
+ @note, @vel = note, vel
341
+ end
342
+
343
+ attr_accessor :note, :vel
344
+
345
+ alias_method :velocity, :vel
346
+ alias_method :velocity=, :vel=
347
+
348
+ def == (other)
349
+ super && note == other.note && vel == other.vel
350
+ end
351
+
352
+ end
353
+
354
+ class PolyphonicKeyPressure < VoiceMessage
355
+
356
+ def initialize(offset, ch, note, val)
357
+ # note:0/2**7-1, val:0/2**7-1
358
+ super(offset, ch)
359
+ @note, @val = note, val
360
+ end
361
+
362
+ attr_accessor :note, :val
363
+
364
+ alias_method :value, :val
365
+ alias_method :value=, :val=
366
+
367
+ def == (other)
368
+ super && note == other.note && val == other.val
369
+ end
370
+
371
+ end
372
+
373
+ class ControlChange < VoiceMessage
374
+
375
+ def initialize(offset, ch, num, val)
376
+ # num:0/119, val:0/2**7-1
377
+ super(offset, ch)
378
+ @num, @val = num, val
379
+ end
380
+
381
+ attr_accessor :num, :val
382
+
383
+ alias_method :number, :num
384
+ alias_method :number=, :num=
385
+
386
+ alias_method :value, :val
387
+ alias_method :value=, :val=
388
+
389
+ def == (other)
390
+ super && num == other.num && val == other.val
391
+ end
392
+
393
+ end
394
+
395
+ class ProgramChange < VoiceMessage
396
+
397
+ def initialize(offset, ch, num)
398
+ # num:0/2**7-1
399
+ super(offset, ch)
400
+ @num = num
401
+ end
402
+
403
+ attr_accessor :num
404
+
405
+ alias_method :number, :num
406
+ alias_method :number=, :num=
407
+
408
+ def == (other)
409
+ super && num == other.num
410
+ end
411
+
412
+ end
413
+
414
+ class ChannelPressure < VoiceMessage
415
+
416
+ def initialize(offset, ch, val)
417
+ # val:0/2**7-1
418
+ super(offset, ch)
419
+ @val = val
420
+ end
421
+
422
+ attr_accessor :val
423
+
424
+ alias_method :value, :val
425
+ alias_method :value=, :val=
426
+
427
+ def == (other)
428
+ super && val == other.val
429
+ end
430
+
431
+ end
432
+
433
+ class PitchBendChange < VoiceMessage
434
+
435
+ def initialize(offset, ch, val)
436
+ # val:-2**13/2**13-1
437
+ super(offset, ch)
438
+ @val = val
439
+ end
440
+
441
+ attr_accessor :val
442
+
443
+ alias_method :value, :val
444
+ alias_method :value=, :val=
445
+
446
+ def == (other)
447
+ super && val == other.val
448
+ end
449
+
450
+ end
451
+
452
+ class ChannelModeMessage < ChannelMessage; end
453
+
454
+ [ 'AllSoundOff',
455
+ 'ResetAllControllers',
456
+ 'AllNotesOff',
457
+ 'OmniOff',
458
+ 'OmniOn',
459
+ 'PolyMode',
460
+ ].each do |name|
461
+ module_eval <<-"end;"
462
+ class #{name} < ChannelModeMessage
463
+
464
+ def initialize(offset, ch)
465
+ super(offset, ch)
466
+ end
467
+
468
+ end
469
+ end;
470
+ end
471
+
472
+ [ 'LocalControl', # val:0/127
473
+ 'MonoMode', # val:0/16
474
+ ].each do |name|
475
+ module_eval <<-"end;"
476
+ class #{name} < ChannelModeMessage
477
+
478
+ def initialize(offset, ch, val)
479
+ super(offset, ch)
480
+ @val = val
481
+ end
482
+
483
+ attr_accessor :val
484
+
485
+ alias_method :value, :val
486
+ alias_method :value=, :val=
487
+
488
+ def == (other)
489
+ super && val == other.val
490
+ end
491
+
492
+ end
493
+ end;
494
+ end
495
+
496
+ class SystemMessage < Event; end
497
+ class ExclusiveMessage < SystemMessage; end
498
+
499
+ class ExclusiveF0 < ExclusiveMessage
500
+
501
+ def initialize(offset, data)
502
+ # data.length:0/2**28-1
503
+ super(offset)
504
+ @data = data
505
+ end
506
+
507
+ attr_accessor :data
508
+
509
+ def == (other)
510
+ super && data == other.data
511
+ end
512
+
513
+ end
514
+
515
+ class ExclusiveF7 < ExclusiveMessage
516
+
517
+ def initialize(offset, data)
518
+ # data.length:0/2**28-1
519
+ super(offset)
520
+ @data = data
521
+ end
522
+
523
+ attr_accessor :data
524
+
525
+ def == (other)
526
+ super && data == other.data
527
+ end
528
+
529
+ end
530
+
531
+ class Meta < Event
532
+
533
+ def initialize(offset)
534
+ super(offset)
535
+ end
536
+
537
+ end
538
+
539
+ class SequenceNumber < Meta
540
+
541
+ def initialize(offset, num)
542
+ # num:0/2**16-1
543
+ super(offset)
544
+ @num = num
545
+ end
546
+
547
+ attr_accessor :num
548
+
549
+ alias_method :number, :num
550
+ alias_method :number=, :num=
551
+
552
+ def == (other)
553
+ super && num == other.num
554
+ end
555
+
556
+ end
557
+
558
+ class Text < Meta
559
+
560
+ def initialize(offset, text)
561
+ # text.length:0/2**28-1
562
+ super(offset)
563
+ @text = text
564
+ end
565
+
566
+ attr_accessor :text
567
+
568
+ def == (other)
569
+ super && text == other.text
570
+ end
571
+
572
+ end
573
+
574
+ %w(GeneralPurposeText CopyrightNotice TrackName
575
+ InstrumentName Lyric Marker CuePoint ProgramName
576
+ DeviceName Text0A Text0B Text0C Text0D Text0E Text0F).
577
+ each do |name|
578
+ module_eval <<-"end;"
579
+ class #{name} < Text
580
+
581
+ def initialize(offset, text)
582
+ super(offset, text)
583
+ end
584
+
585
+ end
586
+ end;
587
+ end
588
+
589
+ Text01 = GeneralPurposeText
590
+ Text02 = CopyrightNotice
591
+ SequenceName = TrackName
592
+ Text03 = TrackName
593
+ Text04 = InstrumentName
594
+ Display = Lyric
595
+ Text05 = Lyric
596
+ Text06 = Marker
597
+ Text07 = CuePoint
598
+ Text08 = ProgramName
599
+ Text09 = DeviceName
600
+
601
+ class ChannelPrefix < Meta
602
+
603
+ def initialize(offset, ch)
604
+ # ch:0/2**4-1
605
+ super(offset)
606
+ @ch = ch
607
+ end
608
+
609
+ attr_accessor :ch
610
+
611
+ alias_method :channel, :ch
612
+ alias_method :channel=, :ch=
613
+
614
+ def == (other)
615
+ super && ch == other.ch
616
+ end
617
+
618
+ end
619
+
620
+ class MIDIPort < Meta
621
+
622
+ def initialize(offset, num)
623
+ # num:0/2**8-1
624
+ super(offset)
625
+ @num = num
626
+ end
627
+
628
+ attr_accessor :num
629
+
630
+ alias_method :number, :num
631
+ alias_method :number=, :num=
632
+
633
+ def == (other)
634
+ super && num == other.num
635
+ end
636
+
637
+ end
638
+
639
+ class EndOfTrack < Meta
640
+
641
+ def initialize(offset)
642
+ super(offset)
643
+ end
644
+
645
+ end
646
+
647
+ class SetTempo < Meta
648
+
649
+ def initialize(offset, tempo)
650
+ # tempo:1/2**24-1
651
+ super(offset)
652
+ @tempo = tempo
653
+ end
654
+
655
+ attr_accessor :tempo
656
+
657
+ def == (other)
658
+ super && tempo == other.tempo
659
+ end
660
+
661
+ end
662
+
663
+ class SMPTEOffset < Meta
664
+
665
+ def initialize(offset, hr, mn, se, fr, ff, tc)
666
+ # hr:0/23, mn:0/59, se:0/59, fr:0/29, ff:0/99, tc:24|25|29|30
667
+ super(offset)
668
+ @hr, @mn, @se, @fr, @ff, @tc = hr, mn, se, fr, ff, tc
669
+ end
670
+
671
+ attr_accessor :hr, :mn, :se, :fr, :ff, :tc
672
+
673
+ def == (other)
674
+ super &&
675
+ hr == other.hr &&
676
+ mn == other.mn &&
677
+ se == other.se &&
678
+ fr == other.fr &&
679
+ ff == other.ff &&
680
+ tc == other.tc
681
+ end
682
+
683
+ end
684
+
685
+ class TimeSignature < Meta
686
+
687
+ def initialize(offset, nn, dd, cc, bb)
688
+ # nn,cc,bb:1/2**8-1, dd:0/2**8-1
689
+ super(offset)
690
+ @nn, @dd, @cc, @bb = nn, dd, cc, bb
691
+ end
692
+
693
+ attr_accessor :nn, :dd, :cc, :bb
694
+
695
+ def == (other)
696
+ super &&
697
+ nn == other.nn &&
698
+ dd == other.dd &&
699
+ cc == other.cc &&
700
+ bb == other.bb
701
+ end
702
+
703
+ end
704
+
705
+ class KeySignature < Meta
706
+
707
+ def initialize(offset, sf, mi)
708
+ # sf:-2**7/2**7-1, mi:0/1
709
+ super(offset)
710
+ @sf, @mi = sf, mi
711
+ end
712
+
713
+ attr_accessor :sf, :mi
714
+
715
+ def == (other)
716
+ super && sf == other.sf && mi == other.mi
717
+ end
718
+ end
719
+
720
+ class SequencerSpecific < Meta
721
+
722
+ def initialize(offset, data)
723
+ # data.length:0/2**28-1
724
+ super(offset)
725
+ @data = data
726
+ end
727
+
728
+ attr_accessor :data
729
+
730
+ def == (other)
731
+ super && data == other.data
732
+ end
733
+
734
+ end
735
+
736
+ end