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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 030ec4626cbd1d8bbd61fe4e13b993ec2c27cfd6
4
- data.tar.gz: f4a8aea294b67884dad7449c5ba524db6b162e76
3
+ metadata.gz: 5502e954b9a84c81d1589125b9c6bff866c7a47c
4
+ data.tar.gz: 7a54373e442e7d92e5200fd699bd99cbddff5118
5
5
  SHA512:
6
- metadata.gz: c91c1d55a355e8bd9a35999df025fdbe95f1f1532e72e5f94fac6e6b9b0256a43543cf60383bf7865e5a3f692a2e3fccb3a27a2570449a32b5f5ba891936a0b3
7
- data.tar.gz: fe30d0f2596410987755d5fadb450340ae7070c820e5de1b548054967b0ce7f30b680c425dad433a3f07445cc5edfcd2aaabd8011be45aa7bf00e023b897dbf5
6
+ metadata.gz: 3724df4add3c3d66ac9cc733149a5762bf8e899d0bf28e673d4d01b066b529d72ed612f77cca459612ea5ee06df9bd2d3669f0668fcc2f3320ac318108624117
7
+ data.tar.gz: f65ca001292854935dfd31c15d73d5556d7e4fee703026a864d62760c4fea85b5746b44434239caa49964f0e189fee9e484ec0f18ba648431615cb620a4cf514
data/README_smml.md CHANGED
@@ -1,4 +1,4 @@
1
- # Smml
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 outfile.mid
34
- $ smml -d "cdefgab" -o outfile.mid
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="mml.mid"
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', '{64}', '_snare!', '{d,g,-b}', ':cmaj7,'
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
- attr_accessor :type, :time, :value
207
- def initialize ty=:e,*arg
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
- when :c,:raw
213
- @time=0
263
+ # event without time; except ':e'
264
+ when :comment,:raw
265
+ settime(0)
214
266
  @value=arg[0]
215
267
  when :ahead
216
- @time=arg[0]
217
- when :o,:off
268
+ settime(arg[0])
269
+ when :on,:off
218
270
  when :mark
219
271
  @mark,@track,@value=arg
220
- else
221
- @time=arg[0]
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 :c,:o,:off
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
- @prepareSet=[@tbase,@ch,@velocity,@velocityFuzzy,@basekey,@gateRate,@bendrange,@bendCent]
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(:o)]
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
- r=[]
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(:c,"# #{cmd} #{arg}")
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].time+=ahead
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.time+=after;after=0) if after>0
1452
- (i.time+=after;after=0) if after<0 && i.time+after>=0
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 :c,:raw,:mark
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 "make start: ",cmd if $DEBUG
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<<[:rawsound,rand(0x7f)]
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
@@ -1,3 +1,3 @@
1
1
  class Smml
2
- VERSION = "0.1.0.1"
2
+ VERSION = "0.1.0.4"
3
3
  end
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.1
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-22 00:00:00.000000000 Z
11
+ date: 2014-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler