Hacker News new | ask | show | jobs
by chaosprint 1074 days ago
Interesting! thanks for sharing.

I have added this to my feature list for https://glicol.org

the source code looks fairly straightforward. very cool

```js function makeFormantNode(ctx, f1, f2) { const sinOsc = ctx.createOscillator(); sinOsc.type = 'sawtooth'; sinOsc.frequency.value = 110; sinOsc.start();

  const bandPass = ctx.createBiquadFilter();
  bandPass.type = 'bandpass';
  bandPass.frequency.value = (f1 + f2) / 2;
  bandPass.Q.value = ((f1 + f2) / 2) / (f2 - f1);

  const gainNode = ctx.createGain();
  gainNode.gain.value = 0.0;

  sinOsc.connect(bandPass);
  bandPass.connect(gainNode);
  gainNode.connect(ctx.destination);

  return {
    start() {
      gainNode.gain.setTargetAtTime(0.75, ctx.currentTime, 0.015);
    },
    stop() {
      gainNode.gain.setTargetAtTime(0.0, ctx.currentTime, 0.015);
    },
    panic() {
      gainNode.gain.cancelScheduledValues(ctx.currentTime);
      gainNode.gain.setTargetAtTime(0, ctx.currentTime, 0.015);
    },
  };
}

function makeSibilanceNode(ctx) { const buffer = ctx.createBuffer(1, NOISE_BUFFER_SIZE, ctx.sampleRate); const data = buffer.getChannelData(0); for (let i = 0; i < NOISE_BUFFER_SIZE; ++i) { data[i] = Math.random(); }

  const noise = ctx.createBufferSource();
  noise.buffer = buffer;
  noise.loop = true;

  const noiseFilter = ctx.createBiquadFilter();
  noiseFilter.type = 'bandpass';
  noiseFilter.frequency.value = 5000;
  noiseFilter.Q.value = 0.5;

  const noiseGain = ctx.createGain();
  noiseGain.gain.value = 0.0;

  noise.connect(noiseFilter);
  noiseFilter.connect(noiseGain);
  noiseGain.connect(ctx.destination);
  noise.start();

  return {
    start() {
      noiseGain.gain.setTargetAtTime(0.75, ctx.currentTime, 0.015);
    },
    stop() {
      noiseGain.gain.setTargetAtTime(0.0, ctx.currentTime, 0.015);
    },
    panic() {
      noiseGain.gain.cancelScheduledValues(ctx.currentTime);
      noiseGain.gain.setTargetAtTime(0, ctx.currentTime, 0.015);
    },
  };
}

function initialize() { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); audioNodes['a'] = makeFormantNode(audioCtx, 0, 225); audioNodes['s'] = makeFormantNode(audioCtx, 225, 450); audioNodes['d'] = makeFormantNode(audioCtx, 450, 700); audioNodes['f'] = makeFormantNode(audioCtx, 700, 1000); audioNodes['v'] = makeFormantNode(audioCtx, 1000, 1400); audioNodes['b'] = makeFormantNode(audioCtx, 1400, 2000); audioNodes['h'] = makeFormantNode(audioCtx, 2000, 2700); audioNodes['j'] = makeFormantNode(audioCtx, 2700, 3800); audioNodes['k'] = makeFormantNode(audioCtx, 3800, 5400); audioNodes['l'] = makeFormantNode(audioCtx, 5400, 7500); audioNodes[' '] = makeSibilanceNode(audioCtx); } ```

1 comments

Just checked out GLICOL. It's quite cool! Is there MIDI support or any plans to add it?