smml 0.1.6 → 0.1.8

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: 399ce12531f91fa0f95a418517a7eaf3a9033119
4
- data.tar.gz: 075f0f29408e73724c191251ed701b56c1818182
3
+ metadata.gz: e2a5f8a92f538689c4376fde815e064a7d4887ec
4
+ data.tar.gz: cb84d1b91997d306b5de5bbdb4033c3a01e0a1ca
5
5
  SHA512:
6
- metadata.gz: 0d8dfed6fcff8b3364fc72a52988fd389a841e1eb93f0b472a2ad08aa4e00787f26ef05c030afdf9bbfa5c208a7e6cc6e93738055c10c026e08666494b907e37
7
- data.tar.gz: af807db0f9b857c2aee7a086fb5e9a16f8ee12738fb4c2ae752b54eb6c0df9135353d44d04fd09d4c54bb24a45e6ecf28719add73df77db387d7fe8be1639a41
6
+ metadata.gz: d31c883cdba860e6dc39175eccad5d8ce55cfe95c31fba806042473ae9e5dff29bf3506f8b6c762c62d75fba36b6cfa20b56c257700e03b11fe4fe36d711fd95
7
+ data.tar.gz: 14dff95b8b0cdf6c81eedb3fa284cb16c9e0d9ed7250022b0eb0928e4c626f68849e1c6614c27896197e4a5825ce6856e8806b87adbe4b2f3e66df2d578ad589
data/lib/smml/msm.rb CHANGED
@@ -7,7 +7,7 @@ $debuglevel=0
7
7
 
8
8
  # as gem or this file only
9
9
  def version
10
- if defined?(Smml) && ( Smml.constants.member?("VERSION") || Smml.constants.member?("VERSION") )
10
+ if defined?(Smml) && ( Smml.constants.member?("VERSION") || Smml.constants.member?(:VERSION) )
11
11
  Smml::VERSION
12
12
  else
13
13
  File.mtime(__FILE__).strftime("%Y-%m-%d")
@@ -170,14 +170,14 @@ end
170
170
 
171
171
  #===========================================================
172
172
  module MmlReg
173
- def self.r key, sort=true
173
+ def self.r key, sort=true, pre=""
174
174
  raise if sort.class==Symbol
175
175
  case key
176
176
  when Array
177
177
  raise if (key-@@keys).size>0
178
178
  ks=key
179
179
  ks=(@@keys-(@@keys-ks)) if sort
180
- ks.map{|i|@@h[i]}*"|"
180
+ ks.map{|i|"#{pre}#{@@h[i]}"}*"|"
181
181
  else
182
182
  @@h[key]
183
183
  end
@@ -185,13 +185,24 @@ module MmlReg
185
185
  puts "Regex part,arg bug",[key-@@keys]
186
186
  raise
187
187
  end
188
+ def self.rPlusPre key, pre, sort=true
189
+ self.r(key,sort,pre)
190
+ end
188
191
  def self.trackr
189
- self.r([:hexraw,:sharps,: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,:note,:mod,:note?,:sound?])
193
+ end
194
+ def self.multipletr
195
+ self.r([:word,:note,:sound,:chord,:num,:sharp,:octave,:mod])
196
+ end
197
+ def self.macroDefr
198
+ self::MacroDef
199
+ end
200
+ def self.repeatr
201
+ self.r([:repStart,:repEnd,:repmark])
190
202
  end
191
203
  @@h={} # mml regex key hash. order is in @@keys
192
204
  @@keys=[
193
205
  :comment,
194
- :keyword,
195
206
  :macrodefAStart,
196
207
  :macrodefA,
197
208
  :macrodefStart,
@@ -208,13 +219,12 @@ module MmlReg
208
219
  :repEnd,
209
220
  :word,
210
221
  :modifier,
211
- :sharps,
222
+ :sharp,
212
223
  :wordStart,
213
224
  :word?,
214
225
  :chord,
215
226
  :velocity,
216
227
  :sound,
217
- :DCmark,
218
228
  :tempo,
219
229
  :mod,
220
230
  :octave,
@@ -233,12 +243,15 @@ module MmlReg
233
243
  :sound?,
234
244
  :plusMinus,
235
245
  :lineSep,
246
+ :repmark,
247
+ :DCmark?,
236
248
  :chord?,
237
249
  ]
250
+ @@h[:repmark]="\\.FINE|\\.DS|\\.DC|\\.\\$|\\.toCODA|\\.CODA|\\.SKIP"
238
251
  @@h[:comment]="\\( *comment[^\(\)]*\\)"
239
252
  @@h[:word]="\\([^\(\):]*:[^\(\)]*\\)"
240
253
  @@h[:wordStart]="\\([^\(\):]*:"
241
- @@h[:sharps]="\\([+-]*[[:digit:]]*\\)"
254
+ @@h[:sharp]="\\([+-]*[[:digit:]\\.]*\\)"
242
255
  @@h[:word?]="\\([^\(\)]*\\)"
243
256
  @@h[:chord]="\\{[^\{\}]+,[^\{\},]+\\}|:[[:alpha:]][[:alnum:]]*,"
244
257
  @@h[:velocity]="v[[:digit:]]+"
@@ -248,7 +261,7 @@ module MmlReg
248
261
  @@h[:randNote]="\\?"
249
262
  @@h[:sound]="_[^!]+!|=|~"
250
263
  @@h[:sound?]="[[:alpha:]]"
251
- @@h[:DCmark]="\\.\\$|\\.[[:alpha:]]+"
264
+ @@h[:DCmark?]="\\.[[:alpha:]]+"
252
265
  @@h[:tempo]="[><][[:digit:]]*"
253
266
  @@h[:mod]="[`'^]"
254
267
  @@h[:octave]= "[+-][[:digit:]]*"
@@ -262,13 +275,12 @@ module MmlReg
262
275
  @@h[:num]="[-+*]?[[:digit:]]+\\.[[:digit:]]+|[-+*]?[[:digit:]]+"
263
276
  @@h[:hexraw]="&\\([^()]*\\)"
264
277
  @@h[:hexrawStart]="&\\("
265
- @@h[:keyword]="macro +"
266
278
  @@h[:macroA]="\\$\\{[^}]+\\}\\[[^\\]]+\\]|\\$[^}\\$\\{\\(\\)]+\\[[^\\]]+\\]"
267
279
  @@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]+"
280
+ @@h[:macrodefAStart]="[[:alnum:]]+\\([,[:alpha:]]+\\):= *\\( *[;\\z]"
281
+ @@h[:macrodefA]= "[[:alnum:]]+\\([,[:alpha:]]+\\):= *[^\\(;\\n][^;\\n]*"
282
+ @@h[:macrodefStart]="[[:alnum:]]+:= *\\( *[;\\z]"
283
+ @@h[:macrodef]= "[[:alnum:]]+:= *[^\\(;\\n][^;\\n]+"
272
284
  @@h[:blank]="[[:blank:]]+"
273
285
  @@h[:valueSep]=","
274
286
  @@h[:parenStart]="\\("
@@ -281,7 +293,9 @@ module MmlReg
281
293
  @@h[:modifier]="_[^_]__[^\\?]+\\?"
282
294
  r=self.r(@@keys)
283
295
  RwAll=/#{r}|./
284
- MacroDef=self.r([:macrodefAStart,:macrodefStart,:macrodefA,:macrodef])
296
+ MacroDef=self.rPlusPre([:macrodefAStart,:macrodefStart,:macrodefA,:macrodef],"macro *")+"|"+
297
+ self.r([:macrodefAStart,:macrodefStart,:macrodefA,:macrodef])
298
+ RepStrArray=["[","]",".CODA",".DS",".DC",".FINE",".toCODA",".$",".SKIP"]
285
299
  ArgIsOne=%w[ bendCent mark p gm gs xg loadf text ]
286
300
  def self.event m,rest=[]
287
301
  ((@@keys-rest).map{|k|m=~/\A#{@@h[k]}\z/ ? k : nil}-[nil])[0]
@@ -628,7 +642,6 @@ end
628
642
  def trackSizeHex d,cmark="#"
629
643
  d=d.commentoff("",cmark).split.join
630
644
  i=(d.size+8)/2
631
- # p [d,i,i.to_s(16)]
632
645
  #("00000000"+i.to_s(16))[-8..-1]
633
646
  format("%08x",i)+" # size: #{i}"
634
647
  end
@@ -708,8 +721,8 @@ def txt2hex t
708
721
  [r*" ",varlenHex(size)]
709
722
  end
710
723
  def bendHex d
711
- c=d.to_i+8192
712
- c=[[c,0].max,16383].min
724
+ c=d.to_i+MidiHex::BendHalf
725
+ c=[[c,0].max,MidiHex::BendMax].min
713
726
  a=c>>7
714
727
  b=c & 0b01111111
715
728
  r=[a,b,b*0x100+a]
@@ -816,7 +829,7 @@ def worddata word,d
816
829
  depth=$3.split(',').map{|i|
817
830
  case i
818
831
  when "+","-" ; i
819
- else ; i.to_f
832
+ else ; i
820
833
  end
821
834
  }
822
835
  [:"#{word}",pos,depth]
@@ -1012,9 +1025,12 @@ def guitarTuning
1012
1025
  %W[-e -a d g b +e]
1013
1026
  end
1014
1027
  module MidiHex
1028
+ BendMax=16383
1029
+ BendHalf=8192
1015
1030
  # 設定のため最初に呼ばなければならない
1016
1031
  def self.prepare bpm=120,tbase=480,vel=0x40,oct=:near,vfuzzy=2,strict=false
1017
1032
  @ready=true
1033
+ @bendHalfMax=BendHalf
1018
1034
  @strictmode=strict
1019
1035
  @autopan= strict ? false : true
1020
1036
  @strokefaster= strict ? 1 : 3
@@ -1033,7 +1049,9 @@ module MidiHex
1033
1049
  @rythmChannel=9
1034
1050
  @notes=Notes.new
1035
1051
  @ch=0
1036
- @expression=0x7f
1052
+ @expressionRest=0x60
1053
+ @expressionDef=0x7f
1054
+ @expression=@expressionDef
1037
1055
  @velocity=vel
1038
1056
  @velocityOrg=vel
1039
1057
  @velocityFuzzy=vfuzzy
@@ -1046,7 +1064,7 @@ module MidiHex
1046
1064
  @pancenter=64
1047
1065
  @scalenotes=ScaleNotes.new.reset
1048
1066
  @gtune=guitarTuning
1049
- @prepareSet=[@tbase,@ch,@velocity,@expression,@velocityFuzzy,@basekey,@gateRate,@bendrange,@bendCent,@scalenotes,@gtune]
1067
+ self.setDefault
1050
1068
  @chmax=15
1051
1069
  @bendrangemax=127
1052
1070
  file="midi-programChange-list.txt"
@@ -1058,6 +1076,15 @@ module MidiHex
1058
1076
  self.loadPercussionMap(pfile)
1059
1077
  self.dumpstatus if $DEBUG && $debuglevel>3
1060
1078
  end
1079
+ def self.setDefault
1080
+ @prepareSet=[
1081
+ @tbase,@ch,@velocity,@expression,@velocityFuzzy,@basekey,@gateRate,@bendrange,@bendCent,@scalenotes,@gtune,@expressionRest,@expressionDef
1082
+ ]
1083
+ end
1084
+ def self.getDefault
1085
+ @tbase,@ch,@velocity,@expression,@velocityFuzzy,@basekey,@gateRate,@bendrange,@bendCent,@scalenotes,@gtune,@expressionRest,@expressionDef=
1086
+ @prepareSet
1087
+ end
1061
1088
  def self.dumpstatus
1062
1089
  self.instance_variables.each{|i|
1063
1090
  val=self.instance_variable_get(i)
@@ -1098,6 +1125,7 @@ module MidiHex
1098
1125
  @gateRate=[g,100].min
1099
1126
  end
1100
1127
  def self.bendRange v
1128
+ @lastbend=0
1101
1129
  case v
1102
1130
  when /^\+/
1103
1131
  @bendrange+=$'.to_i
@@ -1115,10 +1143,12 @@ module MidiHex
1115
1143
  end
1116
1144
  def self.bendCent on
1117
1145
  @bendCent=1
1118
- @bendCent=8192/@bendrange/100.0 if on
1146
+ @bendCent=@bendHalfMax/@bendrange/100.0 if on
1147
+ @lastbend=0
1119
1148
  end
1120
1149
  def self.trackPrepare tc=0
1121
- @tbase,@ch,@velocity,@expression,@velocityFuzzy,@basekey,@gateRate,@bendrange,@bendCent,@scalenotes,@gtune=@prepareSet
1150
+ self.getDefault
1151
+ @theremin=false
1122
1152
  @strokespeed=0
1123
1153
  @strokeUpDown=1
1124
1154
  @preGate=[]
@@ -1195,6 +1225,20 @@ module MidiHex
1195
1225
  r<<Event.new(:end,start," 8#{ch} #{key} 00 # #{start} sound off only [#{(@nowtime/@tbase).to_i}, #{@nowtime%@tbase}]\n")
1196
1226
  r
1197
1227
  end
1228
+ def self.thereminNote pos,key,velocity,ch,exp=@expressionDef
1229
+ r=[]
1230
+ @expression=exp
1231
+ if @expression
1232
+ r<<self.expre(0,@expression)
1233
+ end
1234
+ start=@waitingtime
1235
+ @waitingtime=0
1236
+ pos-=start
1237
+ depth=(key-@thereminNote)*100
1238
+ r<<self.bend(start,depth.to_s,ch)
1239
+ r<<self.bend(pos,depth.to_s,ch)
1240
+ r
1241
+ end
1198
1242
  def self.oneNote len=@tbase,key=@basekey,velocity=@velocity,ch=@ch,sharp=0
1199
1243
  velocity=@preVelocity.shift if @preVelocity.size>0
1200
1244
  gate=@gateRate
@@ -1203,6 +1247,7 @@ module MidiHex
1203
1247
  velocity=[velocity,0x7f].min
1204
1248
  key+=sharp
1205
1249
  @key=[[key,0x7f].min,0].max
1250
+ return self.thereminNote(len,key,velocity,ch) if @theremin
1206
1251
  key=format("%02x",@key)
1207
1252
  ch=format("%01x",ch)
1208
1253
  vel=format("%02x",velocity)
@@ -1270,7 +1315,8 @@ module MidiHex
1270
1315
  vel+=@accentPlus if accent
1271
1316
  self.oneNote(len,key,vel,@rythmChannel,sharp)
1272
1317
  end
1273
- def self.notes c,l=false,accent=false,sharp=0
1318
+ def self.notes c,l=false,accent=false,sharp=0,sharpFloat=false
1319
+ @lastnoteName=c
1274
1320
  n=@notes[c]
1275
1321
  if @octmode==:near && n.class != Array
1276
1322
  if @lastnote
@@ -1282,7 +1328,17 @@ module MidiHex
1282
1328
  (@basekey-=12;@lastnote+=12) if n<0
1283
1329
  n=@lastnote
1284
1330
  end
1285
- self.notekey(n,l,accent,sharp)
1331
+ r=[]
1332
+ if sharpFloat && sharpFloat!=0
1333
+ v=sharpFloat*@bendHalfMax
1334
+ v=sharpFloat*100 if @bendCent>1
1335
+ r<<self.bend(0,v)
1336
+ r<<self.notekey(n,l,accent,sharp)
1337
+ r<<self.bend(0,0)
1338
+ else
1339
+ r<<self.notekey(n,l,accent,sharp)
1340
+ end
1341
+ r
1286
1342
  end
1287
1343
  def self.shiftChord chord, base, limit=6
1288
1344
  octave=12
@@ -1419,12 +1475,19 @@ module MidiHex
1419
1475
  chx=format("%01x",ch)
1420
1476
  @nowtime+=len
1421
1477
  r=[]
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")
1478
+ if @theremin
1479
+ min=@expressionRest
1480
+ r<<Event.new(:comment,"# rest; ")
1481
+ r<<self.expre(0,min)
1482
+ r<<self.expre(len,min)
1483
+ else
1484
+ r<<Event.new(:end,len," 8#{chx} 3C 00 # rest #{len.to_i}(#{len.round(2)})ticks later, off:ch#{ch}, key:3C\n")
1485
+ end
1423
1486
  r
1424
1487
  end
1425
1488
  def self.restHex len=@tbase,ch=@ch
1426
1489
  r=self.rest(len,ch)
1427
- r[0].data
1490
+ r[0]
1428
1491
  end
1429
1492
  # d : hex data
1430
1493
  def self.metaEvent d,type=1
@@ -1436,7 +1499,7 @@ module MidiHex
1436
1499
  hexd,len=txt2hex(d)
1437
1500
  delta=varlenHex(pos)
1438
1501
  e=self.metaEvent hexd,type
1439
- "#{delta} #{e} # #{d}\n"
1502
+ Event.new(:raw,"#{delta} #{e} # #{d}\n")
1440
1503
  end
1441
1504
  def self.metaTitle d=@title,pos=0
1442
1505
  return "" if not d
@@ -1461,7 +1524,7 @@ module MidiHex
1461
1524
  delta=varlenHex(pos)
1462
1525
  t=format("%02X",type)
1463
1526
  len=varlenHex(d.split.join.size/2)
1464
- "#{delta} FF #{t} #{len} #{d} # #{pos} #{comment}\n"
1527
+ Event.new(:raw,"#{delta} FF #{t} #{len} #{d} # #{pos} #{comment}\n")
1465
1528
  end
1466
1529
  def self.tempo bpm, len=0
1467
1530
  @bpmStart=bpm if ! @bpm
@@ -1611,6 +1674,21 @@ module MidiHex
1611
1674
  end
1612
1675
  def self.bend pos,depth,ch=false
1613
1676
  ch=@ch if ! ch
1677
+ depth.to_s=~/([+-]*)/
1678
+ sign=$1
1679
+ plus=false
1680
+ case sign.size
1681
+ when 0..1
1682
+ depth=depth.to_f
1683
+ plus=true if sign=="+"
1684
+ when 2
1685
+ depth=depth[1..-1].to_f
1686
+ plus=true
1687
+ else
1688
+ STDERR.puts "bend: ?"
1689
+ end
1690
+ depth=@lastbend+depth if plus
1691
+ @lastbend=depth
1614
1692
  depth=(depth*@bendCent).to_i
1615
1693
  pos+=@waitingtime
1616
1694
  @waitingtime=0
@@ -1805,9 +1883,41 @@ module MidiHex
1805
1883
  @strokespeed=s.abs
1806
1884
  end
1807
1885
  end
1886
+ def self.setTheremin flag
1887
+ r=[]
1888
+ if flag
1889
+ if not @lastnote
1890
+ @lastnoteName="c"
1891
+ @lastnote=@notes["c"]
1892
+ end
1893
+ @thereminNote=@lastnote+@basekey
1894
+ r<<self.notes(@lastnoteName,0)
1895
+ key=format("%02x",@thereminNote)
1896
+ ch=format("%01x",@ch)
1897
+ vel=format("%02x",@velocity)
1898
+ r<<Event.new(:e,0," 9#{ch} #{key} #{vel} # theremin sound on note #{@thereminNote} velocity #{@velocity}\n")
1899
+ r<<self.bendRange(12*4)
1900
+ self.bendCent(true)
1901
+ else
1902
+ @thereminNote=false
1903
+ self.bendCent(false)
1904
+ end
1905
+ @theremin=flag
1906
+ r
1907
+ end
1808
1908
  def self.setmark m
1809
- n=@marktrack.getcount(m,@tracknum)
1810
- m="#{m}@#{n+1}" if n>0
1909
+ m=~/^([^,]+),/
1910
+ count=$'.to_i
1911
+ if $&
1912
+ if count>1
1913
+ m="#{$1}@#{$'.to_i}"
1914
+ else
1915
+ m=$1
1916
+ end
1917
+ else
1918
+ n=@marktrack.getcount(m,@tracknum)
1919
+ m="#{m}@#{n+1}" if n>0
1920
+ end
1811
1921
  @marktrack.set(m,@tracknum,@nowtime)
1812
1922
  Event.new(:mark,m,@tracknum,@nowtime)
1813
1923
  end
@@ -1883,14 +1993,8 @@ module MidiHex
1883
1993
  end
1884
1994
  end
1885
1995
  }
1886
- rr.map{|i|
1887
- case i
1888
- when String
1889
- i
1890
- when Event
1891
- i.data
1892
- end
1893
- }
1996
+ # Array of String or Event class instance
1997
+ rr
1894
1998
  end
1895
1999
  def self.makefraze mmldata,tc
1896
2000
  return "" if not mmldata
@@ -1905,6 +2009,7 @@ module MidiHex
1905
2009
  @shiftbase=40
1906
2010
  accent=false
1907
2011
  sharp=0
2012
+ sharpFloat=0
1908
2013
  @h<<[:controlChange,"10,#{@panoftrack}"] if @autopan
1909
2014
  cmd=mmldata.scan(/#{MmlReg.trackr}|./)
1910
2015
  cmd<<" " # dummy
@@ -1930,19 +2035,21 @@ module MidiHex
1930
2035
  end
1931
2036
  end
1932
2037
  wait.each{|m,c|
2038
+ arg=[c,t,accent,sharp]
2039
+ arg2=[c,t,accent,sharp,sharpFloat]
1933
2040
  case m
1934
2041
  when :percussion
1935
- @h<<[:percussionNote,c,t,accent,sharp]
2042
+ @h<<[:percussionNote,*arg]
1936
2043
  when :rawsound
1937
- @h<<[:byKey,c,t,accent,sharp]
2044
+ @h<<[:byKey,*arg]
1938
2045
  when :sound
1939
- @h<<[:notes,c,t,accent,sharp]
2046
+ @h<<[:notes,*arg2]
1940
2047
  when :dummyNote
1941
- @h<<[:dummyNote,c,t,accent,sharp]
2048
+ @h<<[:dummyNote,*arg]
1942
2049
  when :chord
1943
- @h<<[:chord,c,t,accent,sharp]
2050
+ @h<<[:chord,*arg]
1944
2051
  when :chordName
1945
- @h<<[:chordName,c,t,accent,sharp]
2052
+ @h<<[:chordName,*arg]
1946
2053
  when :rest
1947
2054
  @h<<[:rest,t]
1948
2055
  end
@@ -1951,20 +2058,35 @@ module MidiHex
1951
2058
  wait=[]
1952
2059
  accent=false
1953
2060
  sharp=0
2061
+ sharpFloat=0
1954
2062
  end
1955
2063
  case i
1956
- when /^\(([-+]*)([[:digit:]])?\)/
1957
- n=$2 ? $2.to_i : 1
1958
- if $1.size>1
1959
- n=$1.size
2064
+ when /^\(([-+]*)([[:digit:]\.]+)?\)/
2065
+ s1,s2=$1,$2
2066
+ n=1
2067
+ sharpFloat=0
2068
+ if s2
2069
+ n=s2.to_i
2070
+ if s2=~/\./
2071
+ sharpFloat=s2.to_f-n
2072
+ end
2073
+ end
2074
+ if s1.size>1
2075
+ n=s1.size
1960
2076
  end
1961
- sh=$1 ? $1[0..0] : "+"
1962
- sh="#{sh}#{n}".to_i
1963
- sharp=sh
2077
+ plus=s1 ? s1[0..0] : "+"
2078
+ sharpFloat*=-1 if plus=="-"
2079
+ sharp="#{plus}#{n}".to_i
1964
2080
  when /^\(key:(-?)\+?([[:digit:]]+)\)/
1965
2081
  tr=$2.to_i
1966
2082
  tr*=-1 if $1=="-"
1967
2083
  @h<<[:basekeyPlus,tr]
2084
+ when /^\(theremin:(.*)\)/
2085
+ if $1=~/off/
2086
+ @h<<[:setTheremin,false]
2087
+ else
2088
+ @h<<[:setTheremin,true]
2089
+ end
1968
2090
  when /^\(mark:(.*)\)/
1969
2091
  @h<<[:setmark,$1]
1970
2092
  when /^\(V:(.*)\)/
@@ -2007,7 +2129,7 @@ module MidiHex
2007
2129
  instrument=$4.to_i
2008
2130
  end
2009
2131
  @h<<[:ProgramChange,channel,instrument]
2010
- when /^\(bend:(([[:digit:]]+),)?([-,.[:digit:]]+)\)|^_b__([^?]+)\?/
2132
+ when /^\(bend:(([[:digit:]]+),)?([-+,.[:digit:]]+)\)|^_b__([^?]+)\?/
2011
2133
  i="(bend:#{$4.gsub('_'){','}})" if $4
2012
2134
  x,pos,b=worddata("bend",i)
2013
2135
  npos=0
@@ -2178,7 +2300,17 @@ module MidiHex
2178
2300
  puts "float rest add times: #{@frestc}" if $DEBUG
2179
2301
  @h=self.eventlist2str(@h)
2180
2302
  p [:number_with_totaltime, Event.new(:dummy).showTotalTime],[:allevent,@eventlist.map{|i|i.display}] if $DEBUG && $debuglevel>2
2181
- @h*"\n# track: #{@tracknum} ==== \n"
2303
+ @h
2304
+ end
2305
+ def self.eventArray2str data,tc
2306
+ data.map{|i|
2307
+ case i
2308
+ when String
2309
+ i
2310
+ when Event
2311
+ i.data
2312
+ end
2313
+ }*"\n# track: #{tc} ==== \n"
2182
2314
  end
2183
2315
  def self.loadMap file, base=0
2184
2316
  if not File.exist?(file)
@@ -2285,15 +2417,15 @@ module MidiHex
2285
2417
  end
2286
2418
  end
2287
2419
  # substitute mark comment lines with shift delta time and dummy event hex data to adjust to most preceding track.
2288
- def self.trackMake data
2420
+ def self.trackMake data,tc
2289
2421
  @marksh||=@marktrack.calc
2290
- data=data.split("\n").map{|i|
2422
+ data=self.eventArray2str(data,tc).split("\n").map{|i|
2291
2423
  i=~/^# marktrack\(([^\)]+)\)/
2292
2424
  if $&
2293
2425
  key=$1
2294
2426
  pos=@marksh[key]
2295
2427
  c="position mark: #{key}, #{pos*1.0/@tbase}"
2296
- @marksh.keys.member?(key) ? self.dummyEvent(c,pos) : i
2428
+ @marksh.keys.member?(key) ? self.dummyEvent(c,pos).data : i
2297
2429
  else
2298
2430
  i
2299
2431
  end
@@ -2323,7 +2455,8 @@ def multiplet d,tbase
2323
2455
  else
2324
2456
  total=tbase*rate
2325
2457
  end
2326
- r=i.scan(/=|\(\?:[^\]]+\)|\(x:[^\]]+\)|\(chord:[^)]+\)|\(C:[^)]+\)|:[^\(,]+\([^\)]+\),|:[^,]+,|[[:digit:]\.]+|_[^!]+!|~|\([-+]*[[:digit:]]?\)|[-+]+[[:digit:]]*|[\^`'<>]|\([^\)]*\)|./)
2458
+ regex=MmlReg.multipletr
2459
+ r=i.scan(/#{regex}|./)
2327
2460
  lengths=[]
2328
2461
  notes=[]
2329
2462
  mod=[]
@@ -2406,7 +2539,8 @@ def macroDef data
2406
2539
  tmp=[]
2407
2540
  name=""
2408
2541
  num=1
2409
- s=data.scan(/macro +[^ ;:=]+ *:= *\( *;|macro +[^ ;:=]+ *:=[^;]+|[^ ;:=]+ *:= *\( *;|[^ ;:=]+ *:=[^;]+| *\) *;|[^;]+|./)
2542
+ rstr=MmlReg.macroDefr
2543
+ s=data.scan(/#{rstr}| *\) *;|[^;]+|./)
2410
2544
  data=s.map{|i|
2411
2545
  case i
2412
2546
  when /^(macro +)? *([^ ;:=]+) *:= *\( *;/
@@ -2442,7 +2576,7 @@ def macroDef data
2442
2576
  end
2443
2577
  def nestsearch d,macro
2444
2578
  a=d.scan(/\[[^\[\]]*\] *[[:digit:]]+/)!=[]
2445
- r=d.scan(/\/[^\/]+\/|\[|\]|\.FINE|\.DS|\.DC|\.\$|\.toCODA|\.CODA|\.SKIP|\$\{[^ \{\}]+\}|\$[^ ;\$*_^`'+-]+|;|./).map{|i|
2579
+ r=d.scan(/\/[^\/]+\/|#{MmlReg.repeatr}|\$\{[^ \{\}]+\}|\$[^ ;\$*_^`'+-]+|;|./).map{|i|
2446
2580
  case i
2447
2581
  when /^\$\{([^\}]+)\}/
2448
2582
  $1
@@ -2466,7 +2600,7 @@ def tie d,tbase
2466
2600
  res=[]
2467
2601
  # if no length word after '~' length is 1
2468
2602
  d.gsub!(/~([^*[:digit:]])?/){$1 ? "~1#{$1}" : $&} while d=~/~[^*[:digit:]]/
2469
- li=d.scan(/\$\{[^\}]+\}|\$[^ ;\$_*^`'+-]+|\([^)\(]*\)|:[^\(,]+\([^)]+\),|:[^,]+,|_[^!]+!|_[^_]__[^?]+\?|v[[:digit:]]+|[<>\-+][[:digit:]]*|\*?[[:digit:].]+|\([VGABLN]:[^)]+\)|~|./)
2603
+ li=d.scan(MmlReg::RwAll)
2470
2604
  li.each{|i|
2471
2605
  case i
2472
2606
  when /^(\*)?([[:digit:].]+)/
@@ -2530,7 +2664,8 @@ def repCalc line,macro,tbase
2530
2664
  r ? r : b
2531
2665
  end
2532
2666
  }*""
2533
- regex=/\/[^\/]+\/|\[|\]|\.FINE|\.DS|\.DC|\.\$|\.toCODA|\.CODA|\.SKIP|\$\{[^ \{\}]+\}|\$[^ ;\$_*^,\)\(`'\/+-]+|\([^\)]*:|\)|./
2667
+ repmark=MmlReg.repeatr
2668
+ regex=/\/[^\/]+\/|#{repmark}|\$\{[^ \{\}]+\}|\$[^ ;\$_*^,\)\(`'\/+-]+|\([^\)]*:|\)|./
2534
2669
  a=line.scan(regex)
2535
2670
  a=a.map{|i|
2536
2671
  if i=~/^\/[^\/]+\//
@@ -2607,7 +2742,7 @@ def repCalc line,macro,tbase
2607
2742
  end
2608
2743
  res<<current
2609
2744
  end
2610
- res=(res-["[","]",".CODA",".DS",".DC",".FINE",".toCODA",".$",".SKIP"])*""
2745
+ res=(res-MmlReg::RepStrArray)*""
2611
2746
  res=repCalc(res,macro,tbase) while macro.keys.size>0 && nestsearch(res,macro)
2612
2747
  p res if $DEBUG && $debuglevel>1
2613
2748
  # 空白
@@ -2758,15 +2893,21 @@ class Smml
2758
2893
  @mx.autopan(@autopan)
2759
2894
  tc=0
2760
2895
  # remember starting position check if data exist before sound
2761
- @htracks << @mx.metaTitle + @mx.generaterText + @mx.starttempo.data + @mx.makefraze(@rundatas[0],tc) + @mx.lastrest
2896
+ @htracks[tc]=[]
2897
+ @htracks[tc]=[@mx.metaTitle, @mx.generaterText, @mx.starttempo, @mx.makefraze(@rundatas[0],tc), @mx.lastrest].flatten
2762
2898
  @rundatas[1..-1].each{|track|
2763
2899
  tc+=1
2764
- @htracks<< @mx.restHex + @mx.makefraze(track,tc) + @mx.lastrest
2900
+ @htracks[tc]=[]
2901
+ @htracks[tc]=[@mx.restHex,@mx.makefraze(track,tc), @mx.lastrest].flatten
2765
2902
  }
2766
2903
  end
2767
2904
  def pack
2768
2905
  @header=@mx.header(1, @tracknum, @tbase)
2769
- alla=[@header]+@htracks.map{|t|@mx.trackMake(t)}.flatten
2906
+ tc=0
2907
+ alla=[@header]+@htracks.map{|t|
2908
+ tc+=1
2909
+ @mx.trackMake(t,tc-1)
2910
+ }.flatten
2770
2911
  puts alla if $DEBUG
2771
2912
  all=alla.map{|i|i.commentoff("","#")}*""
2772
2913
  array=[all.split.join]
data/lib/smml/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Smml
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.8"
3
3
  end
@@ -72,7 +72,7 @@ BS:=ccecffcfccefgfec fffcffffcccbaacC dcbagGabccaadd-gg
72
72
  |||
73
73
  |||
74
74
  |||
75
- TR(x):=(mark:p@$x) r*120 /2:ergrre/
75
+ TR(x):=(mark:p,$x) r*120 /2:ergrre/
76
76
  |||(p:trum)+(v:90)(g:70)(mark:p) r*120 /2:ergrre/ $TR(:4,9,10,11,12)
77
77
 
78
78
 
File without changes
data/smml.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "https://github.com/tabasano/wavseq"
14
14
  spec.license = "MIT"
15
15
 
16
- spec.files = Dir.glob("lib/*")+Dir.glob("lib/smml/*")+Dir.glob("bin/*")+["Gemfile","Rakefile","LICENSE.txt","smml.gemspec","README_smml.md","tutorial_smml.md"]+["sample/midi-preModifier.txt","sample/midi-test.mml"]
16
+ spec.files = Dir.glob("lib/*")+Dir.glob("lib/smml/*")+Dir.glob("bin/*")+["Gemfile","Rakefile","LICENSE.txt","smml.gemspec","README_smml.md","tutorial_smml.md"]+["sample/midi-preModifier.txt","sample/midi-test.mml","sample/ssmml.rb"]
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.extra_rdoc_files =%w[README_smml.md LICENSE.txt tutorial_smml.md]
data/tutorial_smml.md CHANGED
@@ -188,7 +188,9 @@ minus value is for to stroke up. currently, up value affects once only as it sim
188
188
  (+)a (-)b (0)c
189
189
  ```
190
190
 
191
- strange ways can be affective currently. '(+4)a' etc.
191
+ strange ways of sharp/flat can be affective currently. ```(+4)a``` , ```(-1.2)a``` etc. in float value, bend data is used inside.
192
+
193
+
192
194
  ;; instead of 'd' etc., note numbers can be used if you want.
193
195
  ;; 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
196
 
@@ -242,6 +244,21 @@ _snare! = = =
242
244
 
243
245
  first two tracks are 'organ' sound by the track names declared.
244
246
 
247
+
248
+ currenly track names are not used, and tracks continue with apprearing order. so if there are no data in some tracks in mid parts of pages,
249
+ use blank tracks by track seperaters.
250
+
251
+ ```
252
+ c ;; track 1
253
+ ||| e ;; track 2
254
+ ||| g ;; track 3
255
+ ///////////////////////////////////////
256
+ abc ;; track 1
257
+ ||| ;; track 2 , no data but it can't be omitted to adjust track counters after this track.
258
+ ||| def ;; track 3
259
+ ```
260
+
261
+
245
262
  ## page
246
263
  ;; then seperate pages by three or longer one line '/'.
247
264
  ;; but this command do not adjust time potisions. it simply resets track number increment.
@@ -297,6 +314,7 @@ these are played like this.
297
314
  ```
298
315
 
299
316
  ;; 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.
317
+ or use a comma , '(mark:hoge@3)' = '(mark:hoge,3)'
300
318
 
301
319
  ```
302
320
  a b c (mark:m) a b c (mark:m@2) a b c (mark:m@3)
@@ -333,36 +351,40 @@ so in this list, instrument number 1,2 and 3 match the keyword 'piano'.
333
351
  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.
334
352
 
335
353
  ## hex data
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.
337
- search MIDI format and set hex data.
354
+ ;; until smml syntax is completed, or other reasons, raw hex parts can be used for deep level data and things you don't know how to inprement by smml data.
355
+ search MIDI format and set valid hex data.
338
356
 
339
357
  ```
340
358
  &(00 00 00)
341
359
  ```
342
360
 
361
+ hex data must be ``` 00 01 02 ... FD FE FF ```. one byte is by two hex letters. seperaters are a blank or comma.
343
362
  ;; currently hex only can be used. oct/decimal may be able to use someday.
344
363
  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.
345
364
  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.
346
365
  also '$se(F0 41 ..)' can be used for system exclusive message data.
347
366
  currently, nest data of parenthesis is not implemented except very limited cases.
367
+ anyway, when you use hex data, be careful not to set invalid data. smml don't check its MIDI data validation.
368
+
348
369
 
349
- ## macro define
370
+ ## define and apply macro variable
350
371
  ;; for repeating phrase, macro can be used. use prefix '$' for refering.
351
372
 
352
373
  ```
353
- Macr:=cde
374
+ VeryLongPhraze:=cde
354
375
  macro W:=abc
355
376
 
356
- ggg $Macr fff $W
377
+ ggg $VeryLongPhraze fff $W
357
378
  ```
358
379
 
359
- the 4th line will be subsituted by
380
+ the 4th line will be replaced by
360
381
 
361
382
  ```
362
- ggg cde fff abc.
383
+ ggg cde fff abc
363
384
  ```
364
385
 
365
- the keyword 'macro' is used just for reading and will simply be ignored.
386
+ the keyword 'macro' is used just for easy readability and will simply be ignored.
387
+ a macro definition is normally within and whole one line. you can write any valid smml data after '```:=```'.
366
388
 
367
389
 
368
390
  ;; macro with args
@@ -385,10 +407,11 @@ will be
385
407
  ab10 (wait:4) ab20 (wait:4) ab30
386
408
  ```
387
409
 
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' ).
410
+ '(wait:4)' was inserted by '4' in first place before args. it means 4 beats of rest (exact mean of '(wait:..)' is
411
+ 'do nothing, set it free even if sound is on and wait for the next command' ).
389
412
 
390
413
 
391
- multiline macro definition
414
+ multiline macro definition is ;
392
415
 
393
416
  ```
394
417
  EFF:=(
@@ -399,7 +422,8 @@ EFF:=(
399
422
  )
400
423
  ```
401
424
 
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.
425
+ after parenthesis, don't set any letters without blanks.
426
+ but now, this is for easy way of writing only, and may not be so useful. to use this multi line values, each line must be seperated.
403
427
 
404
428
  ```
405
429
  $EFF[1] $EFF[2] $EFF[3] $EFF[4]
@@ -413,11 +437,12 @@ but, these are MIDI system exclusive HEX data, so to make it really effective da
413
437
  ```
414
438
 
415
439
  ```$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.
440
+ ```$delta(0)``` is ```00``` , so both of these are effective. inside ```$delta()``` value is not hex, use decimal number.
417
441
 
442
+ '${ff}' can be used for '$ff' as macro variable.
418
443
 
419
444
  ## comment
420
- ;; ignored after ';;' of each line. write comments there.
445
+ ;; words after ';;' of each line are ignored. write comments there.
421
446
  multi line comments start with longer ';'.
422
447
  end mark is same or longer mark of ';' than start mark. these must start from the top of the line.
423
448
 
@@ -618,11 +643,20 @@ so,
618
643
 
619
644
  ;; set this track's channel 1. when several tracks use same channel, for example it will behave as the same instrument.
620
645
 
646
+
647
+ ```
648
+ (bend:100) c
649
+ ```
650
+
651
+ pitch bend 100 of note 'c'.
652
+
621
653
  ```
622
- (bend:100)
654
+ (bend:+100) c
655
+ (bend:+-200) c
623
656
  ```
624
657
 
625
- pitch bend 100
658
+ '+' relative value. if these are after above, three notes are bend 100 of 'c', bend 200 of 'c' and bend 0 of 'c'.
659
+
626
660
 
627
661
  ```
628
662
  (bendRange:12)
@@ -693,6 +727,16 @@ now, note type commands are :
693
727
 
694
728
  ```'~'``` seems likely note type, but it is compressed to preceding note as calculated note length. most commands cannot be set inside of ```'c~~~'.```
695
729
 
730
+ ;; theremin like sound,
731
+
732
+ ```
733
+ (p:organ)
734
+ (theremin:on)
735
+ ab /:cde/ f
736
+ ```
737
+
738
+ after on command, data is manipulated as bend data inside smml. not completed about modifiers for this.
739
+
696
740
 
697
741
  ## preprocess
698
742
  ;; some pre-process commands.
@@ -720,6 +764,7 @@ all after that are real values. the '+' adds 10 to latest value as default.
720
764
  so expression data is ;``` 40,50,60,70,80,70,60,50,40,50,60,70,80...``` with each 20 ticks interval.
721
765
  bend and expression values inside these parts will be reseted after the modified note ends.
722
766
  series of ```(A:..)``` parts are merged. if not, old one is overwtitten.
767
+ 'o' is dummy and it set nil value and simply ignored. it is for visibility purpose only.
723
768
 
724
769
 
725
770
  ## text
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.6
4
+ version: 0.1.8
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-01 00:00:00.000000000 Z
11
+ date: 2014-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,7 +44,6 @@ email:
44
44
  executables:
45
45
  - mmlsmml
46
46
  - smml
47
- - ssmml
48
47
  extensions: []
49
48
  extra_rdoc_files:
50
49
  - README_smml.md
@@ -58,7 +57,6 @@ files:
58
57
  - lib/smml/version.rb
59
58
  - bin/mmlsmml
60
59
  - bin/smml
61
- - bin/ssmml
62
60
  - Gemfile
63
61
  - Rakefile
64
62
  - LICENSE.txt
@@ -67,6 +65,7 @@ files:
67
65
  - tutorial_smml.md
68
66
  - sample/midi-preModifier.txt
69
67
  - sample/midi-test.mml
68
+ - sample/ssmml.rb
70
69
  homepage: https://github.com/tabasano/wavseq
71
70
  licenses:
72
71
  - MIT