module Xi::Pattern::Generators

Public Instance Methods

geom(start=0, grow=1, length=inf) click to toggle source

Create a geometric series pattern of length values, being start the starting value and step the multiplication factor.

@example

peek P.geom                 #=> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
peek P.geom(3)              #=> [3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
peek P.geom(1, 2)           #=> [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
peek P.geom(1, 1/2, 6)      #=> [1, (1/2), (1/4), (1/8), (1/16), (1/32)]
peek P.geom(1, -1, 8)       #=> [1, -1, 1, -1, 1, -1, 1, -1]

@param start [Numeric] (default: 0) @param grow [Numeric] (default: 1) @param length [Numeric, Symbol] number or inf (default: inf) @return [Pattern]

# File lib/xi/pattern/generators.rb, line 43
def geom(start=0, grow=1, length=inf)
  Pattern.new(size: length) do |y|
    i = start
    loop_n(length) do
      y << i
      i *= grow
    end
  end
end
isaw(*args) click to toggle source

Generates an inverse sawtooth waveform, discretized to quant events for the duration of delta cycles

Values range from 0 to 1

@see P.saw

@example

peek P.isaw(8)
  #=> [(1/1), (7/8), (3/4), (5/8), (1/2), (3/8), (1/4), (1/8), (1/1), (7/8)]

@param quant [Integer] @param delta [Integer] (default: 1) @return [Pattern]

# File lib/xi/pattern/generators.rb, line 191
def isaw(*args)
  -P.saw(*args) + 1
end
rand(list, repeats=1) click to toggle source

Choose items from the list randomly, repeats number of times

list can be a finite enumerable or Pattern.

@see Pattern::Transforms#rand

@example

peek P.rand([1, 2, 3])          #=> [2]
peek P.rand([1, 2, 3, 4], 6)    #=> [1, 3, 2, 2, 4, 3]

@param list [#each] list of values @param repeats [Integer, Symbol] number or inf (default: 1) @return [Pattern]

# File lib/xi/pattern/generators.rb, line 67
def rand(list, repeats=1)
  Pattern.new(list, size: repeats) do |y|
    ls = list.to_a
    loop_n(repeats) { y << ls.sample }
  end
end
saw(quant, delta=1) click to toggle source

Generates values from a sawtooth waveform, discretized to quant events for the duration of delta cycles

Values range from 0 to 1

@example

peek P.saw(8)
  #=> [(0/1), (1/8), (1/4), (3/8), (1/2), (5/8), (3/4), (7/8), (0/1), (1/8)]

@example quant determines the size, delta the total duration

P.saw(8).size           #=> 8
P.saw(22).duration      #=> (1/1)
P.saw(19, 2).duration   #=> (2/1)

@param quant [Integer] @param delta [Integer] (default: 1) @return [Pattern]

# File lib/xi/pattern/generators.rb, line 168
def saw(quant, delta=1)
  Pattern.new(size: quant, delta: delta / quant) do |y|
    quant.times do |i|
      y << i / quant
    end
  end
end
series(start=0, step=1, length=inf) click to toggle source

Create an arithmetic series pattern of length values, being start the starting value and step the addition factor.

@example

peek P.series                 #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
peek P.series(3)              #=> [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
peek P.series(0, 2)           #=> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
peek P.series(0, 0.25, 8)     #=> [0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75]

@param start [Numeric] (default: 0) @param step [Numeric] (default: 1) @param length [Numeric, Symbol] number or inf (default: inf) @return [Pattern]

# File lib/xi/pattern/generators.rb, line 18
def series(start=0, step=1, length=inf)
  Pattern.new(size: length) do |y|
    i = start
    loop_n(length) do
      y << i
      i += step
    end
  end
end
shuf(list, repeats=1) click to toggle source

Shuffle the list in random order, and use the same random order repeats times

list can be a finite enumerable or Pattern.

@see Pattern::Transforms#shuf

@example

peek P.shuf([1, 2, 3, 4, 5])    #=> [5, 3, 4, 1, 2]
peek P.shuf([1, 2, 3], 3)       #=> [2, 3, 1, 2, 3, 1, 2, 3, 1]

@param list [#each] list of values @param repeats [Integer, Symbol] number or inf (default: 1) @return [Pattern]

# File lib/xi/pattern/generators.rb, line 115
def shuf(list, repeats=1)
  Pattern.new(list, size: list.size * repeats) do |y|
    xs = list.to_a.shuffle
    loop_n(repeats) do |i|
      xs.each { |x| y << x }
    end
  end
end
sin(quant, delta=1) click to toggle source

Generates values from a sinewave discretized to quant events for the duration of delta cycles.

Values range from 0 to 1

@example

peek P.sin(8).map { |i| i.round(2) }
  #=> [0.5, 0.85, 1.0, 0.85, 0.5, 0.15, 0.0, 0.15, 0.5, 0.85]

@example quant determines the size, delta the total duration

P.sin(8).size           #=> 8
P.sin(22).duration      #=> (1/1)
P.sin(19, 2).duration   #=> (2/1)

@param quant [Integer] @param delta [Integer] (default: 1) @return [Pattern]

# File lib/xi/pattern/generators.rb, line 142
def sin(quant, delta=1)
  Pattern.new(size: quant, delta: delta / quant) do |y|
    quant.times do |i|
      y << (Math.sin(i / quant * 2 * Math::PI) + 1) / 2
    end
  end
end
tri(quant, delta=1) click to toggle source

Generates a triangle waveform, discretized to quant events for the duration of delta cycles

Values range from 0 to 1

@example

peek P.tri(8)
  #=> [(0/1), (1/4), (1/2), (3/4), (1/1), (3/4), (1/2), (1/4), (0/1), (1/4)]

@param quant [Integer] @param delta [Integer] (default: 1) @return [Pattern]

# File lib/xi/pattern/generators.rb, line 208
def tri(quant, delta=1)
  Pattern.new(size: quant, delta: delta / quant) do |y|
    half_quant = quant / 2
    up_half = half_quant.to_f.ceil
    down_half = quant - up_half

    up_half.times do |i|
      y << i / half_quant
    end
    down_half.times do |i|
      j = down_half - i
      y << j / half_quant
    end
  end
end
xrand(list, repeats=1) click to toggle source

Choose randomly, but only allow repeating the same item after yielding all items from the list.

list can be a finite enumerable or Pattern.

@see Pattern::Transforms#xrand

@example

peek P.xrand([1, 2, 3, 4, 5])    #=> [4]
peek P.xrand([1, 2, 3], 8)       #=> [1, 3, 2, 3, 1, 2, 3, 2]

@param list [#each] list of values @param repeats [Integer, Symbol] number or inf (default: 1) @return [Pattern]

# File lib/xi/pattern/generators.rb, line 89
def xrand(list, repeats=1)
  Pattern.new(list, size: repeats) do |y|
    ls = list.to_a
    xs = nil
    loop_n(repeats) do |i|
      xs = ls.shuffle if i % ls.size == 0
      y << xs[i % ls.size]
    end
  end
end

Private Instance Methods

loop_n(length) { |i| ... } click to toggle source

@private

# File lib/xi/pattern/generators.rb, line 227
def loop_n(length)
  i = 0
  loop do
    break if length != inf && i == length
    yield i
    i += 1
  end
end