smf 0.15.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/MANUAL +172 -0
  2. data/MANUAL.en +135 -0
  3. data/MANUAL.en.html +150 -0
  4. data/MANUAL.en.rd +144 -0
  5. data/MANUAL.html +201 -0
  6. data/MANUAL.rd +179 -0
  7. data/README +33 -0
  8. data/README.en +33 -0
  9. data/lib/smf.rb +736 -0
  10. data/lib/smf/divert.rb +21 -0
  11. data/lib/smf/io.rb +1278 -0
  12. data/lib/smf/toy/beatmap.rb +73 -0
  13. data/lib/smf/toy/gm.rb +327 -0
  14. data/lib/smf/toy/groove.rb +34 -0
  15. data/lib/smf/toy/macro.rb +282 -0
  16. data/lib/smf/toy/macro/mml.rb +34 -0
  17. data/lib/smf/toy/macro/mml/parser.rb +545 -0
  18. data/lib/smf/toy/macro/mml/parser.ry +239 -0
  19. data/lib/smf/toy/macro/stt.rb +33 -0
  20. data/lib/smf/toy/morse.rb +126 -0
  21. data/lib/smf/toy/quantize.rb +32 -0
  22. data/lib/smf/toy/rmi.rb +29 -0
  23. data/lib/smf/toy/searchsegment.rb +24 -0
  24. data/lib/smf/toy/shuffle.rb +39 -0
  25. data/lib/smf/toy/tempomap.rb +75 -0
  26. data/lib/smf/toy/text.rb +369 -0
  27. data/lib/smf/toy/velcomp.rb +42 -0
  28. data/lib/smf/toy/virtual.rb +118 -0
  29. data/lib/smf/toy/xml.rb +377 -0
  30. data/sample/Makefile +58 -0
  31. data/sample/bwv772.mid +0 -0
  32. data/sample/bwv772.mml +94 -0
  33. data/sample/bwv775.mid +0 -0
  34. data/sample/bwv775.mml +157 -0
  35. data/sample/bwv787.mid +0 -0
  36. data/sample/bwv787.mml +129 -0
  37. data/sample/groove.grv +33 -0
  38. data/sample/groove.rb +45 -0
  39. data/sample/ltvddpd2.mid +0 -0
  40. data/sample/ltvddpd2.stt +60 -0
  41. data/sample/merge.rb +38 -0
  42. data/sample/mml-samp.rb +19 -0
  43. data/sample/mml.rb +36 -0
  44. data/sample/morse-samp.rb +11 -0
  45. data/sample/morse.rb +31 -0
  46. data/sample/play-oss.rb +215 -0
  47. data/sample/play-oss2.rb +253 -0
  48. data/sample/play-oss3.rb +150 -0
  49. data/sample/play-spkr.rb +97 -0
  50. data/sample/play-win.rb +195 -0
  51. data/sample/quantize.rb +41 -0
  52. data/sample/rand1.rb +21 -0
  53. data/sample/rand2.rb +24 -0
  54. data/sample/rmi2smf.rb +26 -0
  55. data/sample/shuffle.rb +43 -0
  56. data/sample/smf2rmi.rb +26 -0
  57. data/sample/smf2smf.rb +26 -0
  58. data/sample/smf2text.rb +27 -0
  59. data/sample/smf2wav.rb +123 -0
  60. data/sample/smf2xml.rb +27 -0
  61. data/sample/split.rb +40 -0
  62. data/sample/stt-samp.rb +19 -0
  63. data/sample/stt.rb +36 -0
  64. data/sample/text2smf.rb +28 -0
  65. data/sample/velcomp.rb +45 -0
  66. data/sample/virtual-samp.rb +19 -0
  67. data/sample/xml2smf.rb +28 -0
  68. metadata +128 -0
@@ -0,0 +1,239 @@
1
+ # parser.ry: Written by Tadayoshi Funaba 1999-2005,2008
2
+ # $Id: parser.ry,v 1.3 2008-02-16 16:56:21+09 tadf Exp $
3
+
4
+ class SMF::MMLParser
5
+
6
+ prechigh
7
+ nonassoc UMINUS
8
+ left '*' '/'
9
+ left '+' '-'
10
+ preclow
11
+
12
+ rule
13
+
14
+ prog : list { result = val[0] } ;
15
+
16
+ list : { result = [:list, []] }
17
+ | list stmt { val[0][1] << val[1]; result = val[0] }
18
+ ;
19
+
20
+ stmt : expr { result = [:stmt, val[0]] }
21
+ | expr '&' { result = [:stmt, val[0], val[1]] }
22
+ ;
23
+
24
+ expr : step { result = [:step, val[0]] }
25
+ | note | text | asgn
26
+ | '{' list '}' { result = val[1] }
27
+ ;
28
+
29
+ note : NOTE { result = [:note, val[0]] } ;
30
+ text : TEXT { result = [:text, val[0]] } ;
31
+
32
+ asgn : VAR AOP num
33
+ { result = [:asgn, val[0], val[1], val[2]] }
34
+ | VAR AOP num ',' num
35
+ { result = [:asgn, val[0], val[1], val[2], val[4]] }
36
+ ;
37
+
38
+ step : step '+' step { result = [:add, val[0], val[2]] }
39
+ | step '-' step { result = [:sub, val[0], val[2]] }
40
+ | step '*' num { result = [:mul, val[0], val[2]] }
41
+ | step '/' num { result = [:div, val[0], val[2]] }
42
+ | '(' step ')' { result = val[1] }
43
+ | STEP { result = [:imm, val[0]] }
44
+ ;
45
+
46
+ num : num '+' num { result = [:add, val[0], val[2]] }
47
+ | num '-' num { result = [:sub, val[0], val[2]] }
48
+ | num '*' num { result = [:mul, val[0], val[2]] }
49
+ | num '/' num { result = [:div, val[0], val[2]] }
50
+ | '-' num = UMINUS { result = [:negate, val[1]] }
51
+ | '(' num ')' { result = val[1] }
52
+ | NUM { result = [:imm, val[0]] }
53
+ ;
54
+
55
+ end
56
+
57
+ ---- header ----
58
+
59
+ require 'smf'
60
+ require 'smf/toy/macro'
61
+ require 'rational'
62
+
63
+ class SemanticError < StandardError; end
64
+
65
+ ---- inner ----
66
+
67
+ STEPTAB = { 'w'=>1.to_r/1, 'h'=>1.to_r/2,
68
+ 'q'=>1.to_r/4, 'i'=>1.to_r/8,
69
+ 's'=>1.to_r/16,'z'=>1.to_r/32,
70
+ 'u'=>1.to_r/1920 }
71
+
72
+ NOTETAB = { 'a'=>9, 'b'=>11, 'c'=>0, 'd'=>2, 'e'=>4, 'f'=>5, 'g'=>7 }
73
+
74
+ def lineno() @co end
75
+
76
+ def parse(str)
77
+ @co = 1
78
+ @str = str
79
+ do_parse
80
+ end
81
+
82
+ def next_token
83
+ loop do
84
+ @str = @str.sub(/\A([\s\v]+)/, '')
85
+ if $1
86
+ @co += $1.count("\n")
87
+ end
88
+ @str = @str.sub(%r|\A(//.*)$|, '')
89
+ break unless $1
90
+ end
91
+ return [false, false] if @str.size == 0
92
+
93
+ if /\A([whqiszu])\b(\.+)?/i =~ @str
94
+ @str = $'
95
+ n = STEPTAB[$1.downcase]
96
+ i = if $2 then $2.size else 0 end
97
+ p = 1
98
+ i.times do |j|
99
+ p += Rational(1, 2 ** (j + 1))
100
+ end
101
+ s = n * p
102
+ return [:STEP, s]
103
+ end
104
+
105
+ if /\Ar\b/i =~ @str
106
+ @str = $'
107
+ return [:NOTE, nil]
108
+ end
109
+
110
+ if /\A([abcdefg])\b([$%#]+)?([,']+)?/i =~ @str
111
+ @str = $'
112
+ na = NOTETAB[$1.downcase]
113
+ if $2
114
+ s1 = 0
115
+ s1 -= $2.count('$')
116
+ s1 += $2.count('#')
117
+ end
118
+ if $3
119
+ s12 = 0
120
+ s12 -= $3.count(",") * 12
121
+ s12 += $3.count("'") * 12
122
+ end
123
+ return [:NOTE, [na, s1, s12]]
124
+ end
125
+
126
+ if /\A"/ =~ @str
127
+ @str = $'
128
+ s = '"'
129
+ until /\A"/ =~ @str
130
+ case @str
131
+ when /\A(\\.|.)/m; s << $1
132
+ end
133
+ @co += $1.count("\n")
134
+ @str = $'
135
+ end
136
+ s << '"'
137
+ @str = $'
138
+ return [:TEXT, eval(s)]
139
+ end
140
+
141
+ if /\A([a-z][a-z0-9]*)/i =~ @str
142
+ @str = $'
143
+ return [:VAR, $1]
144
+ end
145
+
146
+ if %r|\A([-+*/]?=)| =~ @str
147
+ @str = $'
148
+ return [:AOP, $1[0]]
149
+ end
150
+
151
+ if /\A(\d+)/ =~ @str
152
+ @str = $'
153
+ return [:NUM, Rational($1.to_i)]
154
+ end
155
+
156
+ if /\A(.)/ =~ @str
157
+ @str = $'
158
+ return [$1, $1]
159
+ end
160
+ end
161
+
162
+ ---- footer ----
163
+
164
+ module SMF
165
+
166
+ class MMLEvaluator
167
+
168
+ def initialize(de) @de = de end
169
+
170
+ def evaluate(st)
171
+ case st[0]
172
+ when :list
173
+ @de.push
174
+ st[1].each do |st2|
175
+ evaluate(st2)
176
+ end
177
+ of = @de[:of]
178
+ @de.pop
179
+ @de[:of] = of
180
+ @de.snap
181
+ when :stmt
182
+ of = @de[:of]
183
+ evaluate(st[1])
184
+ if st[2]
185
+ @de[:of] = of
186
+ end
187
+ when :step
188
+ @de[:le] = evaluate(st[1])
189
+ when :add
190
+ return evaluate(st[1]) + evaluate(st[2])
191
+ when :sub
192
+ return evaluate(st[1]) - evaluate(st[2])
193
+ when :mul
194
+ return evaluate(st[1]) * evaluate(st[2])
195
+ when :div
196
+ return evaluate(st[1]) / evaluate(st[2])
197
+ when :negate
198
+ return - evaluate(st[1])
199
+ when :imm
200
+ return st[1]
201
+ when :note
202
+ @de[:_no] = st[1]
203
+ @de.snap
204
+ @de[:_no] = nil
205
+ @de[:of] += @de[:le]
206
+ when :text
207
+ @de[:_tx] = st[1]
208
+ @de.snap
209
+ @de[:_tx] = nil
210
+ when :asgn
211
+ va = st[1]
212
+ op = st[2]
213
+ ob = evaluate(st[3])
214
+ if st[4]
215
+ ob2 = evaluate(st[4])
216
+ ob = [ob, ob2]
217
+ end
218
+ va = va.intern
219
+ v = @de[va]
220
+ case op
221
+ when ?+; v += ob
222
+ when ?-; v -= ob
223
+ when ?*; v *= ob
224
+ when ?/; v /= ob
225
+ when ?=; v = ob
226
+ end
227
+ if va == :ke
228
+ @de[:_ke] = v
229
+ @de.snap
230
+ @de[:_ke] = nil
231
+ end
232
+ @de[va] = v
233
+ @de.snap
234
+ end
235
+ end
236
+
237
+ end
238
+
239
+ end
@@ -0,0 +1,33 @@
1
+ # stt.rb: Written by Tadayoshi Funaba 2005
2
+ # $Id: stt.rb,v 1.2 2005-07-17 17:08:20+09 tadf Exp $
3
+
4
+ $KCODE = 'e'
5
+
6
+ require 'smf/toy/macro/mml'
7
+ require 'kconv'
8
+ require 'jcode'
9
+
10
+ module SMF
11
+
12
+ class STT < MML
13
+
14
+ NOTETAB = { '��'=>'a', '��' =>'b', '��'=>'c', '��'=>'d',
15
+ '��'=>'e', '�ե�'=>'f', '��'=>'g', '��'=>'r' }
16
+
17
+ def << (s)
18
+ s2 = s.toeuc.
19
+ gsub(/(��|��|��|��|��|�ե�|��|��)([$%#�����]+)?([,'����]+)?(��+)?/) do
20
+ n, s, o, x = $1, $2, $3, $4
21
+ no = NOTETAB[n]
22
+ no += s.tr('�����', '$%#') if s
23
+ no += o.tr('����', ",'") if o
24
+ le = 1
25
+ le += x.jsize if x
26
+ format('{le*=%d %s}', le, no)
27
+ end
28
+ super(s2)
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,126 @@
1
+ # morse.rb: Written by Tadayoshi Funaba 2005,2006
2
+ # $Id: morse.rb,v 1.4 2006-11-10 21:58:21+09 tadf Exp $
3
+
4
+ require 'smf'
5
+ require 'smf/toy/gm'
6
+
7
+ module SMF
8
+
9
+ class Morse
10
+
11
+ PLAIN = {
12
+ # '!' => 'exclamation mark',
13
+ # '"' => 'quotation mark',
14
+ '#' => 'number sign',
15
+ # '$' => 'dollar sign',
16
+ '%' => 'percent sign',
17
+ # '&' => 'ampersand',
18
+ # "'" => 'apostrophe',
19
+ # '(' => 'left parenthesis',
20
+ # ')' => 'right parenthesis',
21
+ '*' => 'asterisk',
22
+ '+' => 'plus sign',
23
+ # ',' => 'comma',
24
+ # '-' => 'hyphen', # -minus
25
+ # '.' => 'full stop',
26
+ # '/' => 'solidus',
27
+ # ':' => 'colon',
28
+ # ';' => 'semicolon',
29
+ '<' => 'less than sign',
30
+ # '=' => 'equals sign',
31
+ '>' => 'greater than sign',
32
+ # '?' => 'question mark',
33
+ # '@' => 'commercial at',
34
+ '[' => 'left square bracket',
35
+ '\\' => 'reverse solidus',
36
+ ']' => 'right square bracket',
37
+ '^' => 'circumflex accent',
38
+ # '_' => 'low line',
39
+ '`' => 'grave accent',
40
+ '{' => 'left curly bracket',
41
+ '|' => 'vertical line',
42
+ '}' => 'right curly bracket',
43
+ '~' => 'tilde'
44
+ }
45
+
46
+ CODE = {
47
+ ?! => '-.-.--', ?" => '.-..-.', ?$ => '...-..-',
48
+ ?& => '. ...', ?' => '.----.', ?( => '-.--.-', # '
49
+ ?) => '-.--.-', ?* => '-..-', ?+ => '.-.-.',
50
+ ?, => '--..--', ?- => '-....-', ?. => '.-.-.-',
51
+ ?/ => '-..-.',
52
+
53
+ ?0 => '-----', ?1 => '.----', ?2 => '..---',
54
+ ?3 => '...--', ?4 => '....-', ?5 => '.....',
55
+ ?6 => '-....', ?7 => '--...', ?8 => '---..',
56
+ ?9 => '----.',
57
+
58
+ ?: => '---...', ?; => '-.-.-', ?= => '-...-',
59
+ ?? => '..--..', ?@ => '.--.-.',
60
+
61
+ ?a => '.-', ?b => '-...', ?c => '-.-.',
62
+ ?d => '-..', ?e => '.', ?f => '..-.',
63
+ ?g => '--.', ?h => '....', ?i => '..',
64
+ ?j => '.---', ?k => '-.-', ?l => '.-..',
65
+ ?m => '--', ?n => '-.', ?o => '---',
66
+ ?p => '.--.', ?q => '--.-', ?r => '.-.',
67
+ ?s => '...', ?t => '-', ?u => '..-',
68
+ ?v => '...-', ?w => '.--', ?x => '-..-',
69
+ ?y => '-.--', ?z => '--..',
70
+
71
+ ?_ => '..--.-'
72
+ }
73
+
74
+ def initialize(sq, te=120)
75
+ @sq = sq << Track.new
76
+ @te = te
77
+ @mesg = []
78
+ end
79
+
80
+ def << (s) @mesg << s end
81
+
82
+ def plain(s)
83
+ s = s.dup
84
+ PLAIN.each_pair{|k, v| s.gsub!(k, ' %s ' % v)}
85
+ s
86
+ end
87
+
88
+ def encode(s)
89
+ s.downcase.scan(/\S+/).collect {|w|
90
+ w.scan(/./).collect{|c|
91
+ (CODE[c[0]] || '').scan(/./).join("\s")
92
+ }.join("\s"*3)
93
+ }.join("\s"*7) + "\s"*15
94
+ end
95
+
96
+ private :plain, :encode
97
+
98
+ def generate
99
+ of = 0
100
+ @sq[0] << SetTempo.new(of, 60000000 / 240)
101
+ @sq[0] << GMSystemOn.new(of)
102
+ of += @sq.division / 2
103
+ @sq[0] << ProgramChange.new(of, 0, 81)
104
+ of += @sq.division / 2
105
+ @sq[0] << SetTempo.new(of, 60000000 / @te)
106
+ @mesg.each do |s|
107
+ @sq[0] << Marker.new(of, s)
108
+ encode(plain(s)).each_byte do |c|
109
+ case c
110
+ when ?.; le = (@sq.division / 8) * 1
111
+ when ?-; le = (@sq.division / 8) * 3
112
+ else; le = (@sq.division / 8) * 1
113
+ end
114
+ if c == ?. || c == ?-
115
+ @sq[0] << NoteOn .new(of, 0, 69, 96)
116
+ @sq[0] << NoteOff.new(of + le, 0, 69, 64)
117
+ end
118
+ of += le
119
+ end
120
+ end
121
+ @sq[0] << EndOfTrack.new(of)
122
+ end
123
+
124
+ end
125
+
126
+ end
@@ -0,0 +1,32 @@
1
+ # quantize.rb: Written by Tadayoshi Funaba 1999-2005
2
+ # $Id: quantize.rb,v 1.1 2005-07-09 07:36:31+09 tadf Exp $
3
+
4
+ module SMF
5
+
6
+ class Quantize
7
+
8
+ def initialize(div, unit=1.0/8)
9
+ @unit = unit * div * 4
10
+ self.min = 0.0
11
+ self.max = 1.0
12
+ self.rand = 0.0
13
+ end
14
+
15
+ def min=(v) @min = @unit * v end
16
+ def max=(v) @max = @unit * v end
17
+ def rand=(v) @rand = @unit * v end
18
+
19
+ def quantize(ev)
20
+ offset = (ev.offset + @unit / 2) / @unit * @unit
21
+ if @rand != 0
22
+ offset += rand(@rand) - @rand / 2
23
+ end
24
+ offset = offset.round
25
+ if (@min..@max) === (ev.offset - offset).abs
26
+ ev.offset = offset
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,29 @@
1
+ # rmi.rb: Written by Tadayoshi Funaba 2001-2005
2
+ # $Id: rmi.rb,v 1.1 2005-07-09 07:36:31+09 tadf Exp $
3
+
4
+ module SMF
5
+
6
+ module RMI
7
+
8
+ def smf2rmi(s)
9
+ pad = s.size % 2
10
+ o = 'RIFF'
11
+ o << [12 + s.size + pad].pack('V')
12
+ o << 'RMID'
13
+ o << 'data'
14
+ o << [s.size].pack('V')
15
+ o << s
16
+ pad.times do o << "\000" end
17
+ o
18
+ end
19
+
20
+ def rmi2smf(s)
21
+ x, = s[16,4].unpack('V')
22
+ s[20,x]
23
+ end
24
+
25
+ module_function :smf2rmi, :rmi2smf
26
+
27
+ end
28
+
29
+ end