mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-27 13:38:40 +00:00
add vowel
This commit is contained in:
parent
48a950faf8
commit
4406dd88d1
37
packages/webaudio/vowel.mjs
Normal file
37
packages/webaudio/vowel.mjs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// credits to webdirt: https://github.com/dktr0/WebDirt/blob/41342e81d6ad694a2310d491fef7b7e8b0929efe/js-src/Graph.js#L597
|
||||||
|
export var vowelFormant = {
|
||||||
|
a: { freqs: [660, 1120, 2750, 3000, 3350], gains: [1, 0.5012, 0.0708, 0.0631, 0.0126], qs: [80, 90, 120, 130, 140] },
|
||||||
|
e: { freqs: [440, 1800, 2700, 3000, 3300], gains: [1, 0.1995, 0.1259, 0.1, 0.1], qs: [70, 80, 100, 120, 120] },
|
||||||
|
i: { freqs: [270, 1850, 2900, 3350, 3590], gains: [1, 0.0631, 0.0631, 0.0158, 0.0158], qs: [40, 90, 100, 120, 120] },
|
||||||
|
o: { freqs: [430, 820, 2700, 3000, 3300], gains: [1, 0.3162, 0.0501, 0.0794, 0.01995], qs: [40, 80, 100, 120, 120] },
|
||||||
|
u: { freqs: [370, 630, 2750, 3000, 3400], gains: [1, 0.1, 0.0708, 0.0316, 0.01995], qs: [40, 60, 100, 120, 120] },
|
||||||
|
};
|
||||||
|
|
||||||
|
class VowelNode extends GainNode {
|
||||||
|
constructor(ac, letter) {
|
||||||
|
super(ac);
|
||||||
|
if (!vowelFormant[letter]) {
|
||||||
|
throw new Error('vowel: unknown vowel ' + letter);
|
||||||
|
}
|
||||||
|
const { gains, qs, freqs } = vowelFormant[letter];
|
||||||
|
const makeupGain = ac.createGain();
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const gain = ac.createGain();
|
||||||
|
gain.gain.value = gains[i];
|
||||||
|
const filter = ac.createBiquadFilter();
|
||||||
|
filter.type = 'bandpass';
|
||||||
|
filter.Q.value = qs[i];
|
||||||
|
filter.frequency.value = freqs[i];
|
||||||
|
this.connect(filter);
|
||||||
|
filter.connect(gain);
|
||||||
|
gain.connect(makeupGain);
|
||||||
|
}
|
||||||
|
makeupGain.gain.value = 8; // how much makeup gain to add?
|
||||||
|
this.connect = (target) => makeupGain.connect(target);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioContext.prototype.createVowelFilter = function (letter) {
|
||||||
|
return new VowelNode(this, letter);
|
||||||
|
};
|
||||||
@ -9,6 +9,7 @@ import * as strudel from '@strudel.cycles/core';
|
|||||||
import { fromMidi, toMidi } from '@strudel.cycles/core';
|
import { fromMidi, toMidi } from '@strudel.cycles/core';
|
||||||
import { loadBuffer } from './sampler.mjs';
|
import { loadBuffer } from './sampler.mjs';
|
||||||
const { Pattern } = strudel;
|
const { Pattern } = strudel;
|
||||||
|
import './vowel.mjs';
|
||||||
|
|
||||||
// export const getAudioContext = () => Tone.getContext().rawContext;
|
// export const getAudioContext = () => Tone.getContext().rawContext;
|
||||||
|
|
||||||
@ -158,6 +159,7 @@ Pattern.prototype.out = function () {
|
|||||||
speed = 1, // sample playback speed
|
speed = 1, // sample playback speed
|
||||||
begin = 0,
|
begin = 0,
|
||||||
end = 1,
|
end = 1,
|
||||||
|
vowel,
|
||||||
} = hap.value;
|
} = hap.value;
|
||||||
const { velocity = 1 } = hap.context;
|
const { velocity = 1 } = hap.context;
|
||||||
gain *= velocity; // legacy fix for velocity
|
gain *= velocity; // legacy fix for velocity
|
||||||
@ -258,6 +260,7 @@ Pattern.prototype.out = function () {
|
|||||||
cutoff !== undefined && chain.push(getFilter('lowpass', cutoff, resonance));
|
cutoff !== undefined && chain.push(getFilter('lowpass', cutoff, resonance));
|
||||||
hcutoff !== undefined && chain.push(getFilter('highpass', hcutoff, hresonance));
|
hcutoff !== undefined && chain.push(getFilter('highpass', hcutoff, hresonance));
|
||||||
bandf !== undefined && chain.push(getFilter('bandpass', bandf, bandq));
|
bandf !== undefined && chain.push(getFilter('bandpass', bandf, bandq));
|
||||||
|
vowel !== undefined && chain.push(ac.createVowelFilter(vowel));
|
||||||
// TODO vowel
|
// TODO vowel
|
||||||
// TODO delay / delaytime / delayfeedback
|
// TODO delay / delaytime / delayfeedback
|
||||||
// panning
|
// panning
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user