midilib 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +87 -0
- data/Credits +8 -0
- data/README +361 -0
- data/Rakefile +68 -0
- data/TODO +25 -0
- data/examples/NoFences.mid +0 -0
- data/examples/from_scratch.mid +0 -0
- data/examples/from_scratch.rb +56 -0
- data/examples/reader2text.rb +220 -0
- data/examples/seq2text.rb +41 -0
- data/examples/strings.rb +34 -0
- data/examples/transpose.rb +75 -0
- data/html/classes/MIDI.html +738 -0
- data/html/classes/MIDI/ActiveSense.html +156 -0
- data/html/classes/MIDI/ActiveSense.src/M000136.html +18 -0
- data/html/classes/MIDI/ActiveSense.src/M000137.html +18 -0
- data/html/classes/MIDI/ChannelEvent.html +179 -0
- data/html/classes/MIDI/ChannelEvent.src/M000124.html +20 -0
- data/html/classes/MIDI/ChannelEvent.src/M000125.html +18 -0
- data/html/classes/MIDI/ChannelPressure.html +184 -0
- data/html/classes/MIDI/ChannelPressure.src/M000088.html +19 -0
- data/html/classes/MIDI/ChannelPressure.src/M000089.html +21 -0
- data/html/classes/MIDI/ChannelPressure.src/M000090.html +18 -0
- data/html/classes/MIDI/Clock.html +156 -0
- data/html/classes/MIDI/Clock.src/M000134.html +18 -0
- data/html/classes/MIDI/Clock.src/M000135.html +18 -0
- data/html/classes/MIDI/Continue.html +156 -0
- data/html/classes/MIDI/Continue.src/M000132.html +18 -0
- data/html/classes/MIDI/Continue.src/M000133.html +18 -0
- data/html/classes/MIDI/Controller.html +189 -0
- data/html/classes/MIDI/Controller.src/M000129.html +21 -0
- data/html/classes/MIDI/Controller.src/M000130.html +22 -0
- data/html/classes/MIDI/Controller.src/M000131.html +18 -0
- data/html/classes/MIDI/Event.html +424 -0
- data/html/classes/MIDI/Event.src/M000145.html +27 -0
- data/html/classes/MIDI/Event.src/M000146.html +18 -0
- data/html/classes/MIDI/Event.src/M000147.html +18 -0
- data/html/classes/MIDI/Event.src/M000148.html +18 -0
- data/html/classes/MIDI/Event.src/M000149.html +18 -0
- data/html/classes/MIDI/Event.src/M000150.html +18 -0
- data/html/classes/MIDI/Event.src/M000151.html +18 -0
- data/html/classes/MIDI/Event.src/M000152.html +18 -0
- data/html/classes/MIDI/Event.src/M000153.html +18 -0
- data/html/classes/MIDI/Event.src/M000154.html +22 -0
- data/html/classes/MIDI/Event.src/M000155.html +18 -0
- data/html/classes/MIDI/Event.src/M000156.html +18 -0
- data/html/classes/MIDI/Event.src/M000157.html +18 -0
- data/html/classes/MIDI/IO.html +121 -0
- data/html/classes/MIDI/IO/MIDIFile.html +925 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000028.html +22 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000029.html +24 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000030.html +19 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000031.html +19 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000032.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000033.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000034.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000035.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000036.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000037.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000038.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000039.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000040.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000041.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000042.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000043.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000044.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000045.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000046.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000047.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000048.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000049.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000050.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000051.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000052.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000053.html +43 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000054.html +34 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000055.html +96 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000056.html +18 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000057.html +48 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000058.html +42 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000059.html +19 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000060.html +19 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000061.html +20 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000062.html +21 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000063.html +31 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000064.html +20 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000065.html +22 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000066.html +30 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000067.html +18 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000068.html +20 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000069.html +18 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000070.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.html +460 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000001.html +22 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000002.html +22 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000003.html +21 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000004.html +34 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000005.html +26 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000006.html +28 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000007.html +21 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000008.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000009.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000010.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000011.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000012.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000013.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000014.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000015.html +27 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000016.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000017.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000018.html +18 -0
- data/html/classes/MIDI/IO/SeqWriter.html +267 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000019.html +19 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000020.html +25 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000021.html +22 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000022.html +54 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000023.html +49 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000024.html +21 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000025.html +19 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000026.html +24 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000027.html +26 -0
- data/html/classes/MIDI/Marker.html +139 -0
- data/html/classes/MIDI/Marker.src/M000107.html +18 -0
- data/html/classes/MIDI/MetaEvent.html +189 -0
- data/html/classes/MIDI/MetaEvent.src/M000167.html +21 -0
- data/html/classes/MIDI/MetaEvent.src/M000168.html +23 -0
- data/html/classes/MIDI/MetaEvent.src/M000169.html +53 -0
- data/html/classes/MIDI/NoteEvent.html +233 -0
- data/html/classes/MIDI/NoteEvent.src/M000091.html +21 -0
- data/html/classes/MIDI/NoteEvent.src/M000092.html +20 -0
- data/html/classes/MIDI/NoteEvent.src/M000093.html +18 -0
- data/html/classes/MIDI/NoteEvent.src/M000094.html +22 -0
- data/html/classes/MIDI/NoteOffEvent.html +169 -0
- data/html/classes/MIDI/NoteOffEvent.src/M000086.html +19 -0
- data/html/classes/MIDI/NoteOffEvent.src/M000087.html +19 -0
- data/html/classes/MIDI/NoteOnEvent.html +169 -0
- data/html/classes/MIDI/NoteOnEvent.src/M000102.html +19 -0
- data/html/classes/MIDI/NoteOnEvent.src/M000103.html +19 -0
- data/html/classes/MIDI/PitchBend.html +184 -0
- data/html/classes/MIDI/PitchBend.src/M000104.html +19 -0
- data/html/classes/MIDI/PitchBend.src/M000105.html +22 -0
- data/html/classes/MIDI/PitchBend.src/M000106.html +18 -0
- data/html/classes/MIDI/PolyPressure.html +186 -0
- data/html/classes/MIDI/PolyPressure.src/M000170.html +18 -0
- data/html/classes/MIDI/PolyPressure.src/M000171.html +18 -0
- data/html/classes/MIDI/PolyPressure.src/M000172.html +18 -0
- data/html/classes/MIDI/PolyPressure.src/M000173.html +19 -0
- data/html/classes/MIDI/ProgramChange.html +184 -0
- data/html/classes/MIDI/ProgramChange.src/M000099.html +19 -0
- data/html/classes/MIDI/ProgramChange.src/M000100.html +21 -0
- data/html/classes/MIDI/ProgramChange.src/M000101.html +18 -0
- data/html/classes/MIDI/Realtime.html +171 -0
- data/html/classes/MIDI/Realtime.src/M000083.html +19 -0
- data/html/classes/MIDI/Realtime.src/M000084.html +20 -0
- data/html/classes/MIDI/Realtime.src/M000085.html +18 -0
- data/html/classes/MIDI/Sequence.html +469 -0
- data/html/classes/MIDI/Sequence.src/M000108.html +28 -0
- data/html/classes/MIDI/Sequence.src/M000109.html +21 -0
- data/html/classes/MIDI/Sequence.src/M000110.html +22 -0
- data/html/classes/MIDI/Sequence.src/M000113.html +18 -0
- data/html/classes/MIDI/Sequence.src/M000114.html +27 -0
- data/html/classes/MIDI/Sequence.src/M000115.html +18 -0
- data/html/classes/MIDI/Sequence.src/M000116.html +19 -0
- data/html/classes/MIDI/Sequence.src/M000117.html +19 -0
- data/html/classes/MIDI/Sequence.src/M000118.html +20 -0
- data/html/classes/MIDI/Sequence.src/M000119.html +19 -0
- data/html/classes/MIDI/Sequence.src/M000120.html +18 -0
- data/html/classes/MIDI/SongPointer.html +184 -0
- data/html/classes/MIDI/SongPointer.src/M000138.html +19 -0
- data/html/classes/MIDI/SongPointer.src/M000139.html +22 -0
- data/html/classes/MIDI/SongPointer.src/M000140.html +18 -0
- data/html/classes/MIDI/SongSelect.html +184 -0
- data/html/classes/MIDI/SongSelect.src/M000126.html +19 -0
- data/html/classes/MIDI/SongSelect.src/M000127.html +21 -0
- data/html/classes/MIDI/SongSelect.src/M000128.html +18 -0
- data/html/classes/MIDI/Start.html +156 -0
- data/html/classes/MIDI/Start.src/M000097.html +18 -0
- data/html/classes/MIDI/Start.src/M000098.html +18 -0
- data/html/classes/MIDI/Stop.html +156 -0
- data/html/classes/MIDI/Stop.src/M000095.html +18 -0
- data/html/classes/MIDI/Stop.src/M000096.html +18 -0
- data/html/classes/MIDI/SystemCommon.html +139 -0
- data/html/classes/MIDI/SystemCommon.src/M000144.html +19 -0
- data/html/classes/MIDI/SystemExclusive.html +184 -0
- data/html/classes/MIDI/SystemExclusive.src/M000141.html +19 -0
- data/html/classes/MIDI/SystemExclusive.src/M000142.html +23 -0
- data/html/classes/MIDI/SystemExclusive.src/M000143.html +18 -0
- data/html/classes/MIDI/SystemReset.html +156 -0
- data/html/classes/MIDI/SystemReset.src/M000081.html +18 -0
- data/html/classes/MIDI/SystemReset.src/M000082.html +18 -0
- data/html/classes/MIDI/Tempo.html +250 -0
- data/html/classes/MIDI/Tempo.src/M000158.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000159.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000160.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000161.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000162.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000163.html +25 -0
- data/html/classes/MIDI/Tempo.src/M000164.html +18 -0
- data/html/classes/MIDI/Track.html +380 -0
- data/html/classes/MIDI/Track.src/M000071.html +23 -0
- data/html/classes/MIDI/Track.src/M000072.html +21 -0
- data/html/classes/MIDI/Track.src/M000073.html +26 -0
- data/html/classes/MIDI/Track.src/M000074.html +18 -0
- data/html/classes/MIDI/Track.src/M000075.html +22 -0
- data/html/classes/MIDI/Track.src/M000076.html +20 -0
- data/html/classes/MIDI/Track.src/M000077.html +22 -0
- data/html/classes/MIDI/Track.src/M000078.html +22 -0
- data/html/classes/MIDI/Track.src/M000079.html +18 -0
- data/html/classes/MIDI/Track.src/M000080.html +19 -0
- data/html/classes/MIDI/TuneRequest.html +171 -0
- data/html/classes/MIDI/TuneRequest.src/M000121.html +18 -0
- data/html/classes/MIDI/TuneRequest.src/M000122.html +20 -0
- data/html/classes/MIDI/TuneRequest.src/M000123.html +18 -0
- data/html/classes/MIDI/Utils.html +190 -0
- data/html/classes/MIDI/Utils.src/M000165.html +20 -0
- data/html/classes/MIDI/Utils.src/M000166.html +25 -0
- data/html/created.rid +1 -0
- data/html/files/README.html +599 -0
- data/html/files/TODO.html +142 -0
- data/html/files/lib/midilib/consts_rb.html +107 -0
- data/html/files/lib/midilib/event_rb.html +109 -0
- data/html/files/lib/midilib/info_rb.html +101 -0
- data/html/files/lib/midilib/io/midifile_rb.html +108 -0
- data/html/files/lib/midilib/io/seqreader_rb.html +110 -0
- data/html/files/lib/midilib/io/seqwriter_rb.html +115 -0
- data/html/files/lib/midilib/sequence_rb.html +109 -0
- data/html/files/lib/midilib/track_rb.html +108 -0
- data/html/files/lib/midilib/utils_rb.html +101 -0
- data/html/files/lib/midilib_rb.html +124 -0
- data/html/fr_class_index.html +59 -0
- data/html/fr_file_index.html +38 -0
- data/html/fr_method_index.html +199 -0
- data/html/index.html +24 -0
- data/html/rdoc-style.css +208 -0
- data/install.rb +57 -0
- data/lib/midilib.rb +16 -0
- data/lib/midilib/consts.rb +422 -0
- data/lib/midilib/event.rb +559 -0
- data/lib/midilib/info.rb +9 -0
- data/lib/midilib/io/midifile.rb +446 -0
- data/lib/midilib/io/seqreader.rb +198 -0
- data/lib/midilib/io/seqwriter.rb +151 -0
- data/lib/midilib/sequence.rb +144 -0
- data/lib/midilib/track.rb +115 -0
- data/lib/midilib/utils.rb +36 -0
- data/test/event_equality.rb +81 -0
- data/test/test_event.rb +116 -0
- data/test/test_io.rb +55 -0
- data/test/test_sequence.rb +68 -0
- data/test/test_track.rb +111 -0
- data/test/test_varlen.rb +40 -0
- metadata +330 -0
data/Rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require_gem 'rake'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/contrib/rubyforgepublisher'
|
6
|
+
require 'rake/runtest'
|
7
|
+
|
8
|
+
PROJECT_NAME = 'midilib'
|
9
|
+
RUBYFORGE_USER = 'jimm'
|
10
|
+
RDOC_DIR = 'html'
|
11
|
+
|
12
|
+
PKG_FILES = FileList[ 'ChangeLog', 'Credits', 'README', 'Rakefile', 'TODO',
|
13
|
+
'examples/**/*',
|
14
|
+
'html/**/*',
|
15
|
+
'install.rb',
|
16
|
+
'lib/**/*.rb',
|
17
|
+
'test/**/*.rb']
|
18
|
+
|
19
|
+
task :default => [:package]
|
20
|
+
|
21
|
+
spec = Gem::Specification.new do |s|
|
22
|
+
s.platform = Gem::Platform::RUBY
|
23
|
+
s.name = PROJECT_NAME
|
24
|
+
s.version = `ruby -Ilib -e 'require "midilib/info"; puts MIDI::Version'`.strip
|
25
|
+
s.requirements << 'none'
|
26
|
+
|
27
|
+
s.require_path = 'lib'
|
28
|
+
s.autorequire = PROJECT_NAME
|
29
|
+
|
30
|
+
s.files = PKG_FILES.to_a
|
31
|
+
|
32
|
+
s.has_rdoc = true
|
33
|
+
s.rdoc_options << '--main' << 'README'
|
34
|
+
s.extra_rdoc_files = ['README', 'TODO']
|
35
|
+
|
36
|
+
s.author = 'Jim Menard'
|
37
|
+
s.email = 'jimm@io.com'
|
38
|
+
s.homepage = 'http://midilib.rubyforge.org'
|
39
|
+
s.rubyforge_project = PROJECT_NAME
|
40
|
+
|
41
|
+
s.summary = "MIDI file and event manipulation library"
|
42
|
+
s.description = <<EOF
|
43
|
+
midilib is a pure Ruby MIDI library useful for reading and
|
44
|
+
writing standard MIDI files and manipulating MIDI event data.
|
45
|
+
EOF
|
46
|
+
end
|
47
|
+
|
48
|
+
# Creates a :package task (also named :gem). Also useful are :clobber_package
|
49
|
+
# and :repackage.
|
50
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
51
|
+
pkg.need_zip = true
|
52
|
+
pkg.need_tar = true
|
53
|
+
end
|
54
|
+
|
55
|
+
# creates an "rdoc" task
|
56
|
+
Rake::RDocTask.new do | rd |
|
57
|
+
rd.main = 'README'
|
58
|
+
rd.title = PROJECT_NAME
|
59
|
+
rd.rdoc_files.include('README', 'TODO', 'lib/**/*.rb')
|
60
|
+
end
|
61
|
+
|
62
|
+
task :rubyforge => [:rdoc] do
|
63
|
+
Rake::RubyForgePublisher.new(PROJECT_NAME, RUBYFORGE_USER).upload
|
64
|
+
end
|
65
|
+
|
66
|
+
task :test do
|
67
|
+
Rake::run_tests
|
68
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
== Bugs
|
2
|
+
|
3
|
+
* None known.
|
4
|
+
|
5
|
+
== Features
|
6
|
+
|
7
|
+
* Method to translate event's time_from_start to number of milliseconds from
|
8
|
+
start.
|
9
|
+
|
10
|
+
* Swing quantizing. (Implied by list email from Carl Youngblood
|
11
|
+
<carl.youngblood@gmail.com>)
|
12
|
+
|
13
|
+
* Implement key signature in SeqReader.
|
14
|
+
|
15
|
+
* Format 0 files.
|
16
|
+
|
17
|
+
* Format 2 files(?).
|
18
|
+
|
19
|
+
== Documentation
|
20
|
+
|
21
|
+
* Write better docs.
|
22
|
+
|
23
|
+
== Tests
|
24
|
+
|
25
|
+
* More needed?
|
Binary file
|
Binary file
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# usage: from_scratch.rb
|
4
|
+
#
|
5
|
+
# This script shows you how to create a new sequence from scratch and save it
|
6
|
+
# to a MIDI file. It creates a file called 'from_scratch.mid'.
|
7
|
+
|
8
|
+
# Start looking for MIDI module classes in the directory above this one.
|
9
|
+
# This forces us to use the local copy, even if there is a previously
|
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'
|
15
|
+
include MIDI
|
16
|
+
|
17
|
+
seq = Sequence.new()
|
18
|
+
|
19
|
+
# Create a first track for the sequence. This holds tempo events and stuff
|
20
|
+
# like that.
|
21
|
+
track = Track.new(seq)
|
22
|
+
seq.tracks << track
|
23
|
+
track.events << Tempo.new(Tempo.bpm_to_mpq(120))
|
24
|
+
track.events << MetaEvent.new(META_SEQ_NAME, 'Sequence Name')
|
25
|
+
|
26
|
+
# Create a track to hold the notes. Add it to the sequence.
|
27
|
+
track = Track.new(seq)
|
28
|
+
seq.tracks << track
|
29
|
+
|
30
|
+
# Give the track a name and an instrument name (optional).
|
31
|
+
track.name = 'My New Track'
|
32
|
+
track.instrument = GM_PATCH_NAMES[0]
|
33
|
+
|
34
|
+
# Add a volume controller event (optional).
|
35
|
+
track.events << Controller.new(0, CC_VOLUME, 127)
|
36
|
+
|
37
|
+
# Add events to the track: a major scale. Arguments for note on and note off
|
38
|
+
# constructors are channel, note, velocity, and delta_time. Channel numbers
|
39
|
+
# start at zero. We use the new Sequence#note_to_delta method to get the
|
40
|
+
# delta time length of a single quarter note.
|
41
|
+
track.events << ProgramChange.new(0, 1, 0)
|
42
|
+
quarter_note_length = seq.note_to_delta('quarter')
|
43
|
+
[0, 2, 4, 5, 7, 9, 11, 12].each { | offset |
|
44
|
+
track.events << NoteOnEvent.new(0, 64 + offset, 127, 0)
|
45
|
+
track.events << NoteOffEvent.new(0, 64 + offset, 127, quarter_note_length)
|
46
|
+
}
|
47
|
+
|
48
|
+
# Calling recalc_times is not necessary, because that only sets the events'
|
49
|
+
# start times, which are not written out to the MIDI file. The delta times are
|
50
|
+
# what get written out.
|
51
|
+
|
52
|
+
# track.recalc_times
|
53
|
+
|
54
|
+
File.open('from_scratch.mid', 'wb') { | file |
|
55
|
+
seq.write(file)
|
56
|
+
}
|
@@ -0,0 +1,220 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# usage: reader2text.rb [midi_file]
|
4
|
+
#
|
5
|
+
# This script translates a MIDI file into text. It subclasses MIDI::MIDIFile
|
6
|
+
# and overrides the methods that are called when various events are seen
|
7
|
+
# in the file.
|
8
|
+
#
|
9
|
+
# For a simpler way to do the same thing, see seq2text.rb.
|
10
|
+
#
|
11
|
+
|
12
|
+
# Start looking for MIDI module classes in the directory above this one.
|
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'
|
18
|
+
require 'midilib/io/midifile'
|
19
|
+
|
20
|
+
DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
|
21
|
+
|
22
|
+
class TextTranslator < MIDI::IO::MIDIFile
|
23
|
+
|
24
|
+
def initialize(seq, proc = nil)
|
25
|
+
super()
|
26
|
+
@seq = seq
|
27
|
+
@track = nil
|
28
|
+
@update_block = block_given?() ? Proc.new() : proc
|
29
|
+
end
|
30
|
+
|
31
|
+
# Generate a unique number for a channel/note combination. This is used
|
32
|
+
# to remember pending note on events.
|
33
|
+
def note_hash(chan, note)
|
34
|
+
return (chan << 8) + note
|
35
|
+
end
|
36
|
+
|
37
|
+
# Print a delta time.
|
38
|
+
def pdelta
|
39
|
+
print "#{@curr_ticks}: "
|
40
|
+
end
|
41
|
+
|
42
|
+
# The remaining methods are overrides of methods in MIDI::IO::MIDIFile.
|
43
|
+
|
44
|
+
def header(format, ntrks, division)
|
45
|
+
puts "header: format = #{format}, ntrks = #{ntrks}," +
|
46
|
+
" division = #{division}"
|
47
|
+
|
48
|
+
@ntrks = ntrks
|
49
|
+
@update_block.call(nil, @ntrks, 0) if @update_block
|
50
|
+
end
|
51
|
+
|
52
|
+
def start_track()
|
53
|
+
pdelta()
|
54
|
+
puts "track start"
|
55
|
+
|
56
|
+
@pending = []
|
57
|
+
@chan_mask = 0
|
58
|
+
end
|
59
|
+
|
60
|
+
def end_track()
|
61
|
+
pdelta()
|
62
|
+
puts "track end; chans used bitmask = #{@chan_mask}"
|
63
|
+
# Write message for any pending note on messages
|
64
|
+
@pending.each_with_index { | num, chan |
|
65
|
+
puts "pending note off missing for chan #{num >> 8}," +
|
66
|
+
" note #{num & 0xff}" if note_obj
|
67
|
+
}
|
68
|
+
@pending = nil
|
69
|
+
|
70
|
+
# call update block
|
71
|
+
@update_block.call(@track, @ntrks, @seq.tracks.length) if @update_block
|
72
|
+
end
|
73
|
+
|
74
|
+
def note_on(chan, note, vel)
|
75
|
+
pdelta()
|
76
|
+
if vel == 0
|
77
|
+
print "(note on, vel 0) "
|
78
|
+
note_off(chan, note, 64)
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
puts "note on chan #{chan}, note #{note}, vel #{vel}"
|
83
|
+
@pending << note_hash(chan, note)
|
84
|
+
track_uses_channel(chan)
|
85
|
+
end
|
86
|
+
|
87
|
+
def note_off(chan, note, vel)
|
88
|
+
pdelta()
|
89
|
+
# Find note on, create note off, connect the two, and remove
|
90
|
+
# note on from pending list.
|
91
|
+
pnum = note_hash(chan, note)
|
92
|
+
@pending.each_with_index { | num, i |
|
93
|
+
if pnum == num
|
94
|
+
puts "note off chan #{chan}, note #{note}, vel #{vel}"
|
95
|
+
@pending.delete_at(i)
|
96
|
+
return
|
97
|
+
end
|
98
|
+
}
|
99
|
+
puts "note off with no earlier note on (ch #{chan}, note" +
|
100
|
+
" #{note}, vel #{vel})"
|
101
|
+
end
|
102
|
+
|
103
|
+
def pressure(chan, note, press)
|
104
|
+
pdelta()
|
105
|
+
puts "pressure chan #{chan}, note #{note}, press #{press}"
|
106
|
+
track_uses_channel(chan)
|
107
|
+
end
|
108
|
+
|
109
|
+
def controller(chan, control, value)
|
110
|
+
pdelta()
|
111
|
+
puts "controller chan #{chan}, control #{control}, value #{value}"
|
112
|
+
track_uses_channel(chan)
|
113
|
+
end
|
114
|
+
|
115
|
+
def pitch_bend(chan, msb, lsb)
|
116
|
+
pdelta()
|
117
|
+
puts "pitch bend chan #{chan}, msb #{msb}, lsb #{lsb}"
|
118
|
+
track_uses_channel(chan)
|
119
|
+
end
|
120
|
+
|
121
|
+
def program(chan, program)
|
122
|
+
pdelta()
|
123
|
+
puts "program chan #{chan}, program #{program}"
|
124
|
+
track_uses_channel(chan)
|
125
|
+
end
|
126
|
+
|
127
|
+
def chan_pressure(chan, press)
|
128
|
+
pdelta()
|
129
|
+
puts "chan press chan #{chan}, press #{press}"
|
130
|
+
track_uses_channel(chan)
|
131
|
+
end
|
132
|
+
|
133
|
+
def sysex(msg)
|
134
|
+
pdelta()
|
135
|
+
puts "sysex size #{msg.length}"
|
136
|
+
end
|
137
|
+
|
138
|
+
def meta_misc(type, msg)
|
139
|
+
pdelta()
|
140
|
+
puts "meta misc type #{type}, length #{msg.length}"
|
141
|
+
end
|
142
|
+
|
143
|
+
def sequencer_specific(type, msg)
|
144
|
+
pdelta()
|
145
|
+
puts "sequencer specific type #{type}, msg #{msg.length}"
|
146
|
+
end
|
147
|
+
|
148
|
+
def sequence_number(num)
|
149
|
+
pdelta()
|
150
|
+
puts "sequence number #{num}"
|
151
|
+
end
|
152
|
+
|
153
|
+
def text(type, msg)
|
154
|
+
pdelta()
|
155
|
+
case type
|
156
|
+
when MIDI::META_SEQ_NAME
|
157
|
+
puts "seq or track name #{msg}"
|
158
|
+
when MIDI::META_INSTRUMENT
|
159
|
+
puts "instrument name #{msg}"
|
160
|
+
when MIDI::META_MARKER
|
161
|
+
puts "marker #{msg}"
|
162
|
+
else
|
163
|
+
puts "text = #{msg}, type = #{type}"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def eot()
|
168
|
+
pdelta()
|
169
|
+
puts "end of track event"
|
170
|
+
end
|
171
|
+
|
172
|
+
def time_signature(numer, denom, clocks, qnotes)
|
173
|
+
pdelta()
|
174
|
+
puts "time sig numer #{numer}, denom #{denom}, clocks #{clocks}," +
|
175
|
+
" qnotes #{qnotes}"
|
176
|
+
end
|
177
|
+
|
178
|
+
def smpte(hour, min, sec, frame, fract)
|
179
|
+
pdelta()
|
180
|
+
puts "smpte #{hour}:#{min}.#{sec}, frame #{frame}, fract #{fract}"
|
181
|
+
end
|
182
|
+
|
183
|
+
def tempo(microsecs)
|
184
|
+
pdelta()
|
185
|
+
bpm = 1.0 / microsecs # quarter notes per microsecond
|
186
|
+
bpm *= 1000000.0 # quarter notes per second
|
187
|
+
bpm *= 60.0 # quarter notes per minute
|
188
|
+
puts "tempo microsecs pqn = #{microsecs} (#{bpm} bpm)"
|
189
|
+
end
|
190
|
+
|
191
|
+
def key_signature(sharpflat, is_minor)
|
192
|
+
pdelta()
|
193
|
+
puts "key sig sharpflat #{sharpflat}, is_minor #{is_minor}"
|
194
|
+
end
|
195
|
+
|
196
|
+
def arbitrary(msg)
|
197
|
+
pdelta()
|
198
|
+
puts "arbitrary length = #{msg.length}"
|
199
|
+
end
|
200
|
+
|
201
|
+
def track_uses_channel(chan)
|
202
|
+
@chan_mask = @chan_mask | (1 << chan)
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
# ================================================================
|
208
|
+
|
209
|
+
seq = MIDI::Sequence.new()
|
210
|
+
|
211
|
+
# Specify what class to use when reading the MIDI file.
|
212
|
+
seq.reader_class = TextTranslator
|
213
|
+
|
214
|
+
File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') { | file |
|
215
|
+
# The block we pass in to Sequence.read is called at the end of every
|
216
|
+
# track read. It is optional, but is useful for progress reports.
|
217
|
+
seq.read(file) { | track, num_tracks, i |
|
218
|
+
puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
|
219
|
+
}
|
220
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# usage: seq2text.rb [midi_file]
|
4
|
+
#
|
5
|
+
# This script translates a MIDI file into text. It reads the file into
|
6
|
+
# a MIDI::Sequence and calls to_s for each event.
|
7
|
+
#
|
8
|
+
# For a different (and more verbose) way to do the same thing, see
|
9
|
+
# reader2tex.rb.
|
10
|
+
#
|
11
|
+
|
12
|
+
# Start looking for MIDI module classes in the directory above this one.
|
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'
|
18
|
+
|
19
|
+
DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
|
20
|
+
|
21
|
+
# Read from MIDI file
|
22
|
+
seq = MIDI::Sequence.new()
|
23
|
+
|
24
|
+
File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') { | file |
|
25
|
+
# The block we pass in to Sequence.read is called at the end of every
|
26
|
+
# track read. It is optional, but is useful for progress reports.
|
27
|
+
seq.read(file) { | track, num_tracks, i |
|
28
|
+
puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
seq.each { | track |
|
33
|
+
puts "*** track name \"#{track.name}\""
|
34
|
+
puts "instrument name \"#{track.instrument}\""
|
35
|
+
puts "#{track.events.length} events"
|
36
|
+
track.each { | e |
|
37
|
+
e.print_decimal_numbers = true # default = false (print hex)
|
38
|
+
e.print_note_names = true # default = false (print note numbers)
|
39
|
+
puts e
|
40
|
+
}
|
41
|
+
}
|
data/examples/strings.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# usage: strings.rb [midi_file]
|
4
|
+
#
|
5
|
+
# Prints all strings (track names, etc.) found in the MIDI file.
|
6
|
+
#
|
7
|
+
|
8
|
+
# Start looking for MIDI module classes in the directory above this one.
|
9
|
+
# This forces us to use the local copy, even if there is a previously
|
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'
|
15
|
+
|
16
|
+
DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
|
17
|
+
|
18
|
+
seq = MIDI::Sequence.new()
|
19
|
+
File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') { | file |
|
20
|
+
# The block we pass in to Sequence.read is called at the end of every
|
21
|
+
# track read. It is optional, but is useful for progress reports.
|
22
|
+
seq.read(file) { | track, num_tracks, i |
|
23
|
+
puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
include MIDI
|
28
|
+
seq.each { | track |
|
29
|
+
track.each { | event |
|
30
|
+
puts event.data if event.meta? &&
|
31
|
+
[META_TEXT, META_COPYRIGHT, META_SEQ_NAME, META_INSTRUMENT,
|
32
|
+
META_LYRIC, META_CUE, META_MARKER].include?(event.meta_type)
|
33
|
+
}
|
34
|
+
}
|