musa-dsl 0.22.5 → 0.22.6
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 +4 -4
- data/lib/musa-dsl.rb +1 -1
- data/lib/musa-dsl/core-ext/inspect-nice.rb +1 -2
- data/lib/musa-dsl/datasets/p.rb +33 -14
- data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +14 -12
- data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +32 -6
- data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +24 -10
- data/lib/musa-dsl/logger/logger.rb +6 -1
- data/lib/musa-dsl/midi/midi-voices.rb +1 -0
- data/lib/musa-dsl/music/scales.rb +1 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +2 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +2 -0
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +4 -2
- data/lib/musa-dsl/series/base-series.rb +1 -1
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +24 -8
- data/lib/musa-dsl/series/main-serie-constructors.rb +3 -3
- data/lib/musa-dsl/series/main-serie-operations.rb +7 -2
- data/lib/musa-dsl/series/timed-serie.rb +16 -14
- data/musa-dsl.gemspec +3 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e85f0a7bc9ddbb82ea9b6b36741a87c1dc04f2feb1c10ea0f5fcb92e4dfc7a37
|
4
|
+
data.tar.gz: 13ad3537ac0a2e03c07c589174a12a8dd9af5013be79f5bd1ee769820cd94347
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06f58c414bbbd873179850c378f3022e1bc40eba16325b787824e1cb88b27229c7ac19d08032c8b0385c792ae38324c982970dcc94c91e7fd3d924208b640aa4
|
7
|
+
data.tar.gz: 63398fc18d40799119742df1587735f9736abec4a0c1d97e9a9b29202395b6f4223cea7c01075e95d6f0ae4d752dd7297ba88c9df8c2ac7c76dea439732a8435
|
data/lib/musa-dsl.rb
CHANGED
@@ -12,7 +12,6 @@ module Musa
|
|
12
12
|
alias to_s inspect
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
15
|
refine Rational.singleton_class do
|
17
16
|
attr_accessor :to_s_as_inspect
|
18
17
|
end
|
@@ -43,7 +42,7 @@ module Musa
|
|
43
42
|
end
|
44
43
|
|
45
44
|
def to_s
|
46
|
-
inspect simple:
|
45
|
+
inspect simple: !Rational.to_s_as_inspect
|
47
46
|
end
|
48
47
|
end
|
49
48
|
end
|
data/lib/musa-dsl/datasets/p.rb
CHANGED
@@ -28,20 +28,7 @@ module Musa::Datasets
|
|
28
28
|
|
29
29
|
base_duration ||= 1/4r # TODO review incoherence between neumalang 1/4r base duration for quarter notes and general 1r size of bar
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
Musa::Series::E(clone, base_duration, context: { time: time_start }) do |p, base_duration, context: |
|
34
|
-
value = p.shift
|
35
|
-
|
36
|
-
if value
|
37
|
-
r = { time: context[:time], value: value } if !value.nil?
|
38
|
-
|
39
|
-
delta_time = p.shift
|
40
|
-
context[:time] += delta_time * base_duration if delta_time
|
41
|
-
|
42
|
-
r&.extend(AbsTimed)
|
43
|
-
end
|
44
|
-
end
|
31
|
+
PtoTimedSerie.new(self, base_duration, time_start)
|
45
32
|
end
|
46
33
|
|
47
34
|
def map(&block)
|
@@ -57,5 +44,37 @@ module Musa::Datasets
|
|
57
44
|
end
|
58
45
|
end
|
59
46
|
end
|
47
|
+
|
48
|
+
class PtoTimedSerie
|
49
|
+
include Musa::Series::Serie
|
50
|
+
|
51
|
+
attr_reader :origin
|
52
|
+
|
53
|
+
def initialize(origin, base_duration, time_start)
|
54
|
+
@origin = origin
|
55
|
+
@base_duration = base_duration
|
56
|
+
@time_start = time_start
|
57
|
+
|
58
|
+
_restart
|
59
|
+
|
60
|
+
mark_as_prototype!
|
61
|
+
end
|
62
|
+
|
63
|
+
def _restart
|
64
|
+
@p = @origin.clone
|
65
|
+
@time = @time_start
|
66
|
+
end
|
67
|
+
|
68
|
+
def _next_value
|
69
|
+
if value = @p.shift
|
70
|
+
r = { time: @time, value: value }.extend(AbsTimed)
|
71
|
+
|
72
|
+
delta_time = @p.shift
|
73
|
+
@time += delta_time * @base_duration if delta_time
|
74
|
+
|
75
|
+
r
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
60
79
|
end
|
61
80
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'prime'
|
2
2
|
|
3
3
|
module Musa::Datasets::Score::ToMXML
|
4
|
-
|
4
|
+
using Musa::Extension::InspectNice
|
5
5
|
|
6
|
-
def process_pdv(measure, bar, divisions_per_bar, element, pointer, logger, do_log)
|
6
|
+
private def process_pdv(measure, bar, divisions_per_bar, element, pointer, logger, do_log)
|
7
7
|
|
8
8
|
pitch, octave, sharps = pitch_and_octave_and_sharps(element[:dataset])
|
9
9
|
|
@@ -21,24 +21,26 @@ module Musa::Datasets::Score::ToMXML
|
|
21
21
|
decompose_as_sum_of_simple_durations(effective_duration))
|
22
22
|
|
23
23
|
if do_log
|
24
|
-
logger.debug
|
25
|
-
logger.debug ""
|
26
|
-
logger.debug
|
27
|
-
logger.debug "
|
28
|
-
logger.debug "
|
24
|
+
logger.debug ''
|
25
|
+
logger.debug('process_pdv') { "processing #{element.inspect}" }
|
26
|
+
logger.debug { "" }
|
27
|
+
logger.debug { " pointer #{pointer.inspect} continue_from_previous #{continue_from_previous_bar} continue_to_next #{continue_to_next_bar}" }
|
28
|
+
logger.debug { " effective_start #{effective_start.inspect} effective_duration #{effective_duration.inspect}" }
|
29
|
+
logger.debug { " duration decomposition #{effective_duration_decomposition}" }
|
29
30
|
end
|
30
31
|
|
31
32
|
if pointer > effective_start
|
32
33
|
duration_to_go_back = (pointer - effective_start)
|
33
34
|
|
34
|
-
logger.debug
|
35
|
+
logger.debug ''
|
36
|
+
logger.debug { " -> adding backup #{duration_to_go_back * divisions_per_bar}" } if do_log
|
35
37
|
|
36
38
|
measure.add_backup(duration_to_go_back * divisions_per_bar)
|
37
39
|
pointer -= duration_to_go_back
|
38
40
|
|
39
41
|
|
40
42
|
elsif pointer < effective_start
|
41
|
-
warn "
|
43
|
+
logger.warn { " -> adding start rest duration #{effective_start - pointer} start #{bar + pointer} finish #{bar + effective_start}" } if do_log
|
42
44
|
|
43
45
|
pointer = process_pdv(measure, bar, divisions_per_bar,
|
44
46
|
{ start: bar + pointer,
|
@@ -125,7 +127,7 @@ module Musa::Datasets::Score::ToMXML
|
|
125
127
|
pointer
|
126
128
|
end
|
127
129
|
|
128
|
-
def pitch_and_octave_and_sharps(pdv)
|
130
|
+
private def pitch_and_octave_and_sharps(pdv)
|
129
131
|
if pdv[:pitch] == :silence
|
130
132
|
[:silence, nil, nil]
|
131
133
|
else
|
@@ -143,7 +145,7 @@ module Musa::Datasets::Score::ToMXML
|
|
143
145
|
end
|
144
146
|
end
|
145
147
|
|
146
|
-
def dynamics_index_of(midi_velocity)
|
148
|
+
private def dynamics_index_of(midi_velocity)
|
147
149
|
return nil unless midi_velocity
|
148
150
|
|
149
151
|
# ppp = midi 16 ... fff = midi 127
|
@@ -153,7 +155,7 @@ module Musa::Datasets::Score::ToMXML
|
|
153
155
|
.index { |r| r.cover? midi_velocity.round.to_i }
|
154
156
|
end
|
155
157
|
|
156
|
-
def dynamics_to_string(dynamics_index)
|
158
|
+
private def dynamics_to_string(dynamics_index)
|
157
159
|
return nil unless dynamics_index
|
158
160
|
['pppppp', 'ppppp', 'pppp', 'ppp', 'pp', 'p', 'mp', 'mf', 'f', 'ff', 'fff'][dynamics_index.round.to_i]
|
159
161
|
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module Musa::Datasets::Score::ToMXML
|
2
|
-
|
2
|
+
using Musa::Extension::InspectNice
|
3
3
|
|
4
4
|
DynamicsContext = Struct.new(:last_dynamics)
|
5
5
|
private_constant :DynamicsContext
|
6
6
|
|
7
|
-
def process_ps(measure, element, context, logger, do_log)
|
7
|
+
private def process_ps(measure, element, context, logger, do_log)
|
8
8
|
context ||= DynamicsContext.new
|
9
9
|
|
10
|
-
logger.debug
|
10
|
+
logger.debug ''
|
11
|
+
logger.debug('process_ps') { "processing #{element.inspect}" } if do_log
|
11
12
|
|
12
13
|
case element[:dataset][:type]
|
13
14
|
when :crescendo, :diminuendo
|
@@ -15,7 +16,14 @@ module Musa::Datasets::Score::ToMXML
|
|
15
16
|
dynamics = dynamics_to_string(element[:dataset][:from])
|
16
17
|
|
17
18
|
if dynamics != context.last_dynamics
|
18
|
-
|
19
|
+
if dynamics
|
20
|
+
if element[:dataset][:from] < 0
|
21
|
+
logger.warn { "dynamics #{element[:dataset][:from]} not renderizable" } if do_log
|
22
|
+
elsif element[:dataset][:from] > 0
|
23
|
+
measure.add_dynamics dynamics, placement: 'below'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
19
27
|
context.last_dynamics = dynamics
|
20
28
|
end
|
21
29
|
|
@@ -29,7 +37,16 @@ module Musa::Datasets::Score::ToMXML
|
|
29
37
|
|
30
38
|
dynamics = dynamics_to_string(element[:dataset][:to])
|
31
39
|
|
32
|
-
|
40
|
+
if dynamics != context.last_dynamics
|
41
|
+
if dynamics
|
42
|
+
if element[:dataset][:to] < 0
|
43
|
+
logger.warn { "dynamics #{element[:dataset][:to]} not renderizable" } if do_log
|
44
|
+
elsif element[:dataset][:to] > 0
|
45
|
+
measure.add_dynamics dynamics, placement: 'below'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
33
50
|
context.last_dynamics = dynamics
|
34
51
|
end
|
35
52
|
|
@@ -37,7 +54,16 @@ module Musa::Datasets::Score::ToMXML
|
|
37
54
|
dynamics = dynamics_to_string(element[:dataset][:from])
|
38
55
|
|
39
56
|
if dynamics != context.last_dynamics
|
40
|
-
|
57
|
+
|
58
|
+
|
59
|
+
if dynamics
|
60
|
+
if element[:dataset][:from] < 0
|
61
|
+
logger.warn { "dynamics #{element[:dataset][:to]} not renderizable" } if do_log
|
62
|
+
elsif element[:dataset][:from] > 0
|
63
|
+
measure.add_dynamics dynamics, placement: 'below'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
41
67
|
context.last_dynamics = dynamics
|
42
68
|
end
|
43
69
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative '../../../logger'
|
2
2
|
require_relative '../../../musicxml'
|
3
|
+
require_relative '../../../core-ext/inspect-nice'
|
3
4
|
|
4
5
|
require_relative 'process-time'
|
5
6
|
require_relative 'process-pdv'
|
@@ -10,6 +11,8 @@ module Musa::Datasets; class Score
|
|
10
11
|
include Musa::MusicXML::Builder
|
11
12
|
include Musa::Datasets
|
12
13
|
|
14
|
+
using Musa::Extension::InspectNice
|
15
|
+
|
13
16
|
def to_mxml(beats_per_bar, ticks_per_beat,
|
14
17
|
bpm: nil,
|
15
18
|
title: nil,
|
@@ -22,7 +25,12 @@ module Musa::Datasets; class Score
|
|
22
25
|
bpm ||= 90
|
23
26
|
title ||= 'Untitled'
|
24
27
|
creators ||= { composer: 'Unknown' }
|
25
|
-
|
28
|
+
|
29
|
+
if logger.nil?
|
30
|
+
logger = Musa::Logger::Logger.new
|
31
|
+
logger.debug! if do_log
|
32
|
+
end
|
33
|
+
|
26
34
|
do_log ||= nil
|
27
35
|
|
28
36
|
mxml = ScorePartwise.new do |_|
|
@@ -54,12 +62,16 @@ module Musa::Datasets; class Score
|
|
54
62
|
end
|
55
63
|
|
56
64
|
if do_log
|
57
|
-
logger.debug
|
58
|
-
logger.debug
|
65
|
+
logger.debug ""
|
66
|
+
logger.debug"score.to_mxml log:"
|
67
|
+
logger.debug"------------------"
|
59
68
|
end
|
60
69
|
|
61
70
|
parts.each_key do |part_id|
|
62
|
-
fill_part mxml.parts[part_id],
|
71
|
+
fill_part mxml.parts[part_id],
|
72
|
+
beats_per_bar * ticks_per_beat,
|
73
|
+
(parts.size > 1 ? part_id : nil),
|
74
|
+
logger, do_log
|
63
75
|
end
|
64
76
|
|
65
77
|
mxml
|
@@ -74,7 +86,7 @@ module Musa::Datasets; class Score
|
|
74
86
|
(1..finish || 0).each do |bar|
|
75
87
|
if do_log
|
76
88
|
logger.debug ""
|
77
|
-
logger.debug msg = "filling part #{part.name} (#{instrument}): processing bar #{bar}"
|
89
|
+
logger.debug msg = "filling part #{part.name} (#{instrument || 'nil'}): processing bar #{bar}"
|
78
90
|
logger.debug "-" * msg.size
|
79
91
|
end
|
80
92
|
|
@@ -83,7 +95,7 @@ module Musa::Datasets; class Score
|
|
83
95
|
|
84
96
|
pointer = 0r
|
85
97
|
|
86
|
-
instrument_score = subset { |dataset| dataset[:instrument] == instrument }
|
98
|
+
instrument_score = subset { |dataset| instrument.nil? || dataset[:instrument] == instrument }
|
87
99
|
|
88
100
|
bar_elements = \
|
89
101
|
(instrument_score.changes_between(bar, bar + 1).select { |p| p[:dataset].is_a?(PS) } +
|
@@ -92,7 +104,7 @@ module Musa::Datasets; class Score
|
|
92
104
|
e[:dataset].is_a?(PS) ? 0 : 1 ] }
|
93
105
|
|
94
106
|
if pdvs.empty?
|
95
|
-
logger.debug "\
|
107
|
+
logger.debug "\nadding full bar silence..." if do_log
|
96
108
|
|
97
109
|
process_pdv(measure, bar, divisions_per_bar,
|
98
110
|
{ start: bar,
|
@@ -104,7 +116,7 @@ module Musa::Datasets; class Score
|
|
104
116
|
else
|
105
117
|
first = bar_elements.first
|
106
118
|
|
107
|
-
logger.debug "\nfirst element #{first}" if do_log
|
119
|
+
logger.debug "\nfirst element #{first.inspect}" if do_log
|
108
120
|
|
109
121
|
# TODO habrá que arreglar el cálculo de pointer cuando haya avances y retrocesos para que
|
110
122
|
# TODO no añada silencios incorrectos al principio o al final
|
@@ -113,7 +125,7 @@ module Musa::Datasets; class Score
|
|
113
125
|
|
114
126
|
silence_duration = first[:start_in_interval] - bar
|
115
127
|
|
116
|
-
logger.debug "\
|
128
|
+
logger.debug "\nadding initial silence for duration #{silence_duration}..." if do_log
|
117
129
|
|
118
130
|
pointer = process_pdv(measure, bar, divisions_per_bar,
|
119
131
|
{ start: bar,
|
@@ -124,6 +136,8 @@ module Musa::Datasets; class Score
|
|
124
136
|
do_log)
|
125
137
|
end
|
126
138
|
|
139
|
+
logger.debug "\nadding PDV and PS elements..." if do_log
|
140
|
+
|
127
141
|
bar_elements.each do |element|
|
128
142
|
case element[:dataset]
|
129
143
|
when PDV
|
@@ -140,7 +154,7 @@ module Musa::Datasets; class Score
|
|
140
154
|
if pointer < 1r
|
141
155
|
silence_duration = 1r - pointer
|
142
156
|
|
143
|
-
logger.debug "\nadded ending silence for duration #{silence_duration}" if do_log
|
157
|
+
logger.debug "\nadded ending silence for duration #{silence_duration}..." if do_log
|
144
158
|
|
145
159
|
process_pdv(measure, bar, divisions_per_bar,
|
146
160
|
{ start: bar + pointer,
|
@@ -1,7 +1,12 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
|
+
require_relative '../core-ext/inspect-nice'
|
4
|
+
|
5
|
+
|
3
6
|
module Musa; module Logger
|
4
7
|
class Logger < ::Logger
|
8
|
+
using Musa::Extension::InspectNice
|
9
|
+
|
5
10
|
def initialize(sequencer: nil, position_format: nil)
|
6
11
|
super STDERR, level: WARN
|
7
12
|
|
@@ -22,7 +27,7 @@ module Musa; module Logger
|
|
22
27
|
|
23
28
|
progname = "[#{progname}]" if progname
|
24
29
|
|
25
|
-
"#{position}#{level}#{progname} #{msg}\n"
|
30
|
+
"#{position}#{level}#{progname}#{' ' if position || level || progname}#{msg}\n"
|
26
31
|
else
|
27
32
|
"\n"
|
28
33
|
end
|
@@ -169,6 +169,7 @@ module Musa
|
|
169
169
|
private_constant :ControllersControl
|
170
170
|
|
171
171
|
class NoteControl
|
172
|
+
attr_reader :voice, :pitch, :velocity, :velocity_off, :duration
|
172
173
|
attr_reader :start_position, :end_position
|
173
174
|
|
174
175
|
def initialize(voice, pitch:, velocity: nil, duration: nil, velocity_off: nil)
|
@@ -303,7 +303,7 @@ module Musa
|
|
303
303
|
|
304
304
|
def [](grade_or_symbol)
|
305
305
|
|
306
|
-
raise ArgumentError, "grade_or_symbol '#{grade_or_symbol}' should be a
|
306
|
+
raise ArgumentError, "grade_or_symbol '#{grade_or_symbol}' should be a Integer, String or Symbol" unless grade_or_symbol.is_a?(Symbol) || grade_or_symbol.is_a?(String) || grade_or_symbol.is_a?(Integer)
|
307
307
|
|
308
308
|
wide_grade, sharps = grade_of(grade_or_symbol)
|
309
309
|
|
@@ -66,9 +66,10 @@ module Musa; module Sequencer
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
_numeric_at start_position +
|
69
|
+
_numeric_at _quantize_position(start_position + time, warn: true), control do
|
70
70
|
binder.call(values,
|
71
71
|
**extra_attributes,
|
72
|
+
time: start_position + time,
|
72
73
|
started_ago: started_ago,
|
73
74
|
control: control)
|
74
75
|
|
@@ -9,6 +9,8 @@ module Musa; module Sequencer
|
|
9
9
|
include Musa::Extension::SmartProcBinder
|
10
10
|
include Musa::Extension::DeepCopy
|
11
11
|
|
12
|
+
using Musa::Extension::InspectNice
|
13
|
+
|
12
14
|
private def _tick(position_to_run)
|
13
15
|
@before_tick.each { |block| block.call position_to_run }
|
14
16
|
queue = @timeslots[position_to_run]
|
@@ -3,6 +3,8 @@ module Musa
|
|
3
3
|
class BaseSequencer
|
4
4
|
module TickBasedTiming
|
5
5
|
|
6
|
+
using Musa::Extension::InspectNice
|
7
|
+
|
6
8
|
attr_reader :position, :ticks_per_bar, :tick_duration
|
7
9
|
|
8
10
|
def tick
|
@@ -48,8 +50,8 @@ module Musa
|
|
48
50
|
|
49
51
|
if warn
|
50
52
|
@logger.warn('BaseSequencer') { "_check_position: rounding "\
|
51
|
-
"position #{original_position} (#{original_position.to_f.round(5)}) "\
|
52
|
-
"to tick precision: #{position} (#{position.to_f.round(5)})" }
|
53
|
+
"position #{original_position.inspect} (#{original_position.to_f.round(5)}) "\
|
54
|
+
"to tick precision: #{position.inspect} (#{position.to_f.round(5)})" }
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
@@ -53,7 +53,7 @@ module Musa
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
def
|
56
|
+
def to_ary
|
57
57
|
if @proxy.array_mode?
|
58
58
|
[].tap { |_| @proxy.components.each { |i| _[i] = self[i] } }
|
59
59
|
else
|
@@ -66,6 +66,9 @@ module Musa
|
|
66
66
|
|
67
67
|
def initialize(hash_or_array_serie)
|
68
68
|
@source = hash_or_array_serie
|
69
|
+
|
70
|
+
infer_components
|
71
|
+
|
69
72
|
restart restart_source: false
|
70
73
|
|
71
74
|
mark_regarding! @source
|
@@ -76,14 +79,20 @@ module Musa
|
|
76
79
|
def hash_mode?; @hash_mode; end
|
77
80
|
def array_mode?; @array_mode; end
|
78
81
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
82
|
+
def restart(key_or_index = nil, restart_source: true)
|
83
|
+
if key_or_index
|
84
|
+
@asked_to_restart[key_or_index] = true
|
85
|
+
else
|
86
|
+
@components.each { |c| @asked_to_restart[c] = true }
|
87
|
+
end
|
83
88
|
|
84
|
-
|
85
|
-
|
89
|
+
if @asked_to_restart.values.all?
|
90
|
+
@source.restart if restart_source
|
91
|
+
infer_components
|
92
|
+
end
|
93
|
+
end
|
86
94
|
|
95
|
+
private def infer_components
|
87
96
|
source = @source.instance
|
88
97
|
sample = source.current_value || source.peek_next_value
|
89
98
|
|
@@ -103,10 +112,17 @@ module Musa
|
|
103
112
|
@values = nil
|
104
113
|
@array_mode = @hash_mode = false
|
105
114
|
end
|
115
|
+
|
116
|
+
@asked_to_restart = {}
|
117
|
+
|
118
|
+
@components.each do |component|
|
119
|
+
@asked_to_restart[component] = false
|
120
|
+
end
|
106
121
|
end
|
107
122
|
|
108
123
|
def next_value(key_or_index)
|
109
124
|
if @values[key_or_index].nil? || @values[key_or_index].empty?
|
125
|
+
|
110
126
|
hash_or_array_value = @source.next_value
|
111
127
|
|
112
128
|
case hash_or_array_value
|
@@ -142,7 +158,7 @@ module Musa
|
|
142
158
|
end
|
143
159
|
|
144
160
|
def _restart
|
145
|
-
@source.restart
|
161
|
+
@source.restart @key_or_index
|
146
162
|
end
|
147
163
|
|
148
164
|
def _next_value
|
@@ -192,11 +192,11 @@ module Musa
|
|
192
192
|
private_constant :Sequence
|
193
193
|
|
194
194
|
class FromEvalBlockWithParameters
|
195
|
-
using Musa::Extension::DeepCopy
|
196
|
-
|
197
195
|
include Serie
|
198
196
|
include Musa::Extension::SmartProcBinder
|
199
197
|
|
198
|
+
using Musa::Extension::DeepCopy
|
199
|
+
|
200
200
|
attr_reader :block
|
201
201
|
|
202
202
|
def initialize(*values, **key_values, &block)
|
@@ -222,7 +222,7 @@ module Musa
|
|
222
222
|
|
223
223
|
def _next_value
|
224
224
|
@value = if !@value.nil? || @value.nil? && @first
|
225
|
-
@value = @block.call(*@value_parameters, last_value: @value, **@key_parameters)
|
225
|
+
@value = @block.call(*@value_parameters, last_value: @value, caller: self, **@key_parameters)
|
226
226
|
else
|
227
227
|
nil
|
228
228
|
end
|
@@ -190,10 +190,15 @@ module Musa
|
|
190
190
|
end
|
191
191
|
|
192
192
|
def _next_value
|
193
|
+
previous_value = @source.current_value
|
193
194
|
value = @source.next_value
|
194
195
|
peek_next_value = @source.peek_next_value
|
195
196
|
|
196
|
-
|
197
|
+
if value.nil?
|
198
|
+
nil
|
199
|
+
else
|
200
|
+
@block.call(previous_value, value, peek_next_value)
|
201
|
+
end
|
197
202
|
end
|
198
203
|
|
199
204
|
def infinite?
|
@@ -962,7 +967,7 @@ module Musa
|
|
962
967
|
|
963
968
|
def _next_value
|
964
969
|
if value = @source.next_value
|
965
|
-
while @block.call(value, @history)
|
970
|
+
while value && @block.call(value, @history)
|
966
971
|
@history << value
|
967
972
|
value = @source.next_value
|
968
973
|
end
|
@@ -8,15 +8,15 @@ module Musa
|
|
8
8
|
raise ArgumentError, 'Can\'t union an array of series with a hash of series' if array_of_timed_series.any? && hash_of_timed_series.any?
|
9
9
|
|
10
10
|
if array_of_timed_series.any?
|
11
|
-
|
11
|
+
TimedUnionOfArrayOfTimedSeries.new(array_of_timed_series)
|
12
12
|
elsif hash_of_timed_series.any?
|
13
|
-
|
13
|
+
TimedUnionOfHashOfTimedSeries.new(hash_of_timed_series)
|
14
14
|
else
|
15
15
|
raise ArgumentError, 'Missing argument series'
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
class
|
19
|
+
class TimedUnionOfArrayOfTimedSeries
|
20
20
|
include Serie
|
21
21
|
|
22
22
|
attr_reader :sources
|
@@ -34,7 +34,7 @@ module Musa
|
|
34
34
|
end
|
35
35
|
|
36
36
|
private def _restart(restart_sources = true)
|
37
|
-
@sources.each
|
37
|
+
@sources.each(&:restart) if restart_sources
|
38
38
|
@sources_next_values = Array.new(@sources.size)
|
39
39
|
|
40
40
|
@components = nil
|
@@ -74,7 +74,7 @@ module Musa
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
result
|
77
|
+
result.extend(Musa::Datasets::AbsTimed)
|
78
78
|
else
|
79
79
|
nil
|
80
80
|
end
|
@@ -146,9 +146,9 @@ module Musa
|
|
146
146
|
return components, hash_mode, array_mode
|
147
147
|
end
|
148
148
|
|
149
|
-
private_constant :
|
149
|
+
private_constant :TimedUnionOfArrayOfTimedSeries
|
150
150
|
|
151
|
-
class
|
151
|
+
class TimedUnionOfHashOfTimedSeries
|
152
152
|
include Serie
|
153
153
|
|
154
154
|
attr_reader :sources
|
@@ -168,15 +168,17 @@ module Musa
|
|
168
168
|
end
|
169
169
|
|
170
170
|
private def _restart(restart_sources = true)
|
171
|
-
@sources.each_value
|
171
|
+
@sources.each_value(&:restart) if restart_sources
|
172
172
|
@sources_next_values = @components.collect { |k| [k, nil] }.to_h
|
173
173
|
@other_attributes = nil
|
174
174
|
end
|
175
175
|
|
176
176
|
private def _next_value
|
177
|
-
sources_values =
|
178
|
-
|
179
|
-
|
177
|
+
sources_values = {}
|
178
|
+
|
179
|
+
@components.each do |key|
|
180
|
+
sources_values[key] = @sources_next_values[key] || (@sources_next_values[key] = @sources[key].next_value)
|
181
|
+
end
|
180
182
|
|
181
183
|
@other_attributes = infer_other_attributes(sources_values) unless @other_attributes
|
182
184
|
|
@@ -205,7 +207,7 @@ module Musa
|
|
205
207
|
end
|
206
208
|
end
|
207
209
|
|
208
|
-
result
|
210
|
+
result.extend(Musa::Datasets::AbsTimed)
|
209
211
|
else
|
210
212
|
nil
|
211
213
|
end
|
@@ -228,7 +230,7 @@ module Musa
|
|
228
230
|
end
|
229
231
|
end
|
230
232
|
|
231
|
-
private_constant :
|
233
|
+
private_constant :TimedUnionOfHashOfTimedSeries
|
232
234
|
|
233
235
|
module SerieOperations
|
234
236
|
def flatten_timed
|
@@ -300,7 +302,7 @@ module Musa
|
|
300
302
|
result = source_value.clone.extend(Musa::Datasets::AbsTimed)
|
301
303
|
end
|
302
304
|
|
303
|
-
result
|
305
|
+
result.extend(Musa::Datasets::AbsTimed)
|
304
306
|
else
|
305
307
|
nil
|
306
308
|
end
|
data/musa-dsl.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'musa-dsl'
|
3
|
-
s.version = '0.22.
|
4
|
-
s.date = '2020-11-
|
3
|
+
s.version = '0.22.6'
|
4
|
+
s.date = '2020-11-25'
|
5
5
|
s.summary = 'A simple Ruby DSL for making complex music'
|
6
|
-
s.description = 'Musa-DSL: A Ruby DSL for algorithmic
|
6
|
+
s.description = 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical thinking and composition'
|
7
7
|
s.authors = ['Javier Sánchez Yeste']
|
8
8
|
s.email = 'javier.sy@gmail.com'
|
9
9
|
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|samples)/}) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: musa-dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.22.
|
4
|
+
version: 0.22.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javier Sánchez Yeste
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: citrus
|
@@ -70,8 +70,8 @@ dependencies:
|
|
70
70
|
- - ">="
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: 0.2.4
|
73
|
-
description: 'Musa-DSL: A Ruby DSL for algorithmic
|
74
|
-
|
73
|
+
description: 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical
|
74
|
+
thinking and composition'
|
75
75
|
email: javier.sy@gmail.com
|
76
76
|
executables: []
|
77
77
|
extensions: []
|