Class: Deftones::Event::Pattern

Inherits:
Object
  • Object
show all
Includes:
CallbackBehavior
Defined in:
lib/deftones/event/pattern.rb

Constant Summary collapse

PATTERNS =
%i[up down up_down down_up alternate_up alternate_down random random_walk].freeze
PATTERN_ALIASES =
{
  upDown: :up_down,
  downUp: :down_up,
  alternateUp: :alternate_up,
  alternateDown: :alternate_down,
  randomWalk: :random_walk
}.freeze

Instance Attribute Summary

Attributes included from CallbackBehavior

#humanize, #mute, #playback_rate, #probability, #state

Instance Method Summary collapse

Methods included from CallbackBehavior

#callback_interval, #callback_permitted?, #callback_time, #humanized_time, #initialize_callback_behavior, #mark_started, #mark_stopped, #mute?, #playbackRate=

Constructor Details

#initialize(values:, pattern: :up, interval: "4n", transport: Deftones.transport, probability: 1.0, humanize: false, mute: false, playback_rate: 1.0, seed: nil, rng: nil, &callback) ⇒ Pattern

Returns a new instance of Pattern.

Raises:

  • (ArgumentError)


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/deftones/event/pattern.rb', line 17

def initialize(values:, pattern: :up, interval: "4n", transport: Deftones.transport,
               probability: 1.0, humanize: false, mute: false, playback_rate: 1.0,
               seed: nil, rng: nil, &callback)
  raise ArgumentError, "callback is required" unless callback

  @values = Array(values)
  raise ArgumentError, "Pattern values must not be empty" if @values.empty?

  @pattern = normalize_pattern(pattern)
  @interval = interval
  @transport = transport
  @callback = callback
  @event_id = nil
  @index = 0
  @direction = 1
  initialize_callback_behavior(
    probability: probability,
    humanize: humanize,
    mute: mute,
    playback_rate: playback_rate,
    seed: seed,
    rng: rng
  )
end

Instance Method Details

#alternate_value(start_direction) ⇒ Object (private)



116
117
118
119
120
121
122
# File 'lib/deftones/event/pattern.rb', line 116

def alternate_value(start_direction)
  cycle = @index / @values.length
  offset = @index % @values.length
  @index += 1
  descending = start_direction == :down ? cycle.even? : cycle.odd?
  descending ? @values.reverse[offset] : @values[offset]
end

#bounce_valueObject (private)



100
101
102
103
104
105
106
# File 'lib/deftones/event/pattern.rb', line 100

def bounce_value
  value = @values[@index]
  @direction = -1 if @index >= @values.length - 1
  @direction = 1 if @index <= 0
  @index += @direction
  value
end

#cancelObject



54
55
56
57
58
59
# File 'lib/deftones/event/pattern.rb', line 54

def cancel
  @transport.cancel(event_id: @event_id) if @event_id
  @event_id = nil
  mark_stopped
  self
end

#descending_bounce_valueObject (private)



108
109
110
111
112
113
114
# File 'lib/deftones/event/pattern.rb', line 108

def descending_bounce_value
  value = @values.reverse[@index]
  @direction = -1 if @index >= @values.length - 1
  @direction = 1 if @index <= 0
  @index += @direction
  value
end

#descending_valueObject (private)



94
95
96
97
98
# File 'lib/deftones/event/pattern.rb', line 94

def descending_value
  value = @values.reverse[@index % @values.length]
  @index += 1
  value
end

#disposeObject



61
62
63
# File 'lib/deftones/event/pattern.rb', line 61

def dispose
  cancel
end

#next_valueObject (private)



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/deftones/event/pattern.rb', line 67

def next_value
  case @pattern
  when :up
    ordered_value
  when :down
    descending_value
  when :up_down
    bounce_value
  when :down_up
    descending_bounce_value
  when :alternate_up
    alternate_value(:up)
  when :alternate_down
    alternate_value(:down)
  when :random
    @values[@rng.rand(@values.length)]
  when :random_walk
    random_walk_value
  end
end

#normalize_pattern(pattern) ⇒ Object (private)

Raises:

  • (ArgumentError)


131
132
133
134
135
136
# File 'lib/deftones/event/pattern.rb', line 131

def normalize_pattern(pattern)
  normalized = PATTERN_ALIASES.fetch(pattern.to_sym, pattern.to_sym)
  return normalized if PATTERNS.include?(normalized)

  raise ArgumentError, "Unsupported pattern: #{pattern}"
end

#ordered_valueObject (private)



88
89
90
91
92
# File 'lib/deftones/event/pattern.rb', line 88

def ordered_value
  value = @values[@index % @values.length]
  @index += 1
  value
end

#random_walk_valueObject (private)



124
125
126
127
128
129
# File 'lib/deftones/event/pattern.rb', line 124

def random_walk_value
  value = @values[@index]
  @direction = [-1, 1][@rng.rand(2)]
  @index = (@index + @direction).clamp(0, @values.length - 1)
  value
end

#start(time = 0) ⇒ Object



42
43
44
45
46
47
48
# File 'lib/deftones/event/pattern.rb', line 42

def start(time = 0)
  @event_id = @transport.schedule_repeat(callback_interval(@interval), start_time: time) do |scheduled_time|
    @callback.call(humanized_time(scheduled_time), next_value) if callback_permitted?
  end
  mark_started
  self
end

#stop(_time = nil) ⇒ Object



50
51
52
# File 'lib/deftones/event/pattern.rb', line 50

def stop(_time = nil)
  cancel
end