diff --git a/examples/hello.js b/examples/hello.js index 1ae5206..f66fcaa 100644 --- a/examples/hello.js +++ b/examples/hello.js @@ -29,7 +29,7 @@ function process(args) { var rgb = hsvToRgb(h, 1, 1) args.lights[i] = rgb args.switchLights[i] = rgb - args.outputs[i] = Math.sin(2 * Math.PI * h) * 10 + args.outputs[i] = Math.sin(2 * Math.PI * h) * 5 + 5 } } diff --git a/examples/vco.js b/examples/vco.js new file mode 100644 index 0000000..d8c800a --- /dev/null +++ b/examples/vco.js @@ -0,0 +1,28 @@ +// Voltage-controlled oscillator example +// by Andrew Belt + +// JavaScript isn't ideal for audio generating and processing due to it being 10-100 less efficient than C++, but it's still an easy way to learn simple DSP. + +config.frameDivider = 1 + +var phase = 0 +function process(args) { + // Knob ranges from -5 to 5 octaves + var pitch = args.knobs[0] * 10 - 5 + // Input follows 1V/oct standard + pitch += args.inputs[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) + display("Freq: " + freq.toFixed(3) + " Hz") + + // Accumulate phase + phase += args.sampleTime * config.frameDivider * freq + // Wrap phase around range [0, 1] + phase %= 1 + + // Convert phase to sine output + args.outputs[0] = Math.sin(2 * Math.PI * phase) * 5 +} \ No newline at end of file diff --git a/src/Prototype.cpp b/src/Prototype.cpp index 1e20707..84d7deb 100644 --- a/src/Prototype.cpp +++ b/src/Prototype.cpp @@ -43,7 +43,7 @@ struct Prototype : Module { Prototype() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); for (int i = 0; i < NUM_ROWS; i++) - configParam(KNOB_PARAMS + i, 0.f, 1.f, 0.f, string::f("Knob %d", i + 1)); + configParam(KNOB_PARAMS + i, 0.f, 1.f, 0.5f, string::f("Knob %d", i + 1)); for (int i = 0; i < NUM_ROWS; i++) configParam(SWITCH_PARAMS + i, 0.f, 1.f, 0.f, string::f("Switch %d", i + 1));