mirror of
https://codeberg.org/uzu/strudel
synced 2026-08-03 05:56:34 -04:00
Merge branch 'main' into glossing/transient-processor
This commit is contained in:
@@ -401,12 +401,13 @@ export const { accelerate } = registerControl('accelerate');
|
||||
* Sets the velocity from 0 to 1. Is multiplied together with gain.
|
||||
*
|
||||
* @name velocity
|
||||
* @synonyms vel
|
||||
* @example
|
||||
* s("hh*8")
|
||||
* .gain(".4!2 1 .4!2 1 .4 1")
|
||||
* .velocity(".4 1")
|
||||
*/
|
||||
export const { velocity } = registerControl('velocity');
|
||||
export const { velocity, vel } = registerControl('velocity', 'vel');
|
||||
/**
|
||||
* Controls the gain by an exponential amount.
|
||||
*
|
||||
@@ -1482,14 +1483,13 @@ export const { lpdepth } = registerControl('lpdepth');
|
||||
* Depth of the LFO for the lowpass filter, in HZ
|
||||
*
|
||||
* @name lpdepthfrequency
|
||||
* @synonyms
|
||||
* lpdethfreq
|
||||
* @synonyms lpdepthfreq
|
||||
* @param {number | Pattern} depth depth of modulation
|
||||
* @example
|
||||
* note("<c c c# c c c4>*16").s("sawtooth").lpf(600).lpdepthfrequency("<200 500 100 0>")
|
||||
*/
|
||||
|
||||
export const { lpdepthfrequency } = registerControl('lpdepthfrequency', 'lpdepthfreq');
|
||||
export const { lpdepthfrequency, lpdepthfreq } = registerControl('lpdepthfrequency', 'lpdepthfreq');
|
||||
|
||||
/**
|
||||
* Shape of the LFO for the lowpass filter
|
||||
@@ -1543,14 +1543,13 @@ export const { bpdepth } = registerControl('bpdepth');
|
||||
* Depth of the LFO for the bandpass filter, in HZ
|
||||
*
|
||||
* @name bpdepthfrequency
|
||||
* @synonyms
|
||||
* bpdethfreq
|
||||
* @synonyms bpdepthfreq
|
||||
* @param {number | Pattern} depth depth of modulation
|
||||
* @example
|
||||
* note("<c c c# c c c4>*16").s("sawtooth").lpf(600).bpdepthfrequency("<200 500 100 0>")
|
||||
*/
|
||||
|
||||
export const { bpdepthfrequency } = registerControl('bpdepthfrequency', 'bpdepthfreq');
|
||||
export const { bpdepthfrequency, bpdepthfreq } = registerControl('bpdepthfrequency', 'bpdepthfreq');
|
||||
|
||||
/**
|
||||
* Shape of the LFO for the bandpass filter
|
||||
@@ -1598,20 +1597,19 @@ export const { hpsync } = registerControl('hpsync');
|
||||
* @name hpdepth
|
||||
* @param {number | Pattern} depth depth of modulation
|
||||
*/
|
||||
export const { hpdepth, hpdepthfreq } = registerControl('hpdepth');
|
||||
export const { hpdepth } = registerControl('hpdepth');
|
||||
|
||||
/**
|
||||
* Depth of the LFO for the hipass filter, in hz
|
||||
*
|
||||
* @name hpdepthfrequency
|
||||
* @synonyms
|
||||
* hpdethfreq
|
||||
* @synonyms hpdepthfreq
|
||||
* @param {number | Pattern} depth depth of modulation
|
||||
* @example
|
||||
* note("<c c c# c c c4>*16").s("sawtooth").lpf(600).hpdepthfrequency("<200 500 100 0>")
|
||||
*/
|
||||
|
||||
export const { hpdepthfrequency } = registerControl('hpdepthfrequency', 'hpdepthfreq');
|
||||
export const { hpdepthfrequency, hpdepthfreq } = registerControl('hpdepthfrequency', 'hpdepthfreq');
|
||||
|
||||
/**
|
||||
* Shape of the LFO for the highpass filter
|
||||
|
||||
@@ -574,7 +574,8 @@ export class Pattern {
|
||||
* Returns a new Pattern, which only returns haps that meet the given test.
|
||||
* @param {Function} hap_test - a function which returns false for haps to be removed from the pattern
|
||||
* @returns Pattern
|
||||
* @noAutocomplete
|
||||
* @example
|
||||
* s("bd*8").velocity(rand).filterHaps((h) => (h.whole.begin % 1) < h.value.velocity)
|
||||
*/
|
||||
filterHaps(hap_test) {
|
||||
return new Pattern((state) => this.query(state).filter(hap_test));
|
||||
@@ -585,7 +586,11 @@ export class Pattern {
|
||||
* inside haps.
|
||||
* @param {Function} value_test
|
||||
* @returns Pattern
|
||||
* @noAutocomplete
|
||||
* @example
|
||||
* const drums = s("bd sd bd sd")
|
||||
* kick: drums.filterValues((v) => v.s === 'bd').duck(2)
|
||||
* snare: drums.filterValues((v) => v.s === 'sd')
|
||||
* bass: s("saw!4").note("G#1").lpf(80).lpenv(4).orbit(2)
|
||||
*/
|
||||
filterValues(value_test) {
|
||||
return new Pattern((state) => this.query(state).filter((hap) => value_test(hap.value))).setSteps(this._steps);
|
||||
@@ -1587,7 +1592,13 @@ export const func = curry((a, b) => reify(b).func(a));
|
||||
*
|
||||
* @param {string | string[]} name name of the function, or an array of names to be used as synonyms
|
||||
* @param {function} func function with 1 or more params, where last is the current pattern
|
||||
* @noAutocomplete
|
||||
* @param {bool} patternify defaults to true; if set to false, you will have more control over the arguments to `func` as they will be
|
||||
* in their raw form and it will be up to you to patternify them and/or query them for values
|
||||
* @example
|
||||
* const vlpf = register('vlpf', (freq, pat) => {
|
||||
* return pat.fmap((v) => ({...v, cutoff: freq * (v.velocity ?? 1) }));
|
||||
* })
|
||||
* s("saw").seg(8).velocity(rand).vlpf(800)
|
||||
*
|
||||
*/
|
||||
export function register(name, func, patternify = true, preserveSteps = false, join = (x) => x.innerJoin()) {
|
||||
@@ -2676,8 +2687,13 @@ export const hsl = register('hsl', (h, s, l, pat) => {
|
||||
/**
|
||||
* Tags each Hap with an identifier. Good for filtering. The function populates Hap.context.tags (Array).
|
||||
* @name tag
|
||||
* @noAutocomplete
|
||||
* @param {string} tag anything unique
|
||||
* @example
|
||||
* s("saw!16").note("F1")
|
||||
* .lpf(tri.range(40, 80).slow(4)).lpenv(5).lpq(4).lpd(0.15)
|
||||
* .when(rand.late(0.1).gte(0.5), x => x.transpose("12").tag('altered'))
|
||||
* .when(rand.late(0.2).gte(0.5), x => x.s("square").tag('altered'))
|
||||
* .when("<0 1>", x => x.filter((hap) => hap.hasTag('altered')))
|
||||
*/
|
||||
Pattern.prototype.tag = function (tag) {
|
||||
return this.withContext((ctx) => ({ ...ctx, tags: (ctx.tags || []).concat([tag]) }));
|
||||
@@ -2688,15 +2704,16 @@ Pattern.prototype.tag = function (tag) {
|
||||
* @name filter
|
||||
* @param {Function} test function to test Hap
|
||||
* @example
|
||||
* s("hh!7 oh").filter(hap => hap.value.s==='hh')
|
||||
* s("hh!7 oh").filter(hap => hap.value.s === 'hh')
|
||||
*/
|
||||
export const filter = register('filter', (test, pat) => pat.withHaps((haps) => haps.filter(test)));
|
||||
|
||||
/**
|
||||
* Filters haps by their begin time
|
||||
* @name filterWhen
|
||||
* @noAutocomplete
|
||||
* @param {Function} test function to test Hap.whole.begin
|
||||
* @example
|
||||
* oneCycle: s("bd*4").filterWhen((t) => t < 1)
|
||||
*/
|
||||
export const filterWhen = register('filterWhen', (test, pat) => pat.filter((h) => test(h.whole.begin)));
|
||||
|
||||
|
||||
@@ -290,8 +290,8 @@ function getPhaser(time, end, frequency = 1, depth = 0.5, centerFrequency = 1000
|
||||
const lfo = getLfo(ac, time, end, { frequency, depth: sweep * 2 });
|
||||
|
||||
//filters
|
||||
const numStages = 2; //num of filters in series
|
||||
let fOffset = 0;
|
||||
const numStages = 1; //num of filters in series
|
||||
let fOffset = 282; //for backward compat in #1800
|
||||
const filterChain = [];
|
||||
for (let i = 0; i < numStages; i++) {
|
||||
const filter = ac.createBiquadFilter();
|
||||
@@ -302,12 +302,9 @@ function getPhaser(time, end, frequency = 1, depth = 0.5, centerFrequency = 1000
|
||||
|
||||
lfo.connect(filter.detune);
|
||||
fOffset += 282;
|
||||
if (i > 0) {
|
||||
filterChain[i - 1].connect(filter);
|
||||
}
|
||||
filterChain.push(filter);
|
||||
}
|
||||
return { phaser: filterChain[filterChain.length - 1], lfo };
|
||||
return { filterChain, lfo };
|
||||
}
|
||||
|
||||
function getFilterType(ftype) {
|
||||
@@ -716,9 +713,9 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
}
|
||||
// phaser
|
||||
if (phaserrate !== undefined && phaserdepth > 0) {
|
||||
const { phaser, lfo } = getPhaser(t, endWithRelease, phaserrate, phaserdepth, phasercenter, phasersweep);
|
||||
const { filterChain, lfo } = getPhaser(t, endWithRelease, phaserrate, phaserdepth, phasercenter, phasersweep);
|
||||
audioNodes.push(lfo);
|
||||
chain.push(phaser);
|
||||
chain.push(...filterChain);
|
||||
}
|
||||
|
||||
// last gain
|
||||
|
||||
Reference in New Issue
Block a user