smml 0.1.9 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 85649d364edc63918512902fb5a190e1a9ae3bcc
4
- data.tar.gz: 0abe67520e10480fe4dee9fd115b7f33ec1805e9
3
+ metadata.gz: 922842aff19418ca5f712d524dd4c6260bba7b05
4
+ data.tar.gz: 88c1dd28f5c1f2ac2b1501dffae83e5a767e40c0
5
5
  SHA512:
6
- metadata.gz: 8db3bd75b42f437b91c8811f8be7c8beaf7ea057f1a7b04c3bd62c7cebdfcb228561f9deb80b848db00fe625b8336c7dfc4506fde10dd83a6195ec09ed8b794f
7
- data.tar.gz: fe2ade57a8a79b77fb085e3a4f7f6cdcc84a5dbb4f6ada084c736af5e66bf5a109acbd2e0e2afc7e6a2197b29c4b5b93ccc09f976a1221eea3b1a09256ca2734
6
+ metadata.gz: cb7ec5dc247cad1eed654dda4fa955bf609dbd393872037812269d5e073fb400f4cc25dd6a20e8f1d50ef098858ceacd0b686a477d35046b5bd001f07eef1c64
7
+ data.tar.gz: f7791a499278203e5684c6a740ac8ac1b45cdd186954e294be8016eac45f98c2f29aa9763564a26d9c19c59cc21ec772bb02d19180937d4c03e947be05648c37
data/lib/smml/msm.rb CHANGED
@@ -189,7 +189,7 @@ module MmlReg
189
189
  self.r(key,sort,pre)
190
190
  end
191
191
  def self.trackr
192
- self.r([:hexraw,:sharp,:chord,:word,:sound,:modifier,:velocity,:tempo,:num,:octave,:note,:mod,:note?,:sound?])
192
+ self.r([:hexraw,:sharp,:chord,:word,:sound,:modifier,:velocity,:tempo,:num,:octave,:note2,:note,:mod,:note?,:sound?])
193
193
  end
194
194
  def self.multipletr
195
195
  self.r([:note2,:word,:note,:sound,:chord,:num,:sharp,:octave,:mod])
@@ -250,8 +250,8 @@ module MmlReg
250
250
  ]
251
251
  @@h[:repmark]="\\.FINE|\\.DS|\\.DC|\\.\\$|\\.toCODA|\\.CODA|\\.SKIP"
252
252
  @@h[:comment]="\\( *comment[^\(\)]*\\)"
253
- @@h[:note2]="\\( *tne *:[^\(\)]*\\)"
254
- @@h[:word]="\\([^\(\):]*:[^\(\)]*\\)"
253
+ @@h[:note2]="\\( *tne *:[^\(\)]*\\)|\\( *[[:alpha:]\\-\\+]+,[^,]*\\)"
254
+ @@h[:word]="\\([^\(\):,]*:[^\(\)]*\\)"
255
255
  @@h[:wordStart]="\\([^\(\):]*:"
256
256
  @@h[:sharp]="\\([+-]*[[:digit:]\\.]*\\)"
257
257
  @@h[:word?]="\\([^\(\)]*\\)"
@@ -261,7 +261,7 @@ module MmlReg
261
261
  @@h[:note?]="[BE]"
262
262
  @@h[:dummyNote]="o"
263
263
  @@h[:randNote]="\\?"
264
- @@h[:sound]="_[^!]+!|=|~"
264
+ @@h[:sound]="_[^!]+!|=|~|w"
265
265
  @@h[:sound?]="[[:alpha:]]"
266
266
  @@h[:DCmark?]="\\.[[:alpha:]]+"
267
267
  @@h[:tempo]="[><][[:digit:]]*"
@@ -612,20 +612,20 @@ def mymerge span,*arg
612
612
  r=[]
613
613
  arg.each{|ar|
614
614
  next if ! ar
615
- m,steps,vs=ar
615
+ m,steps,start,vs=ar
616
616
  steps=[steps] if steps.class!=Array
617
617
  steps=steps*(vs.size-1) if steps.size==1
618
- r<<[0,m,vs[0]]
618
+ r<<[start,m,vs[0]]
619
619
  if vs.size>1
620
- stepsum=steps.inject{|s,i|s+i}
620
+ stepsum=steps.inject{|s,i|s+i}+start
621
621
  vsize=vs.size-1
622
622
  if stepsum>span
623
- rate=span*1.0/stepsum
623
+ rate=(span-start)*1.0/stepsum
624
624
  steps=steps.map{|i|(i*rate).to_i}
625
625
  end
626
626
  n=1
627
627
  r+=vs[1..-1].map{|i|
628
- t=steps.shift*n
628
+ t=steps.shift*n+start
629
629
  n+=1
630
630
  [t,m,i]
631
631
  }
@@ -800,6 +800,9 @@ def apply d,macro
800
800
  end
801
801
  }*""
802
802
  end
803
+ def innerdata pre,a
804
+ "_#{pre}__#{a*"_"}?"
805
+ end
803
806
  def rawHexPart d,macro={}
804
807
  li=d.scan(/\$se\([^)]*\)|\$delta\([^)]*\)|\$bend\([^)]*\)|\(bend:[^)]*\)|\(expression:[^)]*\)|\(expre:[^)]*\)|./)
805
808
  res=[]
@@ -814,29 +817,42 @@ def rawHexPart d,macro={}
814
817
  d=apply($1,macro)
815
818
  bendHex(d)
816
819
  when /\(bend:([^)]*)\)/
817
- "_b__#{$1.split(',')*"_"}?"
820
+ innerdata("b",$1.split(','))
818
821
  when /\(expre(ssion)?:([^)]*)\)/
819
- "_e__#{$2.split(',')*"_"}?"
822
+ innerdata("e",$1.split(','))
820
823
  else
821
824
  i
822
825
  end
823
826
  }*""
824
827
  end
825
- def revertPre d
826
- d.gsub(/_b__([^?]*)\?/){"(bend:#{$1.split("_")*","})"}.
827
- gsub(/_e__([^?]*)\?/){"(expre:#{$1.split("_")*","})"}
828
- end
829
828
  def worddata word,d
830
- d=~/\(#{word}:(([[:digit:].]+),)?([-+,.[:digit:]]+)\)/
829
+ d=~/\(#{word}:(([[:digit:].]+),)?([-+,.[:alnum:]]+|[[:alpha:]]+)\)/
831
830
  if $&
831
+ start=0
832
+ vp,vm=0,0
833
+ case word
834
+ when "bend"
835
+ vi=self.bendVibrato
836
+ vp,vm="+#{vi}","+-#{vi}"
837
+ when "expre"
838
+ vi=self.expreVibrato
839
+ vp,vm="+-#{vi}","+#{vi}"
840
+ when "panpot"
841
+ vi=self.panpotVibrato
842
+ vp,vm="+-#{vi}","+#{vi}"
843
+ end
832
844
  pos=$1 ? $2.to_i : 0
833
845
  depth=$3.split(',').map{|i|
834
846
  case i
835
847
  when "+","-" ; i
848
+ when /\Astart([[:digit:].]+)\z/
849
+ start=$1.to_i
850
+ false
851
+ when "vibrato" ; [vp,vm,vp,vm]
836
852
  else ; i
837
853
  end
838
- }
839
- [:"#{word}",pos,depth]
854
+ }.flatten-[false]
855
+ [:"#{word}",pos,start,depth]
840
856
  else
841
857
  false
842
858
  end
@@ -1146,6 +1162,7 @@ module MidiHex
1146
1162
  @bendrange=[[@bendrange,@bendrangemax].min,0].max
1147
1163
  self.bendCentReset
1148
1164
  r=[]
1165
+ r<<Event.new(:comment,"# bendRange #{@bendrange}")
1149
1166
  r<<self.controlChange("101,0")
1150
1167
  r<<self.controlChange("100,0")
1151
1168
  r<<self.controlChange("6,#{@bendrange}")
@@ -1155,6 +1172,34 @@ module MidiHex
1155
1172
  cent= @bendCentOn ? 100.0 : 1
1156
1173
  @bendCent=@bendHalfMax/@bendrange/cent
1157
1174
  end
1175
+ def self.vibratoMode m
1176
+ @vibratoMode=
1177
+ case m
1178
+ when /^expre/
1179
+ "expre"
1180
+ when /^bend/
1181
+ "bend"
1182
+ when /^pan/
1183
+ "panpot"
1184
+ else
1185
+ "bend"
1186
+ end
1187
+ end
1188
+ def self.bendVibrato
1189
+ @vibratoRate||=0.4
1190
+ v=@vibratoRate*@bendCent
1191
+ v.to_i
1192
+ end
1193
+ def self.expreVibrato
1194
+ @vibratoRate||=0.1
1195
+ v=@vibratoRate*@expression
1196
+ v.to_i
1197
+ end
1198
+ def self.panpotVibrato
1199
+ @vibratoRate||=0.5
1200
+ v=@vibratoRate*0x7f
1201
+ v.to_i
1202
+ end
1158
1203
  def self.bendCent on
1159
1204
  @bendCentOn=on
1160
1205
  self.bendCentReset
@@ -1245,6 +1290,7 @@ module MidiHex
1245
1290
  end
1246
1291
  def self.thereminNote pos,key,velocity,ch,exp=@expression
1247
1292
  r=[]
1293
+ r<<Event.new(:comment,"# use theremin")
1248
1294
  @expression=exp
1249
1295
  if @expression
1250
1296
  r<<self.expre(0,@expression)
@@ -1283,12 +1329,15 @@ module MidiHex
1283
1329
  if b
1284
1330
  bends=worddata("bend",b)
1285
1331
  expre=worddata("expre",b)
1286
- mymerge(slen,bends,expre).each{|t,m,d|
1332
+ panpot=worddata("panpot",b)
1333
+ mymerge(slen,bends,expre,panpot).each{|t,m,d|
1287
1334
  case m
1288
1335
  when :bend
1289
1336
  r<<self.bend(t,d)
1290
1337
  when :expre
1291
1338
  r<<self.expre(t,d)
1339
+ when :panpot
1340
+ r<<self.panpot(d,t)
1292
1341
  when :rest
1293
1342
  slen=t
1294
1343
  end
@@ -1359,6 +1408,7 @@ module MidiHex
1359
1408
  end
1360
1409
  bendStart=@bendNow
1361
1410
  @lastnoteName=c
1411
+ @basekey=@basekeyCenter+12*(rand(5)-2) if @broken
1362
1412
  n,@lastnote,@basekey=self.noteCalc(c,@lastnote,@basekey)
1363
1413
  r=[]
1364
1414
  if sharpFloat && sharpFloat!=0
@@ -1508,6 +1558,9 @@ module MidiHex
1508
1558
  def self.strokeUpDownReset
1509
1559
  @strokeUpDown=1
1510
1560
  end
1561
+ def self.setExpressionRest v
1562
+ @expressionRest=v.to_i
1563
+ end
1511
1564
  def self.rest len=@tbase,ch=@ch
1512
1565
  chx=format("%01x",ch)
1513
1566
  @nowtime+=len
@@ -1590,13 +1643,40 @@ module MidiHex
1590
1643
  @nowtime+=t
1591
1644
  Event.new(:e,t," B#{ch} #{n} #{data}\n")
1592
1645
  end
1646
+ def self.panpot v,pos=0
1647
+ @pan||=@panoftrack
1648
+ @pan=self.valueplus(@pan,v)
1649
+ self.controlChange("10,#{@pan},#{pos}")
1650
+ end
1651
+ def self.valueplus org,d
1652
+ d=d.to_s
1653
+ d=~/([+-]*)/
1654
+ sign=$1
1655
+ plus=false
1656
+ case sign
1657
+ when /^\+/
1658
+ d=d[1..-1].to_i
1659
+ plus=true
1660
+ when /^-/,""
1661
+ d=d.to_i
1662
+ else
1663
+ STDERR.puts "plus: ?"
1664
+ end
1665
+ if plus
1666
+ org+=d
1667
+ else
1668
+ org=d
1669
+ end
1670
+ org
1671
+ end
1593
1672
  def self.expre len,d
1594
1673
  c=@expression
1595
1674
  explus=10
1596
1675
  case d
1597
1676
  when "+" ; c+=explus
1598
1677
  when "-" ; c-=explus
1599
- else ; c=d.to_i
1678
+ else
1679
+ c=self.valueplus(c,d)
1600
1680
  end
1601
1681
  c=midiVround(c)
1602
1682
  @expression=c
@@ -1711,6 +1791,7 @@ module MidiHex
1711
1791
  @programList.map{|i,v|"#{i} #{v}"}
1712
1792
  end
1713
1793
  def self.bend pos,depth,ch=false
1794
+ @lastbend||=0
1714
1795
  ch=@ch if ! ch
1715
1796
  depth.to_s=~/([+-]*)/
1716
1797
  sign=$1
@@ -1725,9 +1806,11 @@ module MidiHex
1725
1806
  else
1726
1807
  STDERR.puts "bend: ?"
1727
1808
  end
1728
- depth=@lastbend+depth if plus
1729
- @lastbend=depth
1730
1809
  depth=(depth*@bendCent).to_i if @bendCentOn
1810
+ if plus
1811
+ depth=@lastbend+depth
1812
+ end
1813
+ @lastbend=depth
1731
1814
  pos+=@waitingtime
1732
1815
  @waitingtime=0
1733
1816
  @nowtime+=pos
@@ -1882,6 +1965,13 @@ module MidiHex
1882
1965
  end
1883
1966
  }
1884
1967
  end
1968
+ def self.revertPre d
1969
+ mode=@vibratoMode
1970
+ d.gsub(/_b__([^?]*)\?/){"(bend:#{$1.split("_")*","})"}.
1971
+ gsub(/_e__([^?]*)\?/){"(expre:#{$1.split("_")*","})"}.
1972
+ gsub(/_p__([^?]*)\?/){"(panpot:#{$1.split("_")*","})"}.
1973
+ gsub(/_m__([^?]*)\?/){"(#{mode}:#{$1.split("_")*","})"}
1974
+ end
1885
1975
  def self.preAfter v
1886
1976
  @preAfter=v.map{|i|
1887
1977
  case i
@@ -1995,12 +2085,25 @@ module MidiHex
1995
2085
  r<<self.expre(restl,e)
1996
2086
  r
1997
2087
  end
2088
+ def self.noteExpression arg,t,accent,sharp,sharpFloat
2089
+ lexpression=@expression
2090
+ n,e=arg.split(',')
2091
+ r=[]
2092
+ r<<self.expre(0,e)
2093
+ r<<self.notes(n,t,accent,sharp,sharpFloat)
2094
+ r<<self.expre(0,lexpression)
2095
+ r
2096
+ end
1998
2097
  # transition rate, note, expression
1999
2098
  def self.tne arg,t,accent,sharp,sharpFloat
2000
2099
  exp=@expression
2001
2100
  trans,n,e=arg.split(',')
2101
+ trans=0.3 if trans.size==0
2002
2102
  trans=trans.to_f
2003
- trans=0.3 if trans==0
2103
+ if trans>1
2104
+ STDERR.puts "(tne) transition rate must be between 0 and 1."
2105
+ trans=1.0
2106
+ end
2004
2107
  bchange=0
2005
2108
  @nowTne=[n,e,sharp,sharpFloat,@basekey]
2006
2109
  if @lastTne
@@ -2021,6 +2124,21 @@ module MidiHex
2021
2124
  @lastTne[-1]=@basekey
2022
2125
  r
2023
2126
  end
2127
+ def self.broken v
2128
+ v=~/off/
2129
+ @broken= $& ? false : true
2130
+ @basekeyCenter=@basekey
2131
+ end
2132
+ def self.dumpVar v
2133
+ v=~/\A[[:alnum:]]+\z/
2134
+ if $&
2135
+ puts "@#{v} #{eval("@#{v}")}"
2136
+ elsif v=="?"
2137
+ puts self.instance_variables.map{|i|i.to_s[1..-1]}.sort
2138
+ else
2139
+ puts "bad name '#{v}'"
2140
+ end
2141
+ end
2024
2142
  def self.eventlist2str elist
2025
2143
  @eventlist=[]
2026
2144
  r=@eventlist
@@ -2028,7 +2146,7 @@ module MidiHex
2028
2146
  elist.each{|h|
2029
2147
  cmd,*arg=h
2030
2148
  e=Event.new(:comment,"# #{cmd} #{arg}")
2031
- r<<Event.new(:raw,self.metaText("#{cmd} #{arg}")) if $DEBUG && $debuglevel>5
2149
+ r<<Event.new(:raw,self.metaText("#{cmd} #{arg}").data) if $debuglevel>5
2032
2150
  r<<e
2033
2151
  case cmd
2034
2152
  when :comment
@@ -2046,6 +2164,20 @@ module MidiHex
2046
2164
  @ch=arg[0]
2047
2165
  when :waitingtime
2048
2166
  @waitingtime+=arg[0]
2167
+ when :setInt
2168
+ name,v=arg
2169
+ if name.to_s=~/\A[[:alnum:]]+\z/
2170
+ eval("@#{name}=#{v.to_i}")
2171
+ else
2172
+ STDERR.puts "setInt: bad name '#{name}'"
2173
+ end
2174
+ when :setFloat
2175
+ name,v=arg
2176
+ if name.to_s=~/\A[[:alnum:]]+\z/
2177
+ eval("@#{name}=#{v.to_f}")
2178
+ else
2179
+ STDERR.puts "setFloat: bad name '#{name}'"
2180
+ end
2049
2181
  when :call
2050
2182
  cmd,*arg=arg
2051
2183
  method(cmd).call(*arg)
@@ -2111,7 +2243,7 @@ module MidiHex
2111
2243
  accent=false
2112
2244
  sharp=0
2113
2245
  sharpFloat=0
2114
- @h<<[:controlChange,"10,#{@panoftrack}"] if @autopan
2246
+ @h<<[:panpot,@panoftrack] if @autopan
2115
2247
  cmd=mmldata.scan(/#{MmlReg.trackr}|./)
2116
2248
  cmd<<" " # dummy
2117
2249
  p "track hex; start making: ",cmd if $DEBUG
@@ -2143,6 +2275,8 @@ module MidiHex
2143
2275
  @h<<[:percussionNote,*arg]
2144
2276
  when :rawsound
2145
2277
  @h<<[:byKey,*arg]
2278
+ when :noteExpression
2279
+ @h<<[:noteExpression,*arg2]
2146
2280
  when :tne
2147
2281
  @h<<[:tne,*arg2]
2148
2282
  when :sound
@@ -2184,10 +2318,17 @@ module MidiHex
2184
2318
  tr=$2.to_i
2185
2319
  tr*=-1 if $1=="-"
2186
2320
  @h<<[:basekeyPlus,tr]
2321
+ when /^\(broken:(.*)\)/
2322
+ @h<<[:call,:broken,$1]
2187
2323
  when /^\(tne:(.*)\)/
2188
2324
  wait<<[:tne,$1]
2325
+ when /^\(([[:alpha:]\-\+]+),([^,]*)\)/
2326
+ v="#{$1},#{$2}"
2327
+ wait<<[:noteExpression,v]
2189
2328
  when /^\(lg:(.*)\)/
2190
2329
  @h<<[:call,:setlenforgate,$1]
2330
+ when /^\(expressionRest:(.*)\)/
2331
+ @h<<[:call,:setExpressionRest,$1]
2191
2332
  when /^\(theremin:(.*)\)/
2192
2333
  if $1=~/off/
2193
2334
  @h<<[:setTheremin,false]
@@ -2221,6 +2362,19 @@ module MidiHex
2221
2362
  @h<<[:call,:preBefore,s]
2222
2363
  when /^\(roll:(.*)\)/
2223
2364
  @shiftbase=$1.to_i
2365
+ when /^\(vibratoMode:(.*)\)/
2366
+ @h<<[:call,:vibratoMode,$1]
2367
+ when /^\(vibrato:(.*)\)/
2368
+ v=$1
2369
+ @h<<[:setFloat,:vibratoRate,v]
2370
+ when /^\(setFloat:(.*)\)/
2371
+ name,v=$1.split(",")
2372
+ @h<<[:setFloat,name,v]
2373
+ when /^\(setInt:(.*)\)/
2374
+ name,v=$1.split(",")
2375
+ @h<<[:setInt,name,v]
2376
+ when /^\(dumpVar:(.*)\)/
2377
+ @h<<[:call,:dumpVar,$1]
2224
2378
  when /^\(oct(ave)?:(.*)\)/
2225
2379
  oct=($2.to_i+2)*12
2226
2380
  @h<<[:call,:basekeySet,oct]
@@ -2238,8 +2392,8 @@ module MidiHex
2238
2392
  @h<<[:ProgramChange,channel,instrument]
2239
2393
  when /^\(bend:(([[:digit:]]+),)?([-+,.[:digit:]]+)\)|^_b__([^?]+)\?/
2240
2394
  i="(bend:#{$4.gsub('_'){','}})" if $4
2241
- x,pos,b=worddata("bend",i)
2242
- npos=0
2395
+ x,pos,start,b=worddata("bend",i)
2396
+ npos=start
2243
2397
  b.each{|depth|
2244
2398
  @h<<[:bend,npos,depth]
2245
2399
  npos=pos
@@ -2301,12 +2455,12 @@ module MidiHex
2301
2455
  pan=$2.to_i
2302
2456
  case $1
2303
2457
  when ">"
2304
- pan+=64
2458
+ pan=64+pan
2305
2459
  when "<"
2306
- pan-=64
2460
+ pan=64-pan
2307
2461
  else
2308
2462
  end
2309
- @h<<[:controlChange,"10,#{pan}"]
2463
+ @h<<[:panpot,pan]
2310
2464
  when /^\(wait:(\*)?(.*)\)/
2311
2465
  @h<<[:waitingtime,$1? $2.to_i : $2.to_f*@tbase]
2312
2466
  when /^\(accent:([^)]*)\)/
@@ -2575,7 +2729,7 @@ def multiplet d,tbase
2575
2729
  when /^[-+]+[[:digit:]]*/,/^[\^`',<>]/,/^\([-+]*[[:digit:]]?\)/
2576
2730
  mod<<i
2577
2731
  # note
2578
- when /^\((\?|x|C|chord|tne):[^\)]+\)|^\^?:[^,]+,|^=/
2732
+ when /^\((\?|x|C|chord|tne):[^\)]+\)|^\^?:[^,]+,|^=|\([[:alpha:]\\-\\+]+,[^,]*\)/
2579
2733
  lengths<<1
2580
2734
  notes<<"#{mod*""}#{i}"
2581
2735
  mod=[]
@@ -2583,7 +2737,7 @@ def multiplet d,tbase
2583
2737
  when /^[[:digit:]]+/
2584
2738
  lengths[-1]*=i.to_f
2585
2739
  when " "
2586
- when /^\([^\)]*\)/
2740
+ when /^\([^\(\):,]*:.*\)/
2587
2741
  mod<<i
2588
2742
  else
2589
2743
  lengths<<1
@@ -2708,8 +2862,16 @@ end
2708
2862
  def tie d,tbase
2709
2863
  res=[]
2710
2864
  # if no length word after '~' length is 1
2711
- d.gsub!(/~([^*[:digit:]])?/){$1 ? "~1#{$1}" : $&} while d=~/~[^*[:digit:]]/
2712
- li=d.scan(MmlReg::RwAll)
2865
+ li=[]
2866
+ li0=d.scan(MmlReg::RwAll)
2867
+ li0.size.times{|i|
2868
+ li<<li0[i]
2869
+ case li0[i]
2870
+ when "~","w"
2871
+ li<<"1" if li0[i+1] !~ /^(\*)?[[:digit:]]/
2872
+ else
2873
+ end
2874
+ }
2713
2875
  li.each{|i|
2714
2876
  case i
2715
2877
  when /^(\*)?([[:digit:].]+)/
@@ -2721,6 +2883,13 @@ def tie d,tbase
2721
2883
  end
2722
2884
  when "~"
2723
2885
  res<<[:tick,tbase] if res[-1][0]==:e
2886
+ when "w"
2887
+ lasttick=0
2888
+ lasttick=res[-1][1] if res[-1][0]==:tick
2889
+ res<<[:tick,tbase] if res[-1][0]==:e
2890
+ m="m"
2891
+ d=innerdata(m,["100_start#{lasttick}_vibrato"])
2892
+ res.insert(-3,[:modifier,"(A:#{d})"])
2724
2893
  when /^\([VGABLN]:[^)]+/
2725
2894
  res<<[:modifier,i]
2726
2895
  else
@@ -2760,7 +2929,14 @@ end
2760
2929
  # '(:..)' => '(lastcmd:..)'
2761
2930
  def repCalc line,macro,tbase
2762
2931
  rpt=/\[([^\[\]]*)\] *([[:digit:]]+)/
2763
- line.gsub!(rpt){$1*$2.to_i} while line=~rpt
2932
+ line.gsub!(rpt){
2933
+ data,rep=$1,$2.to_i
2934
+ r=""
2935
+ rep.times{|i|
2936
+ r<<data.gsub(/_REPEAT_([-\*\+[:digit:]]*)/){eval("#{i+1}#{$1}")}
2937
+ }
2938
+ r
2939
+ } while line=~rpt
2764
2940
  chord=/([^$]|^)\{([^\{\}]*)\}/
2765
2941
  line.gsub!(chord){"#{$1}(C:#{$2})"} while line=~chord
2766
2942
  line=line.scan(/(\.\$)|(\$([[:alnum:]]+)\(([^\)]+)\))|(.)/).map{|a,b,bname,barg,c|
data/lib/smml/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Smml
2
- VERSION = "0.1.9"
2
+ VERSION = "0.1.11"
3
3
  end
data/tutorial_smml.md CHANGED
@@ -814,6 +814,27 @@ f~~(lg:1.0)f~~f~~
814
814
 
815
815
  rest of second 'f' is 30% of one beat instead others are 30% of three beats.
816
816
 
817
+ ;; vibrato
818
+
819
+ ```
820
+ f~~ww~~
821
+ ```
822
+
823
+ note f then vibrato. bend or expression, under construction.
824
+
825
+ ;; _REPEAT_ variable
826
+
827
+ ```
828
+ [ a _REPEAT_ ] 3 ;; => a1 a2 a3
829
+ ```
830
+
831
+ ;; broken mode
832
+ as if uncontrolled
833
+
834
+ ```
835
+ (broken:on) (broken:off)
836
+ ```
837
+
817
838
  ## preprocess
818
839
  ;; some pre-process commands.
819
840
  set it in the top of file.
@@ -852,3 +873,14 @@ text implement to MIDI file.
852
873
 
853
874
  but now blanks are removed. someday maybe fixed ?
854
875
 
876
+
877
+ ## test, debug etc.
878
+
879
+ ```
880
+ (setInt: varName,10)
881
+ (setFloat: varName,10.1)
882
+ (dumpVar: varName)
883
+ ```
884
+
885
+ directly set local MidiHex variable, dump while compiling if the varName and value are valid.
886
+
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.9
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - tabasano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-09 00:00:00.000000000 Z
11
+ date: 2014-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler