smml 0.1.9 → 0.1.11

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 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