Skip to content

Commit

Permalink
feat(examples): update ramp-synth oscillator (6x unison)
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Dec 15, 2019
1 parent d25584e commit e4e8b98
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 10 deletions.
4 changes: 2 additions & 2 deletions examples/ramp-synth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ visualization to move their position. Markers cannot be moved past their
neighbors.

Audio must be explicitly enabled by pressing `a`. Sonification uses the
current ramp as wave table for a 2-voice oscillator w/ 30 Hz base
frequency.
current ramp as wave table for a 6-voice unison stereo oscillator w/ 60
Hz base frequency (configurable via `BASE_FREQ` in `api.ts`).

### Hotkeys

Expand Down
2 changes: 1 addition & 1 deletion examples/ramp-synth/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const PAD = 20;
export const CWIDTH = WIDTH - 2 * PAD;
export const CHEIGHT = HEIGHT - 2 * PAD;
export const SNAP = 5 / WIDTH;
export const BASE_FREQ = 30;
export const BASE_FREQ = 60;

export const PRESETS: Vec[][] = [
[
Expand Down
24 changes: 17 additions & 7 deletions examples/ramp-synth/src/audio.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { fract } from "@thi.ng/math";
import { IRamp } from "@thi.ng/ramp";

let actx: AudioContext | undefined;
Expand All @@ -9,7 +10,7 @@ export const isAudioActive = () => !!actx;
export const initAudio = (freq: number) => {
if (actx) return;
actx = new AudioContext();
buf = actx.createBuffer(1, actx.sampleRate / freq, actx.sampleRate);
buf = actx.createBuffer(2, actx.sampleRate / freq, actx.sampleRate);
src = actx.createBufferSource();
src.buffer = buf;
src.loop = true;
Expand All @@ -23,13 +24,22 @@ export const stopAudio = () => {
actx = undefined;
};

export const updateAudio = (ramp: IRamp, osc2freq = 2) => {
export const updateAudio = (ramp: IRamp, detune = 0.01) => {
if (!actx) return;
const bufData = buf.getChannelData(0);
for (let i = 0, n = bufData.length; i < n; i++) {
const t = i / n;
const left = buf.getChannelData(0);
const right = buf.getChannelData(1);
const f4 = 1 + detune;
const f5 = 2 + detune;
const f6 = 4 + detune;
for (let i = 0, n = left.length; i < n; i++) {
let t = i / n;
const y1 = ramp.at(t);
const y2 = ramp.at(t * osc2freq);
bufData[i] = y1 + y2 - 1;
const y2 = ramp.at(t * 2);
const y3 = ramp.at(t * 4);
const y4 = ramp.at(fract(t * f4));
const y5 = ramp.at(fract(t * f5));
const y6 = ramp.at(fract(t * f6));
left[i] = y1 * 0.5 + y5 * 0.2 + y3 * 0.3 - 1;
right[i] = y4 * 0.5 + y2 * 0.3 + y6 * 0.2 - 1;
}
};

0 comments on commit e4e8b98

Please sign in to comment.