smml 0.1.4 → 0.1.6
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.
- 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
|