Class: Musa::Series::Operations::Processor Private

Inherits:
Object
  • Object
show all
Includes:
Serie::Base, Serie::WithSmartBlock, Serie::WithSource
Defined in:
lib/musa-dsl/series/main-serie-operations.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Serie operation that processes/transforms values using a block.

Applies transformation function to each value from source serie. The block can return single values or arrays (which are flattened into the output stream).

Uses smart block binding for flexible parameter handling.

Examples:

Simple transformation

serie = FromArray.new([1, 2, 3])
processor = Processor.new(serie, {}) { |v| v * 2 }
processor.next_value  # => 2
processor.next_value  # => 4

Transformation with parameters

processor = Processor.new(serie, multiplier: 3) { |v, multiplier:| v * multiplier }

Returning arrays (flattened)

processor = Processor.new(serie, {}) { |v| [v, v + 1] }
processor.next_value  # => 1
processor.next_value  # => 2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(serie, parameters, &processor) ⇒ Processor

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Processor.



1194
1195
1196
1197
1198
1199
1200
1201
# File 'lib/musa-dsl/series/main-serie-operations.rb', line 1194

def initialize(serie, parameters, &processor)
  self.source = serie

  self.parameters = parameters
  self.proc = processor if processor

  init
end

Instance Attribute Details

#parametersObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



1203
1204
1205
# File 'lib/musa-dsl/series/main-serie-operations.rb', line 1203

def parameters
  @parameters
end

Instance Method Details

#+(other) ⇒ Sequence Originally defined in module Musa::Series::Operations

Appends another serie (operator alias for after).

Examples:

Concatenate

s = S(1, 2) + S(3, 4)
s.i.to_a  # => [1, 2, 3, 4]

Parameters:

  • other (Serie)

    serie to append

Returns:

  • (Sequence)

    sequential combination

#after(*series) ⇒ Sequence Originally defined in module Musa::Series::Operations

Appends series sequentially.

Alias for MERGE - plays this serie, then others in sequence.

Examples:

Append

s = S(1, 2).after(S(3, 4), S(5, 6))
s.i.to_a  # => [1, 2, 3, 4, 5, 6]

Parameters:

Returns:

  • (Sequence)

    sequential combination

#anticipate {|current, next_value| ... } ⇒ Anticipate Originally defined in module Musa::Series::Operations

Evaluates block one step ahead (anticipate).

Block receives current value and NEXT value (peeked). Enables look-ahead transformations and transitions.

Examples:

Smooth transitions

s = S(1, 5, 3, 8).anticipate { |current, next_val|
  next_val ? (current + next_val) / 2.0 : current
}

Add interval information

notes = S(60, 64, 67, 72).anticipate { |pitch, next_pitch|
  interval = next_pitch ? next_pitch - pitch : nil
  {pitch: pitch, interval: interval}
}

Yields:

  • anticipation block

Yield Parameters:

  • current (Object)

    current value

  • next_value (Object, nil)

    next value (nil if last)

Yield Returns:

  • (Object)

    transformed value

Returns:

  • (Anticipate)

    anticipating serie

#autorestartAutorestart Originally defined in module Musa::Series::Operations

Auto-restarts serie when exhausted.

Creates an infinite serie from an original serie that automatically restarts from beginning when it reaches the end.

Examples:

Infinite loop

pattern = S(1, 2, 3).autorestart
pattern.infinite?  # => true
inst = pattern.i
inst.max_size(7).to_a  # => [1, 2, 3, 1, 2, 3, 1]

Returns:

  • (Autorestart)

    auto-restarting serie

#buffered(sync: false) ⇒ BufferSerie, SyncBufferSerie Originally defined in module Musa::Series::Operations

Creates a buffered serie allowing multiple independent iterations over same source.

Provides buffering mechanism enabling multiple "readers" to independently iterate over the same serie source without interfering with each other.

Buffering Modes

  • Async (default): Buffers fill independently, each progresses at own pace
  • Sync: All buffers synchronized, restart affects all

Use Cases

  • Multiple voices reading same melodic sequence at different speeds
  • Polyphonic playback from single source
  • Canonic structures (rounds, fugues)
  • Independent transformations of same base material

Memory Management

History is automatically cleaned when all buffers have progressed past old values, preventing unbounded memory growth.

Examples:

Create buffered serie

buffered = S(1, 2, 3, 4).buffered
reader1 = buffered.buffer.i
reader2 = buffered.buffer.i

Multiple independent readers

source = S(1, 2, 3, 4).buffered
reader1 = source.buffer.i
reader2 = source.buffer.i

reader1.next_value  # => 1
reader2.next_value  # => 1 (independent)
reader1.next_value  # => 2
reader2.next_value  # => 2

Canon structure

melody = S(60, 64, 67, 72).buffered
voice1 = melody.buffer
voice2 = melody.buffer
# Play voice2 delayed by N beats

Parameters:

  • sync (Boolean) (defaults to: false)

    synchronized mode (default: false)

Returns:

  • (BufferSerie, SyncBufferSerie)

    buffered serie

#compact_timedTimedCompacter Originally defined in module Musa::Series::Operations

Removes timed events where all values are nil.

Filters out temporal "gaps" where no sources have active values. Useful after union operations that create nil placeholders, or for cleaning sparse sequences.

Removal logic:

  • Direct nil: { time: t, value: nil } → removed
  • All-nil Hash: { time: t, value: { a: nil, b: nil } } → removed
  • Partial Hash: { time: t, value: { a: 1, b: nil } } → kept (has non-nil)
  • All-nil Array: { time: t, value: [nil, nil] } → removed
  • Partial Array: { time: t, value: [1, nil] } → kept (has non-nil)

Examples:

Remove direct nil events

s = S({ time: 0r, value: 1 },
      { time: 1r, value: nil },
      { time: 2r, value: 3 })

s.compact_timed.i.to_a
# => [{ time: 0r, value: 1 },
#     { time: 2r, value: 3 }]

Remove all-nil hash events

s = S({ time: 0r, value: { a: 1, b: 2 } },
      { time: 1r, value: { a: nil, b: nil } },
      { time: 2r, value: { a: 3, b: nil } })

s.compact_timed.i.to_a
# => [{ time: 0r, value: { a: 1, b: 2 } },
#     { time: 2r, value: { a: 3, b: nil } }]  # Kept: has non-nil 'a'

Clean sparse union results

s1 = S({ time: 0r, value: 1 }, { time: 2r, value: 3 })
s2 = S({ time: 1r, value: 10 })

union = TIMED_UNION(melody: s1, bass: s2).i.to_a
# => [{ time: 0r, value: { melody: 1, bass: nil } },
#     { time: 1r, value: { melody: nil, bass: 10 } },
#     { time: 2r, value: { melody: 3, bass: nil } }]

# All events have at least one non-nil, so none removed

Returns:

  • (TimedCompacter)

    compacted serie

See Also:

#composer { ... } ⇒ ComposerAsOperationSerie Originally defined in module Musa::Series::Operations

Creates a composer transformation pipeline for complex multi-stage transformations.

Composer provides declarative DSL for building transformation pipelines with multiple inputs, outputs, and intermediate processing stages.

Composer Concepts

  • Pipelines: Named transformation chains
  • Inputs: Named input series (proxied and buffered)
  • Outputs: Named output series
  • Operations: Transformation steps in pipeline
  • Auto-commit: Automatic finalization of pipelines

DSL Structure

composer do
  input_name >> operation1 >> operation2 >> :output_name
  :other_input >> transform >> :other_output
end

Musical Applications

  • Complex multi-voice processing
  • Effect chains and routing
  • Algorithmic composition pipelines
  • Multi-stage transformations
  • Modular synthesis-style routing

Examples:

Basic composer

s = S(1, 2, 3).composer do
  input.map { |x| x * 2 } >> :output
end
s.i.to_a  # => [2, 4, 6]

Multi-pipeline

composer = Composer.new(input: S(1, 2, 3)) do
  input.map { |x| x * 2 } >> :doubled
  input.map { |x| x * 3 } >> :tripled
end
composer.output(:doubled).i.to_a  # => [2, 4, 6]
composer.output(:tripled).i.to_a  # => [3, 6, 9]

Simple transformation

s.composer do
  input.map { |x| x + 1 } >> :output
end

Yields:

  • composer DSL block

Returns:

#cut(length) ⇒ Cutter Originally defined in module Musa::Series::Operations

Cuts serie into chunks of specified length.

Returns serie of arrays, each containing length values.

Examples:

Cut into pairs

s = S(1, 2, 3, 4, 5, 6).cut(2)
s.i.to_a  # => [[1, 2], [3, 4], [5, 6]]

Parameters:

  • length (Integer)

    chunk size

Returns:

  • (Cutter)

    chunked serie

#defined?Boolean Originally defined in module Serie::Prototyping

Checks if serie state is defined (not undefined).

Returns:

  • (Boolean)

    true if prototype or instance, false if undefined

#flattenFlattener Originally defined in module Musa::Series::Operations

Flattens nested series into single level.

Recursively consumes series elements that are themselves series.

Examples:

Flatten nested

s = S(S(1, 2), S(3, 4), 5).flatten
s.i.to_a  # => [1, 2, 3, 4, 5]

Returns:

  • (Flattener)

    flattened serie

#flatten_timedTimedFlattener Originally defined in module Musa::Series::Operations

Splits compound timed values into individual timed events.

Converts events with Hash or Array values into separate timed events per element, preserving time and extra attributes. Direct values pass through unchanged.

Hash values → Hash of timed events (keyed by original keys):

{ time: 0, value: { a: 1, b: 2 }, velocity: { a: 80, b: 90 } }
# becomes:
{ a: { time: 0, value: 1, velocity: 80 },
  b: { time: 0, value: 2, velocity: 90 } }

Array values → Array of timed events (indexed):

{ time: 0, value: [1, 2], velocity: [80, 90] }
# becomes:
[{ time: 0, value: 1, velocity: 80 },
 { time: 0, value: 2, velocity: 90 }]

Direct values → Pass through unchanged (already flat)

Use Cases

  • Separate polyphonic events into individual voices
  • Split multi-track sequences for independent processing
  • Prepare for voice-specific routing via split
  • Enable per-voice filtering with compact_timed

Examples:

Hash values to individual voices

s = S({ time: 0r, value: { a: 60, b: 64 }, velocity: { a: 80, b: 90 } })

flat = s.flatten_timed.i
flat.next_value
# => { a: { time: 0r, value: 60, velocity: 80 },
#      b: { time: 0r, value: 64, velocity: 90 } }

Array values to indexed events

s = S({ time: 0r, value: [60, 64], velocity: [80, 90] })

flat = s.flatten_timed.i
flat.next_value
# => [{ time: 0r, value: 60, velocity: 80 },
#     { time: 0r, value: 64, velocity: 90 }]

Direct values pass through

s = S({ time: 0r, value: 60, velocity: 80 })

flat = s.flatten_timed.i
flat.next_value  # => { time: 0r, value: 60, velocity: 80 }

Returns:

  • (TimedFlattener)

    flattened timed serie

See Also:

#hashify(*keys) ⇒ HashFromSeriesArray Originally defined in module Musa::Series::Operations

Converts array values to hash with specified keys.

Takes array-valued serie and converts to hash using provided keys.

Examples:

Array to hash

s = S([60, 96], [64, 80]).hashify(:pitch, :velocity)
s.i.next_value  # => {pitch: 60, velocity: 96}

Parameters:

  • keys (Array)

    hash keys for array elements

Returns:

  • (HashFromSeriesArray)

    hashified serie

#infinite?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


1239
1240
1241
# File 'lib/musa-dsl/series/main-serie-operations.rb', line 1239

def infinite?
  @source.infinite?
end

#instanceSerie Also known as: i Originally defined in module Serie::Prototyping

Creates or returns instance of serie.

  • If already instance, returns self
  • If prototype, creates new instance by cloning
  • If undefined, raises PrototypingError

Cloning Process

  1. Clones serie structure
  2. Marks clone as :instance
  3. Propagates instance creation to sources
  4. Calls init if defined

Each call creates independent instance with separate state.

Examples:

Create instances

proto = S(1, 2, 3)
a = proto.instance
b = proto.instance  # Different instance

a.next_value  # => 1
b.next_value  # => 1 (independent)

Returns:

  • (Serie)

    instance serie

Raises:

#instance?Boolean Originally defined in module Serie::Prototyping

Checks if serie is in instance state.

Returns:

  • (Boolean)

    true if instance, false otherwise

#lazy {|previous| ... } ⇒ LazySerieEval Originally defined in module Musa::Series::Operations

Delays evaluation to next step (lazy evaluation).

Block receives previous value and evaluates for current step. Enables state-dependent transformations.

Examples:

Cumulative sum

s = S(1, 2, 3, 4).lazy { |prev| (prev || 0) + value }

Yields:

  • lazy evaluation block

Yield Parameters:

  • previous (Object, nil)

    previous value

Yield Returns:

Returns:

  • (LazySerieEval)

    lazy-evaluated serie

#lockLocker Originally defined in module Musa::Series::Operations

Locks serie preventing further modifications.

Returns locked copy that cannot be transformed further.

Returns:

  • (Locker)

    locked serie

#map(isolate_values: nil) {|value| ... } ⇒ ProcessWith Originally defined in module Musa::Series::Operations

Maps values via transformation block.

Simplest and most common transformation. Applies block to each value. Shorthand for with without additional series.

Examples:

Transpose notes

notes = S(60, 64, 67).map { |n| n + 12 }
notes.i.to_a  # => [72, 76, 79]

Transform to hash

s = S(1, 2, 3).map { |n| {value: n, squared: n**2} }

Parameters:

  • isolate_values (Boolean, nil) (defaults to: nil)

    clone values to prevent mutation (default: false)

Yields:

  • transformation block

Yield Parameters:

  • value (Object)

    current value

Yield Returns:

  • (Object)

    transformed value

Returns:

  • (ProcessWith)

    mapped serie

#max_size(length) ⇒ LengthLimiter Originally defined in module Musa::Series::Operations

Limits serie to maximum number of values.

Stops after N values regardless of source length.

Examples:

Limit to 5

s = FOR(from: 0, step: 1).max_size(5)
s.i.to_a  # => [0, 1, 2, 3, 4]

Parameters:

  • length (Integer)

    maximum number of values

Returns:

  • (LengthLimiter)

    length-limited serie

#mergeMergeSerieOfSeries Originally defined in module Musa::Series::Operations

Merges serie of series into single serie.

Flattens one level: consumes serie where each element is itself a serie, merging them sequentially.

Examples:

Merge phrases

phrases = S(S(1, 2, 3), S(4, 5, 6))
merged = phrases.merge
merged.i.to_a  # => [1, 2, 3, 4, 5, 6]

Returns:

  • (MergeSerieOfSeries)

    merged serie

#multiplex(*indexed_series, **hash_series) ⇒ MultiplexSelector Originally defined in module Musa::Series::Operations

Multiplexes values from multiple series based on selector.

Like switch but returns composite values instead of switching.

Parameters:

  • indexed_series (Array)

    series to multiplex

  • hash_series (Hash)

    series to multiplex by key

Returns:

  • (MultiplexSelector)

    multiplexed serie

#procProc? #proc(&block) ⇒ Extension::SmartProcBinder::SmartProcBinder Originally defined in module Serie::WithSmartBlock

Gets or sets the proc with SmartProcBinder wrapping.

Overloads:

#proc=(block) ⇒ Object Originally defined in module Serie::WithSmartBlock

Sets the proc with SmartProcBinder wrapping.

Parameters:

  • block (Proc)

    block to wrap and store

#process_with(**parameters) {|value, parameters| ... } ⇒ Processor Originally defined in module Musa::Series::Operations

Processes values with parameterized block.

Generic processor passing values and parameters to block.

Parameters:

  • parameters (Hash)

    parameters passed to processor block

Yields:

  • processor block

Yield Parameters:

  • value (Object)

    current value

  • parameters (Hash)

    processor parameters

Returns:

#prototypeSerie Also known as: p Originally defined in module Serie::Prototyping

Returns prototype of serie.

  • If already prototype, returns self
  • If instance, returns original prototype (if available)
  • If undefined, raises PrototypingError

Examples:

Get prototype

proto = S(1, 2, 3)
inst = proto.instance
inst.prototype  # => proto

Returns:

  • (Serie)

    prototype serie

Raises:

#prototype?Boolean Originally defined in module Serie::Prototyping

Checks if serie is in prototype state.

Returns:

  • (Boolean)

    true if prototype, false otherwise

#proxyObject Originally defined in module Musa::Series::Operations

TODO add test case

#quantize(reference: nil, step: nil, value_attribute: nil, stops: nil, predictive: nil, left_open: nil, right_open: nil) ⇒ RawQuantizer, PredictiveQuantizer Originally defined in module Musa::Series::Operations

Quantizes time-value serie to discrete steps.

Quantization Modes

  • Raw: Rounds values to nearest step, interpolates between points
  • Predictive: Predicts crossings of quantization boundaries

Applications

  • Quantize MIDI controller data to discrete values
  • Convert continuous pitch bends to semitones
  • Snap timing to grid
  • Generate stepped automation curves
  • Convert analog input to digital steps

Examples:

Basic quantization

# Quantize to semitones (12 steps per octave)
pitch_bend = S({time: 0r, value: 60.3}, {time: 1r, value: 61.8})
quantized = pitch_bend.quantize(step: 1)
quantized.i.to_a  # => [{time: 0, value: 60, duration: 1}, ...]

Predictive quantization

continuous = S({time: 0r, value: 0}, {time: 4r, value: 10})
pred = continuous.quantize(step: 2, predictive: true)
# Generates crossing points at values 0, 2, 4, 6, 8, 10

Parameters:

  • reference (Numeric, nil) (defaults to: nil)

    quantization reference (default: 0)

  • step (Numeric, nil) (defaults to: nil)

    step size (default: 1)

  • value_attribute (Symbol, nil) (defaults to: nil)

    attribute to quantize (default: :value)

  • stops (Boolean, nil) (defaults to: nil)

    include stop points (default: false)

  • predictive (Boolean, nil) (defaults to: nil)

    use predictive mode (default: false)

  • left_open (Boolean, nil) (defaults to: nil)

    left boundary open (raw mode)

  • right_open (Boolean, nil) (defaults to: nil)

    right boundary open (raw mode)

Returns:

  • (RawQuantizer, PredictiveQuantizer)

    quantized serie

#queuedQueueSerie Originally defined in module Musa::Series::Operations

Wraps this serie in a queue.

Returns:

#randomize(random: nil) ⇒ Randomizer Originally defined in module Musa::Series::Operations

Randomizes order of values.

Shuffles values randomly. Requires finite serie.

Examples:

Shuffle

s = S(1, 2, 3, 4, 5).randomize
s.i.to_a  # => random permutation

Parameters:

  • random (Random, nil) (defaults to: nil)

    Random instance (default: new Random)

Returns:

  • (Randomizer)

    randomized serie

#remove(block = nil) {|value| ... } ⇒ Remover Originally defined in module Musa::Series::Operations

Removes values matching condition.

Filters out values where block returns true.

Examples:

Remove odds

s = S(1, 2, 3, 4, 5).remove { |n| n.odd? }
s.i.to_a  # => [2, 4]

Parameters:

  • block (Proc, nil) (defaults to: nil)

    filter block

Yields:

  • filter condition

Yield Parameters:

  • value (Object)

    current value

Yield Returns:

  • (Boolean)

    true to remove value

Returns:

  • (Remover)

    filtered serie

#repeat(times = nil, condition: nil) { ... } ⇒ Repeater, InfiniteRepeater Originally defined in module Musa::Series::Operations

Repeats serie multiple times or conditionally.

Three modes:

  • times: Repeat exact number of times
  • condition: Repeat while condition true
  • neither: Infinite repetition

Examples:

Fixed repetitions

s = S(1, 2, 3).repeat(3)
s.i.to_a  # => [1, 2, 3, 1, 2, 3, 1, 2, 3]

Conditional repeat

count = 0
s = S(1, 2, 3).repeat { count += 1; count < 3 }

Infinite repeat

s = S(1, 2, 3).repeat
s.infinite?  # => true

Parameters:

  • times (Integer, nil) (defaults to: nil)

    number of repetitions

  • condition (Proc, nil) (defaults to: nil)

    condition block

Yields:

  • optional condition block

Returns:

  • (Repeater, InfiniteRepeater)

    repeating serie

#reverseReverser Originally defined in module Musa::Series::Operations

Reverses order of values.

Consumes entire serie and returns values in reverse order. Requires finite serie.

Examples:

Retrograde

s = S(1, 2, 3, 4).reverse
s.i.to_a  # => [4, 3, 2, 1]

Returns:

  • (Reverser)

    reversed serie

#select(block = nil) {|value| ... } ⇒ Selector Originally defined in module Musa::Series::Operations

Selects values matching condition.

Keeps only values where block returns true.

Examples:

Select evens

s = S(1, 2, 3, 4, 5).select { |n| n.even? }
s.i.to_a  # => [2, 4]

Parameters:

  • block (Proc, nil) (defaults to: nil)

    filter block

Yields:

  • filter condition

Yield Parameters:

  • value (Object)

    current value

Yield Returns:

  • (Boolean)

    true to keep value

Returns:

  • (Selector)

    filtered serie

#shift(shift) ⇒ Shifter Originally defined in module Musa::Series::Operations

Rotates serie elements circularly.

Performs circular rotation of elements:

  • Negative values rotate left (first elements move to end)
  • Positive values rotate right (last elements move to beginning)
  • Zero performs no rotation

Note: Right rotation (positive values) requires finite series as the entire serie must be loaded into memory for rotation.

Examples:

Rotate left (negative shift)

s = S(60, 64, 67).shift(-1)  # First element moves to end
s.i.to_a  # => [64, 67, 60]

Rotate right (positive shift)

s = S(1, 2, 3, 4, 5).shift(2)  # Last 2 elements move to beginning
s.i.to_a  # => [4, 5, 1, 2, 3]

No rotation

s = S(1, 2, 3).shift(0)
s.i.to_a  # => [1, 2, 3]

Parameters:

  • shift (Integer)

    rotation amount

    • Negative: rotate left by N positions
    • Positive: rotate right by N positions
    • Zero: no rotation

Returns:

  • (Shifter)

    rotated serie

#skip(length) ⇒ Skipper Originally defined in module Musa::Series::Operations

Skips first N values.

Discards first length values, returns rest.

Examples:

Skip first 2

s = S(1, 2, 3, 4, 5).skip(2)
s.i.to_a  # => [3, 4, 5]

Parameters:

  • length (Integer)

    number of values to skip

Returns:

  • (Skipper)

    serie with skipped values

#sourceSerie? Originally defined in module Serie::WithSource

Returns the upstream source serie.

Returns:

  • (Serie, nil)

    the upstream source serie

#source=(serie) ⇒ Object Originally defined in module Serie::WithSource

Sets the source serie.

Parameters:

  • serie (Serie)

    source serie (must match current state)

Raises:

  • (ArgumentError)

    if state mismatch between source and this serie

#splitSplitter Originally defined in module Musa::Series::Operations

Serie splitter for decomposing hash/array values into component series.

Splits series of hash or array values into individual component series, enabling independent access to each component.

Splitting Modes

  • Hash mode: Split {pitch: 60, velocity: 96} into separate series for :pitch and :velocity
  • Array mode: Split [60, 96] into separate series for indices 0, 1

Component Access

  • Hash: splitter[:pitch], splitter[:velocity]
  • Array: splitter[0], splitter[1]
  • Enumerable: splitter.each { |component| ... }

Use Cases

  • Separate polyphonic voices from single source
  • Independent processing of musical parameters
  • Extract specific components (pitch, duration, velocity, etc.)
  • Multi-track decomposition

Examples:

Split hash values

notes = S({pitch: 60, vel: 96}, {pitch: 64, vel: 80})
splitter = notes.split.i

pitches = splitter[:pitch]
velocities = splitter[:vel]

pitches.next_value  # => 60
velocities.next_value  # => 96

Split array values

pairs = S([1, 10], [2, 20], [3, 30]).split.i
first = pairs[0]
second = pairs[1]

Returns:

  • (Splitter)

    hash/array splitter

#stateSymbol Originally defined in module Serie::Prototyping

Returns current state of serie.

Attempts to resolve undefined state from sources before returning. State is one of: :prototype, :instance, or :undefined.

Returns:

  • (Symbol)

    current state (:prototype, :instance, :undefined)

#switch(*indexed_series, **hash_series) ⇒ Switcher Originally defined in module Musa::Series::Operations

Switches between multiple series based on selector values.

Uses selector serie to choose which source serie to read from. Selector values can be indices (Integer) or keys (Symbol).

Examples:

Index switching

s1 = S(1, 2, 3)
s2 = S(10, 20, 30)
selector = S(0, 1, 0, 1)
result = selector.switch(s1, s2)
result.i.to_a  # => [1, 10, 2, 20]

Parameters:

  • indexed_series (Array)

    series indexed by integer

  • hash_series (Hash)

    series indexed by symbol key

Returns:

  • (Switcher)

    switching serie

#switch_serie(*indexed_series, **hash_series) ⇒ SwitchFullSerie Originally defined in module Musa::Series::Operations

Switches to entirely different series based on selector.

Changes which serie is being consumed entirely.

Parameters:

  • indexed_series (Array)

    series to switch between

  • hash_series (Hash)

    series to switch between by key

Returns:

  • (SwitchFullSerie)

    serie switcher

#undefined?Boolean Originally defined in module Serie::Prototyping

Checks if serie is in undefined state.

Returns:

  • (Boolean)

    true if undefined, false otherwise

#union_timed(*other_timed_series, key: nil, **other_key_timed_series) ⇒ TimedUnionOfArrayOfTimedSeries, TimedUnionOfHashOfTimedSeries Originally defined in module Musa::Series::Operations

Combines this timed serie with others via TIMED_UNION.

Convenience method for unioning series, supporting both array and hash modes. Calls Constructors#TIMED_UNION constructor with appropriate parameters.

Array mode: s1.union_timed(s2, s3) Hash mode: s1.union_timed(key: :melody, bass: s2, drums: s3)

Examples:

Array mode

melody = S({ time: 0r, value: 60 })
bass = S({ time: 0r, value: 36 })

melody.union_timed(bass).i.next_value
# => { time: 0r, value: [60, 36] }

Hash mode

melody = S({ time: 0r, value: 60 })
bass = S({ time: 0r, value: 36 })
drums = S({ time: 0r, value: 38 })

melody.union_timed(key: :melody, bass: bass, drums: drums).i.next_value
# => { time: 0r, value: { melody: 60, bass: 36, drums: 38 } }

Parameters:

  • other_timed_series (Array<Serie>)

    additional series (array mode)

  • key (Symbol, nil) (defaults to: nil)

    key name for this serie (hash mode)

  • other_key_timed_series (Hash{Symbol => Serie})

    named series (hash mode)

Returns:

  • (TimedUnionOfArrayOfTimedSeries, TimedUnionOfHashOfTimedSeries)

    union

Raises:

  • (ArgumentError)

    if mixing array and hash modes

See Also:

#with(*with_series, on_restart: nil, isolate_values: nil, **with_key_series) {|main_value, with_values, with_key_values| ... } ⇒ With Also known as: eval Originally defined in module Musa::Series::Operations

Combines multiple series for mapping.

Synchronously iterates multiple series, passing all values to block. Enables multi-voice transformations and combinations.

Parameters

  • with_series: Positional series (passed as array to block)
  • with_key_series: Named series (passed as keywords to block)
  • on_restart: Block called on restart
  • isolate_values: Clone values to prevent mutation

Block Parameters

Block receives:

  • Main serie value (first argument)
  • Positional with_series values (array)
  • Keyword with_key_series values (keywords)

Examples:

Combine pitches and velocities

pitches = S(60, 64, 67)
velocities = S(96, 80, 64)
notes = pitches.with(velocities) { |p, v| {pitch: p, velocity: v} }
notes.i.to_a  # => [{pitch: 60, velocity: 96}, ...]

Named series

melody = S(60, 64, 67)
rhythm = S(1r, 0.5r, 0.5r)
combined = melody.with(duration: rhythm) { |pitch, duration:|
  {pitch: pitch, duration: duration}
}

Parameters:

  • with_series (Array<Serie>)

    positional series to combine

  • on_restart (Proc, nil) (defaults to: nil)

    restart callback

  • isolate_values (Boolean, nil) (defaults to: nil)

    clone values to prevent mutation

  • with_key_series (Hash)

    keyword series to combine

Yields:

  • combination block

Yield Parameters:

  • main_value (Object)

    value from main serie

  • with_values (Array)

    values from positional series

  • with_key_values (Hash)

    values from keyword series

Yield Returns:

Returns:

  • (With)

    combined serie