xi-lang 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/README.md +2 -2
- data/lib/xi/core_ext/numeric.rb +2 -2
- data/lib/xi/osc.rb +0 -1
- data/lib/xi/pattern/generators.rb +65 -12
- data/lib/xi/pattern/transforms.rb +10 -8
- data/lib/xi/scale.rb +21 -1
- data/lib/xi/stream.rb +14 -1
- data/lib/xi/supercollider/stream.rb +0 -4
- data/lib/xi/supercollider.rb +0 -1
- data/lib/xi/version.rb +1 -1
- data/xi.gemspec +1 -0
- metadata +16 -4
- data/lib/xi/osc/version.rb +0 -5
- data/lib/xi/supercollider/version.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da63fd14e08f6b37c4a915b77bc517b1e42d57979c336a09aebab8b2122ec798
|
4
|
+
data.tar.gz: 33873883823d14e5356ef6580b5dd8e34eb983f78d7c35e7634ce91a8daf4d65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 575c7d49a0b42294acc8c6d405354ca7060fae687375d00a0461f8b65d2d301a6515edb9cd022d86c8bc42003d6c64e677480ca4261229f96e56a1a485c092a1
|
7
|
+
data.tar.gz: '08d14d4326fd8b901eb3bc5012c2c12b2a4074ca357630ab5c8aaf4cc2a1f69b86f0287ed6b528915c4890210c38d2be201c115ba14ccaab27b9e0d8dae311f2'
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -14,7 +14,7 @@ multiple known bugs, missing features, documentation and tests.
|
|
14
14
|
## Example
|
15
15
|
|
16
16
|
```ruby
|
17
|
-
melody = [
|
17
|
+
melody = [0,3,6,7,8]
|
18
18
|
scale = [Scale.iwato, Scale.jiao]
|
19
19
|
|
20
20
|
fm.set degree: melody.p(1/2,1/8,1/8,1/8,1/16,1/8,1/8).seq(2),
|
@@ -28,7 +28,7 @@ fm.set degree: melody.p(1/2,1/8,1/8,1/8,1/16,1/8,1/8).seq(2),
|
|
28
28
|
|
29
29
|
kick.set freq: s("xi.x .ix. | xi.x xx.x", 70, 200), amp: 0.8, gate: :freq
|
30
30
|
|
31
|
-
clap.set n: s("..x. xyz. .x.. .xyx", 60, 61, 60).p.
|
31
|
+
clap.set n: s("..x. xyz. .x.. .xyx", 60, 61, 60).p.slow(2),
|
32
32
|
gate: :n,
|
33
33
|
amp: 0.35,
|
34
34
|
pan: P.sin(16, 2) * 0.6,
|
data/lib/xi/core_ext/numeric.rb
CHANGED
@@ -10,8 +10,8 @@ module Xi::CoreExt
|
|
10
10
|
|
11
11
|
def degree_to_key(scale, steps_per_octave)
|
12
12
|
accidental = (self - self.to_i) * 10.0
|
13
|
-
inner_key = scale[
|
14
|
-
base_key = (
|
13
|
+
inner_key = scale[self % scale.size]
|
14
|
+
base_key = (self / scale.size).to_i * steps_per_octave + inner_key
|
15
15
|
if accidental != 0
|
16
16
|
base_key + accidental * (steps_per_octave / 12.0)
|
17
17
|
else
|
data/lib/xi/osc.rb
CHANGED
@@ -124,13 +124,11 @@ module Xi
|
|
124
124
|
# Generates values from a sinewave discretized to +quant+ events
|
125
125
|
# for the duration of +delta+ cycles.
|
126
126
|
#
|
127
|
-
# Values range from
|
128
|
-
#
|
129
|
-
# @see #sin1 for the same function but constrained on 0 to 1 values
|
127
|
+
# Values range from 0 to 1
|
130
128
|
#
|
131
129
|
# @example
|
132
130
|
# peek P.sin(8).map { |i| i.round(2) }
|
133
|
-
# #=> [0.
|
131
|
+
# #=> [0.5, 0.85, 1.0, 0.85, 0.5, 0.15, 0.0, 0.15, 0.5, 0.85]
|
134
132
|
#
|
135
133
|
# @example +quant+ determines the size, +delta+ the total duration
|
136
134
|
# P.sin(8).size #=> 8
|
@@ -144,28 +142,83 @@ module Xi
|
|
144
142
|
def sin(quant, delta=1)
|
145
143
|
Pattern.new(size: quant, delta: delta / quant) do |y|
|
146
144
|
quant.times do |i|
|
147
|
-
y << Math.sin(i / quant * 2 * Math::PI)
|
145
|
+
y << (Math.sin(i / quant * 2 * Math::PI) + 1) / 2
|
148
146
|
end
|
149
147
|
end
|
150
148
|
end
|
151
149
|
|
152
|
-
# Generates values from a
|
153
|
-
# for the duration of +delta+ cycles
|
150
|
+
# Generates values from a sawtooth waveform, discretized to +quant+ events
|
151
|
+
# for the duration of +delta+ cycles
|
154
152
|
#
|
155
153
|
# Values range from 0 to 1
|
156
154
|
#
|
157
|
-
# @
|
155
|
+
# @example
|
156
|
+
# peek P.saw(8)
|
157
|
+
# #=> [(0/1), (1/8), (1/4), (3/8), (1/2), (5/8), (3/4), (7/8), (0/1), (1/8)]
|
158
|
+
#
|
159
|
+
# @example +quant+ determines the size, +delta+ the total duration
|
160
|
+
# P.saw(8).size #=> 8
|
161
|
+
# P.saw(22).duration #=> (1/1)
|
162
|
+
# P.saw(19, 2).duration #=> (2/1)
|
163
|
+
#
|
164
|
+
# @param quant [Integer]
|
165
|
+
# @param delta [Integer] (default: 1)
|
166
|
+
# @return [Pattern]
|
167
|
+
#
|
168
|
+
def saw(quant, delta=1)
|
169
|
+
Pattern.new(size: quant, delta: delta / quant) do |y|
|
170
|
+
quant.times do |i|
|
171
|
+
y << i / quant
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Generates an inverse sawtooth waveform, discretized to +quant+ events
|
177
|
+
# for the duration of +delta+ cycles
|
178
|
+
#
|
179
|
+
# Values range from 0 to 1
|
180
|
+
#
|
181
|
+
# @see P.saw
|
182
|
+
#
|
183
|
+
# @example
|
184
|
+
# peek P.isaw(8)
|
185
|
+
# #=> [(1/1), (7/8), (3/4), (5/8), (1/2), (3/8), (1/4), (1/8), (1/1), (7/8)]
|
186
|
+
#
|
187
|
+
# @param quant [Integer]
|
188
|
+
# @param delta [Integer] (default: 1)
|
189
|
+
# @return [Pattern]
|
190
|
+
#
|
191
|
+
def isaw(*args)
|
192
|
+
-P.saw(*args) + 1
|
193
|
+
end
|
194
|
+
|
195
|
+
# Generates a triangle waveform, discretized to +quant+ events for the
|
196
|
+
# duration of +delta+ cycles
|
197
|
+
#
|
198
|
+
# Values range from 0 to 1
|
158
199
|
#
|
159
200
|
# @example
|
160
|
-
# peek P.
|
161
|
-
# #=> [0
|
201
|
+
# peek P.tri(8)
|
202
|
+
# #=> [(0/1), (1/4), (1/2), (3/4), (1/1), (3/4), (1/2), (1/4), (0/1), (1/4)]
|
162
203
|
#
|
163
204
|
# @param quant [Integer]
|
164
205
|
# @param delta [Integer] (default: 1)
|
165
206
|
# @return [Pattern]
|
166
207
|
#
|
167
|
-
def
|
168
|
-
|
208
|
+
def tri(quant, delta=1)
|
209
|
+
Pattern.new(size: quant, delta: delta / quant) do |y|
|
210
|
+
half_quant = quant / 2
|
211
|
+
up_half = half_quant.to_f.ceil
|
212
|
+
down_half = quant - up_half
|
213
|
+
|
214
|
+
up_half.times do |i|
|
215
|
+
y << i / half_quant
|
216
|
+
end
|
217
|
+
down_half.times do |i|
|
218
|
+
j = down_half - i
|
219
|
+
y << j / half_quant
|
220
|
+
end
|
221
|
+
end
|
169
222
|
end
|
170
223
|
|
171
224
|
private
|
@@ -219,6 +219,7 @@ module Xi
|
|
219
219
|
def normalize(min, max)
|
220
220
|
map { |v| v.respond_to?(:-) ? (v - min) / (max - min) : v }
|
221
221
|
end
|
222
|
+
alias_method :norm, :normalize
|
222
223
|
|
223
224
|
# Scales a pattern of normalized values (0..1) to a custom range
|
224
225
|
# +min+..+max+
|
@@ -239,6 +240,7 @@ module Xi
|
|
239
240
|
def denormalize(min, max)
|
240
241
|
map { |v| v.respond_to?(:*) ? (max - min) * v + min : v }
|
241
242
|
end
|
243
|
+
alias_method :denorm, :denormalize
|
242
244
|
|
243
245
|
# Scale from one range of values to another range of values
|
244
246
|
#
|
@@ -259,36 +261,36 @@ module Xi
|
|
259
261
|
# Slows down a pattern by stretching start and duration of events
|
260
262
|
# +num+ times.
|
261
263
|
#
|
262
|
-
# It is the inverse operation of #
|
264
|
+
# It is the inverse operation of #fast
|
263
265
|
#
|
264
|
-
# @see #
|
266
|
+
# @see #fast
|
265
267
|
#
|
266
268
|
# @example
|
267
|
-
# peek_events %w(a b c d).p([1/4, 1/8, 1/6]).
|
269
|
+
# peek_events %w(a b c d).p([1/4, 1/8, 1/6]).slow(2)
|
268
270
|
# #=> [E["a",0,1/2], E["b",1/2,1/4], E["c",3/4,1/3], E["d",13/12,1/2]]
|
269
271
|
#
|
270
272
|
# @param num [Numeric]
|
271
273
|
# @return [Pattern]
|
272
274
|
#
|
273
|
-
def
|
275
|
+
def slow(num)
|
274
276
|
Pattern.new(self, delta: delta.p * num)
|
275
277
|
end
|
276
278
|
|
277
279
|
# Advance a pattern by shrinking start and duration of events
|
278
280
|
# +num+ times.
|
279
281
|
#
|
280
|
-
# It is the inverse operation of #
|
282
|
+
# It is the inverse operation of #slow
|
281
283
|
#
|
282
|
-
# @see #
|
284
|
+
# @see #slow
|
283
285
|
#
|
284
286
|
# @example
|
285
|
-
# peek_events %w(a b c d).p([1/2, 1/4]).
|
287
|
+
# peek_events %w(a b c d).p([1/2, 1/4]).fast(2)
|
286
288
|
# #=> [E["a",0,1/4], E["b",1/4,1/8], E["c",3/8,1/4], E["d",5/8,1/8]]
|
287
289
|
#
|
288
290
|
# @param num [Numeric]
|
289
291
|
# @return [Pattern]
|
290
292
|
#
|
291
|
-
def
|
293
|
+
def fast(num)
|
292
294
|
Pattern.new(self, delta: delta.p / num)
|
293
295
|
end
|
294
296
|
|
data/lib/xi/scale.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
class Xi::Scale
|
4
|
+
extend Forwardable
|
5
|
+
|
2
6
|
DEGREES = {
|
3
7
|
# TWELVE TONES PER OCTAVE
|
4
8
|
# 5 note scales
|
@@ -91,7 +95,23 @@ class Xi::Scale
|
|
91
95
|
|
92
96
|
class << self
|
93
97
|
DEGREES.each do |name, list|
|
94
|
-
define_method(name) { list }
|
98
|
+
define_method(name) { self.new(list) }
|
95
99
|
end
|
96
100
|
end
|
101
|
+
|
102
|
+
attr_reader :notes
|
103
|
+
|
104
|
+
def initialize(notes)
|
105
|
+
@notes = notes
|
106
|
+
end
|
107
|
+
|
108
|
+
def_delegators :@notes, :size, :[], :to_a, :first
|
109
|
+
|
110
|
+
def p(*delta, **metadata)
|
111
|
+
[@notes].p(*delta, **metadata)
|
112
|
+
end
|
113
|
+
|
114
|
+
#def size
|
115
|
+
#@notes.size
|
116
|
+
#end
|
97
117
|
end
|
data/lib/xi/stream.rb
CHANGED
@@ -33,8 +33,9 @@ module Xi
|
|
33
33
|
|
34
34
|
def set(delta: nil, gate: nil, **source)
|
35
35
|
@mutex.synchronize do
|
36
|
+
remove_parameters_from_prev_source(source)
|
36
37
|
@source = source
|
37
|
-
@gate = gate
|
38
|
+
@gate = gate || parameter_with_smallest_delta(source)
|
38
39
|
@delta = delta if delta
|
39
40
|
@reset = true unless @playing
|
40
41
|
update_internal_structures
|
@@ -279,9 +280,21 @@ module Xi
|
|
279
280
|
n_value, _ = enum.peek
|
280
281
|
update_state(p, n_value)
|
281
282
|
end
|
283
|
+
transform_state
|
282
284
|
@reset = false
|
283
285
|
end
|
284
286
|
|
287
|
+
def parameter_with_smallest_delta(source)
|
288
|
+
source.min_by { |param, enum|
|
289
|
+
delta = enum.p.delta
|
290
|
+
delta.is_a?(Array) ? delta.min : delta
|
291
|
+
}.first
|
292
|
+
end
|
293
|
+
|
294
|
+
def remove_parameters_from_prev_source(new_source)
|
295
|
+
(@source.keys - new_source.keys).each { |k| @state.delete(k) } unless @source.nil?
|
296
|
+
end
|
297
|
+
|
285
298
|
def latency_sec
|
286
299
|
0.05
|
287
300
|
end
|
data/lib/xi/supercollider.rb
CHANGED
data/lib/xi/version.rb
CHANGED
data/xi.gemspec
CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "pry-byebug"
|
29
29
|
spec.add_development_dependency "guard"
|
30
30
|
spec.add_development_dependency "guard-minitest"
|
31
|
+
spec.add_development_dependency "yard"
|
31
32
|
|
32
33
|
spec.add_dependency 'pry'
|
33
34
|
spec.add_dependency 'osc-ruby'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xi-lang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Damián Silvani
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: yard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: pry
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -156,7 +170,6 @@ files:
|
|
156
170
|
- lib/xi/error_log.rb
|
157
171
|
- lib/xi/logger.rb
|
158
172
|
- lib/xi/osc.rb
|
159
|
-
- lib/xi/osc/version.rb
|
160
173
|
- lib/xi/pattern.rb
|
161
174
|
- lib/xi/pattern/generators.rb
|
162
175
|
- lib/xi/pattern/transforms.rb
|
@@ -166,7 +179,6 @@ files:
|
|
166
179
|
- lib/xi/stream.rb
|
167
180
|
- lib/xi/supercollider.rb
|
168
181
|
- lib/xi/supercollider/stream.rb
|
169
|
-
- lib/xi/supercollider/version.rb
|
170
182
|
- lib/xi/tidal_clock.rb
|
171
183
|
- lib/xi/version.rb
|
172
184
|
- synthdefs/other.scd
|
data/lib/xi/osc/version.rb
DELETED