midilib 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (252) hide show
  1. data/ChangeLog +87 -0
  2. data/Credits +8 -0
  3. data/README +361 -0
  4. data/Rakefile +68 -0
  5. data/TODO +25 -0
  6. data/examples/NoFences.mid +0 -0
  7. data/examples/from_scratch.mid +0 -0
  8. data/examples/from_scratch.rb +56 -0
  9. data/examples/reader2text.rb +220 -0
  10. data/examples/seq2text.rb +41 -0
  11. data/examples/strings.rb +34 -0
  12. data/examples/transpose.rb +75 -0
  13. data/html/classes/MIDI.html +738 -0
  14. data/html/classes/MIDI/ActiveSense.html +156 -0
  15. data/html/classes/MIDI/ActiveSense.src/M000136.html +18 -0
  16. data/html/classes/MIDI/ActiveSense.src/M000137.html +18 -0
  17. data/html/classes/MIDI/ChannelEvent.html +179 -0
  18. data/html/classes/MIDI/ChannelEvent.src/M000124.html +20 -0
  19. data/html/classes/MIDI/ChannelEvent.src/M000125.html +18 -0
  20. data/html/classes/MIDI/ChannelPressure.html +184 -0
  21. data/html/classes/MIDI/ChannelPressure.src/M000088.html +19 -0
  22. data/html/classes/MIDI/ChannelPressure.src/M000089.html +21 -0
  23. data/html/classes/MIDI/ChannelPressure.src/M000090.html +18 -0
  24. data/html/classes/MIDI/Clock.html +156 -0
  25. data/html/classes/MIDI/Clock.src/M000134.html +18 -0
  26. data/html/classes/MIDI/Clock.src/M000135.html +18 -0
  27. data/html/classes/MIDI/Continue.html +156 -0
  28. data/html/classes/MIDI/Continue.src/M000132.html +18 -0
  29. data/html/classes/MIDI/Continue.src/M000133.html +18 -0
  30. data/html/classes/MIDI/Controller.html +189 -0
  31. data/html/classes/MIDI/Controller.src/M000129.html +21 -0
  32. data/html/classes/MIDI/Controller.src/M000130.html +22 -0
  33. data/html/classes/MIDI/Controller.src/M000131.html +18 -0
  34. data/html/classes/MIDI/Event.html +424 -0
  35. data/html/classes/MIDI/Event.src/M000145.html +27 -0
  36. data/html/classes/MIDI/Event.src/M000146.html +18 -0
  37. data/html/classes/MIDI/Event.src/M000147.html +18 -0
  38. data/html/classes/MIDI/Event.src/M000148.html +18 -0
  39. data/html/classes/MIDI/Event.src/M000149.html +18 -0
  40. data/html/classes/MIDI/Event.src/M000150.html +18 -0
  41. data/html/classes/MIDI/Event.src/M000151.html +18 -0
  42. data/html/classes/MIDI/Event.src/M000152.html +18 -0
  43. data/html/classes/MIDI/Event.src/M000153.html +18 -0
  44. data/html/classes/MIDI/Event.src/M000154.html +22 -0
  45. data/html/classes/MIDI/Event.src/M000155.html +18 -0
  46. data/html/classes/MIDI/Event.src/M000156.html +18 -0
  47. data/html/classes/MIDI/Event.src/M000157.html +18 -0
  48. data/html/classes/MIDI/IO.html +121 -0
  49. data/html/classes/MIDI/IO/MIDIFile.html +925 -0
  50. data/html/classes/MIDI/IO/MIDIFile.src/M000028.html +22 -0
  51. data/html/classes/MIDI/IO/MIDIFile.src/M000029.html +24 -0
  52. data/html/classes/MIDI/IO/MIDIFile.src/M000030.html +19 -0
  53. data/html/classes/MIDI/IO/MIDIFile.src/M000031.html +19 -0
  54. data/html/classes/MIDI/IO/MIDIFile.src/M000032.html +17 -0
  55. data/html/classes/MIDI/IO/MIDIFile.src/M000033.html +17 -0
  56. data/html/classes/MIDI/IO/MIDIFile.src/M000034.html +17 -0
  57. data/html/classes/MIDI/IO/MIDIFile.src/M000035.html +17 -0
  58. data/html/classes/MIDI/IO/MIDIFile.src/M000036.html +17 -0
  59. data/html/classes/MIDI/IO/MIDIFile.src/M000037.html +17 -0
  60. data/html/classes/MIDI/IO/MIDIFile.src/M000038.html +17 -0
  61. data/html/classes/MIDI/IO/MIDIFile.src/M000039.html +17 -0
  62. data/html/classes/MIDI/IO/MIDIFile.src/M000040.html +17 -0
  63. data/html/classes/MIDI/IO/MIDIFile.src/M000041.html +17 -0
  64. data/html/classes/MIDI/IO/MIDIFile.src/M000042.html +17 -0
  65. data/html/classes/MIDI/IO/MIDIFile.src/M000043.html +17 -0
  66. data/html/classes/MIDI/IO/MIDIFile.src/M000044.html +17 -0
  67. data/html/classes/MIDI/IO/MIDIFile.src/M000045.html +17 -0
  68. data/html/classes/MIDI/IO/MIDIFile.src/M000046.html +17 -0
  69. data/html/classes/MIDI/IO/MIDIFile.src/M000047.html +17 -0
  70. data/html/classes/MIDI/IO/MIDIFile.src/M000048.html +17 -0
  71. data/html/classes/MIDI/IO/MIDIFile.src/M000049.html +17 -0
  72. data/html/classes/MIDI/IO/MIDIFile.src/M000050.html +17 -0
  73. data/html/classes/MIDI/IO/MIDIFile.src/M000051.html +17 -0
  74. data/html/classes/MIDI/IO/MIDIFile.src/M000052.html +17 -0
  75. data/html/classes/MIDI/IO/MIDIFile.src/M000053.html +43 -0
  76. data/html/classes/MIDI/IO/MIDIFile.src/M000054.html +34 -0
  77. data/html/classes/MIDI/IO/MIDIFile.src/M000055.html +96 -0
  78. data/html/classes/MIDI/IO/MIDIFile.src/M000056.html +18 -0
  79. data/html/classes/MIDI/IO/MIDIFile.src/M000057.html +48 -0
  80. data/html/classes/MIDI/IO/MIDIFile.src/M000058.html +42 -0
  81. data/html/classes/MIDI/IO/MIDIFile.src/M000059.html +19 -0
  82. data/html/classes/MIDI/IO/MIDIFile.src/M000060.html +19 -0
  83. data/html/classes/MIDI/IO/MIDIFile.src/M000061.html +20 -0
  84. data/html/classes/MIDI/IO/MIDIFile.src/M000062.html +21 -0
  85. data/html/classes/MIDI/IO/MIDIFile.src/M000063.html +31 -0
  86. data/html/classes/MIDI/IO/MIDIFile.src/M000064.html +20 -0
  87. data/html/classes/MIDI/IO/MIDIFile.src/M000065.html +22 -0
  88. data/html/classes/MIDI/IO/MIDIFile.src/M000066.html +30 -0
  89. data/html/classes/MIDI/IO/MIDIFile.src/M000067.html +18 -0
  90. data/html/classes/MIDI/IO/MIDIFile.src/M000068.html +20 -0
  91. data/html/classes/MIDI/IO/MIDIFile.src/M000069.html +18 -0
  92. data/html/classes/MIDI/IO/MIDIFile.src/M000070.html +18 -0
  93. data/html/classes/MIDI/IO/SeqReader.html +460 -0
  94. data/html/classes/MIDI/IO/SeqReader.src/M000001.html +22 -0
  95. data/html/classes/MIDI/IO/SeqReader.src/M000002.html +22 -0
  96. data/html/classes/MIDI/IO/SeqReader.src/M000003.html +21 -0
  97. data/html/classes/MIDI/IO/SeqReader.src/M000004.html +34 -0
  98. data/html/classes/MIDI/IO/SeqReader.src/M000005.html +26 -0
  99. data/html/classes/MIDI/IO/SeqReader.src/M000006.html +28 -0
  100. data/html/classes/MIDI/IO/SeqReader.src/M000007.html +21 -0
  101. data/html/classes/MIDI/IO/SeqReader.src/M000008.html +19 -0
  102. data/html/classes/MIDI/IO/SeqReader.src/M000009.html +19 -0
  103. data/html/classes/MIDI/IO/SeqReader.src/M000010.html +19 -0
  104. data/html/classes/MIDI/IO/SeqReader.src/M000011.html +19 -0
  105. data/html/classes/MIDI/IO/SeqReader.src/M000012.html +19 -0
  106. data/html/classes/MIDI/IO/SeqReader.src/M000013.html +18 -0
  107. data/html/classes/MIDI/IO/SeqReader.src/M000014.html +18 -0
  108. data/html/classes/MIDI/IO/SeqReader.src/M000015.html +27 -0
  109. data/html/classes/MIDI/IO/SeqReader.src/M000016.html +18 -0
  110. data/html/classes/MIDI/IO/SeqReader.src/M000017.html +18 -0
  111. data/html/classes/MIDI/IO/SeqReader.src/M000018.html +18 -0
  112. data/html/classes/MIDI/IO/SeqWriter.html +267 -0
  113. data/html/classes/MIDI/IO/SeqWriter.src/M000019.html +19 -0
  114. data/html/classes/MIDI/IO/SeqWriter.src/M000020.html +25 -0
  115. data/html/classes/MIDI/IO/SeqWriter.src/M000021.html +22 -0
  116. data/html/classes/MIDI/IO/SeqWriter.src/M000022.html +54 -0
  117. data/html/classes/MIDI/IO/SeqWriter.src/M000023.html +49 -0
  118. data/html/classes/MIDI/IO/SeqWriter.src/M000024.html +21 -0
  119. data/html/classes/MIDI/IO/SeqWriter.src/M000025.html +19 -0
  120. data/html/classes/MIDI/IO/SeqWriter.src/M000026.html +24 -0
  121. data/html/classes/MIDI/IO/SeqWriter.src/M000027.html +26 -0
  122. data/html/classes/MIDI/Marker.html +139 -0
  123. data/html/classes/MIDI/Marker.src/M000107.html +18 -0
  124. data/html/classes/MIDI/MetaEvent.html +189 -0
  125. data/html/classes/MIDI/MetaEvent.src/M000167.html +21 -0
  126. data/html/classes/MIDI/MetaEvent.src/M000168.html +23 -0
  127. data/html/classes/MIDI/MetaEvent.src/M000169.html +53 -0
  128. data/html/classes/MIDI/NoteEvent.html +233 -0
  129. data/html/classes/MIDI/NoteEvent.src/M000091.html +21 -0
  130. data/html/classes/MIDI/NoteEvent.src/M000092.html +20 -0
  131. data/html/classes/MIDI/NoteEvent.src/M000093.html +18 -0
  132. data/html/classes/MIDI/NoteEvent.src/M000094.html +22 -0
  133. data/html/classes/MIDI/NoteOffEvent.html +169 -0
  134. data/html/classes/MIDI/NoteOffEvent.src/M000086.html +19 -0
  135. data/html/classes/MIDI/NoteOffEvent.src/M000087.html +19 -0
  136. data/html/classes/MIDI/NoteOnEvent.html +169 -0
  137. data/html/classes/MIDI/NoteOnEvent.src/M000102.html +19 -0
  138. data/html/classes/MIDI/NoteOnEvent.src/M000103.html +19 -0
  139. data/html/classes/MIDI/PitchBend.html +184 -0
  140. data/html/classes/MIDI/PitchBend.src/M000104.html +19 -0
  141. data/html/classes/MIDI/PitchBend.src/M000105.html +22 -0
  142. data/html/classes/MIDI/PitchBend.src/M000106.html +18 -0
  143. data/html/classes/MIDI/PolyPressure.html +186 -0
  144. data/html/classes/MIDI/PolyPressure.src/M000170.html +18 -0
  145. data/html/classes/MIDI/PolyPressure.src/M000171.html +18 -0
  146. data/html/classes/MIDI/PolyPressure.src/M000172.html +18 -0
  147. data/html/classes/MIDI/PolyPressure.src/M000173.html +19 -0
  148. data/html/classes/MIDI/ProgramChange.html +184 -0
  149. data/html/classes/MIDI/ProgramChange.src/M000099.html +19 -0
  150. data/html/classes/MIDI/ProgramChange.src/M000100.html +21 -0
  151. data/html/classes/MIDI/ProgramChange.src/M000101.html +18 -0
  152. data/html/classes/MIDI/Realtime.html +171 -0
  153. data/html/classes/MIDI/Realtime.src/M000083.html +19 -0
  154. data/html/classes/MIDI/Realtime.src/M000084.html +20 -0
  155. data/html/classes/MIDI/Realtime.src/M000085.html +18 -0
  156. data/html/classes/MIDI/Sequence.html +469 -0
  157. data/html/classes/MIDI/Sequence.src/M000108.html +28 -0
  158. data/html/classes/MIDI/Sequence.src/M000109.html +21 -0
  159. data/html/classes/MIDI/Sequence.src/M000110.html +22 -0
  160. data/html/classes/MIDI/Sequence.src/M000113.html +18 -0
  161. data/html/classes/MIDI/Sequence.src/M000114.html +27 -0
  162. data/html/classes/MIDI/Sequence.src/M000115.html +18 -0
  163. data/html/classes/MIDI/Sequence.src/M000116.html +19 -0
  164. data/html/classes/MIDI/Sequence.src/M000117.html +19 -0
  165. data/html/classes/MIDI/Sequence.src/M000118.html +20 -0
  166. data/html/classes/MIDI/Sequence.src/M000119.html +19 -0
  167. data/html/classes/MIDI/Sequence.src/M000120.html +18 -0
  168. data/html/classes/MIDI/SongPointer.html +184 -0
  169. data/html/classes/MIDI/SongPointer.src/M000138.html +19 -0
  170. data/html/classes/MIDI/SongPointer.src/M000139.html +22 -0
  171. data/html/classes/MIDI/SongPointer.src/M000140.html +18 -0
  172. data/html/classes/MIDI/SongSelect.html +184 -0
  173. data/html/classes/MIDI/SongSelect.src/M000126.html +19 -0
  174. data/html/classes/MIDI/SongSelect.src/M000127.html +21 -0
  175. data/html/classes/MIDI/SongSelect.src/M000128.html +18 -0
  176. data/html/classes/MIDI/Start.html +156 -0
  177. data/html/classes/MIDI/Start.src/M000097.html +18 -0
  178. data/html/classes/MIDI/Start.src/M000098.html +18 -0
  179. data/html/classes/MIDI/Stop.html +156 -0
  180. data/html/classes/MIDI/Stop.src/M000095.html +18 -0
  181. data/html/classes/MIDI/Stop.src/M000096.html +18 -0
  182. data/html/classes/MIDI/SystemCommon.html +139 -0
  183. data/html/classes/MIDI/SystemCommon.src/M000144.html +19 -0
  184. data/html/classes/MIDI/SystemExclusive.html +184 -0
  185. data/html/classes/MIDI/SystemExclusive.src/M000141.html +19 -0
  186. data/html/classes/MIDI/SystemExclusive.src/M000142.html +23 -0
  187. data/html/classes/MIDI/SystemExclusive.src/M000143.html +18 -0
  188. data/html/classes/MIDI/SystemReset.html +156 -0
  189. data/html/classes/MIDI/SystemReset.src/M000081.html +18 -0
  190. data/html/classes/MIDI/SystemReset.src/M000082.html +18 -0
  191. data/html/classes/MIDI/Tempo.html +250 -0
  192. data/html/classes/MIDI/Tempo.src/M000158.html +18 -0
  193. data/html/classes/MIDI/Tempo.src/M000159.html +18 -0
  194. data/html/classes/MIDI/Tempo.src/M000160.html +18 -0
  195. data/html/classes/MIDI/Tempo.src/M000161.html +18 -0
  196. data/html/classes/MIDI/Tempo.src/M000162.html +18 -0
  197. data/html/classes/MIDI/Tempo.src/M000163.html +25 -0
  198. data/html/classes/MIDI/Tempo.src/M000164.html +18 -0
  199. data/html/classes/MIDI/Track.html +380 -0
  200. data/html/classes/MIDI/Track.src/M000071.html +23 -0
  201. data/html/classes/MIDI/Track.src/M000072.html +21 -0
  202. data/html/classes/MIDI/Track.src/M000073.html +26 -0
  203. data/html/classes/MIDI/Track.src/M000074.html +18 -0
  204. data/html/classes/MIDI/Track.src/M000075.html +22 -0
  205. data/html/classes/MIDI/Track.src/M000076.html +20 -0
  206. data/html/classes/MIDI/Track.src/M000077.html +22 -0
  207. data/html/classes/MIDI/Track.src/M000078.html +22 -0
  208. data/html/classes/MIDI/Track.src/M000079.html +18 -0
  209. data/html/classes/MIDI/Track.src/M000080.html +19 -0
  210. data/html/classes/MIDI/TuneRequest.html +171 -0
  211. data/html/classes/MIDI/TuneRequest.src/M000121.html +18 -0
  212. data/html/classes/MIDI/TuneRequest.src/M000122.html +20 -0
  213. data/html/classes/MIDI/TuneRequest.src/M000123.html +18 -0
  214. data/html/classes/MIDI/Utils.html +190 -0
  215. data/html/classes/MIDI/Utils.src/M000165.html +20 -0
  216. data/html/classes/MIDI/Utils.src/M000166.html +25 -0
  217. data/html/created.rid +1 -0
  218. data/html/files/README.html +599 -0
  219. data/html/files/TODO.html +142 -0
  220. data/html/files/lib/midilib/consts_rb.html +107 -0
  221. data/html/files/lib/midilib/event_rb.html +109 -0
  222. data/html/files/lib/midilib/info_rb.html +101 -0
  223. data/html/files/lib/midilib/io/midifile_rb.html +108 -0
  224. data/html/files/lib/midilib/io/seqreader_rb.html +110 -0
  225. data/html/files/lib/midilib/io/seqwriter_rb.html +115 -0
  226. data/html/files/lib/midilib/sequence_rb.html +109 -0
  227. data/html/files/lib/midilib/track_rb.html +108 -0
  228. data/html/files/lib/midilib/utils_rb.html +101 -0
  229. data/html/files/lib/midilib_rb.html +124 -0
  230. data/html/fr_class_index.html +59 -0
  231. data/html/fr_file_index.html +38 -0
  232. data/html/fr_method_index.html +199 -0
  233. data/html/index.html +24 -0
  234. data/html/rdoc-style.css +208 -0
  235. data/install.rb +57 -0
  236. data/lib/midilib.rb +16 -0
  237. data/lib/midilib/consts.rb +422 -0
  238. data/lib/midilib/event.rb +559 -0
  239. data/lib/midilib/info.rb +9 -0
  240. data/lib/midilib/io/midifile.rb +446 -0
  241. data/lib/midilib/io/seqreader.rb +198 -0
  242. data/lib/midilib/io/seqwriter.rb +151 -0
  243. data/lib/midilib/sequence.rb +144 -0
  244. data/lib/midilib/track.rb +115 -0
  245. data/lib/midilib/utils.rb +36 -0
  246. data/test/event_equality.rb +81 -0
  247. data/test/test_event.rb +116 -0
  248. data/test/test_io.rb +55 -0
  249. data/test/test_sequence.rb +68 -0
  250. data/test/test_track.rb +111 -0
  251. data/test/test_varlen.rb +40 -0
  252. 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
+ }
@@ -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
+ }