Module: Cyclotone::Transforms::Alteration
- Included in:
- Pattern
- Defined in:
- lib/cyclotone/transforms/alteration.rb
Constant Summary collapse
- MAX_SEGMENTS =
4096
Instance Method Summary collapse
- #almost_always(&block) ⇒ Object
- #almost_never(&block) ⇒ Object
- #chunk(count, &block) ⇒ Object
- #degrade ⇒ Object
- #degrade_by(probability) ⇒ Object
- #every(period, &block) ⇒ Object
- #every_with_offset(period, offset, &block) ⇒ Object
- #fastspread(function, values) ⇒ Object
- #fold_every(periods, &block) ⇒ Object
- #iter(count) ⇒ Object
- #iter_back(count) ⇒ Object
- #linger(amount) ⇒ Object
- #rarely(&block) ⇒ Object
- #scramble(count) ⇒ Object
- #shuffle(count) ⇒ Object
- #slowstripe(count) ⇒ Object
- #sometimes(&block) ⇒ Object
- #sometimes_by(probability, namespace: :sometimes, &block) ⇒ Object
- #spread(function, values) ⇒ Object
- #stripe(count) ⇒ Object
- #trunc(amount) ⇒ Object
- #zoom(start_point, end_point) ⇒ Object
Instance Method Details
#almost_always(&block) ⇒ Object
53 54 55 |
# File 'lib/cyclotone/transforms/alteration.rb', line 53 def almost_always(&block) sometimes_by(0.9, &block) end |
#almost_never(&block) ⇒ Object
57 58 59 |
# File 'lib/cyclotone/transforms/alteration.rb', line 57 def almost_never(&block) sometimes_by(0.1, &block) end |
#chunk(count, &block) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/cyclotone/transforms/alteration.rb', line 61 def chunk(count, &block) normalized_count = validate_segment_count(count, "chunk count") raise ArgumentError, "chunk requires a block" unless block Pattern.new do |span| selected = span.cycle_number % normalized_count pieces = Array.new(normalized_count) do |index| segment = zoom(Rational(index, normalized_count), Rational(index + 1, normalized_count)) index == selected ? block.call(segment) : segment end Pattern.fastcat(pieces).query_span(span) end end |
#degrade ⇒ Object
114 115 116 |
# File 'lib/cyclotone/transforms/alteration.rb', line 114 def degrade degrade_by(0.5) end |
#degrade_by(probability) ⇒ Object
104 105 106 107 108 109 110 111 112 |
# File 'lib/cyclotone/transforms/alteration.rb', line 104 def degrade_by(probability) normalized_probability = validate_probability(probability, "degrade probability") select_events do |event| cycle = (event.onset || event.part.start).floor seed = [:degrade, normalized_probability, cycle, event.value, event.part.start] Support::Deterministic.float(seed) >= normalized_probability end end |
#every(period, &block) ⇒ Object
8 9 10 |
# File 'lib/cyclotone/transforms/alteration.rb', line 8 def every(period, &block) every_with_offset(period, 0, &block) end |
#every_with_offset(period, offset, &block) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/cyclotone/transforms/alteration.rb', line 12 def every_with_offset(period, offset, &block) normalized_period = validate_positive_rational(period, "every period") normalized_offset = Pattern.to_rational(offset) raise ArgumentError, "every requires a block" unless block Pattern.new do |span| if ((span.cycle_number - normalized_offset) % normalized_period).zero? block.call(self).query_span(span) else query_span(span) end end end |
#fastspread(function, values) ⇒ Object
180 181 182 183 184 185 |
# File 'lib/cyclotone/transforms/alteration.rb', line 180 def fastspread(function, values) normalized_values = validate_values(values, "fastspread values") raise ArgumentError, "fastspread requires a callable function" unless function.respond_to?(:call) Pattern.fastcat(normalized_values.map { |value| function.call(self, value) }) end |
#fold_every(periods, &block) ⇒ Object
26 27 28 29 30 |
# File 'lib/cyclotone/transforms/alteration.rb', line 26 def fold_every(periods, &block) Array(periods).reduce(self) do |pattern, period| pattern.every(period, &block) end end |
#iter(count) ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/cyclotone/transforms/alteration.rb', line 88 def iter(count) normalized_count = validate_segment_count(count, "iter count") reorder_segments(normalized_count) do |cycle| Array.new(normalized_count) { |index| (index + cycle) % normalized_count } end end |
#iter_back(count) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/cyclotone/transforms/alteration.rb', line 96 def iter_back(count) normalized_count = validate_segment_count(count, "iter_back count") reorder_segments(normalized_count) do |cycle| Array.new(normalized_count) { |index| (index - cycle) % normalized_count } end end |
#linger(amount) ⇒ Object
139 140 141 |
# File 'lib/cyclotone/transforms/alteration.rb', line 139 def linger(amount) zoom(0, amount) end |
#rarely(&block) ⇒ Object
49 50 51 |
# File 'lib/cyclotone/transforms/alteration.rb', line 49 def rarely(&block) sometimes_by(0.25, &block) end |
#scramble(count) ⇒ Object
76 77 78 79 80 81 82 |
# File 'lib/cyclotone/transforms/alteration.rb', line 76 def scramble(count) normalized_count = validate_segment_count(count, "scramble count") reorder_segments(normalized_count) do |cycle| Array.new(normalized_count) { |index| index }.shuffle(random: Support::Deterministic.random(:scramble, cycle)) end end |
#shuffle(count) ⇒ Object
84 85 86 |
# File 'lib/cyclotone/transforms/alteration.rb', line 84 def shuffle(count) scramble(count) end |
#slowstripe(count) ⇒ Object
168 169 170 |
# File 'lib/cyclotone/transforms/alteration.rb', line 168 def slowstripe(count) slow(count) end |
#sometimes(&block) ⇒ Object
32 33 34 |
# File 'lib/cyclotone/transforms/alteration.rb', line 32 def sometimes(&block) sometimes_by(0.5, &block) end |
#sometimes_by(probability, namespace: :sometimes, &block) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/cyclotone/transforms/alteration.rb', line 36 def sometimes_by(probability, namespace: :sometimes, &block) normalized_probability = validate_probability(probability, "sometimes probability") raise ArgumentError, "sometimes_by requires a block" unless block Pattern.new do |span| if Support::Deterministic.float(namespace, normalized_probability, span.cycle_number) < normalized_probability block.call(self).query_span(span) else query_span(span) end end end |
#spread(function, values) ⇒ Object
172 173 174 175 176 177 178 |
# File 'lib/cyclotone/transforms/alteration.rb', line 172 def spread(function, values) normalized_values = validate_values(values, "spread values") raise ArgumentError, "spread requires a callable function" unless function.respond_to?(:call) sequence = Pattern.cat(normalized_values.map { |value| function.call(self, value) }) Pattern.new { |span| sequence.query_span(span) } end |
#stripe(count) ⇒ Object
164 165 166 |
# File 'lib/cyclotone/transforms/alteration.rb', line 164 def stripe(count) fast(count) end |
#trunc(amount) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/cyclotone/transforms/alteration.rb', line 118 def trunc(amount) limit = Pattern.to_rational(amount) raise ArgumentError, "trunc amount must be between 0 and 1" if limit.negative? || limit > 1 Pattern.new do |span| cycle_start = Rational(span.cycle_number) allowed = TimeSpan.new(cycle_start, cycle_start + limit) overlap = span.intersection(allowed) next [] unless overlap query_span(overlap).map do |event| clipped_part = event.part.intersection(allowed) next unless clipped_part clipped_whole = event.whole&.intersection(allowed) || event.whole event.with_span(new_whole: clipped_whole, new_part: clipped_part) end.compact end end |
#zoom(start_point, end_point) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/cyclotone/transforms/alteration.rb', line 143 def zoom(start_point, end_point) window_start = Pattern.to_rational(start_point) window_end = Pattern.to_rational(end_point) window_length = window_end - window_start raise ArgumentError, "zoom end must be greater than start" unless window_length.positive? Pattern.new do |span| cycle_start = Rational(span.cycle_number) source_span = TimeSpan.new( cycle_start + window_start + ((span.start - cycle_start) * window_length), cycle_start + window_start + ((span.stop - cycle_start) * window_length) ) query_span(source_span).map do |event| Pattern.map_event(event) do |time| cycle_start + ((time - cycle_start - window_start) / window_length) end end end end |