midilib 0.8.4

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.
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
+ }