Skip to content

Commit 5c6b80e

Browse files
committed
v1.4.2 refactor applyNextPatterns to be able to efficiently handle chord logic in real-time in transport
1 parent 9d7d9dd commit 5c6b80e

File tree

6 files changed

+172
-117
lines changed

6 files changed

+172
-117
lines changed

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,20 +342,38 @@ You need to connect the MIDI device you want to use before starting Facet.
342342
- only play the generated FacetPattern a single time. Without including `once()`, the FacetPattern will regenerate and play back each loop by default.
343343
- example:
344344
- `$('example').noise(4096).play().once();`
345+
---
346+
- **over** ( _n_loops_ = 1 )
347+
- distributes all the events that a FacetPattern would fire over `n_loops` so the pattern can last any number of loops before regenerating.
348+
- works with audio playback, MIDI note/cc/pitchbend, and OSC.
349+
- example:
350+
- `$('example').randsamp('808').play(_.ramp(0,1,16)).over(ri(1,4)); // random sample played 16 times over 1,2,3 or 4 bars`
351+
- `$('example').drunk(2048,0.01).cc().over(128); // drunk walk over 128 bars, creates a drifty process that you can map onto device paramters to slowly randomize something`
345352

346353
### Methods for setting variables
347354
This can be useful when you want to access the same pattern across multiple commands.
348355

349356
- **set** ( _name_ )
350357
- saves a FacetPattern's data in memory, for reference as a variable in operations. Any FacetPatterns stored via `.set()` will only be stored until the server is closed.
351-
- if a pattern stored with `set()` has more than one piece of data in it, the corresponding variable will be an array. If the pattern has one piece of data in it, the corresponding variable will be a float.
358+
- if a pattern stored with `set()` has more than one piece of data in it, the corresponding variable will be an array. If the pattern has one piece of data in it, the corresponding variable will be a float.
352359
- **NOTE**: when you run the `.set()` command for the first time after starting the system, if you're also running commands that reference that variable in the same block, for the first evaluation, the variable will have a value of 0 as it has not fully propagated into the variable storage system.
360+
- **NOTE**: if you want to set more than one variable, you should run all the `.set()` methods in a single command, so they do not create a race condition for when they are evaluated.
353361
- example:
354362
- ```
355363
$('example').tri(100).set('abc').sine(abc).play(); // run it all in one command - just remember the first evaluated sine will have a frequency of 0
356364

357365
$('set_example').noise(32).curve().set('my_var').once(); // first, set the variable here
358366
$('example').noise(100).times(my_var).play(); // now, you can use my_var in commands
367+
368+
// multi-variable example
369+
// step 1: initialize the patterns by running this with .once()
370+
$('p1').noise(64).scale(ri(0,63),ri(64,127)).prob(rf()).sticky(rf(0.9,1)).round().set('p1').once();
371+
$('p2').noise(64).scale(ri(0,63),ri(64,127)).prob(rf()).sticky(rf(0.9,1)).round().set('p2').once();
372+
$('p3').noise(64).scale(ri(0,63),ri(64,127)).prob(rf()).sticky(rf(0.9,1)).round().set('p3').once();
373+
$('p4').noise(64).scale(ri(0,63),ri(64,127)).prob(rf()).sticky(rf(0.9,1)).round().set('p4').once();
374+
375+
// step 2: start the process to continually modify some of the values in the d1-d4 patterns, in one command
376+
$('example').from(p1).jam(0.1, 10).wrap(0,127).round().set('p1').from(p2).jam(0.1, 10).wrap(0,127).round().set('p2').from(p3).jam(0.1, 10).wrap(0,127).round().set('p3').from(p4).jam(0.1, 10).wrap(0,127).round().set('p4');
359377
```
360378
- **inc** ( _name_, _amount_to_add_ = 1 )
361379
- increments a variable called `name` by `amount_to_add`. This variable can be used in operations.

js/FacetPattern.js

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class FacetPattern {
4646
this.pan_mode = 0;
4747
this.play_once = false;
4848
this.original_command = '';
49+
this.over_n = 1;
4950
this.osc_data = [];
5051
this.pitchbend_data = [];
5152
this.saveas_filename = false;
@@ -1489,20 +1490,14 @@ waveformSample(waveform, phase) {
14891490
prob = Number(prob);
14901491
let jammed_sequence = [];
14911492
for (const [key, step] of Object.entries(this.data)) {
1492-
if ( step != 0 ) {
1493-
if ( Math.random() < prob) {
1494-
// changed
1495-
let step_distance = Math.random() * amt;
1496-
// half the time make it smaller
1497-
if ( Math.random() < 0.5 ) {
1498-
step_distance *= -1;
1499-
}
1500-
jammed_sequence[key] = Number((Number(step) + Number(step_distance)));
1501-
}
1502-
else {
1503-
// unchanged
1504-
jammed_sequence[key] = step;
1493+
if ( Math.random() < prob) {
1494+
// changed
1495+
let step_distance = Math.random() * amt;
1496+
// half the time make it smaller
1497+
if ( Math.random() < 0.5 ) {
1498+
step_distance *= -1;
15051499
}
1500+
jammed_sequence[key] = Number((Number(step) + Number(step_distance)));
15061501
}
15071502
else {
15081503
// unchanged
@@ -2257,11 +2252,13 @@ scaleLT1 (outMin, outMax, exponent = 1) {
22572252
return this;
22582253
}
22592254

2255+
over (n = 1) {
2256+
this.over_n = n;
2257+
this.whenmod(n);
2258+
return this;
2259+
}
2260+
22602261
whenmod (modulo, equals_value = 0) {
2261-
let current_bar_number = this.getBars();
2262-
if ((current_bar_number-1) % modulo !== equals_value) {
2263-
this.skipped = true;
2264-
}
22652262
this.whenmod_modulo_operand = modulo;
22662263
this.whenmod_equals = equals_value;
22672264
return this;

js/pattern_generator.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -367,19 +367,6 @@ function postMetaDataToTransport (fp,data_type) {
367367
});
368368
}
369369

370-
function sliceEndFade(array) {
371-
if ( array.length < 1024 ) {
372-
return array;
373-
}
374-
let result = [...array];
375-
let fadeLength = 128;
376-
for (let i = array.length - fadeLength; i < array.length; i++) {
377-
let t = (i - (array.length - fadeLength)) / fadeLength;
378-
result[i] = array[i] * (1 - t);
379-
}
380-
return result;
381-
}
382-
383370
function panning(input_value, input_channel, total_channels, pan_mode) {
384371
let fade_range = 2 / total_channels;
385372
let channel_start = (input_channel * fade_range) - 1;

0 commit comments

Comments
 (0)