Merge pull request #693 from Bubobubobubobubo/vibrato
Adding vibrato to base oscillators
This commit is contained in:
commit
38a51324b2
4 changed files with 109 additions and 6 deletions
|
|
@ -640,6 +640,36 @@ const generic_params = [
|
||||||
*/
|
*/
|
||||||
// currently an alias of 'hcutoff' https://github.com/tidalcycles/strudel/issues/496
|
// currently an alias of 'hcutoff' https://github.com/tidalcycles/strudel/issues/496
|
||||||
// ['hpf'],
|
// ['hpf'],
|
||||||
|
/**
|
||||||
|
* Applies a vibrato to the frequency of the oscillator.
|
||||||
|
*
|
||||||
|
* @name vib
|
||||||
|
* @synonyms vibrato, v
|
||||||
|
* @param {number | Pattern} frequency of the vibrato in hertz
|
||||||
|
* @example
|
||||||
|
* note("a")
|
||||||
|
* .vib("<.5 1 2 4 8 16>")
|
||||||
|
* @example
|
||||||
|
* // change the modulation depth with ":"
|
||||||
|
* note("a")
|
||||||
|
* .vib("<.5 1 2 4 8 16>:12")
|
||||||
|
*/
|
||||||
|
[['vib', 'vibmod'], 'vibrato', 'v'],
|
||||||
|
/**
|
||||||
|
* Sets the vibrato depth in semitones. Only has an effect if `vibrato` | `vib` | `v` is is also set
|
||||||
|
*
|
||||||
|
* @name vibmod
|
||||||
|
* @synonyms vmod
|
||||||
|
* @param {number | Pattern} depth of vibrato (in semitones)
|
||||||
|
* @example
|
||||||
|
* note("a").vib(4)
|
||||||
|
* .vibmod("<.25 .5 1 2 12>")
|
||||||
|
* @example
|
||||||
|
* // change the vibrato frequency with ":"
|
||||||
|
* note("a")
|
||||||
|
* .vibmod("<.25 .5 1 2 12>:8")
|
||||||
|
*/
|
||||||
|
[['vibmod', 'vib'], 'vmod'],
|
||||||
[['hcutoff', 'hresonance'], 'hpf', 'hp'],
|
[['hcutoff', 'hresonance'], 'hpf', 'hp'],
|
||||||
/**
|
/**
|
||||||
* Controls the **h**igh-**p**ass **q**-value.
|
* Controls the **h**igh-**p**ass **q**-value.
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ export function registerSynthSounds() {
|
||||||
fmrelease: fmRelease,
|
fmrelease: fmRelease,
|
||||||
fmvelocity: fmVelocity,
|
fmvelocity: fmVelocity,
|
||||||
fmwave: fmWaveform = 'sine',
|
fmwave: fmWaveform = 'sine',
|
||||||
|
vib = 0,
|
||||||
|
vibmod = 0.5,
|
||||||
} = value;
|
} = value;
|
||||||
let { n, note, freq } = value;
|
let { n, note, freq } = value;
|
||||||
// with synths, n and note are the same thing
|
// with synths, n and note are the same thing
|
||||||
|
|
@ -53,7 +55,14 @@ export function registerSynthSounds() {
|
||||||
}
|
}
|
||||||
// maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default)
|
// maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default)
|
||||||
// make oscillator
|
// make oscillator
|
||||||
const { node: o, stop } = getOscillator({ t, s: wave, freq, partials: n });
|
const { node: o, stop } = getOscillator({
|
||||||
|
t,
|
||||||
|
s: wave,
|
||||||
|
freq,
|
||||||
|
vib,
|
||||||
|
vibmod,
|
||||||
|
partials: n,
|
||||||
|
});
|
||||||
|
|
||||||
// FM + FM envelope
|
// FM + FM envelope
|
||||||
let stopFm, fmEnvelope;
|
let stopFm, fmEnvelope;
|
||||||
|
|
@ -137,8 +146,8 @@ export function waveformN(partials, type) {
|
||||||
return osc;
|
return osc;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOscillator({ s, freq, t, partials }) {
|
export function getOscillator({ s, freq, t, vib, vibmod, partials }) {
|
||||||
// make oscillator
|
// Make oscillator with partial count
|
||||||
let o;
|
let o;
|
||||||
if (!partials || s === 'sine') {
|
if (!partials || s === 'sine') {
|
||||||
o = getAudioContext().createOscillator();
|
o = getAudioContext().createOscillator();
|
||||||
|
|
@ -148,7 +157,25 @@ export function getOscillator({ s, freq, t, partials }) {
|
||||||
}
|
}
|
||||||
o.frequency.value = Number(freq);
|
o.frequency.value = Number(freq);
|
||||||
o.start(t);
|
o.start(t);
|
||||||
//o.stop(t + duration + release);
|
|
||||||
const stop = (time) => o.stop(time);
|
// Additional oscillator for vibrato effect
|
||||||
return { node: o, stop };
|
let vibrato_oscillator;
|
||||||
|
if (vib > 0) {
|
||||||
|
vibrato_oscillator = getAudioContext().createOscillator();
|
||||||
|
vibrato_oscillator.frequency.value = vib;
|
||||||
|
const gain = getAudioContext().createGain();
|
||||||
|
// Vibmod is the amount of vibrato, in semitones
|
||||||
|
gain.gain.value = vibmod * 100;
|
||||||
|
vibrato_oscillator.connect(gain);
|
||||||
|
gain.connect(o.detune);
|
||||||
|
vibrato_oscillator.start(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
node: o,
|
||||||
|
stop: (time) => {
|
||||||
|
vibrato_oscillator?.stop(time);
|
||||||
|
o.stop(time);
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4758,6 +4758,42 @@ exports[`runs examples > example "velocity" example index 0 1`] = `
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "vib" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/1 | note:a vib:0.5 ]",
|
||||||
|
"[ 1/1 → 2/1 | note:a vib:1 ]",
|
||||||
|
"[ 2/1 → 3/1 | note:a vib:2 ]",
|
||||||
|
"[ 3/1 → 4/1 | note:a vib:4 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "vib" example index 1 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/1 | note:a vib:0.5 vibmod:12 ]",
|
||||||
|
"[ 1/1 → 2/1 | note:a vib:1 vibmod:12 ]",
|
||||||
|
"[ 2/1 → 3/1 | note:a vib:2 vibmod:12 ]",
|
||||||
|
"[ 3/1 → 4/1 | note:a vib:4 vibmod:12 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "vibmod" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/1 | note:a vib:4 vibmod:0.25 ]",
|
||||||
|
"[ 1/1 → 2/1 | note:a vib:4 vibmod:0.5 ]",
|
||||||
|
"[ 2/1 → 3/1 | note:a vib:4 vibmod:1 ]",
|
||||||
|
"[ 3/1 → 4/1 | note:a vib:4 vibmod:2 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "vibmod" example index 1 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/1 | note:a vibmod:0.25 vib:8 ]",
|
||||||
|
"[ 1/1 → 2/1 | note:a vibmod:0.5 vib:8 ]",
|
||||||
|
"[ 2/1 → 3/1 | note:a vibmod:1 vib:8 ]",
|
||||||
|
"[ 3/1 → 4/1 | note:a vibmod:2 vib:8 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "voicing" example index 0 1`] = `
|
exports[`runs examples > example "voicing" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/1 | note:E4 ]",
|
"[ 0/1 → 1/1 | note:E4 ]",
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,16 @@ You can also set `n` directly in mini notation with `sound`:
|
||||||
Note for tidal users: `n` in tidal is synonymous to `note` for synths only.
|
Note for tidal users: `n` in tidal is synonymous to `note` for synths only.
|
||||||
In strudel, this is not the case, where `n` will always change timbre, be it though different samples or different waveforms.
|
In strudel, this is not the case, where `n` will always change timbre, be it though different samples or different waveforms.
|
||||||
|
|
||||||
|
## Vibrato
|
||||||
|
|
||||||
|
### vib
|
||||||
|
|
||||||
|
<JsDoc client:idle name="vib" h={0} />
|
||||||
|
|
||||||
|
### vibmod
|
||||||
|
|
||||||
|
<JsDoc client:idle name="vibmod" h={0} />
|
||||||
|
|
||||||
## FM Synthesis
|
## FM Synthesis
|
||||||
|
|
||||||
FM Synthesis is a technique that changes the frequency of a basic waveform rapidly to alter the timbre.
|
FM Synthesis is a technique that changes the frequency of a basic waveform rapidly to alter the timbre.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue