smml 0.1.4 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/smml/msm.rb +206 -16
- data/lib/smml/version.rb +1 -1
- data/tutorial_smml.md +181 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 399ce12531f91fa0f95a418517a7eaf3a9033119
|
4
|
+
data.tar.gz: 075f0f29408e73724c191251ed701b56c1818182
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d8dfed6fcff8b3364fc72a52988fd389a841e1eb93f0b472a2ad08aa4e00787f26ef05c030afdf9bbfa5c208a7e6cc6e93738055c10c026e08666494b907e37
|
7
|
+
data.tar.gz: af807db0f9b857c2aee7a086fb5e9a16f8ee12738fb4c2ae752b54eb6c0df9135353d44d04fd09d4c54bb24a45e6ecf28719add73df77db387d7fe8be1639a41
|
data/lib/smml/msm.rb
CHANGED
@@ -5,9 +5,17 @@ require 'optparse'
|
|
5
5
|
|
6
6
|
$debuglevel=0
|
7
7
|
|
8
|
+
# as gem or this file only
|
9
|
+
def version
|
10
|
+
if defined?(Smml) && ( Smml.constants.member?("VERSION") || Smml.constants.member?("VERSION") )
|
11
|
+
Smml::VERSION
|
12
|
+
else
|
13
|
+
File.mtime(__FILE__).strftime("%Y-%m-%d")
|
14
|
+
end
|
15
|
+
end
|
8
16
|
def hintminimum
|
9
17
|
cmd="smml"
|
10
|
-
puts "Smml v#{
|
18
|
+
puts "Smml v#{version}"
|
11
19
|
puts <<EOF
|
12
20
|
usage:
|
13
21
|
data to mid
|
@@ -159,6 +167,154 @@ def multilineTrim l,com
|
|
159
167
|
puts " ? mismatch end mark of multiline comment." if on
|
160
168
|
r
|
161
169
|
end
|
170
|
+
|
171
|
+
#===========================================================
|
172
|
+
module MmlReg
|
173
|
+
def self.r key, sort=true
|
174
|
+
raise if sort.class==Symbol
|
175
|
+
case key
|
176
|
+
when Array
|
177
|
+
raise if (key-@@keys).size>0
|
178
|
+
ks=key
|
179
|
+
ks=(@@keys-(@@keys-ks)) if sort
|
180
|
+
ks.map{|i|@@h[i]}*"|"
|
181
|
+
else
|
182
|
+
@@h[key]
|
183
|
+
end
|
184
|
+
rescue
|
185
|
+
puts "Regex part,arg bug",[key-@@keys]
|
186
|
+
raise
|
187
|
+
end
|
188
|
+
def self.trackr
|
189
|
+
self.r([:hexraw,:sharps,:chord,:word,:sound,:modifier,:velocity,:tempo,:num,:octave,:note,:mod,:note?,:sound?])
|
190
|
+
end
|
191
|
+
@@h={} # mml regex key hash. order is in @@keys
|
192
|
+
@@keys=[
|
193
|
+
:comment,
|
194
|
+
:keyword,
|
195
|
+
:macrodefAStart,
|
196
|
+
:macrodefA,
|
197
|
+
:macrodefStart,
|
198
|
+
:macrodef,
|
199
|
+
:hexraw,
|
200
|
+
:hexrawStart,
|
201
|
+
:tSep,
|
202
|
+
:pSep,
|
203
|
+
:multipletStart,
|
204
|
+
:multipletmark,
|
205
|
+
:macroA,
|
206
|
+
:macro,
|
207
|
+
:repStart,
|
208
|
+
:repEnd,
|
209
|
+
:word,
|
210
|
+
:modifier,
|
211
|
+
:sharps,
|
212
|
+
:wordStart,
|
213
|
+
:word?,
|
214
|
+
:chord,
|
215
|
+
:velocity,
|
216
|
+
:sound,
|
217
|
+
:DCmark,
|
218
|
+
:tempo,
|
219
|
+
:mod,
|
220
|
+
:octave,
|
221
|
+
:num,
|
222
|
+
:blank,
|
223
|
+
:valueSep,
|
224
|
+
:parenStart,
|
225
|
+
:parenEnd,
|
226
|
+
:chordStart,
|
227
|
+
:chordEnd,
|
228
|
+
:cmdValSep,
|
229
|
+
:note,
|
230
|
+
:dummyNote,
|
231
|
+
:randNote,
|
232
|
+
:note?,
|
233
|
+
:sound?,
|
234
|
+
:plusMinus,
|
235
|
+
:lineSep,
|
236
|
+
:chord?,
|
237
|
+
]
|
238
|
+
@@h[:comment]="\\( *comment[^\(\)]*\\)"
|
239
|
+
@@h[:word]="\\([^\(\):]*:[^\(\)]*\\)"
|
240
|
+
@@h[:wordStart]="\\([^\(\):]*:"
|
241
|
+
@@h[:sharps]="\\([+-]*[[:digit:]]*\\)"
|
242
|
+
@@h[:word?]="\\([^\(\)]*\\)"
|
243
|
+
@@h[:chord]="\\{[^\{\}]+,[^\{\},]+\\}|:[[:alpha:]][[:alnum:]]*,"
|
244
|
+
@@h[:velocity]="v[[:digit:]]+"
|
245
|
+
@@h[:note]="[abcdefgACDFGr]|\\{[[:digit:]]+\\}"
|
246
|
+
@@h[:note?]="[BE]"
|
247
|
+
@@h[:dummyNote]="o"
|
248
|
+
@@h[:randNote]="\\?"
|
249
|
+
@@h[:sound]="_[^!]+!|=|~"
|
250
|
+
@@h[:sound?]="[[:alpha:]]"
|
251
|
+
@@h[:DCmark]="\\.\\$|\\.[[:alpha:]]+"
|
252
|
+
@@h[:tempo]="[><][[:digit:]]*"
|
253
|
+
@@h[:mod]="[`'^]"
|
254
|
+
@@h[:octave]= "[+-][[:digit:]]*"
|
255
|
+
@@h[:plusMinus]="[+-][[:digit:]]*"
|
256
|
+
@@h[:tSep]="\\|\\|\\|"
|
257
|
+
@@h[:pSep]="\\/\\/\\/+"
|
258
|
+
@@h[:repStart]="\\["
|
259
|
+
@@h[:repEnd]="\\]"
|
260
|
+
@@h[:multipletStart]="\\/\\*?[[:digit:]\\.]*:"
|
261
|
+
@@h[:multipletmark]="\\/"
|
262
|
+
@@h[:num]="[-+*]?[[:digit:]]+\\.[[:digit:]]+|[-+*]?[[:digit:]]+"
|
263
|
+
@@h[:hexraw]="&\\([^()]*\\)"
|
264
|
+
@@h[:hexrawStart]="&\\("
|
265
|
+
@@h[:keyword]="macro +"
|
266
|
+
@@h[:macroA]="\\$\\{[^}]+\\}\\[[^\\]]+\\]|\\$[^}\\$\\{\\(\\)]+\\[[^\\]]+\\]"
|
267
|
+
@@h[:macro]="\\$[[:alnum:]]+\\([^)]*\\)|\\$[[:alnum:]]+|\\$\\{[^}]+\\}"
|
268
|
+
@@h[:macrodefAStart]="[[:alnum:]]+\\([,[:alpha:]]+\\):= *\\( *\\z"
|
269
|
+
@@h[:macrodefA]= "[[:alnum:]]+\\([,[:alpha:]]+\\):= *[^\\n]+"
|
270
|
+
@@h[:macrodefStart]="[[:alnum:]]+:= *\\( *\\z"
|
271
|
+
@@h[:macrodef]= "[[:alnum:]]+:= *[^\\n]+"
|
272
|
+
@@h[:blank]="[[:blank:]]+"
|
273
|
+
@@h[:valueSep]=","
|
274
|
+
@@h[:parenStart]="\\("
|
275
|
+
@@h[:parenEnd]="\\)"
|
276
|
+
@@h[:chordStart]="\\{"
|
277
|
+
@@h[:chordEnd]="\\}"
|
278
|
+
@@h[:cmdValSep]=":"
|
279
|
+
@@h[:lineSep]=";"
|
280
|
+
@@h[:chord?]=":[^=,]+,"
|
281
|
+
@@h[:modifier]="_[^_]__[^\\?]+\\?"
|
282
|
+
r=self.r(@@keys)
|
283
|
+
RwAll=/#{r}|./
|
284
|
+
MacroDef=self.r([:macrodefAStart,:macrodefStart,:macrodefA,:macrodef])
|
285
|
+
ArgIsOne=%w[ bendCent mark p gm gs xg loadf text ]
|
286
|
+
def self.event m,rest=[]
|
287
|
+
((@@keys-rest).map{|k|m=~/\A#{@@h[k]}\z/ ? k : nil}-[nil])[0]
|
288
|
+
end
|
289
|
+
def self.item m,rest=[]
|
290
|
+
[self.event(m,rest),m]
|
291
|
+
end
|
292
|
+
def self.hexitem m
|
293
|
+
m=~/([[:digit:]]{2})|(\$[^ ]+)|([, ])/
|
294
|
+
if $1
|
295
|
+
[:hex,m]
|
296
|
+
elsif $2
|
297
|
+
[:macro,m]
|
298
|
+
elsif $3
|
299
|
+
[:hexSep,m]
|
300
|
+
else
|
301
|
+
[hex?,m]
|
302
|
+
end
|
303
|
+
end
|
304
|
+
def self.keyAll
|
305
|
+
@@keys
|
306
|
+
end
|
307
|
+
def self.regmakeExcept ex
|
308
|
+
r=self.r(@@keys-ex)
|
309
|
+
/#{r}|./
|
310
|
+
end
|
311
|
+
def self.blanks
|
312
|
+
[:comment,:blank,:lineSep]
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
#===============================================
|
317
|
+
|
162
318
|
def allTrackMark c
|
163
319
|
"(mark:.ALL_TRACK_MARK_#{c}.)"
|
164
320
|
end
|
@@ -227,6 +383,19 @@ class Array
|
|
227
383
|
end
|
228
384
|
r
|
229
385
|
end
|
386
|
+
def lastIsPreAfter
|
387
|
+
self[-1][0..1]==[:call,:preAfter]
|
388
|
+
end
|
389
|
+
end
|
390
|
+
def mergeValues a,b
|
391
|
+
r=[]
|
392
|
+
size = a.size>b.size ? a.size : b.size
|
393
|
+
size.times{|i|
|
394
|
+
tmp=[a[i],b[i]]-["o"]
|
395
|
+
tmp=["o"] if tmp==[]
|
396
|
+
r<<tmp*""
|
397
|
+
}
|
398
|
+
r
|
230
399
|
end
|
231
400
|
class Notes < Hash
|
232
401
|
@@rythmChannel=9
|
@@ -355,7 +524,7 @@ class Event
|
|
355
524
|
@value=""
|
356
525
|
case @type
|
357
526
|
# event without time; except ':e'
|
358
|
-
when :comment,:raw
|
527
|
+
when :comment,:raw,:debugcomment
|
359
528
|
settime(0)
|
360
529
|
@value=arg[0]
|
361
530
|
when :ahead
|
@@ -403,6 +572,18 @@ class Event
|
|
403
572
|
varlenHex(@time)+@value
|
404
573
|
end
|
405
574
|
end
|
575
|
+
def debugdata
|
576
|
+
case @type
|
577
|
+
when :raw
|
578
|
+
"raw"
|
579
|
+
when :mark
|
580
|
+
"mark(#{@track}_#{@mark}) [#{@value}]"
|
581
|
+
when :comment
|
582
|
+
@value
|
583
|
+
else
|
584
|
+
""
|
585
|
+
end
|
586
|
+
end
|
406
587
|
def display
|
407
588
|
"#{@pos}(#{@time}) #{@type} => #{@value}"
|
408
589
|
end
|
@@ -995,7 +1176,7 @@ module MidiHex
|
|
995
1176
|
@waitingtime=0
|
996
1177
|
@nowtime+=start
|
997
1178
|
r=[Event.new(:on)]
|
998
|
-
r<<Event.new(:e,start," 9#{ch} #{key} #{vel} # #{start}
|
1179
|
+
r<<Event.new(:e,start," 9#{ch} #{key} #{vel} # #{start} later, sound on only , note #{@key} velocity #{velocity}\n")
|
999
1180
|
r
|
1000
1181
|
end
|
1001
1182
|
def self.soundOff key=@basekey,ch=@ch,sharp=0
|
@@ -1030,7 +1211,7 @@ module MidiHex
|
|
1030
1211
|
slen,rest=self.byGate(len,gate)
|
1031
1212
|
@nowtime+=start
|
1032
1213
|
r=[]
|
1033
|
-
r<<Event.new(:e,start," 9#{ch} #{key} #{vel} # #{start}
|
1214
|
+
r<<Event.new(:e,start," 9#{ch} #{key} #{vel} # #{start} later, sound on note #{@key} velocity #{velocity}\n")
|
1034
1215
|
b=@preAfter.shift
|
1035
1216
|
bends=expre=false
|
1036
1217
|
if b
|
@@ -1048,7 +1229,7 @@ module MidiHex
|
|
1048
1229
|
}
|
1049
1230
|
end
|
1050
1231
|
@nowtime+=slen
|
1051
|
-
r<<Event.new(:e,slen," 8#{ch} #{key} 00 # #{slen}(gate:#{@gateRate})- #{len.to_i}(#{len.round(2)})
|
1232
|
+
r<<Event.new(:e,slen," 8#{ch} #{key} 00 # #{slen}(gate:#{@gateRate})- #{len.to_i}(#{len.round(2)})ticks later, sound off [#{(@nowtime/@tbase).to_i}, #{@nowtime%@tbase}]\n")
|
1052
1233
|
r<<self.bend(0,0) if bends
|
1053
1234
|
r<<self.expre(0,127) if expre
|
1054
1235
|
if rest>0
|
@@ -1238,7 +1419,7 @@ module MidiHex
|
|
1238
1419
|
chx=format("%01x",ch)
|
1239
1420
|
@nowtime+=len
|
1240
1421
|
r=[]
|
1241
|
-
r<<Event.new(:end,len," 8#{chx} 3C 00 # rest #{len.to_i}(#{len.round(2)})
|
1422
|
+
r<<Event.new(:end,len," 8#{chx} 3C 00 # rest #{len.to_i}(#{len.round(2)})ticks later, off:ch#{ch}, key:3C\n")
|
1242
1423
|
r
|
1243
1424
|
end
|
1244
1425
|
def self.restHex len=@tbase,ch=@ch
|
@@ -1268,9 +1449,8 @@ module MidiHex
|
|
1268
1449
|
self.metaHook d,1,pos
|
1269
1450
|
end
|
1270
1451
|
def self.generaterText
|
1271
|
-
|
1272
|
-
thisVer="
|
1273
|
-
thisVer="" if $debuglevel && $debuglevel>1
|
1452
|
+
thisVer="v#{version}"
|
1453
|
+
thisVer="" if $debuglevel>1
|
1274
1454
|
pos=@tbase
|
1275
1455
|
self.metaText("generated by midi-simple-make.rb (#{thisVer})",pos)
|
1276
1456
|
end
|
@@ -1320,7 +1500,10 @@ module MidiHex
|
|
1320
1500
|
end
|
1321
1501
|
c=midiVround(c)
|
1322
1502
|
@expression=c
|
1323
|
-
|
1503
|
+
r=[]
|
1504
|
+
r<<Event.new(:comment,"# expression #{d}")
|
1505
|
+
r<<self.controlChange("11,#{c},#{len}")
|
1506
|
+
r
|
1324
1507
|
end
|
1325
1508
|
def self.ProgramChange ch,inst,len=0
|
1326
1509
|
ch=@ch if ch==false
|
@@ -1634,7 +1817,9 @@ module MidiHex
|
|
1634
1817
|
# EventList : [func,args] or [callonly, func,args] or others
|
1635
1818
|
elist.each{|h|
|
1636
1819
|
cmd,*arg=h
|
1637
|
-
|
1820
|
+
e=Event.new(:comment,"# #{cmd} #{arg}")
|
1821
|
+
r<<Event.new(:raw,self.metaText("#{cmd} #{arg}")) if $DEBUG && $debuglevel>5
|
1822
|
+
r<<e
|
1638
1823
|
case cmd
|
1639
1824
|
when :basekeyPlus
|
1640
1825
|
@basekey+=arg[0]
|
@@ -1691,7 +1876,7 @@ module MidiHex
|
|
1691
1876
|
(i.addtime(after);after=0) if after>0
|
1692
1877
|
(i.addtime(after);after=0) if after<0 && i.time+after>=0
|
1693
1878
|
rr<<i
|
1694
|
-
when :comment,:raw,:mark
|
1879
|
+
when :comment,:raw,:mark,:debugcomment
|
1695
1880
|
rr<<i
|
1696
1881
|
else
|
1697
1882
|
"? #{i}"
|
@@ -1707,8 +1892,8 @@ module MidiHex
|
|
1707
1892
|
end
|
1708
1893
|
}
|
1709
1894
|
end
|
1710
|
-
def self.makefraze
|
1711
|
-
return "" if not
|
1895
|
+
def self.makefraze mmldata,tc
|
1896
|
+
return "" if not mmldata
|
1712
1897
|
self.trackPrepare(tc)
|
1713
1898
|
@systemWait=120
|
1714
1899
|
@h=[]
|
@@ -1721,7 +1906,7 @@ module MidiHex
|
|
1721
1906
|
accent=false
|
1722
1907
|
sharp=0
|
1723
1908
|
@h<<[:controlChange,"10,#{@panoftrack}"] if @autopan
|
1724
|
-
cmd=
|
1909
|
+
cmd=mmldata.scan(/#{MmlReg.trackr}|./)
|
1725
1910
|
cmd<<" " # dummy
|
1726
1911
|
p "track hex; start making: ",cmd if $DEBUG
|
1727
1912
|
cmd.each{|i|
|
@@ -1796,7 +1981,12 @@ module MidiHex
|
|
1796
1981
|
@h<<[:call,:preGate,gs]
|
1797
1982
|
when /^\(A:(.*)\)/
|
1798
1983
|
s=$1.split(",")
|
1799
|
-
@h
|
1984
|
+
if @h.lastIsPreAfter
|
1985
|
+
s=mergeValues(s,@h.last[2])
|
1986
|
+
@h[-1]=[:call,:preAfter,s]
|
1987
|
+
else
|
1988
|
+
@h<<[:call,:preAfter,s]
|
1989
|
+
end
|
1800
1990
|
when /^\(B:(.*)\)/
|
1801
1991
|
s=$1.split(",")
|
1802
1992
|
@h<<[:call,:preBefore,s]
|
data/lib/smml/version.rb
CHANGED
data/tutorial_smml.md
CHANGED
@@ -14,13 +14,14 @@ c
|
|
14
14
|
```
|
15
15
|
r c d e d c3 r
|
16
16
|
```
|
17
|
+
|
17
18
|
;; capital letters are notes with sharps
|
18
19
|
|
19
20
|
```
|
20
21
|
e D e f F g g2
|
21
22
|
```
|
22
23
|
|
23
|
-
## octave
|
24
|
+
## octave level
|
24
25
|
;; change octave hight by '-', '+' or '(octave:3)' etc.
|
25
26
|
|
26
27
|
```
|
@@ -29,105 +30,168 @@ e D e f F g g2
|
|
29
30
|
- e d c2
|
30
31
|
```
|
31
32
|
|
32
|
-
;; >< tempo up/down.
|
33
|
+
;; >< tempo up/down a little bit.
|
33
34
|
|
34
35
|
```
|
35
36
|
f r > f r > f r > f r <<< fr fr fr fr
|
36
37
|
```
|
38
|
+
|
39
|
+
|
37
40
|
## note length
|
38
41
|
;; use note length. set it after note charactors. no length means 1.
|
42
|
+
|
39
43
|
```
|
40
44
|
c d2 e3 f4
|
41
45
|
```
|
46
|
+
|
42
47
|
;; float numbers as length too.
|
48
|
+
|
43
49
|
```
|
44
50
|
c d0.5 d0.5 e0.25 e0.25 e0.25 e0.25
|
45
51
|
```
|
52
|
+
|
46
53
|
;; ( thus, length expression is far from standard MML. usualy it is similiar to musical note name. )
|
47
54
|
|
48
55
|
## multiplet
|
49
56
|
;; but above is similiar to bellow
|
57
|
+
|
50
58
|
```
|
51
59
|
c /: dd / /: eeee /
|
52
60
|
```
|
61
|
+
|
53
62
|
;; because for example '/3: dd /' means that two 'd' notes are set inside '3' beats.
|
63
|
+
|
54
64
|
```
|
55
|
-
/3:
|
65
|
+
/3:dd/ /3:ddd/ /3:dddddd/ /3:dddddddddddd/
|
66
|
+
```
|
67
|
+
|
68
|
+
these are all in 3 beats. when the total beat length word between ```/``` and ```:``` is omitted, it will be set to 1 beat.
|
69
|
+
each note length is set by each rate and total length.
|
70
|
+
each line of below is same meaning.
|
71
|
+
|
72
|
+
```
|
73
|
+
a0.5 c0.25 c0.25
|
74
|
+
/1: a2 c c /
|
75
|
+
/: a2 c c /
|
76
|
+
/: a4 c2 c2 /
|
56
77
|
```
|
57
78
|
|
58
79
|
## gate time
|
59
80
|
;; real tone length is important sometimes. gate time command is a percentage of tone length. (staccato etc.)
|
81
|
+
|
60
82
|
```
|
61
83
|
(g:100) a b c
|
62
84
|
(g:70) a b c
|
63
85
|
```
|
64
|
-
|
86
|
+
|
87
|
+
first line is played like with a slur. second one will be played by more shorter sounds.
|
65
88
|
|
66
89
|
|
67
90
|
;; set velocity. max is 127.
|
91
|
+
|
68
92
|
```
|
69
93
|
(v:70) c (v:40) c (v:20) c (v:70) c (v:90) c
|
70
94
|
```
|
95
|
+
|
71
96
|
;; set panpot. value is between 0 and 127. when using '><', right or left value (from 0 to 63).
|
97
|
+
|
72
98
|
```
|
73
99
|
(pan:>30) c d e
|
74
100
|
```
|
101
|
+
|
75
102
|
if you don't, smml sets panpot values automatically.
|
76
103
|
|
77
104
|
|
78
|
-
## repeat
|
105
|
+
## repeat phrase
|
79
106
|
;; repeat 3 times
|
107
|
+
|
80
108
|
```
|
81
109
|
[ c d e f ]3
|
82
110
|
```
|
111
|
+
|
83
112
|
;; a melody goes near up/down side note without octave commands as default.
|
113
|
+
|
84
114
|
```
|
85
115
|
[ cdefgab ] 4
|
86
116
|
```
|
117
|
+
|
87
118
|
;; if you don't want do so, use octave command '-'. '--' is same to '-2'
|
119
|
+
|
88
120
|
```
|
89
121
|
[ cdefgab - ] 4
|
90
122
|
[ cdefgab cdefgab -- ] 4
|
91
123
|
```
|
124
|
+
|
92
125
|
;; to make long tones easy to read, '~' is used. 'c3' is same to 'c~~'. it can be set whereever notes can be set.
|
126
|
+
|
93
127
|
```
|
94
128
|
c d e ~ e d c ~
|
95
129
|
c /:~de/ d ~
|
96
130
|
```
|
97
|
-
|
131
|
+
|
132
|
+
;; the same note to the preceding one is '='.
|
133
|
+
|
98
134
|
```
|
99
135
|
c = = = d = = =
|
100
136
|
```
|
101
137
|
|
102
138
|
## chord
|
103
139
|
;; multi notes with length 2.
|
140
|
+
|
104
141
|
```
|
105
142
|
{c,e,g}2
|
106
143
|
```
|
107
144
|
|
108
145
|
;; chord name. used as same way as note commands. currently ',' is not be able to omitted as a part of chord name.
|
146
|
+
|
109
147
|
```
|
110
148
|
:cmaj7, = = = :G7, = = =
|
111
149
|
```
|
150
|
+
|
151
|
+
## tempo
|
112
152
|
;; most commands except note type ones, are inside parenthesis. set the tempo 120 bpm.
|
153
|
+
|
113
154
|
```
|
114
155
|
(tempo:120)
|
115
156
|
```
|
157
|
+
|
116
158
|
;; stroke. after it, multi notes are played shifted note by note.
|
159
|
+
|
117
160
|
```
|
118
161
|
(stroke:4)
|
119
162
|
```
|
120
163
|
|
164
|
+
repeating same command name in parenthesis, use blank.
|
165
|
+
|
166
|
+
```
|
167
|
+
(stroke:4) {a,b,c} = = (:6) = = =
|
168
|
+
```
|
169
|
+
|
170
|
+
is the same to
|
171
|
+
|
172
|
+
```
|
173
|
+
(stroke:4) {a,b,c} = = (stroke:6) = = =
|
174
|
+
```
|
175
|
+
|
176
|
+
```
|
177
|
+
(stroke:4) {a,b,c} = = (:-) = = =
|
178
|
+
```
|
179
|
+
|
180
|
+
minus value is for to stroke up. currently, up value affects once only as it simulates playing the guitar.
|
181
|
+
|
121
182
|
## sharp, flat
|
122
183
|
;; note name etc. is case sencitive, so each of 12 notes in one octave can be expressed by one charactor.
|
123
184
|
;; but in other cases,
|
124
185
|
;; sharp,flat and natural note command can be used. set before the note.
|
186
|
+
|
125
187
|
```
|
126
188
|
(+)a (-)b (0)c
|
127
189
|
```
|
190
|
+
|
128
191
|
strange ways can be affective currently. '(+4)a' etc.
|
129
192
|
;; instead of 'd' etc., note numbers can be used if you want.
|
130
193
|
;; MIDI note value is from 0 to 127. it's over Piano's 88. but too high/low note may not be played and heard.
|
194
|
+
|
131
195
|
```
|
132
196
|
{64}
|
133
197
|
{50,54,58}
|
@@ -135,14 +199,19 @@ strange ways can be affective currently. '(+4)a' etc.
|
|
135
199
|
|
136
200
|
## instrument; program change
|
137
201
|
;; drum sound can be used anywhere, but this is not MIDI way. use instrument name.
|
202
|
+
|
138
203
|
```
|
139
204
|
_snare! = = =
|
140
205
|
```
|
206
|
+
|
141
207
|
;; set instrument. automaticaly searched by even not exact name. (MIDI program change command)
|
208
|
+
|
142
209
|
```
|
143
210
|
(p:piano) c d e f (p:guitar) f e d c
|
144
211
|
```
|
212
|
+
|
145
213
|
;; set drum channel. after it is set, note numbers also can be used as same as '_snare!' etc.
|
214
|
+
|
146
215
|
```
|
147
216
|
(ch:drum) {34} = = = {35} = = =
|
148
217
|
```
|
@@ -150,26 +219,33 @@ _snare! = = =
|
|
150
219
|
## track
|
151
220
|
;; in SMF, MIDI channel is 1 - 16, and drum is in 10 channel. but currently, these are automaticaly set.
|
152
221
|
;; you don't need to think about it. simply seperate tracks with a command '|||'.
|
222
|
+
|
153
223
|
```
|
154
224
|
(p:piano) c d e f ||| (p:organ) e f g a ||| (p:guitar) g a b c
|
155
225
|
```
|
226
|
+
|
156
227
|
;; for visibility, the same
|
228
|
+
|
157
229
|
```
|
158
230
|
(p:piano) c d e f
|
159
231
|
||| (p:organ) e f g a
|
160
232
|
||| (p:guitar) g a b c
|
161
233
|
```
|
234
|
+
|
162
235
|
;; the same track name, the same MIDI channel and setting.
|
236
|
+
|
163
237
|
```
|
164
238
|
(track:foo) (p:organ) aa
|
165
239
|
||| (track:foo) bb
|
166
240
|
||| (track:hoge) cc
|
167
241
|
```
|
242
|
+
|
168
243
|
first two tracks are 'organ' sound by the track names declared.
|
169
244
|
|
170
245
|
## page
|
171
246
|
;; then seperate pages by three or longer one line '/'.
|
172
247
|
;; but this command do not adjust time potisions. it simply resets track number increment.
|
248
|
+
|
173
249
|
```
|
174
250
|
cdef|||efga|||gabc
|
175
251
|
////////////////////
|
@@ -177,19 +253,25 @@ first two tracks are 'organ' sound by the track names declared.
|
|
177
253
|
///////////////////
|
178
254
|
cdef|||efga|||gabc
|
179
255
|
```
|
256
|
+
|
180
257
|
;; the same to below.
|
258
|
+
|
181
259
|
```
|
182
260
|
cdef cdef cdef ||| efga efga efga ||| gabc gabc gabc
|
183
261
|
```
|
262
|
+
|
184
263
|
;; if you want to adjust tracks, use a blank page by two lines of page seperaters. the last three 'c' will be played adjusted.
|
264
|
+
|
185
265
|
```
|
186
266
|
cd ||| e ||| abcde
|
187
267
|
////////////////////
|
188
268
|
////////////////////
|
189
269
|
c|||c|||c
|
190
270
|
```
|
271
|
+
|
191
272
|
## position mark
|
192
273
|
;; or use a position mark command.
|
274
|
+
|
193
275
|
```
|
194
276
|
cd ||| e ||| abcde
|
195
277
|
////////////////////
|
@@ -197,12 +279,15 @@ cd ||| e ||| abcde
|
|
197
279
|
||| (mark:positionName) c
|
198
280
|
||| (mark:positionName) c
|
199
281
|
```
|
282
|
+
|
200
283
|
these are played like this.
|
284
|
+
|
201
285
|
```
|
202
286
|
cdrrr c ;; track 1
|
203
287
|
||| errrr c ;; track 2
|
204
288
|
||| abcde c ;; track 3
|
205
289
|
```
|
290
|
+
|
206
291
|
;; marks are not needed for all tracks. positions will be adjusted automaticaly to the preceeding track while the same marks exist.
|
207
292
|
;; like this, most commands except tempo, a command effects its belonging track only.
|
208
293
|
|
@@ -210,7 +295,9 @@ these are played like this.
|
|
210
295
|
```
|
211
296
|
[ a b c (mark:m) ] 3
|
212
297
|
```
|
298
|
+
|
213
299
|
;; same mark names 'm' in repeated section or one track will be automaticaly substituded by 'm m@2 m@3'. to adjust, use it in other tracks.
|
300
|
+
|
214
301
|
```
|
215
302
|
a b c (mark:m) a b c (mark:m@2) a b c (mark:m@3)
|
216
303
|
```
|
@@ -228,6 +315,7 @@ these are decreared in map files;
|
|
228
315
|
when there are same name files on the current directory, these are used. if not, default files in the gem will be set.
|
229
316
|
data in these map text must start with instrument number.
|
230
317
|
without it, the line text is used for section name. if the word 'Guitar' appears, it is included for searching keyword until the next section name line appears.
|
318
|
+
|
231
319
|
```
|
232
320
|
|
233
321
|
Piano Section
|
@@ -240,15 +328,18 @@ Guitar Section
|
|
240
328
|
5 two
|
241
329
|
|
242
330
|
```
|
331
|
+
|
243
332
|
so in this list, instrument number 1,2 and 3 match the keyword 'piano'.
|
244
333
|
So '(p:guitar,2)' selects an instrument line '5 two' as the 2nd result of searching 'guitar' and will be used instead of no word 'guitar' on it.
|
245
334
|
|
246
335
|
## hex data
|
247
336
|
;; until smml syntax is completed, raw hex parts can be used for complex data and things you don't know how to inprement in data.
|
248
337
|
search MIDI format and set hex data.
|
338
|
+
|
249
339
|
```
|
250
340
|
&(00 00 00)
|
251
341
|
```
|
342
|
+
|
252
343
|
;; currently hex only can be used. oct/decimal may be able to use someday.
|
253
344
|
all in SMF track data, unique formated prefix delta tick time data is needed. so if want, you can use '$delta(240)' for 240 ticks.
|
254
345
|
the tick means a minimum time span in SMF , one beat equals to 480 ticks as default. in this case, delta time is set to half beat.
|
@@ -256,38 +347,49 @@ also '$se(F0 41 ..)' can be used for system exclusive message data.
|
|
256
347
|
currently, nest data of parenthesis is not implemented except very limited cases.
|
257
348
|
|
258
349
|
## macro define
|
259
|
-
;; for repeating
|
350
|
+
;; for repeating phrase, macro can be used. use prefix '$' for refering.
|
351
|
+
|
260
352
|
```
|
261
353
|
Macr:=cde
|
262
354
|
macro W:=abc
|
263
355
|
|
264
356
|
ggg $Macr fff $W
|
265
357
|
```
|
358
|
+
|
266
359
|
the 4th line will be subsituted by
|
360
|
+
|
267
361
|
```
|
268
362
|
ggg cde fff abc.
|
269
363
|
```
|
364
|
+
|
270
365
|
the keyword 'macro' is used just for reading and will simply be ignored.
|
271
366
|
|
272
367
|
|
273
368
|
;; macro with args
|
369
|
+
|
274
370
|
```
|
275
371
|
fn(x):=ab$x
|
276
372
|
```
|
373
|
+
|
277
374
|
;; in this case, '$fn(10)' is substituded by 'ab10'. similarly,
|
375
|
+
|
278
376
|
```
|
279
377
|
$fn(:5,6,7)
|
280
378
|
$fn(4:10,20,30)
|
281
379
|
```
|
380
|
+
|
282
381
|
will be
|
382
|
+
|
283
383
|
```
|
284
384
|
ab5 ab6 ab7
|
285
385
|
ab10 (wait:4) ab20 (wait:4) ab30
|
286
386
|
```
|
387
|
+
|
287
388
|
'(wait:4)' was inserted by '4' in first place before args. it means 4 beats of rest (exact mean of '(wait:..)' is 'do nothing and wait for the next command' ).
|
288
389
|
|
289
390
|
|
290
391
|
multiline macro definition
|
392
|
+
|
291
393
|
```
|
292
394
|
EFF:=(
|
293
395
|
F0,43,10,4C,02,01,00,01,01,F7
|
@@ -296,15 +398,29 @@ EFF:=(
|
|
296
398
|
F0,43,10,4C,02,01,14,70,F7
|
297
399
|
)
|
298
400
|
```
|
401
|
+
|
299
402
|
but now, this is for easy way of writing only, and may not be so useful. to use it, each line must be seperated.
|
403
|
+
|
300
404
|
```
|
301
405
|
$EFF[1] $EFF[2] $EFF[3] $EFF[4]
|
302
406
|
```
|
303
407
|
|
408
|
+
but, these are MIDI system exclusive HEX data, so to make it really effective data, use this,
|
409
|
+
|
410
|
+
```
|
411
|
+
(xg:on)
|
412
|
+
&( $delta(120) $se($EFF[1]) 00 $se($EFF[2]) 00 $se($EFF[3]) 00 $se($EFF[4]) )
|
413
|
+
```
|
414
|
+
|
415
|
+
```$se()``` translates hex SysEx data to SMF hex data, and it needs pre delta-time data by ```$delta(ticks)``` like other data.
|
416
|
+
```$delta(0)``` is ```00``` , so both of these are effective.
|
417
|
+
|
418
|
+
|
304
419
|
## comment
|
305
420
|
;; ignored after ';;' of each line. write comments there.
|
306
421
|
multi line comments start with longer ';'.
|
307
422
|
end mark is same or longer mark of ';' than start mark. these must start from the top of the line.
|
423
|
+
|
308
424
|
```
|
309
425
|
;; comment
|
310
426
|
;;;;;;;;;;;;;;;;;;;;;;;;
|
@@ -321,10 +437,12 @@ end mark is same or longer mark of ';' than start mark. these must start from th
|
|
321
437
|
a b c d e f g
|
322
438
|
;;;;;;;;;;;;;;;;;;;;
|
323
439
|
```
|
440
|
+
|
324
441
|
in this case, active sound commands are 'abc' only.
|
325
442
|
|
326
443
|
## sound elements
|
327
444
|
use parts split note hight, length, velocity, gate time, pre modifier; sound elements.
|
445
|
+
|
328
446
|
```
|
329
447
|
(L: ...)
|
330
448
|
(V: ...)
|
@@ -332,6 +450,7 @@ use parts split note hight, length, velocity, gate time, pre modifier; sound ele
|
|
332
450
|
(B: ...)
|
333
451
|
a b c d e
|
334
452
|
```
|
453
|
+
|
335
454
|
the first value of each part will used for the first note 'a'. and so on.
|
336
455
|
inside parts, position is seperated by ',' or use dummy value 'o'.
|
337
456
|
'(V:,,,60,,)' is '(V:ooo 60 oo)'. last dummy values can be omitted. in this case, 4th note 'd' velocity is set to 60.
|
@@ -339,6 +458,7 @@ if 6th note don't exist, pre modifier element values are simply ignored.
|
|
339
458
|
|
340
459
|
|
341
460
|
in the same way,
|
461
|
+
|
342
462
|
```
|
343
463
|
(N: a b c d e )
|
344
464
|
(L: ...)
|
@@ -347,59 +467,76 @@ in the same way,
|
|
347
467
|
(B: ...)
|
348
468
|
o o o o o
|
349
469
|
```
|
470
|
+
|
350
471
|
is same mean to above. 'o' is dummy note. note hights are substituted by '(N:..)' values.
|
351
472
|
|
352
473
|
|
353
474
|
## dummy note
|
354
475
|
'o' is dummy. '?' is for random note etc.
|
476
|
+
|
355
477
|
```
|
356
478
|
? /2: ???? /
|
357
479
|
```
|
480
|
+
|
358
481
|
will be
|
482
|
+
|
359
483
|
```
|
360
484
|
c /2: defg /
|
361
485
|
```
|
486
|
+
|
362
487
|
or maybe
|
488
|
+
|
363
489
|
```
|
364
490
|
e /2: cagb /
|
365
491
|
```
|
492
|
+
|
366
493
|
etc.
|
367
494
|
if a scale has been defined as below, random notes will be selected from its scale notes.
|
495
|
+
|
368
496
|
```
|
369
497
|
(scale:a,b,c,d,e)
|
370
498
|
(scale:a,+2,+3,+5,+7,+9,+11)
|
371
499
|
```
|
500
|
+
|
372
501
|
still incompleted to use.
|
373
502
|
|
374
503
|
|
375
504
|
another random note.
|
505
|
+
|
376
506
|
```
|
377
507
|
[ (?:56-58) ] 4 ;; use range 56 to 58, note number. in this case, 4 times repeating maybe '{56}{56}{58}{57}' etc.
|
378
508
|
(?:a,b,40,45,90,12) ;; select from a note number or name list.
|
379
509
|
```
|
380
510
|
|
381
511
|
## transpose
|
512
|
+
|
382
513
|
```
|
383
514
|
(key:-4)
|
384
515
|
```
|
516
|
+
|
385
517
|
;; transpose -4 of half tone except drum instrument name like '_snare!'.
|
386
518
|
this does not have relation with the tonality. simply transpose all notes tempolary.
|
387
519
|
major key, minor key ,modulation of keys have not been implimented yet.
|
388
520
|
## Control Change
|
521
|
+
|
389
522
|
```
|
390
523
|
(cc:10,64)
|
391
524
|
```
|
525
|
+
|
392
526
|
controlChange number 10 value 64. see SMF format for details.
|
393
527
|
|
394
528
|
## General MIDI etc.
|
529
|
+
|
395
530
|
```
|
396
531
|
(gm:on)
|
397
532
|
(gs:reset)
|
398
533
|
(xg:on)
|
399
534
|
```
|
535
|
+
|
400
536
|
after these MIDI system commands, it need some time over 50 mili sec. or so for running.
|
401
537
|
implementation of it is not fixed, so for adjusting, please set marks on all tracks. for example '(mark:start)'.
|
402
538
|
or like this.
|
539
|
+
|
403
540
|
```
|
404
541
|
(gm:on)r
|
405
542
|
///////////////
|
@@ -415,45 +552,59 @@ if there are bugs, error can appear by macro definitions appear in the last step
|
|
415
552
|
|
416
553
|
## D.S. al fine
|
417
554
|
musical repeats system marks :
|
555
|
+
|
418
556
|
```
|
419
557
|
.DC .DS .toCODA .CODA .FINE
|
420
558
|
```
|
559
|
+
|
421
560
|
```
|
422
561
|
.SKIP
|
423
562
|
```
|
563
|
+
|
424
564
|
;; skip on second time.
|
565
|
+
|
425
566
|
```
|
426
567
|
.$
|
427
568
|
```
|
569
|
+
|
428
570
|
dal segno jump mark.
|
429
571
|
|
430
572
|
```
|
431
573
|
[ a b c ]
|
432
574
|
```
|
575
|
+
|
433
576
|
if there is no followed number, 'abc' is repeated 2 times.
|
434
577
|
|
435
578
|
## seperater
|
436
579
|
;; ';' can be used for one line data as line seperater.
|
580
|
+
|
437
581
|
```
|
438
582
|
$ smml -d "abc;def|||mc:=ggg;ccc$mc ddd" -o out.mid
|
439
583
|
```
|
584
|
+
|
440
585
|
in this case, macro definition ends by ';', so $mc means 'ggg'.
|
441
586
|
## and so on
|
442
587
|
for more details if you want to understand, see MIDI format.
|
443
588
|
basicaly, a MIDI envent is constructed by preceding time data and event data.
|
444
589
|
so series of event preceding each zero time data mean many event on the same time.
|
445
590
|
but it may not be played as you expect. to fix it, set some delta time for MIDI players.
|
591
|
+
|
446
592
|
```
|
447
593
|
(on:a)
|
448
594
|
```
|
595
|
+
|
449
596
|
note 'a' sound on only. it takes zero tick.
|
597
|
+
|
450
598
|
```
|
451
599
|
(off:a)
|
452
600
|
```
|
601
|
+
|
453
602
|
note 'a' sound off only.
|
603
|
+
|
454
604
|
```
|
455
605
|
(wait:3)
|
456
606
|
```
|
607
|
+
|
457
608
|
it reserves 3 beats for the next note event.
|
458
609
|
so,
|
459
610
|
the note event 'a' is the same as '(on:a)(wait:1)(off:a)'.
|
@@ -464,31 +615,43 @@ so,
|
|
464
615
|
```
|
465
616
|
(ch:1)
|
466
617
|
```
|
618
|
+
|
467
619
|
;; set this track's channel 1. when several tracks use same channel, for example it will behave as the same instrument.
|
620
|
+
|
468
621
|
```
|
469
622
|
(bend:100)
|
470
623
|
```
|
624
|
+
|
471
625
|
pitch bend 100
|
626
|
+
|
472
627
|
```
|
473
628
|
(bendRange:12)
|
474
629
|
```
|
630
|
+
|
475
631
|
set bend range 12. default is normaly 2.
|
632
|
+
|
476
633
|
```
|
477
634
|
(bendCent:on)
|
478
635
|
```
|
636
|
+
|
479
637
|
set bend value unit cent (half tone eqauls 100 cents). defaultly this is 'off' and value is between -8192 and +8192.
|
480
638
|
so, these are same
|
639
|
+
|
481
640
|
```
|
482
641
|
(bendCent:off)(bend:8192)
|
483
642
|
(bendCent:on)(bend:100)
|
484
643
|
```
|
644
|
+
|
485
645
|
```
|
486
646
|
(V:o,o,110)
|
487
647
|
```
|
648
|
+
|
488
649
|
preceding modifier velocities. if next notes are 'abc' ,3rd tone 'c' is with velocity 110. a blank or 'o' mean default value.
|
650
|
+
|
489
651
|
```
|
490
652
|
(G:,,-)
|
491
653
|
```
|
654
|
+
|
492
655
|
preceding modifier gate rates. if next notes are 'abc' ,3rd tone 'c' is with a gate rate shorter.
|
493
656
|
new preceding modifiers will cancel old rest preceding values if it remains.
|
494
657
|
|
@@ -497,21 +660,25 @@ new preceding modifiers will cancel old rest preceding values if it remains.
|
|
497
660
|
` ;; too fast note, play ahead. for changing a value of shift ticks base, use '(roll:45)'.
|
498
661
|
' ;; too late note, lay back.
|
499
662
|
```
|
663
|
+
|
500
664
|
set these modifiers before note commands.
|
501
665
|
|
502
666
|
```
|
503
667
|
(loadf:filename.mid,2)
|
504
668
|
```
|
669
|
+
|
505
670
|
load the second track data of filename.mid. when using it, the track must be itself only. seperate by '|||'.
|
506
671
|
this command do not check about track data strictly. be careful.
|
507
672
|
|
508
673
|
|
509
674
|
;; basicaly, one sound is a note type command with preceding modifiers followed by length number.
|
675
|
+
|
510
676
|
```
|
511
677
|
^`a2
|
512
678
|
```
|
513
679
|
|
514
680
|
now, note type commands are :
|
681
|
+
|
515
682
|
```
|
516
683
|
c ;; single note
|
517
684
|
(-)d ;; single note with flat/sharp/natural modifiers
|
@@ -524,7 +691,7 @@ now, note type commands are :
|
|
524
691
|
|
525
692
|
and other commands are with parentheses.
|
526
693
|
|
527
|
-
```'~'``` seems likely note type, but it is
|
694
|
+
```'~'``` seems likely note type, but it is compressed to preceding note as calculated note length. most commands cannot be set inside of ```'c~~~'.```
|
528
695
|
|
529
696
|
|
530
697
|
## preprocess
|
@@ -545,16 +712,22 @@ limited commands can be used. bend,expre.
|
|
545
712
|
(A: o o o o o o o o (expre:20,40,+,+,+,+,-,-,-,-,+,+,+,+,-,-,-,-,+,+,+,+) o, )
|
546
713
|
a b ~ ~ c ~ ~ d e ~ f g a b c d
|
547
714
|
```
|
715
|
+
|
548
716
|
note loudness is result of velocity, expression and volume values multipled. expression is used for a running note etc..
|
549
717
|
velocity for more long span, volume for total sound level etc.
|
550
718
|
in above case, the 9th note 'b' is with modifier data, expression and bend. the first value is time interval.
|
551
719
|
all after that are real values. the '+' adds 10 to latest value as default.
|
552
720
|
so expression data is ;``` 40,50,60,70,80,70,60,50,40,50,60,70,80...``` with each 20 ticks interval.
|
721
|
+
bend and expression values inside these parts will be reseted after the modified note ends.
|
722
|
+
series of ```(A:..)``` parts are merged. if not, old one is overwtitten.
|
723
|
+
|
553
724
|
|
554
725
|
## text
|
555
726
|
text implement to MIDI file.
|
727
|
+
|
556
728
|
```
|
557
729
|
(text:this_is_a_pen)
|
558
730
|
```
|
731
|
+
|
559
732
|
but now blanks are removed. someday maybe fixed ?
|
560
733
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- tabasano
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|