musa-dsl 0.22.0 → 0.22.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/musa-dsl.rb +1 -1
- data/lib/musa-dsl/datasets/p.rb +3 -1
- data/lib/musa-dsl/matrix/matrix.rb +9 -7
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +7 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +28 -128
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +8 -24
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +5 -7
- data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +3 -5
- data/lib/musa-dsl/sequencer/{base-sequencer-public.rb → base-sequencer.rb} +15 -23
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +7 -4
- data/lib/musa-dsl/sequencer/sequencer.rb +8 -1
- data/lib/musa-dsl/series/base-series.rb +2 -2
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +68 -4
- data/lib/musa-dsl/series/main-serie-constructors.rb +7 -11
- data/lib/musa-dsl/series/main-serie-operations.rb +39 -4
- data/lib/musa-dsl/series/quantizer-serie.rb +25 -15
- data/lib/musa-dsl/series/series.rb +1 -1
- data/lib/musa-dsl/series/timed-serie.rb +354 -0
- data/musa-dsl.gemspec +2 -2
- metadata +4 -4
- data/lib/musa-dsl/series/flattener-timed-serie.rb +0 -61
@@ -30,6 +30,7 @@ module Musa
|
|
30
30
|
else
|
31
31
|
@logger = Musa::Logger::Logger.new(sequencer: self, position_format: log_position_format)
|
32
32
|
|
33
|
+
@logger.fatal!
|
33
34
|
@logger.error! if do_error_log || do_error_log.nil?
|
34
35
|
@logger.debug! if do_log
|
35
36
|
end
|
@@ -82,6 +83,11 @@ module Musa
|
|
82
83
|
@timeslots.empty?
|
83
84
|
end
|
84
85
|
|
86
|
+
def quantize_position(position, warn: nil)
|
87
|
+
warn ||= false
|
88
|
+
_quantize_position(position, warn: warn)
|
89
|
+
end
|
90
|
+
|
85
91
|
def run
|
86
92
|
tick until empty?
|
87
93
|
end
|
@@ -114,22 +120,19 @@ module Musa
|
|
114
120
|
@event_handlers.last.launch event, *value_parameters, **key_parameters
|
115
121
|
end
|
116
122
|
|
117
|
-
def wait(bars_delay,
|
123
|
+
def wait(bars_delay, debug: nil, &block)
|
118
124
|
debug ||= false
|
119
125
|
|
120
126
|
control = EventHandler.new @event_handlers.last
|
121
127
|
@event_handlers.push control
|
122
128
|
|
123
129
|
if bars_delay.is_a? Numeric
|
124
|
-
_numeric_at position + bars_delay.rationalize, control,
|
130
|
+
_numeric_at position + bars_delay.rationalize, control, debug: debug, &block
|
125
131
|
else
|
126
132
|
bars_delay = Series::S(*bars_delay) if bars_delay.is_a?(Array)
|
127
133
|
bars_delay = bars_delay.instance if bars_delay
|
128
134
|
|
129
|
-
|
130
|
-
with = with.instance if with
|
131
|
-
|
132
|
-
_serie_at bars_delay.eval { |delay| position + delay }, control, with: with, debug: debug, &block
|
135
|
+
_serie_at bars_delay.eval { |delay| position + delay }, control, debug: debug, &block
|
133
136
|
end
|
134
137
|
|
135
138
|
@event_handlers.pop
|
@@ -137,11 +140,11 @@ module Musa
|
|
137
140
|
control
|
138
141
|
end
|
139
142
|
|
140
|
-
def now(
|
143
|
+
def now(&block)
|
141
144
|
control = EventHandler.new @event_handlers.last
|
142
145
|
@event_handlers.push control
|
143
146
|
|
144
|
-
_numeric_at position, control,
|
147
|
+
_numeric_at position, control, &block
|
145
148
|
|
146
149
|
@event_handlers.pop
|
147
150
|
|
@@ -154,22 +157,19 @@ module Musa
|
|
154
157
|
nil
|
155
158
|
end
|
156
159
|
|
157
|
-
def at(bar_position,
|
160
|
+
def at(bar_position, debug: nil, &block)
|
158
161
|
debug ||= false
|
159
162
|
|
160
163
|
control = EventHandler.new @event_handlers.last
|
161
164
|
@event_handlers.push control
|
162
165
|
|
163
166
|
if bar_position.is_a? Numeric
|
164
|
-
_numeric_at bar_position.rationalize, control,
|
167
|
+
_numeric_at bar_position.rationalize, control, debug: debug, &block
|
165
168
|
else
|
166
169
|
bar_position = Series::S(*bar_position) if bar_position.is_a? Array
|
167
170
|
bar_position = bar_position.instance if bar_position
|
168
171
|
|
169
|
-
|
170
|
-
with = with.instance if with
|
171
|
-
|
172
|
-
_serie_at bar_position, control, with: with, debug: debug, &block
|
172
|
+
_serie_at bar_position, control, debug: debug, &block
|
173
173
|
end
|
174
174
|
|
175
175
|
@event_handlers.pop
|
@@ -215,9 +215,6 @@ module Musa
|
|
215
215
|
end
|
216
216
|
|
217
217
|
def play_timed(timed_serie,
|
218
|
-
reference: nil,
|
219
|
-
step: nil,
|
220
|
-
right_open: nil,
|
221
218
|
on_stop: nil,
|
222
219
|
after_bars: nil, after: nil,
|
223
220
|
&block)
|
@@ -233,12 +230,7 @@ module Musa
|
|
233
230
|
|
234
231
|
@event_handlers.push control
|
235
232
|
|
236
|
-
_play_timed(timed_serie.instance,
|
237
|
-
control,
|
238
|
-
reference: reference,
|
239
|
-
step: step,
|
240
|
-
right_open: right_open,
|
241
|
-
&block)
|
233
|
+
_play_timed(timed_serie.instance, control, &block)
|
242
234
|
|
243
235
|
@event_handlers.pop
|
244
236
|
|
@@ -17,13 +17,14 @@ module Musa
|
|
17
17
|
:position=,
|
18
18
|
:event_handler
|
19
19
|
|
20
|
-
def_delegators :@context, :position, :logger, :debug
|
21
|
-
def_delegators :@context, :with, :now, :at, :wait, :play, :every, :move
|
20
|
+
def_delegators :@context, :position, :quantize_position, :logger, :debug
|
21
|
+
def_delegators :@context, :with, :now, :at, :wait, :play, :play_timed, :every, :move
|
22
22
|
def_delegators :@context, :everying, :playing, :moving
|
23
23
|
def_delegators :@context, :launch, :on
|
24
24
|
def_delegators :@context, :run
|
25
25
|
|
26
|
-
def initialize(beats_per_bar
|
26
|
+
def initialize(beats_per_bar = nil,
|
27
|
+
ticks_per_beat = nil,
|
27
28
|
sequencer: nil,
|
28
29
|
logger: nil,
|
29
30
|
do_log: nil, do_error_log: nil, log_position_format: nil,
|
@@ -50,7 +51,9 @@ module Musa
|
|
50
51
|
|
51
52
|
def_delegators :@sequencer,
|
52
53
|
:launch, :on,
|
53
|
-
:position, :
|
54
|
+
:position, :quantize_position,
|
55
|
+
:size,
|
56
|
+
:everying, :playing, :moving,
|
54
57
|
:ticks_per_bar, :logger, :debug, :inspect,
|
55
58
|
:run
|
56
59
|
|
@@ -1,3 +1,10 @@
|
|
1
|
-
require_relative 'base-sequencer
|
1
|
+
require_relative 'base-sequencer'
|
2
|
+
|
2
3
|
require_relative 'base-sequencer-implementation'
|
4
|
+
|
5
|
+
require_relative 'base-sequencer-implementation-every'
|
6
|
+
require_relative 'base-sequencer-implementation-move'
|
7
|
+
require_relative 'base-sequencer-implementation-play'
|
8
|
+
require_relative 'base-sequencer-implementation-play-timed'
|
9
|
+
|
3
10
|
require_relative 'sequencer-dsl'
|
@@ -30,7 +30,7 @@ module Musa
|
|
30
30
|
if @is_instance
|
31
31
|
self
|
32
32
|
else
|
33
|
-
clone(freeze: false).tap(&:_instance!).mark_as_instance!(self)
|
33
|
+
clone(freeze: false).tap(&:_instance!).mark_as_instance!(self).tap(&:restart)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -40,7 +40,7 @@ module Musa
|
|
40
40
|
# handle prototyping/instancing automatically.
|
41
41
|
# If there is a @sources attribute with the eventual several sources, SeriePrototyping will handle them by
|
42
42
|
# default.
|
43
|
-
# If needed the subclasses can override this behaviour to
|
43
|
+
# If needed the subclasses can override this behaviour to accommodate to real subclass specificities.
|
44
44
|
#
|
45
45
|
protected def _prototype!
|
46
46
|
@source = @source.prototype if @source
|
@@ -6,6 +6,8 @@ module Musa
|
|
6
6
|
end
|
7
7
|
|
8
8
|
class Splitter
|
9
|
+
include Enumerable
|
10
|
+
|
9
11
|
def initialize(proxy)
|
10
12
|
@proxy = proxy
|
11
13
|
@series = {}
|
@@ -19,6 +21,46 @@ module Musa
|
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
24
|
+
def each
|
25
|
+
if block_given?
|
26
|
+
if @proxy.hash_mode?
|
27
|
+
@proxy.components.each do |key|
|
28
|
+
yield [key, self[key]]
|
29
|
+
end
|
30
|
+
elsif @proxy.array_mode?
|
31
|
+
@proxy.components.each do |index|
|
32
|
+
yield self[index]
|
33
|
+
end
|
34
|
+
else
|
35
|
+
# do nothing
|
36
|
+
end
|
37
|
+
else
|
38
|
+
if @proxy.hash_mode?
|
39
|
+
@proxy.components.collect { |key| [key, self[key]] }.each
|
40
|
+
elsif @proxy.array_mode?
|
41
|
+
@proxy.components.collect { |index| self[index] }.each
|
42
|
+
else
|
43
|
+
[].each
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_hash
|
49
|
+
if @proxy.hash_mode?
|
50
|
+
@proxy.components.collect { |key| [key, self[key]] }.to_h
|
51
|
+
else
|
52
|
+
raise RuntimeError, 'Splitter is not based on Hash: can\'t convert to Hash'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_array
|
57
|
+
if @proxy.array_mode?
|
58
|
+
[].tap { |_| @proxy.components.each { |i| _[i] = self[i] } }
|
59
|
+
else
|
60
|
+
raise RuntimeError, 'Splitter is not based on Array: can\'t convert to Array'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
22
64
|
class BufferedProxy
|
23
65
|
include SeriePrototyping
|
24
66
|
|
@@ -29,6 +71,11 @@ module Musa
|
|
29
71
|
mark_regarding! @source
|
30
72
|
end
|
31
73
|
|
74
|
+
attr_reader :components
|
75
|
+
|
76
|
+
def hash_mode?; @hash_mode; end
|
77
|
+
def array_mode?; @array_mode; end
|
78
|
+
|
32
79
|
protected def _instance!
|
33
80
|
super
|
34
81
|
restart
|
@@ -36,22 +83,39 @@ module Musa
|
|
36
83
|
|
37
84
|
def restart(restart_source: true)
|
38
85
|
@source.restart if restart_source
|
39
|
-
|
86
|
+
|
87
|
+
source = @source.instance
|
88
|
+
sample = source.current_value || source.peek_next_value
|
89
|
+
|
90
|
+
case sample
|
91
|
+
when Array
|
92
|
+
@components = (0..sample.size-1).to_a
|
93
|
+
@values = []
|
94
|
+
@array_mode = true
|
95
|
+
@hash_mode = false
|
96
|
+
when Hash
|
97
|
+
@components = sample.keys.clone
|
98
|
+
@values = {}
|
99
|
+
@array_mode = false
|
100
|
+
@hash_mode = true
|
101
|
+
else
|
102
|
+
@components = []
|
103
|
+
@values = nil
|
104
|
+
@array_mode = @hash_mode = false
|
105
|
+
end
|
40
106
|
end
|
41
107
|
|
42
108
|
def next_value(key_or_index)
|
43
|
-
if @values
|
109
|
+
if @values[key_or_index].nil? || @values[key_or_index].empty?
|
44
110
|
hash_or_array_value = @source.next_value
|
45
111
|
|
46
112
|
case hash_or_array_value
|
47
113
|
when Hash
|
48
|
-
@values ||= {}
|
49
114
|
hash_or_array_value.each do |k, v|
|
50
115
|
@values[k] ||= []
|
51
116
|
@values[k] << v
|
52
117
|
end
|
53
118
|
when Array
|
54
|
-
@values ||= []
|
55
119
|
hash_or_array_value.each_index do |i|
|
56
120
|
@values[i] ||= []
|
57
121
|
@values[i] << hash_or_array_value[i]
|
@@ -192,6 +192,8 @@ module Musa
|
|
192
192
|
private_constant :Sequence
|
193
193
|
|
194
194
|
class FromEvalBlockWithParameters
|
195
|
+
using Musa::Extension::DeepCopy
|
196
|
+
|
195
197
|
include Serie
|
196
198
|
include Musa::Extension::SmartProcBinder
|
197
199
|
|
@@ -211,8 +213,8 @@ module Musa
|
|
211
213
|
end
|
212
214
|
|
213
215
|
def _restart
|
214
|
-
@value_parameters = @original_value_parameters.
|
215
|
-
@key_parameters = @original_key_parameters.
|
216
|
+
@value_parameters = @original_value_parameters.clone(deep: true)
|
217
|
+
@key_parameters = @original_key_parameters.clone(deep: true)
|
216
218
|
|
217
219
|
@first = true
|
218
220
|
@value = nil
|
@@ -268,9 +270,7 @@ module Musa
|
|
268
270
|
@to.nil?
|
269
271
|
end
|
270
272
|
|
271
|
-
private
|
272
|
-
|
273
|
-
def sign_adjust_step
|
273
|
+
private def sign_adjust_step
|
274
274
|
@step = (-@step if @to && (@from < @to && @step < 0 || @from > @to && @step > 0)) || @step
|
275
275
|
end
|
276
276
|
end
|
@@ -337,9 +337,7 @@ module Musa
|
|
337
337
|
end
|
338
338
|
end
|
339
339
|
|
340
|
-
private
|
341
|
-
|
342
|
-
def adjust_step
|
340
|
+
private def adjust_step
|
343
341
|
@step = (-@step if @from < @to && @step < 0 || @from > @to && @step > 0) || @step
|
344
342
|
@step_count = ((@to - @from) / @step).to_i
|
345
343
|
end
|
@@ -411,9 +409,7 @@ module Musa
|
|
411
409
|
value
|
412
410
|
end
|
413
411
|
|
414
|
-
private
|
415
|
-
|
416
|
-
def adjust_step
|
412
|
+
private def adjust_step
|
417
413
|
@step = (-@step if @from < @to && @step < 0 || @from > @to && @step > 0) || @step
|
418
414
|
@step_count = ((@to - @from) / @step).to_i
|
419
415
|
end
|
@@ -112,6 +112,10 @@ module Musa
|
|
112
112
|
ProcessWith.new self, &yield_block
|
113
113
|
end
|
114
114
|
|
115
|
+
def anticipate(&yield_block)
|
116
|
+
Anticipate.new self, &yield_block
|
117
|
+
end
|
118
|
+
|
115
119
|
###
|
116
120
|
### Implementation
|
117
121
|
###
|
@@ -130,7 +134,7 @@ module Musa
|
|
130
134
|
@block = SmartProcBinder.new(block) if block_given?
|
131
135
|
|
132
136
|
if @source.prototype?
|
133
|
-
@sources = @sources.transform_values { |s| s.prototype }
|
137
|
+
@sources = @sources.transform_values { |s| s.prototype }.freeze
|
134
138
|
else
|
135
139
|
@sources = @sources.transform_values { |s| s.instance }
|
136
140
|
end
|
@@ -168,6 +172,37 @@ module Musa
|
|
168
172
|
|
169
173
|
private_constant :ProcessWith
|
170
174
|
|
175
|
+
class Anticipate
|
176
|
+
include Musa::Extension::SmartProcBinder
|
177
|
+
include Serie
|
178
|
+
|
179
|
+
attr_reader :source, :block
|
180
|
+
|
181
|
+
def initialize(serie, &block)
|
182
|
+
@source = serie
|
183
|
+
@block = block
|
184
|
+
|
185
|
+
mark_regarding! @source
|
186
|
+
end
|
187
|
+
|
188
|
+
def _restart
|
189
|
+
@source.restart
|
190
|
+
end
|
191
|
+
|
192
|
+
def _next_value
|
193
|
+
value = @source.next_value
|
194
|
+
peek_next_value = @source.peek_next_value
|
195
|
+
|
196
|
+
@block.call(value, peek_next_value)
|
197
|
+
end
|
198
|
+
|
199
|
+
def infinite?
|
200
|
+
@source.infinite?
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
private_constant :Anticipate
|
205
|
+
|
171
206
|
class Switcher
|
172
207
|
include Serie
|
173
208
|
|
@@ -185,7 +220,7 @@ module Musa
|
|
185
220
|
@sources = hash_series.clone.transform_values(&get)
|
186
221
|
end
|
187
222
|
|
188
|
-
if get == :
|
223
|
+
if get == :prototype!
|
189
224
|
@sources.freeze
|
190
225
|
end
|
191
226
|
|
@@ -236,7 +271,7 @@ module Musa
|
|
236
271
|
|
237
272
|
_restart false
|
238
273
|
|
239
|
-
if get == :
|
274
|
+
if get == :prototype
|
240
275
|
@sources.freeze
|
241
276
|
end
|
242
277
|
|
@@ -293,7 +328,7 @@ module Musa
|
|
293
328
|
@sources = hash_series.clone.transform_values(&get)
|
294
329
|
end
|
295
330
|
|
296
|
-
if get == :
|
331
|
+
if get == :prototype
|
297
332
|
@sources.freeze
|
298
333
|
end
|
299
334
|
|
@@ -65,7 +65,7 @@ module Musa
|
|
65
65
|
case n
|
66
66
|
when nil
|
67
67
|
time = value = nil
|
68
|
-
when AbsTimed
|
68
|
+
when Musa::Datasets::AbsTimed
|
69
69
|
time = n[:time].rationalize
|
70
70
|
value = n[@value_attribute].rationalize
|
71
71
|
when Array
|
@@ -87,8 +87,6 @@ module Musa
|
|
87
87
|
|
88
88
|
attr_reader :source
|
89
89
|
|
90
|
-
attr_reader :points_history
|
91
|
-
|
92
90
|
def initialize(reference, step, source, value_attribute, stops, left_open, right_open)
|
93
91
|
@reference = reference
|
94
92
|
@step_size = step.abs
|
@@ -144,7 +142,9 @@ module Musa
|
|
144
142
|
|
145
143
|
return { time: first[:time],
|
146
144
|
@value_attribute => first[:value],
|
147
|
-
duration: durations_to_sum.sum { |_| _[:duration] } }
|
145
|
+
duration: durations_to_sum.sum { |_| _[:duration] } }
|
146
|
+
.extend(Musa::Datasets::AbsTimed)
|
147
|
+
.extend(Musa::Datasets::AbsD)
|
148
148
|
else
|
149
149
|
i += 1
|
150
150
|
end
|
@@ -179,7 +179,9 @@ module Musa
|
|
179
179
|
|
180
180
|
return { time: first[:time],
|
181
181
|
@value_attribute => first[:value],
|
182
|
-
duration: durations_to_sum.sum { |_| _[:duration] } }
|
182
|
+
duration: durations_to_sum.sum { |_| _[:duration] } }
|
183
|
+
.extend(Musa::Datasets::AbsTimed)
|
184
|
+
.extend(Musa::Datasets::AbsD)
|
183
185
|
else
|
184
186
|
i += 1
|
185
187
|
end
|
@@ -214,13 +216,13 @@ module Musa
|
|
214
216
|
if @segments.last && @segments.last[:time] == from_time
|
215
217
|
|
216
218
|
@segments.last[:duration] = to_time - from_time
|
217
|
-
@segments.last[:info] +=
|
219
|
+
@segments.last[:info] += '; edited on a as start'
|
218
220
|
|
219
221
|
else
|
220
222
|
@segments << { time: from_time,
|
221
223
|
value: from_value,
|
222
224
|
duration: to_time - from_time,
|
223
|
-
info:
|
225
|
+
info: 'added on a as start' }
|
224
226
|
|
225
227
|
end
|
226
228
|
|
@@ -229,7 +231,7 @@ module Musa
|
|
229
231
|
value: from_value,
|
230
232
|
duration: 0,
|
231
233
|
stop: true,
|
232
|
-
info:
|
234
|
+
info: 'added on a as end stop' }
|
233
235
|
end
|
234
236
|
else
|
235
237
|
time_increment = to_time - from_time
|
@@ -264,7 +266,7 @@ module Musa
|
|
264
266
|
@segments.last[:value] == value
|
265
267
|
|
266
268
|
@segments.last[:duration] = step_time_increment
|
267
|
-
@segments.last[:info] +=
|
269
|
+
@segments.last[:info] += '; edited on b'
|
268
270
|
|
269
271
|
# puts "process2: editing #{@segments.last}"
|
270
272
|
|
@@ -272,7 +274,7 @@ module Musa
|
|
272
274
|
@segments << v = { time: intermediate_point_time,
|
273
275
|
value: value,
|
274
276
|
duration: step_time_increment,
|
275
|
-
info:
|
277
|
+
info: 'added on b' }
|
276
278
|
|
277
279
|
# puts "process2: adding #{v.inspect}"
|
278
280
|
end
|
@@ -293,7 +295,7 @@ module Musa
|
|
293
295
|
|
294
296
|
private def process(time, value, last_time_value)
|
295
297
|
if time && value
|
296
|
-
raise RuntimeError,
|
298
|
+
raise RuntimeError, 'time only can go forward' if @last_processed_time && time <= @last_processed_time
|
297
299
|
|
298
300
|
q_value = round_quantize(value)
|
299
301
|
|
@@ -400,7 +402,9 @@ module Musa
|
|
400
402
|
if time > first_time
|
401
403
|
result = { time: first_time,
|
402
404
|
@value_attribute => round_to_nearest_quantize(first_value, value),
|
403
|
-
duration: time - first_time }
|
405
|
+
duration: time - first_time }
|
406
|
+
.extend(Musa::Datasets::AbsD)
|
407
|
+
.extend(Musa::Datasets::AbsTimed)
|
404
408
|
else
|
405
409
|
result = _next_value
|
406
410
|
end
|
@@ -409,7 +413,9 @@ module Musa
|
|
409
413
|
next_time = @crossings[1][:time]
|
410
414
|
result = { time: time,
|
411
415
|
@value_attribute => value,
|
412
|
-
duration: next_time - time }
|
416
|
+
duration: next_time - time }
|
417
|
+
.extend(Musa::Datasets::AbsD)
|
418
|
+
.extend(Musa::Datasets::AbsTimed)
|
413
419
|
|
414
420
|
@crossings.shift
|
415
421
|
|
@@ -417,7 +423,9 @@ module Musa
|
|
417
423
|
if @last_time && @last_time > @crossings[0][:time]
|
418
424
|
result = { time: @crossings[0][:time],
|
419
425
|
@value_attribute => @crossings[0][@value_attribute],
|
420
|
-
duration: @last_time - @crossings[0][:time] }
|
426
|
+
duration: @last_time - @crossings[0][:time] }
|
427
|
+
.extend(Musa::Datasets::AbsD)
|
428
|
+
.extend(Musa::Datasets::AbsTimed)
|
421
429
|
|
422
430
|
@last_time = nil
|
423
431
|
end
|
@@ -427,7 +435,9 @@ module Musa
|
|
427
435
|
if @first && @last_time && @last_time > first_time
|
428
436
|
result = { time: first_time,
|
429
437
|
value: round_to_nearest_quantize(first_value),
|
430
|
-
duration: @last_time - first_time }
|
438
|
+
duration: @last_time - first_time }
|
439
|
+
.extend(Musa::Datasets::AbsD)
|
440
|
+
.extend(Musa::Datasets::AbsTimed)
|
431
441
|
|
432
442
|
@first = false
|
433
443
|
@last_time = false
|