@@ -8,22 +8,22 @@ The CV is split into 120 intervals, each corresponding to a permutation of the i | |||
*/ | |||
function permutation(arr, k) { | |||
var n = arr.length | |||
let n = arr.length | |||
// Clone array | |||
arr = arr.slice(0) | |||
// Compute n! | |||
var factorial = 1 | |||
for (var i = 2; i <= n; i++) { | |||
let factorial = 1 | |||
for (let i = 2; i <= n; i++) { | |||
factorial *= i | |||
} | |||
// Build permutation array by selecting the j'th element from the remaining elements until all are chosen. | |||
var perm = [] | |||
for (var i = n; i >= 1; i--) { | |||
let perm = [] | |||
for (let i = n; i >= 1; i--) { | |||
factorial /= i | |||
var j = Math.floor(k / factorial) | |||
let j = Math.floor(k / factorial) | |||
k %= factorial | |||
var el = arr[j] | |||
let el = arr[j] | |||
arr.splice(j, 1) | |||
perm.push(el) | |||
} | |||
@@ -35,14 +35,14 @@ config.bufferSize = 16 | |||
function process(block) { | |||
// Get factorial index from input 6 | |||
var k = Math.floor(block.inputs[5][0] / 10 * 120) | |||
let k = Math.floor(block.inputs[5][0] / 10 * 120) | |||
k = Math.min(Math.max(k, 0), 120 - 1) | |||
// Get index set permutation | |||
var perm = permutation([1, 2, 3, 4, 5], k) | |||
let perm = permutation([1, 2, 3, 4, 5], k) | |||
display(perm.join(", ")) | |||
for (var i = 0; i < 5; i++) { | |||
for (let i = 0; i < 5; i++) { | |||
// Permute input i | |||
for (var j = 0; j < block.bufferSize; j++) { | |||
for (let j = 0; j < block.bufferSize; j++) { | |||
block.outputs[i][j] = block.inputs[perm[i] - 1][j] | |||
} | |||
} | |||
@@ -1,21 +1,20 @@ | |||
// Simplest possible script using all variables | |||
// Simplest possible script using all variables, demonstrating buffering | |||
// by Andrew Belt | |||
config.frameDivider = 1 | |||
config.bufferSize = 32 | |||
function process(block) { | |||
// Loop through each column | |||
for (let i = 0; i < 6; i++) { | |||
// Get input | |||
let x = block.inputs[i][0] | |||
// Get gain knob | |||
let gain = block.knobs[i] | |||
// Apply gain to input | |||
let y = x * gain | |||
// Set gain light (red = 0) | |||
block.lights[i][0] = gain | |||
// Check mute switch | |||
if (block.switches[i]) { | |||
// Mute output | |||
y = 0 | |||
gain = 0 | |||
// Enable mute light (red = 0) | |||
block.switchLights[i][0] = 1 | |||
} | |||
@@ -23,7 +22,14 @@ function process(block) { | |||
// Disable mute light | |||
block.switchLights[i][0] = 0 | |||
} | |||
// Set output | |||
block.outputs[i][0] = y | |||
// Iterate input/output buffer | |||
for (let j = 0; j < block.bufferSize; j++) { | |||
// Get input | |||
let x = block.inputs[i][j] | |||
// Apply gain to input | |||
let y = x * gain | |||
// Set output | |||
block.outputs[i][j] = y | |||
} | |||
} | |||
} |
@@ -1,28 +1,34 @@ | |||
-- Simplest possible script using all variables, demonstrating buffering | |||
-- by Andrew Belt | |||
config.frameDivider = 1 | |||
config.bufferSize = 32 | |||
function process(block) | |||
-- Loop through each column | |||
for i=1,6 do | |||
-- Get input | |||
x = block.inputs[i][1] | |||
-- Get gain knob | |||
gain = block.knobs[i] | |||
-- Apply gain to input | |||
y = x * gain | |||
-- Set gain light (red = 0) | |||
-- Set gain light (red = 1) | |||
block.lights[i][1] = gain | |||
-- Check mute switch | |||
if block.switches[i] then | |||
-- Mute output | |||
y = 0 | |||
-- Enable mute light (red = 0) | |||
gain = 0 | |||
-- Enable mute light (red = 1) | |||
block.switchLights[i][1] = 1 | |||
else | |||
-- Disable mute light | |||
block.switchLights[i][1] = 0 | |||
end | |||
-- Set output | |||
block.outputs[i][1] = y | |||
-- Iterate input/output buffer | |||
for j=1,block.bufferSize do | |||
-- Get input | |||
x = block.inputs[i][j] | |||
-- Apply gain to input | |||
y = x * gain | |||
-- Set output | |||
block.outputs[i][j] = y | |||
end | |||
end | |||
end |
@@ -8,16 +8,16 @@ config.frameDivider = 256 | |||
// From https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB | |||
function hsvToRgb(h, s, v) { | |||
h *= 6 | |||
var c = v * s | |||
var x = c * (1 - Math.abs(h % 2 - 1)) | |||
var rgb; | |||
let c = v * s | |||
let x = c * (1 - Math.abs(h % 2 - 1)) | |||
let rgb; | |||
if (h < 1) rgb = [c, x, 0] | |||
else if (h < 2) rgb = [x, c, 0] | |||
else if (h < 3) rgb = [0, c, x] | |||
else if (h < 4) rgb = [0, x, c] | |||
else if (h < 5) rgb = [x, 0, c] | |||
else rgb = [c, 0, x] | |||
var m = v - c | |||
let m = v - c | |||
rgb[0] += m | |||
rgb[1] += m | |||
rgb[2] += m | |||
@@ -25,15 +25,15 @@ function hsvToRgb(h, s, v) { | |||
} | |||
var phase = 0 | |||
let phase = 0 | |||
function process(block) { | |||
phase += block.sampleTime * config.frameDivider * 0.5 | |||
phase %= 1 | |||
for (var i = 0; i < 6; i++) { | |||
var h = (1 - i / 6 + phase) % 1 | |||
var rgb = hsvToRgb(h, 1, 1) | |||
for (var c = 0; c < 3; c++) { | |||
for (let i = 0; i < 6; i++) { | |||
let h = (1 - i / 6 + phase) % 1 | |||
let rgb = hsvToRgb(h, 1, 1) | |||
for (let c = 0; c < 3; c++) { | |||
block.lights[i][c] = rgb[c] | |||
block.switchLights[i][c] = rgb[c] | |||
} | |||
@@ -6,22 +6,22 @@ | |||
config.frameDivider = 1 | |||
config.bufferSize = 16 | |||
var phase = 0 | |||
let phase = 0 | |||
function process(block) { | |||
// Knob ranges from -5 to 5 octaves | |||
var pitch = block.knobs[0] * 10 - 5 | |||
let pitch = block.knobs[0] * 10 - 5 | |||
// Input follows 1V/oct standard | |||
pitch += block.inputs[0][0] | |||
// The relationship between 1V/oct pitch and frequency is `freq = 2^pitch`. | |||
// Default frequency is middle C (C4) in Hz. | |||
// https://vcvrack.com/manual/VoltageStandards.html#pitch-and-frequencies | |||
var freq = 261.6256 * Math.pow(2, pitch) | |||
let freq = 261.6256 * Math.pow(2, pitch) | |||
display("Freq: " + freq.toFixed(3) + " Hz") | |||
// Set all samples in output buffer | |||
var deltaPhase = config.frameDivider * block.sampleTime * freq | |||
for (var i = 0; i < block.bufferSize; i++) { | |||
let deltaPhase = config.frameDivider * block.sampleTime * freq | |||
for (let i = 0; i < block.bufferSize; i++) { | |||
// Accumulate phase | |||
phase += deltaPhase | |||
// Wrap phase around range [0, 1] | |||