Module: Musa::Datasets::P
- Includes:
- Dataset
- Defined in:
- lib/musa-dsl/datasets/p.rb
Overview
Point series: sequential points in time with durations.
P (Point series) represents sequential points in time as arrays with alternating structure: [point, duration, point, duration, point, ...].
Structure
The array alternates between points and durations:
[point₀, duration₀, point₁, duration₁, point₂]
- Points (odd positions): Any data (numbers, hashes, complex structures, etc.)
- Durations (even positions): Time between points (numbers)
- Last point: Final point has no duration (sequence end)
This compact format efficiently represents timed sequences without repeating time information.
Conversions
P can be converted to two different representations:
1. Timed Series (to_timed_serie)
Converts to series of AbsTimed events with absolute time and value. Each value gets a timestamp based on cumulative durations.
p = [60, 4, 64, 8, 67].extend(P)
serie = p.to_timed_serie
# Yields:
# { time: 0, value: 60 }
# { time: 1.0, value: 64 } (4 * base_duration = 1.0)
# { time: 3.0, value: 67 } (8 * base_duration = 2.0)
2. Parameter Segment Series (to_ps_serie)
Converts to series of PS (Parameter Segment) objects representing continuous changes between consecutive points.
p = [60, 4, 64, 8, 67].extend(P)
serie = p.to_ps_serie
# Yields PS objects:
# { from: 60, to: 64, duration: 1.0, right_open: true }
# { from: 64, to: 67, duration: 2.0, right_open: false }
Point Transformation
The #map method transforms points while preserving durations:
p = [60, 4, 64, 8, 67].extend(P)
p2 = p.map { |point| point + 12 }
# => [72, 4, 76, 8, 79]
# Durations unchanged, points transformed
Defined Under Namespace
Classes: PtoTimedSerie
Instance Method Summary collapse
-
#map {|point| ... } ⇒ P
Maps over points, preserving durations.
-
#to_ps_serie(base_duration: nil) ⇒ Musa::Series::Serie<PS>
Converts to series of parameter segments.
-
#to_timed_serie(time_start: nil, time_start_component: nil, base_duration: nil) ⇒ PtoTimedSerie
Converts to series of timed events (AbsTimed).
Instance Method Details
#map {|point| ... } ⇒ P
Maps over points, preserving durations.
Transforms each point (odd positions) using the block while keeping durations (even positions) unchanged.
184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/musa-dsl/datasets/p.rb', line 184 def map(&block) i = 0 clone.map! do |element| # Process with block only the points (points are the alternating elements because P # structure is <point> <duration> <point> <duration> <point>) # if (i += 1) % 2 == 1 block.call(element) else element end end end |
#to_ps_serie(base_duration: nil) ⇒ Musa::Series::Serie<PS>
Converts to series of parameter segments.
Creates Musa::Datasets::PS objects representing continuous changes from each point to the next. Useful for glissandi, parameter sweeps, or any continuous interpolation between points.
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/musa-dsl/datasets/p.rb', line 115 def to_ps_serie(base_duration: nil) base_duration ||= 1/4r # TODO review incoherence between neumalang 1/4r base duration for quarter notes and general 1r size of bar # TODO if instead of using clone (needed because of p.shift) we use index counter the P elements would be evaluated on the last moment Musa::Series::Constructors.E(clone, base_duration) do |p, base_duration| (p.size >= 3) ? { from: p.shift, duration: p.shift * base_duration, to: p.first, right_open: (p.length > 1) }.extend(PS).tap { |_| _.base_duration = base_duration } : nil end end |
#to_timed_serie(time_start: nil, time_start_component: nil, base_duration: nil) ⇒ PtoTimedSerie
Converts to series of timed events (AbsTimed).
Creates series yielding AbsTimed events with absolute time and value. Each value is emitted at its calculated time point based on cumulative durations.
156 157 158 159 160 161 162 163 |
# File 'lib/musa-dsl/datasets/p.rb', line 156 def to_timed_serie(time_start: nil, time_start_component: nil, base_duration: nil) time_start ||= 0r time_start += self.first[time_start_component] if time_start_component base_duration ||= 1/4r # TODO review incoherence between neumalang 1/4r base duration for quarter notes and general 1r size of bar PtoTimedSerie.new(self, base_duration, time_start) end |