midilib 4.0.0 → 4.0.2
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 +4 -4
- data/README.rdoc +2 -147
- data/Rakefile +5 -14
- data/examples/from_scratch.rb +2 -7
- data/examples/measures_mbt.rb +1 -6
- data/examples/print_program_changes.rb +1 -3
- data/examples/reader2text.rb +2 -7
- data/examples/seq2text.rb +1 -6
- data/examples/split.rb +1 -6
- data/examples/strings.rb +2 -7
- data/examples/transpose.rb +3 -8
- data/lib/midilib/consts.rb +2 -0
- data/lib/midilib/info.rb +1 -1
- data/test/test_event.rb +1 -6
- data/test/test_io.rb +116 -11
- data/test/test_mergesort.rb +1 -6
- data/test/test_midifile.rb +1 -6
- data/test/test_sequence.rb +1 -6
- data/test/test_track.rb +1 -6
- data/test/test_varlen.rb +1 -6
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21a0b490f3e0df0eb8208d1b07dd7a2d499a3ea7748bdaf89e05c180adc2db84
|
4
|
+
data.tar.gz: 0bece3bec4a4e48044712dd44d40e899283fd2eec9cac1a30ddd91b3ac29bf15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '069eaeafc603927b80d5764593c7ce63bfb9e5d0e3cf3b7c95dee3d42b3a94c604f753b11f2ea6e6ef71d2a203dfaf0acf377a4087531e713b9b16568b390135'
|
7
|
+
data.tar.gz: 7bf1f098d3bdf2587d5e2a3146df7fcc3d3d06c176c693ec9ef504e4c2e03d66913f1067091961832f848ccb7278e569be424e3d971476481f0927957540a0fc
|
data/README.rdoc
CHANGED
@@ -322,7 +322,7 @@ describes the format of MIDI commands.
|
|
322
322
|
= Administrivia
|
323
323
|
|
324
324
|
Author:: Jim Menard (mailto:jim@jimmenard.com)
|
325
|
-
Copyright:: Copyright (c) 2003-
|
325
|
+
Copyright:: Copyright (c) 2003-2023 Jim Menard
|
326
326
|
License:: Distributed under the same license as Ruby.
|
327
327
|
|
328
328
|
|
@@ -335,157 +335,12 @@ http://www.ruby-lang.org/en/LICENSE.txt.
|
|
335
335
|
midilib may be freely copied in its entirety providing this notice, all
|
336
336
|
source code, all documentation, and all other files are included.
|
337
337
|
|
338
|
-
midilib is Copyright (c) 2003-
|
338
|
+
midilib is Copyright (c) 2003-2023 by Jim Menard.
|
339
339
|
|
340
340
|
The song "No Fences" contained in the MIDI file examples/NoFences.mid is
|
341
341
|
Copyright (c) 1992 by Jim Menard (jim@jimmenard.com). It may be freely used
|
342
342
|
for non-commercial purposes as long as the author is given credit.
|
343
343
|
|
344
|
-
|
345
|
-
== Recent Changes
|
346
|
-
|
347
|
-
=== Changes for 2.0.5:
|
348
|
-
|
349
|
-
Updated +install.rb+ to work with newer versions of Ruby by using
|
350
|
-
+fileutils+ instead of +ftools+.
|
351
|
-
|
352
|
-
=== Changes for 2.0.3:
|
353
|
-
|
354
|
-
New MIDI::Sequence.pulses_to_seconds method.
|
355
|
-
|
356
|
-
=== Changes for 2.0.2:
|
357
|
-
|
358
|
-
Stop monkeypatching Array in MIDI::Track.
|
359
|
-
|
360
|
-
=== Changes for 2.0.0:
|
361
|
-
|
362
|
-
MIDI::NoteOnEvent and MIDI::NoteOffEvent renamed to MIDI::NoteOn and
|
363
|
-
MIDI::NoteOff. The old names will still work for a while.
|
364
|
-
|
365
|
-
The MIDI::Event boolean methods like meta? and note? have been removed. Use
|
366
|
-
the event classes themselves (for example, MIDI::MetaEvent === my_event or
|
367
|
-
my_event.kind_of?(MIDI::MetaEvent)). Case statements that use classes work,
|
368
|
-
too:
|
369
|
-
|
370
|
-
case my_event
|
371
|
-
when MIDI::NoteEvent # superclass of note on, note off, poly press
|
372
|
-
do_this()
|
373
|
-
when MIDI::Controller
|
374
|
-
do_that()
|
375
|
-
end
|
376
|
-
|
377
|
-
Introduced Adam Murray's stable sorting code for
|
378
|
-
MIDI::Track#recalc_delta_from_times. See
|
379
|
-
http://wiki.github.com/adamjmurray/cosy/midilib-notes and
|
380
|
-
http://github.com/adamjmurray/cosy/blob/master/lib/cosy/helper/midi_file_renderer_helper.rb
|
381
|
-
for details.
|
382
|
-
|
383
|
-
Aliased MIDI::Track#sort to MIDI::Track#recalc_delta_from_times, since all
|
384
|
-
sort did was sort the events then call recalc_delta_from_times, and
|
385
|
-
recalc_delta_from_times sorts the events before doing anything else.
|
386
|
-
|
387
|
-
MIDI::Tempo#mpq_to_bpm now returns a float.
|
388
|
-
|
389
|
-
=== Changes for 1.2.0:
|
390
|
-
|
391
|
-
Use byte arrays instead of strings for passing around data. All tests now pass
|
392
|
-
for both Ruby 1.8.X and 1.9.X.
|
393
|
-
|
394
|
-
=== New code repository
|
395
|
-
|
396
|
-
The midilib code is now hosted at Github (http://github.com/jimm/midilib).
|
397
|
-
|
398
|
-
=== Changes for 1.1.4:
|
399
|
-
|
400
|
-
* Fixed a bug in KeySig.data_as_bytes. Thanks to Noah Thorp for finding this
|
401
|
-
and the bug fixed in 1.1.3.
|
402
|
-
|
403
|
-
=== Changes for 1.1.3:
|
404
|
-
|
405
|
-
* Fixed the way midilib detects the behavior of IO.getc.
|
406
|
-
|
407
|
-
=== Changes for 1.1.2:
|
408
|
-
|
409
|
-
* Define MIDI::IO::MIDIFile.getc differently for different Ruby versions,
|
410
|
-
instead of checking for String.bytes every time we read a byte.
|
411
|
-
|
412
|
-
=== Changes for 1.1.1:
|
413
|
-
|
414
|
-
* Make MIDI::IO::MIDIFile.getc do the right thing for both Ruby 1.8 and 1.9.
|
415
|
-
|
416
|
-
=== Changes for 1.1.0:
|
417
|
-
|
418
|
-
* Added test/test.mid to list of files to be included when packaging midifile
|
419
|
-
for distribution.
|
420
|
-
|
421
|
-
=== Changes for 1.0.0:
|
422
|
-
|
423
|
-
* Fixed the bug in Track#recalc_delta_from_times found by Christopher Rose.
|
424
|
-
|
425
|
-
=== Changes for 0.8.7:
|
426
|
-
|
427
|
-
* Fixed the misspelled POLY_PRESSURE constant, thanks to Mario Pehle.
|
428
|
-
|
429
|
-
=== Changes for 0.8.6:
|
430
|
-
|
431
|
-
* Added missing test/test.mid.
|
432
|
-
|
433
|
-
=== Changes for 0.8.5:
|
434
|
-
|
435
|
-
* Fixed bugs in MIDI::PitchBend reading and writing, thanks to Emanuel
|
436
|
-
Borsboom.
|
437
|
-
|
438
|
-
* Fixed a bug in MIDI::Track#quantize.
|
439
|
-
|
440
|
-
* The argument to MIDI::Track#quantize has changed: it is now either a note
|
441
|
-
name ("sixteenth", "32nd", "8th triplet") or a length (1 = quarter, 0.25 =
|
442
|
-
sixteenth). This is a drastic change that will break all previous calls to
|
443
|
-
quantize. However, since that method was broken already, I don't feel it's
|
444
|
-
a burden to anybody to change the arguments.
|
445
|
-
|
446
|
-
=== Changes for 0.8.4:
|
447
|
-
|
448
|
-
* Realtime status bytes now set @is_realtime to true and return true when
|
449
|
-
realtime? is called.
|
450
|
-
|
451
|
-
* All system common events now set @is_system to true and return true when
|
452
|
-
system? is called, not just system exclusive events.
|
453
|
-
|
454
|
-
* Added examples/from_scratch.rb, which shows how to create a sequence
|
455
|
-
manually.
|
456
|
-
|
457
|
-
* New MIDI::Sequence methods that turn note length names like "32nd", "dotted
|
458
|
-
quarter", and "16th triplet" into delta times. See the docs below and
|
459
|
-
MIDI::Sequence::length_to_delta, MIDI::Sequence::note_to_length, and
|
460
|
-
MIDI::Sequence::note_to_delta.
|
461
|
-
|
462
|
-
|
463
|
-
=== Changes for 0.8.3:
|
464
|
-
|
465
|
-
* Added MIDI::NoteEvent.note_to_s, which returns note name as a string like
|
466
|
-
"C4" or "F#6".
|
467
|
-
|
468
|
-
* Added new boolean attributes to MIDI::Event: @print_decimal_numbers and
|
469
|
-
@print_note_names. These are used by all Event to_s methods. See
|
470
|
-
examples/seq2text.rb for an example.
|
471
|
-
|
472
|
-
=== Changes for 0.8.2:
|
473
|
-
|
474
|
-
* Changed MIDI::MetaEvent.type to MIDI::MetaEvent.event_type to avoid
|
475
|
-
runtime complaints about Object#type calls.
|
476
|
-
* Added 'b' binary flag to file open modes for Windows.
|
477
|
-
* Fixed $LOAD_PATH in example files.
|
478
|
-
* Fixed read and write block arguments.
|
479
|
-
* Fixed other example script bugs.
|
480
|
-
|
481
|
-
=== Changes for 0.8.1:
|
482
|
-
|
483
|
-
* Fixed track sorting.
|
484
|
-
* Fixed track's recalc_delta_from_times method.
|
485
|
-
* Fixed event quantization.
|
486
|
-
* More tests and documentation.
|
487
|
-
|
488
|
-
|
489
344
|
== Warranty
|
490
345
|
|
491
346
|
This software is provided "as is" and without any express or implied
|
data/Rakefile
CHANGED
@@ -42,20 +42,11 @@ spec = Gem::Specification.new do |s|
|
|
42
42
|
EOF
|
43
43
|
end
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
pkg.need_tar = true
|
51
|
-
end
|
52
|
-
else
|
53
|
-
# Creates a :package task (also named :gem). Also useful are
|
54
|
-
# :clobber_package and :repackage.
|
55
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
56
|
-
pkg.need_zip = true
|
57
|
-
pkg.need_tar = true
|
58
|
-
end
|
45
|
+
# Creates a :package task (also named :gem). Also useful are
|
46
|
+
# :clobber_package and :repackage.
|
47
|
+
Gem::PackageTask.new(spec) do |pkg|
|
48
|
+
pkg.need_zip = true
|
49
|
+
pkg.need_tar = true
|
59
50
|
end
|
60
51
|
|
61
52
|
# creates an "rdoc" task
|
data/examples/from_scratch.rb
CHANGED
@@ -5,13 +5,8 @@
|
|
5
5
|
# This script shows you how to create a new sequence from scratch and save it
|
6
6
|
# to a MIDI file. It creates a file called 'from_scratch.mid'.
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
# installed version out there somewhere.
|
11
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
12
|
-
|
13
|
-
require 'midilib/sequence'
|
14
|
-
require 'midilib/consts'
|
8
|
+
require_relative '../lib/midilib/sequence'
|
9
|
+
require_relative '../lib/midilib/consts'
|
15
10
|
include MIDI
|
16
11
|
|
17
12
|
seq = Sequence.new
|
data/examples/measures_mbt.rb
CHANGED
@@ -6,12 +6,7 @@
|
|
6
6
|
# in a "sequencer-style" manner:
|
7
7
|
# Measure:Beat:Tick Channel: Note-name
|
8
8
|
|
9
|
-
|
10
|
-
# This forces us to use the local copy, even if there is a previously
|
11
|
-
# installed version out there somewhere.
|
12
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
13
|
-
|
14
|
-
require 'midilib/sequence'
|
9
|
+
require_relative '../lib/midilib/sequence'
|
15
10
|
|
16
11
|
seq = MIDI::Sequence.new
|
17
12
|
File.open(ARGV[0], 'rb') { |file| seq.read(file) }
|
@@ -2,9 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Shows use of print_decimal_numbers and print_channel_numbers_from_one.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
require 'midilib/sequence'
|
5
|
+
require_relative '../lib/midilib/sequence'
|
8
6
|
|
9
7
|
DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
|
10
8
|
|
data/examples/reader2text.rb
CHANGED
@@ -9,13 +9,8 @@
|
|
9
9
|
# For a simpler way to do the same thing, see seq2text.rb.
|
10
10
|
#
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
# installed version out there somewhere.
|
15
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
16
|
-
|
17
|
-
require 'midilib/sequence'
|
18
|
-
require 'midilib/io/midifile'
|
12
|
+
require_relative '../lib/midilib/sequence'
|
13
|
+
require_relative '../lib/midilib/io/midifile'
|
19
14
|
|
20
15
|
DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
|
21
16
|
|
data/examples/seq2text.rb
CHANGED
@@ -9,12 +9,7 @@
|
|
9
9
|
# reader2tex.rb.
|
10
10
|
#
|
11
11
|
|
12
|
-
|
13
|
-
# This forces us to use the local copy, even if there is a previously
|
14
|
-
# installed version out there somewhere.
|
15
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
16
|
-
|
17
|
-
require 'midilib/sequence'
|
12
|
+
require_relative '../lib/midilib/sequence'
|
18
13
|
|
19
14
|
DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
|
20
15
|
|
data/examples/split.rb
CHANGED
@@ -9,12 +9,7 @@
|
|
9
9
|
# If -x is specified, the 0th temp track is not included in each file.
|
10
10
|
# Instead, it is output in a separate file named 'tempo_track.mid'.
|
11
11
|
|
12
|
-
|
13
|
-
# This forces us to use the local copy, even if there is a previously
|
14
|
-
# installed version out there somewhere.
|
15
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
16
|
-
|
17
|
-
require 'midilib/sequence'
|
12
|
+
require_relative '../lib/midilib/sequence'
|
18
13
|
|
19
14
|
DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
|
20
15
|
|
data/examples/strings.rb
CHANGED
@@ -5,13 +5,8 @@
|
|
5
5
|
# Prints all strings (track names, etc.) found in the MIDI file.
|
6
6
|
#
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
# installed version out there somewhere.
|
11
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
12
|
-
|
13
|
-
require 'midilib/sequence'
|
14
|
-
require 'midilib/consts'
|
8
|
+
require_relative '../lib/midilib/sequence'
|
9
|
+
require_relative '../lib/midilib/consts'
|
15
10
|
|
16
11
|
DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
|
17
12
|
|
data/examples/transpose.rb
CHANGED
@@ -7,15 +7,10 @@
|
|
7
7
|
# -t half_steps default = 12 (one octave up)
|
8
8
|
#
|
9
9
|
|
10
|
-
# Start looking for MIDI module classes in the directory above this one.
|
11
|
-
# This forces us to use the local copy, even if there is a previously
|
12
|
-
# installed version out there somewhere.
|
13
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
14
|
-
|
15
10
|
require 'getoptlong'
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
require_relative '../lib/midilib/sequence'
|
12
|
+
require_relative '../lib/midilib/io/seqreader'
|
13
|
+
require_relative '../lib/midilib/io/seqwriter'
|
19
14
|
|
20
15
|
def usage
|
21
16
|
$stderr.print <<~EOF
|
data/lib/midilib/consts.rb
CHANGED
@@ -77,6 +77,7 @@ module MIDI
|
|
77
77
|
# = 0 - 31 = continuous, MSB
|
78
78
|
# = 32 - 63 = continuous, LSB
|
79
79
|
# = 64 - 97 = switches
|
80
|
+
CC_BANK_MSB = 0
|
80
81
|
CC_MOD_WHEEL = 1
|
81
82
|
CC_BREATH_CONTROLLER = 2
|
82
83
|
CC_FOOT_CONTROLLER = 4
|
@@ -92,6 +93,7 @@ module MIDI
|
|
92
93
|
CC_GEN_PURPOSE_4 = 19
|
93
94
|
|
94
95
|
# [32 - 63] are LSB for [0 - 31]
|
96
|
+
CC_BANK_LSB = 32
|
95
97
|
CC_DATA_ENTRY_LSB = 38
|
96
98
|
|
97
99
|
#--
|
data/lib/midilib/info.rb
CHANGED
data/test/test_event.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
|
-
# Start looking for MIDI classes in the directory above this one.
|
2
|
-
# This forces us to use the local copy of MIDI, even if there is
|
3
|
-
# a previously installed version out there somewhere.
|
4
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
-
|
6
1
|
require 'test/unit'
|
7
|
-
|
2
|
+
require_relative '../lib/midilib'
|
8
3
|
|
9
4
|
class EventTester < Test::Unit::TestCase
|
10
5
|
def test_note_on
|
data/test/test_io.rb
CHANGED
@@ -1,14 +1,7 @@
|
|
1
|
-
# Start looking for MIDI classes in the directory above this one.
|
2
|
-
# This forces us to use the local copy of MIDI, even if there is
|
3
|
-
# a previously installed version out there somewhere.
|
4
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
-
# Add current directory so we can find event_equality
|
6
|
-
$LOAD_PATH[0, 0] = File.dirname(__FILE__)
|
7
|
-
|
8
1
|
require 'test/unit'
|
9
|
-
|
10
|
-
|
11
|
-
|
2
|
+
require_relative '../lib/midilib'
|
3
|
+
require_relative '../lib/midilib/consts'
|
4
|
+
require_relative 'event_equality'
|
12
5
|
|
13
6
|
class IOTester < Test::Unit::TestCase
|
14
7
|
SEQ_TEST_FILE = File.join(File.dirname(__FILE__), 'test.mid')
|
@@ -146,7 +139,7 @@ class IOTester < Test::Unit::TestCase
|
|
146
139
|
out_track.events << MIDI::NoteOff.new(0, 65, 127, 230)
|
147
140
|
end
|
148
141
|
|
149
|
-
File.open(
|
142
|
+
File.open(TEMPFILE, 'wb') { |file| out_seq.write(file) }
|
150
143
|
|
151
144
|
# Although start times are not written out to the MIDI file, we
|
152
145
|
# calculate them because we are about to compare the out events with the
|
@@ -166,4 +159,116 @@ class IOTester < Test::Unit::TestCase
|
|
166
159
|
assert(e.is_a?(MIDI::MetaEvent))
|
167
160
|
assert(e.meta_type == MIDI::META_TRACK_END)
|
168
161
|
end
|
162
|
+
|
163
|
+
def test_preserve_deltas_multiple_note_offs
|
164
|
+
out_seq = MIDI::Sequence.new
|
165
|
+
out_track = MIDI::Track.new(out_seq)
|
166
|
+
out_seq.tracks << out_track
|
167
|
+
out_track.events << MIDI::Tempo.new(MIDI::Tempo.bpm_to_mpq(120))
|
168
|
+
|
169
|
+
out_track = MIDI::Track.new(out_seq)
|
170
|
+
out_seq.tracks << out_track
|
171
|
+
out_track.events << MIDI::NoteOn.new(0, 65, 127, 100)
|
172
|
+
out_track.events << MIDI::NoteOff.new(0, 65, 127, 100)
|
173
|
+
out_track.events << MIDI::NoteOff.new(0, 65, 127, 100)
|
174
|
+
|
175
|
+
File.open(TEMPFILE, 'wb') { |file| out_seq.write(file) }
|
176
|
+
|
177
|
+
in_seq = MIDI::Sequence.new
|
178
|
+
File.open(TEMPFILE, 'rb') { |file| in_seq.read(file) }
|
179
|
+
in_track = in_seq.tracks[1]
|
180
|
+
|
181
|
+
out_track.recalc_times # so that start times are correct
|
182
|
+
|
183
|
+
assert_equal(out_track.events.length + 1, in_track.events.length)
|
184
|
+
out_track.events.each_with_index do |event, i|
|
185
|
+
assert_equal(event.data_as_bytes, in_track.events[i].data_as_bytes)
|
186
|
+
assert_equal(event.delta_time, in_track.events[i].delta_time)
|
187
|
+
assert_equal(event.time_from_start, in_track.events[i].time_from_start)
|
188
|
+
end
|
189
|
+
|
190
|
+
# Last event is a end of track meta event
|
191
|
+
e = in_track.events.last
|
192
|
+
assert(e.is_a?(MIDI::MetaEvent))
|
193
|
+
assert(e.meta_type == MIDI::META_TRACK_END)
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_preserve_deltas_multiple_note_on_zero_velocity
|
197
|
+
out_seq = MIDI::Sequence.new
|
198
|
+
out_track = MIDI::Track.new(out_seq)
|
199
|
+
out_seq.tracks << out_track
|
200
|
+
out_track.events << MIDI::Tempo.new(MIDI::Tempo.bpm_to_mpq(120))
|
201
|
+
|
202
|
+
out_track = MIDI::Track.new(out_seq)
|
203
|
+
out_seq.tracks << out_track
|
204
|
+
out_track.events << MIDI::NoteOn.new(0, 65, 127, 100)
|
205
|
+
out_track.events << MIDI::NoteOn.new(0, 65, 0, 100)
|
206
|
+
out_track.events << MIDI::NoteOn.new(0, 65, 0, 100)
|
207
|
+
|
208
|
+
File.open(TEMPFILE, 'wb') { |file| out_seq.write(file) }
|
209
|
+
|
210
|
+
in_seq = MIDI::Sequence.new
|
211
|
+
File.open(TEMPFILE, 'rb') { |file| in_seq.read(file) }
|
212
|
+
in_track = in_seq.tracks[1]
|
213
|
+
|
214
|
+
# Turn the note ons with zero velocity into note offs, and recalc start
|
215
|
+
# times so that time_from_start is correct.
|
216
|
+
[1, 2].each do |i|
|
217
|
+
out_track.events[i] = MIDI::NoteOff.new(0, 65, 64, 100)
|
218
|
+
end
|
219
|
+
out_track.recalc_times # so that start times are correct
|
220
|
+
|
221
|
+
assert_equal(out_track.events.length + 1, in_track.events.length)
|
222
|
+
out_track.events.zip(in_track.events).each do |out_event, in_event|
|
223
|
+
assert_equal(out_event.data_as_bytes, in_event.data_as_bytes)
|
224
|
+
assert_equal(out_event.delta_time, in_event.delta_time)
|
225
|
+
assert_equal(out_event.time_from_start, in_event.time_from_start)
|
226
|
+
end
|
227
|
+
|
228
|
+
# Last event is a end of track meta event
|
229
|
+
e = in_track.events.last
|
230
|
+
assert(e.is_a?(MIDI::MetaEvent))
|
231
|
+
assert(e.meta_type == MIDI::META_TRACK_END)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Regression test. Running status output when writing a track's events was
|
235
|
+
# broken.
|
236
|
+
def test_running_status_output
|
237
|
+
out_seq = MIDI::Sequence.new
|
238
|
+
out_track = MIDI::Track.new(out_seq)
|
239
|
+
out_seq.tracks << out_track
|
240
|
+
out_track.events << MIDI::Tempo.new(MIDI::Tempo.bpm_to_mpq(120))
|
241
|
+
|
242
|
+
out_track = MIDI::Track.new(out_seq)
|
243
|
+
out_seq.tracks << out_track
|
244
|
+
out_track.events << MIDI::NoteOn.new(0, 65, 127, 100)
|
245
|
+
out_track.events << MIDI::NoteOn.new(0, 65, 0, 100)
|
246
|
+
out_track.events << MIDI::NoteOn.new(0, 65, 0, 100)
|
247
|
+
|
248
|
+
File.open(TEMPFILE, 'wb') { |file| out_seq.write(file) }
|
249
|
+
|
250
|
+
in_seq = MIDI::Sequence.new
|
251
|
+
File.open(TEMPFILE, 'rb') { |file| in_seq.read(file) }
|
252
|
+
in_track = in_seq.tracks[1]
|
253
|
+
|
254
|
+
# Turn the note ons with zero velocity into note offs, and recalc start
|
255
|
+
# times so that time_from_start is correct.
|
256
|
+
[1, 2].each do |i|
|
257
|
+
out_track.events[i] = MIDI::NoteOff.new(0, 65, 64, 100)
|
258
|
+
end
|
259
|
+
out_track.recalc_times # so that start times are correct
|
260
|
+
|
261
|
+
assert_equal(out_track.events.length + 1, in_track.events.length)
|
262
|
+
out_track.events.each_with_index do |event, i|
|
263
|
+
in_event = in_track.events[i]
|
264
|
+
assert_equal(event.data_as_bytes, in_track.events[i].data_as_bytes)
|
265
|
+
assert_equal(event.delta_time, in_track.events[i].delta_time)
|
266
|
+
assert_equal(event.time_from_start, in_track.events[i].time_from_start)
|
267
|
+
end
|
268
|
+
|
269
|
+
# Last event is a end of track meta event
|
270
|
+
e = in_track.events.last
|
271
|
+
assert(e.is_a?(MIDI::MetaEvent))
|
272
|
+
assert(e.meta_type == MIDI::META_TRACK_END)
|
273
|
+
end
|
169
274
|
end
|
data/test/test_mergesort.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
|
-
# Start looking for MIDI classes in the directory above this one.
|
2
|
-
# This forces us to use the local copy of MIDI, even if there is
|
3
|
-
# a previously installed version out there somewhere.
|
4
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
-
|
6
1
|
require 'test/unit'
|
7
|
-
|
2
|
+
require_relative '../lib/midilib/mergesort'
|
8
3
|
|
9
4
|
class MergesortTester < Test::Unit::TestCase
|
10
5
|
def test_mergesort
|
data/test/test_midifile.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
|
-
# Start looking for MIDI classes in the directory above this one.
|
2
|
-
# This forces us to use the local copy of MIDI, even if there is
|
3
|
-
# a previously installed version out there somewhere.
|
4
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
-
|
6
1
|
require 'test/unit'
|
7
2
|
require 'stringio'
|
8
|
-
|
3
|
+
require_relative '../lib/midilib'
|
9
4
|
|
10
5
|
class MIDI::IO::MIDIFile
|
11
6
|
attr_writer :io
|
data/test/test_sequence.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
|
-
# Start looking for MIDI classes in the directory above this one.
|
2
|
-
# This forces us to use the local copy of MIDI, even if there is
|
3
|
-
# a previously installed version out there somewhere.
|
4
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
-
|
6
1
|
require 'test/unit'
|
7
|
-
|
2
|
+
require_relative '../lib/midilib'
|
8
3
|
|
9
4
|
class SequenceTester < Test::Unit::TestCase
|
10
5
|
def setup
|
data/test/test_track.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
|
-
# Start looking for MIDI classes in the directory above this one.
|
2
|
-
# This forces us to use the local copy of MIDI, even if there is
|
3
|
-
# a previously installed version out there somewhere.
|
4
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
-
|
6
1
|
require 'test/unit'
|
7
|
-
|
2
|
+
require_relative '../lib/midilib'
|
8
3
|
|
9
4
|
class TrackTester < Test::Unit::TestCase
|
10
5
|
def setup
|
data/test/test_varlen.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
|
-
# Start looking for MIDI classes in the directory above this one.
|
2
|
-
# This forces us to use the local copy of MIDI, even if there is
|
3
|
-
# a previously installed version out there somewhere.
|
4
|
-
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
-
|
6
1
|
require 'test/unit'
|
7
|
-
|
2
|
+
require_relative '../lib/midilib'
|
8
3
|
|
9
4
|
class VarLenTester < Test::Unit::TestCase
|
10
5
|
VAR_LEN_TEST_DATA = {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: midilib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Menard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
midilib is a pure Ruby MIDI library useful for reading and
|
@@ -79,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
version: '0'
|
80
80
|
requirements:
|
81
81
|
- none
|
82
|
-
rubygems_version: 3.4.
|
82
|
+
rubygems_version: 3.4.17
|
83
83
|
signing_key:
|
84
84
|
specification_version: 4
|
85
85
|
summary: MIDI file and event manipulation library
|