smml 0.1.0.1 → 0.1.0.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.
- checksums.yaml +4 -4
- data/README_smml.md +13 -4
- data/bin/mmlsmml +4 -2
- data/lib/smml/msm.rb +118 -21
- data/lib/smml/version.rb +1 -1
- 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: 5502e954b9a84c81d1589125b9c6bff866c7a47c
|
4
|
+
data.tar.gz: 7a54373e442e7d92e5200fd699bd99cbddff5118
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3724df4add3c3d66ac9cc733149a5762bf8e899d0bf28e673d4d01b066b529d72ed612f77cca459612ea5ee06df9bd2d3669f0668fcc2f3320ac318108624117
|
7
|
+
data.tar.gz: f65ca001292854935dfd31c15d73d5556d7e4fee703026a864d62760c4fea85b5746b44434239caa49964f0e189fee9e484ec0f18ba648431615cb620a4cf514
|
data/README_smml.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# smml
|
2
2
|
|
3
3
|
simple Music Macro Language to MIDI
|
4
4
|
|
@@ -28,10 +28,19 @@ in a ruby script,
|
|
28
28
|
m=Smml.new
|
29
29
|
m.compile('infile.mml','outfile.mid')
|
30
30
|
|
31
|
-
Or exec command
|
31
|
+
Or exec command.
|
32
|
+
smml to mid (file to mid, mml data to mid, syntax, help)
|
32
33
|
|
33
|
-
$ smml -i infile.mml -o
|
34
|
-
$ smml -d "cdefgab" -o
|
34
|
+
$ smml -i infile.mml -o out.mid
|
35
|
+
$ smml -d "cdefgab" -o out.mid
|
36
|
+
$ smml -s
|
37
|
+
$ smml -h
|
38
|
+
|
39
|
+
mml2smml (file to smml, mml data to smml, mml data to mid)
|
40
|
+
|
41
|
+
$ mmlsmml -i infile.mml > smmlfile
|
42
|
+
$ mmlsmml -d "cdefgab" > smmlfile
|
43
|
+
$ mmlsmml -d "cdefgab" -o out.mid
|
35
44
|
|
36
45
|
## Contributing
|
37
46
|
|
data/bin/mmlsmml
CHANGED
@@ -28,7 +28,7 @@ def help
|
|
28
28
|
end
|
29
29
|
|
30
30
|
infile="infile.mml"
|
31
|
-
outfile="
|
31
|
+
outfile=""
|
32
32
|
data=""
|
33
33
|
|
34
34
|
opt = OptionParser.new
|
@@ -53,7 +53,9 @@ p data
|
|
53
53
|
data=data.split("\n").map{|i|i.commentoff("\n",'#')}*"\n"
|
54
54
|
p data
|
55
55
|
smml=Mml.tosmml(data)
|
56
|
-
puts smml if $smmlshow || $DEBUG
|
56
|
+
puts smml if $smmlshow || $DEBUG || outfile==""
|
57
|
+
exit if outfile==""
|
58
|
+
|
57
59
|
m.octave=:far
|
58
60
|
m.data=smml
|
59
61
|
m.outfile=outfile
|
data/lib/smml/msm.rb
CHANGED
@@ -92,7 +92,12 @@ syntax: ...( will be changed time after time)
|
|
92
92
|
;;;;;; =start mark of multi-line comment. end mark is same or longer mark of ';;'. these must start from the top of line.
|
93
93
|
|
94
94
|
basicaly, one sound is a tone command followed by length number. now, tone type commands are :
|
95
|
-
'c'
|
95
|
+
'c' => single note
|
96
|
+
'(-)d' => single note with flat/sharp modifier
|
97
|
+
'{64}' => single note by absolute note number
|
98
|
+
'_snare!' => drum note by instrument name
|
99
|
+
'{d,g,-b}' => multi note
|
100
|
+
':cmaj7,' => chord name
|
96
101
|
and other commands are with parentheses.
|
97
102
|
EOF
|
98
103
|
end
|
@@ -193,6 +198,22 @@ class Array
|
|
193
198
|
r
|
194
199
|
end
|
195
200
|
end
|
201
|
+
class ScaleNotes < Array
|
202
|
+
def setSampleRate c
|
203
|
+
@samplerate=c
|
204
|
+
end
|
205
|
+
# todo: use sample rate
|
206
|
+
def sample
|
207
|
+
self[rand(self.size)]
|
208
|
+
end
|
209
|
+
def sampleNote
|
210
|
+
if self.size==0
|
211
|
+
rand(0x7f)
|
212
|
+
else
|
213
|
+
self.sample
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
196
217
|
def unirand n,c,reset=false
|
197
218
|
a=[0,n]
|
198
219
|
while c>a.size
|
@@ -202,39 +223,97 @@ def unirand n,c,reset=false
|
|
202
223
|
a.sort_by{rand}
|
203
224
|
end
|
204
225
|
|
226
|
+
# accumulated time with event
|
227
|
+
class TotalTime
|
228
|
+
def initialize t=0
|
229
|
+
@t=t
|
230
|
+
@series={}
|
231
|
+
end
|
232
|
+
def set num,t
|
233
|
+
add(t)
|
234
|
+
@series[num]=@t
|
235
|
+
end
|
236
|
+
def addtime num,t
|
237
|
+
add(t)
|
238
|
+
@series[num]+=t
|
239
|
+
end
|
240
|
+
def add t
|
241
|
+
@t+=t
|
242
|
+
end
|
243
|
+
def get num
|
244
|
+
@series[num]
|
245
|
+
end
|
246
|
+
def all
|
247
|
+
@series
|
248
|
+
end
|
249
|
+
end
|
250
|
+
# midi event etc.
|
205
251
|
class Event
|
206
|
-
|
207
|
-
|
252
|
+
@@counter=0
|
253
|
+
@@tt=TotalTime.new
|
254
|
+
attr_accessor :type, :value
|
255
|
+
attr_reader :time, :number
|
256
|
+
def initialize ty,*arg
|
257
|
+
@number=@@counter
|
258
|
+
@@counter+=1
|
208
259
|
@type=ty
|
209
260
|
@pos=0
|
210
261
|
@value=""
|
211
262
|
case @type
|
212
|
-
|
213
|
-
|
263
|
+
# event without time; except ':e'
|
264
|
+
when :comment,:raw
|
265
|
+
settime(0)
|
214
266
|
@value=arg[0]
|
215
267
|
when :ahead
|
216
|
-
|
217
|
-
when :
|
268
|
+
settime(arg[0])
|
269
|
+
when :on,:off
|
218
270
|
when :mark
|
219
271
|
@mark,@track,@value=arg
|
220
|
-
|
221
|
-
|
272
|
+
# event with delta time; ':e'
|
273
|
+
when :dummy
|
274
|
+
when :e, :end, :sys
|
275
|
+
settime(arg[0])
|
222
276
|
@value=arg[1]
|
277
|
+
else
|
223
278
|
end
|
224
279
|
end
|
280
|
+
def settime t
|
281
|
+
@time=t
|
282
|
+
@@tt.set(@number,@time)
|
283
|
+
posset
|
284
|
+
end
|
285
|
+
def addtime t
|
286
|
+
@time+=t
|
287
|
+
@@tt.addtime(@number,t)
|
288
|
+
posset
|
289
|
+
end
|
290
|
+
def posset
|
291
|
+
@pos=@@tt.get(@number)
|
292
|
+
end
|
293
|
+
def showTotalTime
|
294
|
+
a=@@tt.all
|
295
|
+
a.keys.sort.map{|k|"#{k}: #{a[k]}"}
|
296
|
+
end
|
297
|
+
def reset
|
298
|
+
@@tt=TotalTime.new
|
299
|
+
end
|
225
300
|
def data
|
226
301
|
case @type
|
227
302
|
when :raw
|
228
303
|
rawdata(@value)
|
229
304
|
when :mark
|
230
305
|
"# marktrack(#{@track}_#{@mark}) [#{@value}]\n"
|
231
|
-
when :
|
306
|
+
when :comment,:on,:off
|
232
307
|
@value
|
233
308
|
else
|
234
309
|
varlenHex(@time)+@value
|
235
310
|
end
|
236
311
|
end
|
312
|
+
def display
|
313
|
+
"#{@pos}(#{@time}) #{@type} => #{@value}"
|
314
|
+
end
|
237
315
|
end
|
316
|
+
|
238
317
|
# arg=[steps],[values]
|
239
318
|
def mymerge span,*arg
|
240
319
|
r=[]
|
@@ -690,7 +769,8 @@ module MidiHex
|
|
690
769
|
@bendrange=2
|
691
770
|
@bendCent=1
|
692
771
|
@pancenter=64
|
693
|
-
@
|
772
|
+
@scalenotes=ScaleNotes.new
|
773
|
+
@prepareSet=[@tbase,@ch,@velocity,@velocityFuzzy,@basekey,@gateRate,@bendrange,@bendCent,@scalenotes]
|
694
774
|
@chmax=15
|
695
775
|
@bendrangemax=127
|
696
776
|
file="midi-programChange-list.txt"
|
@@ -755,7 +835,7 @@ module MidiHex
|
|
755
835
|
@bendCent=8192/@bendrange/100.0 if on
|
756
836
|
end
|
757
837
|
def self.trackPrepare tc=0
|
758
|
-
@tbase,@ch,@velocity,@velocityFuzzy,@basekey,@gateRate,@bendrange,@bendCent=@prepareSet
|
838
|
+
@tbase,@ch,@velocity,@velocityFuzzy,@basekey,@gateRate,@bendrange,@bendCent,@scalenotes=@prepareSet
|
759
839
|
@strokespeed=0
|
760
840
|
@preGate=[]
|
761
841
|
@preVelocity=[]
|
@@ -768,6 +848,7 @@ module MidiHex
|
|
768
848
|
tc=@chmax if tc>@chmax
|
769
849
|
@panoftrack=panbytrack(tc)
|
770
850
|
@ch=tc
|
851
|
+
Event.new(:dummy).reset
|
771
852
|
end
|
772
853
|
def self.header format,track,tbase=@tbase
|
773
854
|
format=[format,0xff].min
|
@@ -808,7 +889,7 @@ module MidiHex
|
|
808
889
|
start=@waitingtime
|
809
890
|
@waitingtime=0
|
810
891
|
@nowtime+=start
|
811
|
-
r=[Event.new(:
|
892
|
+
r=[Event.new(:on)]
|
812
893
|
r<<Event.new(:e,start," 9#{ch} #{key} #{vel} # #{start}後, sound on only , note #{@key} velocity #{velocity}\n")
|
813
894
|
r
|
814
895
|
end
|
@@ -874,6 +955,10 @@ module MidiHex
|
|
874
955
|
def self.dummyNote key,len,accent=false,sharp=0
|
875
956
|
vel=@velocity
|
876
957
|
vel+=@accentPlus
|
958
|
+
if key=="?"
|
959
|
+
key=rand(0x7f)
|
960
|
+
key=self.note2key(@scalenotes.sample) if @scalenotes.size>0
|
961
|
+
end
|
877
962
|
key=@preNote.shift if @preNote.size>0
|
878
963
|
len=@preLength.shift if @preLength.size>0
|
879
964
|
self.oneNote(len,key,vel,sharp)
|
@@ -1299,6 +1384,12 @@ module MidiHex
|
|
1299
1384
|
@chordCenter=[[0,@chordCenter].max,0x7f].min
|
1300
1385
|
@firstchordbase=@chordCenter
|
1301
1386
|
end
|
1387
|
+
def self.scale s
|
1388
|
+
s=s.split(",")
|
1389
|
+
s.each{|i|
|
1390
|
+
@scalenotes<<i
|
1391
|
+
}
|
1392
|
+
end
|
1302
1393
|
def self.preLength v
|
1303
1394
|
@preLength=v.map{|i|
|
1304
1395
|
case i
|
@@ -1391,11 +1482,12 @@ module MidiHex
|
|
1391
1482
|
Event.new(:mark,m,@tracknum,@nowtime)
|
1392
1483
|
end
|
1393
1484
|
def self.eventlist2str elist
|
1394
|
-
|
1485
|
+
@eventlist=[]
|
1486
|
+
r=@eventlist
|
1395
1487
|
# EventList : [func,args] or [callonly, func,args] or others
|
1396
1488
|
elist.each{|h|
|
1397
1489
|
cmd,*arg=h
|
1398
|
-
r<<Event.new(:
|
1490
|
+
r<<Event.new(:comment,"# #{cmd} #{arg}")
|
1399
1491
|
case cmd
|
1400
1492
|
when :basekeyPlus
|
1401
1493
|
@basekey+=arg[0]
|
@@ -1434,6 +1526,7 @@ module MidiHex
|
|
1434
1526
|
if i.class==String
|
1435
1527
|
rr<<i
|
1436
1528
|
else
|
1529
|
+
# Event class
|
1437
1530
|
case i.type
|
1438
1531
|
when :ahead
|
1439
1532
|
ahead=i.time
|
@@ -1442,16 +1535,16 @@ module MidiHex
|
|
1442
1535
|
n-=1 until (rr[n].time>0) || n<-10
|
1443
1536
|
if n>-10
|
1444
1537
|
ahead=[ahead,-rr[n].time].max
|
1445
|
-
rr[n].
|
1538
|
+
rr[n].addtime(ahead)
|
1446
1539
|
after=-ahead
|
1447
1540
|
else
|
1448
1541
|
after=0
|
1449
1542
|
end
|
1450
1543
|
when :end,:e,:sys
|
1451
|
-
(i.
|
1452
|
-
(i.
|
1544
|
+
(i.addtime(after);after=0) if after>0
|
1545
|
+
(i.addtime(after);after=0) if after<0 && i.time+after>=0
|
1453
1546
|
rr<<i
|
1454
|
-
when :
|
1547
|
+
when :comment,:raw,:mark
|
1455
1548
|
rr<<i
|
1456
1549
|
else
|
1457
1550
|
"? #{i}"
|
@@ -1483,7 +1576,7 @@ module MidiHex
|
|
1483
1576
|
@h<<[:controlChange,"10,#{@panoftrack}"] if @autopan
|
1484
1577
|
cmd=rundata.scan(/&\([^)]+\)|\([-+]*[[:digit:]]?\)|:[^\(,]+\([^\)\(]+\),|:[^,]+,|\([^:]*:[^)\(]*\)|_[^!_]+!|_[^_]__[^\?]+\?|v[[:digit:]]+|[<>][[:digit:]]*|\*?[[:digit:]]+\.[[:digit:]]+|\*?[[:digit:]]+|[-+[:alpha:]]|\^|`|'|./)
|
1485
1578
|
cmd<<" " # dummy
|
1486
|
-
p "
|
1579
|
+
p "track hex; start making: ",cmd if $DEBUG
|
1487
1580
|
cmd.each{|i|
|
1488
1581
|
if wait.size>0
|
1489
1582
|
t=@tbase
|
@@ -1657,6 +1750,8 @@ module MidiHex
|
|
1657
1750
|
@h<<[:soundOn,i]
|
1658
1751
|
when /^\(off:(.*)\)/
|
1659
1752
|
@h<<[:soundOff,$1]
|
1753
|
+
when /^\(scale:(.*)\)/
|
1754
|
+
@h<<[:call,:scale,$1]
|
1660
1755
|
when /^\(chordcenter:(.*)\)/
|
1661
1756
|
@h<<[:call,:chordCenter,$1]
|
1662
1757
|
when /^\(stroke:(.*)\)/
|
@@ -1722,7 +1817,7 @@ module MidiHex
|
|
1722
1817
|
wait<<[:dummyNote,i]
|
1723
1818
|
when " "
|
1724
1819
|
when "?"
|
1725
|
-
wait<<[:
|
1820
|
+
wait<<[:dummyNote,"?"]
|
1726
1821
|
else
|
1727
1822
|
if @notes.keys.member?(i)
|
1728
1823
|
wait<<[:sound,i]
|
@@ -1734,6 +1829,7 @@ module MidiHex
|
|
1734
1829
|
p @h if $DEBUG
|
1735
1830
|
puts "float rest add times: #{@frestc}" if $DEBUG
|
1736
1831
|
@h=self.eventlist2str(@h)
|
1832
|
+
p [:number_with_totaltime, Event.new(:dummy).showTotalTime],[:allevent,@eventlist.map{|i|i.display}] if $DEBUG && $debuglevel>2
|
1737
1833
|
@h*"\n# track: #{@tracknum} ==== \n"
|
1738
1834
|
end
|
1739
1835
|
def self.loadMap file, base=0
|
@@ -1840,6 +1936,7 @@ module MidiHex
|
|
1840
1936
|
@snare=self.percussionGet("snare")
|
1841
1937
|
end
|
1842
1938
|
end
|
1939
|
+
# substitute mark comment lines with shift delta time and dummy event hex data to adjust to most preceding track.
|
1843
1940
|
def self.trackMake data
|
1844
1941
|
@marksh||=@marktrack.calc
|
1845
1942
|
data=data.split("\n").map{|i|
|
data/lib/smml/version.rb
CHANGED
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.0.
|
4
|
+
version: 0.1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- tabasano
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|