ramekin 0.0.10 → 0.0.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
  SHA256:
3
- metadata.gz: e6d502b095f92786dc1c94da24e1144d744f8462f609a1d7623a9c46a541b5f9
4
- data.tar.gz: 2de364d731e7760f8dc1111d18aad6b4de5a5b713e5d3ec424af3c80f180ec52
3
+ metadata.gz: f9fce3c7ec61c39d7597621bf02fbd71788df731ee7a98cb89018549275eb44e
4
+ data.tar.gz: 0c123977b81c24d92f4f6b3514973ca4713aedf4c8292aa30d126f6b20d541ea
5
5
  SHA512:
6
- metadata.gz: 0a1aed7dde26850dd627da1ac9e0b7445d41097128dcae4ba464afc7c0868e7905f8adb2b395bfc93aa3d9ea28e7739cb2e5bb36fdf6de679726d938913de179
7
- data.tar.gz: 6402af26f0cbd457a8246121eefcfe976a5331925ed97849520fec05faafbdf47c8124a95bdb398a38115dcb6a6dce2fd7ff0bac6e1678787d433e4e7cfcc247
6
+ metadata.gz: 0d4484cc76d708e7b1d36929e2a4b95efe19b34ad5882f51e71d526bd08d1c500725de40054b17e5401922fd388854a2866fca0a2210a15589bdbd5e46bc85b4
7
+ data.tar.gz: cd54afeb74289aaf055344b45aca6b75679b494db546308c0d86d05866c0a4e4cc855921232f7c6507ac8cc6a2b8e6656247ba6ea579806c1589786470ce2f31
data/lib/ramekin/cli.rb CHANGED
@@ -172,6 +172,7 @@ module Ramekin
172
172
  NoteAggregator,
173
173
  RestAggregator,
174
174
  Legato,
175
+ LoopAllocator,
175
176
  Inspector,
176
177
  )
177
178
 
@@ -15,7 +15,7 @@ module Ramekin
15
15
  def self.error!(e, nesting: 0)
16
16
  all << e
17
17
 
18
- if ENV['RAMEKIN_DEBUG'] == '1'
18
+ if ENV['RAMEKIN_DEBUG'] == '1' && ENV['DISABLE_PRY'] != 'true'
19
19
  if nesting >= 0
20
20
  Pry.config.hooks.add_hook(:before_session, :ramekin) do |output, binding, pry|
21
21
  Pry.config.hooks.delete_hook(:before_session, :ramekin)
@@ -25,6 +25,8 @@ module Ramekin
25
25
 
26
26
  binding.pry
27
27
  end
28
+
29
+ nil
28
30
  end
29
31
 
30
32
  def initialize(start, fin, message)
@@ -32,10 +32,10 @@ module Ramekin
32
32
  @note.ticks / 2
33
33
  end
34
34
 
35
- def to_amk(current_octave=nil)
35
+ def to_amk(current_octave=nil, divisor=1)
36
36
  post_ticks = @note.ticks - ticks
37
37
  post_len = KNOWN_LENGTHS.fetch(post_ticks) { "=#{post_ticks}" }
38
- "#{octave_amk(current_octave)}#{note_name}#{length_amk}$f4$01^#{post_len}"
38
+ "#{octave_amk(current_octave)}#{note_name}#{length_amk(divisor)}$f4$01^#{post_len}"
39
39
  end
40
40
 
41
41
  def inspect
@@ -0,0 +1,47 @@
1
+ module Ramekin
2
+ class LoopAllocator < Processor
3
+ def call(&b)
4
+ tokens = @stream.to_a
5
+
6
+ loop_defs = tokens.select do |tok|
7
+ Token === tok && tok.type == :loop && !tok.value.empty?
8
+ end
9
+
10
+ index = 0
11
+ indices = {}
12
+ used = Set.new
13
+
14
+ numbered, named = loop_defs.partition do |tok|
15
+ /\A\d+\z/.match?(tok.value)
16
+ end
17
+
18
+ numbered.each do |tok|
19
+ num = indices[tok.value] = tok.value.to_i
20
+ tok.meta[:number] = num
21
+ used << num
22
+ end
23
+
24
+ named.each do |tok|
25
+ if indices.key?(tok.value)
26
+ error! "multiple definitions of (#{tok.value})", el: tok
27
+ next
28
+ end
29
+
30
+ index += 1
31
+ index += 1 while used.include?(index)
32
+ indices[tok.value] = index
33
+ tok.meta[:number] = index
34
+ end
35
+
36
+ tokens.each do |token|
37
+ if Token === token && token.type == :loop_call
38
+ token.meta[:number] = indices.fetch(token.value) do
39
+ error! "no such loop", el: token
40
+ end
41
+ end
42
+
43
+ yield token
44
+ end
45
+ end
46
+ end
47
+ end
data/lib/ramekin/meta.rb CHANGED
@@ -48,6 +48,34 @@ module Ramekin
48
48
  )
49
49
  end
50
50
 
51
+ def t_value
52
+ t_with_divisor[0]
53
+ end
54
+
55
+ def divisor
56
+ t_with_divisor[1]
57
+ end
58
+
59
+ def t_with_divisor
60
+ return [50, 1] if @tempo.nil?
61
+
62
+ @t_with_divisor ||= begin
63
+ t = case @tempo.type
64
+ when :t then @tempo.value
65
+ when :bpm then (@tempo.value.to_f * 8192 / 20025.0)
66
+ end
67
+
68
+ t = t.to_f
69
+ divisor = 1
70
+ while t > 60
71
+ t /= 2
72
+ divisor *= 2
73
+ end
74
+
75
+ [t.round, divisor]
76
+ end
77
+ end
78
+
51
79
  def parse
52
80
  loop do
53
81
  break if @elements.empty?
@@ -58,7 +86,7 @@ module Ramekin
58
86
  when :amk then @amk = @current
59
87
  when :option then @options[@current.value] = true
60
88
  when :w then @volume = @current
61
- when :t, :bpm then @tempo = @current
89
+ when :t, :bpm then @tempo = @current; @t_with_divisor = nil
62
90
  else
63
91
  error! 'invalid token in header'
64
92
  end
@@ -57,10 +57,16 @@ module Ramekin
57
57
  end
58
58
  end
59
59
 
60
- def length_amk
60
+ def length_amk(div)
61
+ if ticks % div != 0
62
+ divisible = div == 2 ? 'even' : "divisible by #{div}"
63
+ error!("too fast! tick count must be #{divisible} at this tempo", el: self)
64
+ end
65
+
66
+ t = ticks / div
61
67
  # we use l16
62
- return '' if ticks == 12
63
- KNOWN_LENGTHS.fetch(ticks) { "=#{ticks}" }
68
+ return '' if t == 12
69
+ KNOWN_LENGTHS.fetch(t) { "=#{t}" }
64
70
  end
65
71
 
66
72
  def octave_amk(current_octave=nil)
@@ -80,8 +86,8 @@ module Ramekin
80
86
  end
81
87
  end
82
88
 
83
- def to_amk(current_octave=nil)
84
- return "#{octave_amk(current_octave)}#{note_name}#{length_amk}"
89
+ def to_amk(current_octave=nil, divisor=1)
90
+ return "#{octave_amk(current_octave)}#{note_name}#{length_amk(divisor)}"
85
91
  end
86
92
 
87
93
  def repr
@@ -94,7 +100,7 @@ module Ramekin
94
100
 
95
101
  def ticks
96
102
  if @extensions.empty? && default_length.nil?
97
- error! "no length and no default specified with l", el: @note
103
+ return 192 / 16
98
104
  end
99
105
 
100
106
  exts = @extensions
@@ -101,7 +101,7 @@ module Ramekin
101
101
  yield "}\n\n"
102
102
  end
103
103
 
104
- yield "t#{tempo_of(m.tempo)} ; main tempo (0-60)\n" if m.tempo
104
+ yield "t#{m.t_value} ; main tempo (0-60)\n" if m.tempo
105
105
  yield "w#{m.volume.value} ; main volume (0-255)\n" if m.volume
106
106
  yield "l16\n\n"
107
107
 
@@ -143,12 +143,14 @@ module Ramekin
143
143
  if (old_tick-1) / 192 != (@tick-1) / 192
144
144
  yield "\n"
145
145
  end
146
- yield el.to_amk(@octave)
146
+ divisor = @track.meta.divisor
147
+
148
+ yield el.to_amk(@octave, @track.meta.divisor)
147
149
  @octave = el.octave unless el.rest?
148
150
  when MacroDefinition
149
151
  # pass
150
152
  when LegatoStart, LegatoLastNote
151
- yield el.to_amk
153
+ yield el.to_amk(@octave, @track.meta.divisor)
152
154
  when Instrument
153
155
  yield "@#{@instrument_index[el.name.value]}"
154
156
  when Token
@@ -241,14 +243,14 @@ module Ramekin
241
243
  yield " [[ "
242
244
  when :loop
243
245
  if token.value
244
- yield " (#{token.value})[ "
246
+ yield " (#{token.meta[:number]})[ "
245
247
  else
246
248
  yield " [ "
247
249
  end
248
250
  when :loop_end
249
251
  yield " ]#{token.value} "
250
252
  when :loop_call
251
- yield " (#{token.values[0]})#{token.values[1]} "
253
+ yield " (#{token.meta[:number]})#{token.values[1]} "
252
254
  when :star
253
255
  yield "*#{token.value}"
254
256
  when :superloop_end
@@ -243,9 +243,9 @@ module Ramekin
243
243
  return [:superloop_end, m(1)] if match /\]\](\d*)/
244
244
 
245
245
  return [:remote_def, m(1)] if match /[(]!(\d+)[)]\[/
246
- return [:loop, m(1)] if match /(?:[(](\d+)[)])?\[/
246
+ return [:loop, m(1)] if match /(?:[(]([\w-]+)[)])?\[/
247
247
  return [:loop_end, m(1)] if match /\](\d*)/
248
- return [:loop_call, m(1), m(2)] if match /[(](\d+)[)](\d+)?/
248
+ return [:loop_call, m(1), m(2)] if match /[(]([\w-]+)[)](\d+)?/
249
249
 
250
250
  # this needs a reparse
251
251
  return remote(:remote_call, m(1)) if match /[(]!(\d*)/
data/lib/ramekin.rb CHANGED
@@ -11,6 +11,7 @@ require_relative 'ramekin/processor'
11
11
  require_relative 'ramekin/macros'
12
12
  require_relative 'ramekin/note_aggregator'
13
13
  require_relative 'ramekin/legato'
14
+ require_relative 'ramekin/loop_allocator'
14
15
  require_relative 'ramekin/meta'
15
16
  require_relative 'ramekin/channel_separator'
16
17
  require_relative 'ramekin/volume'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ramekin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - jneen
8
8
  autorequire:
9
9
  bindir: gembin
10
10
  cert_chain: []
11
- date: 2025-02-20 00:00:00.000000000 Z
11
+ date: 2025-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: strscan
@@ -85,6 +85,7 @@ files:
85
85
  - lib/ramekin/element.rb
86
86
  - lib/ramekin/errors.rb
87
87
  - lib/ramekin/legato.rb
88
+ - lib/ramekin/loop_allocator.rb
88
89
  - lib/ramekin/macros.rb
89
90
  - lib/ramekin/meta.rb
90
91
  - lib/ramekin/note_aggregator.rb