mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-27 23:38:49 -04:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b523205590 | |||
| 956598da18 | |||
| e011f3b982 | |||
| cb591815ed | |||
| d30df8d4cf | |||
| e10cd22c26 | |||
| 18dc4944bf | |||
| 2f8cabbb6b | |||
| ec26392509 | |||
| 30cd486f37 | |||
| cde0520ed9 | |||
| f4b1baac87 | |||
| d217119391 | |||
| 692359309f | |||
| d65b908bda |
@@ -2234,7 +2234,7 @@ export const brak = register('brak', function (pat) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse all haps in a pattern
|
* Reverse all cycles in a pattern. See also `revv` for reversing a whole pattern.
|
||||||
*
|
*
|
||||||
* @name rev
|
* @name rev
|
||||||
* @memberof Pattern
|
* @memberof Pattern
|
||||||
@@ -2266,6 +2266,23 @@ export const rev = register(
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse a whole pattern. See also `rev` for reversing each cycle.
|
||||||
|
*
|
||||||
|
* @name revv
|
||||||
|
* @memberof Pattern
|
||||||
|
* @returns Pattern
|
||||||
|
* @example
|
||||||
|
* // This is the same as `<[g e] [d c]>`. If `rev()` is used, you get
|
||||||
|
* // the same as `<[d c] [g e]>`, where each cycle reverses, but the order of
|
||||||
|
* // cycles stays the same.
|
||||||
|
* note("<[c d] [e g]>").revv()
|
||||||
|
*/
|
||||||
|
export const revv = register('revv', function (pat) {
|
||||||
|
const negateSpan = (span) => new TimeSpan(Fraction(0).sub(span.end), Fraction(0).sub(span.begin));
|
||||||
|
return pat.withQuerySpan(negateSpan).withHapSpan(negateSpan);
|
||||||
|
});
|
||||||
|
|
||||||
/** Like press, but allows you to specify the amount by which each
|
/** Like press, but allows you to specify the amount by which each
|
||||||
* event is shifted. pressBy(0.5) is the same as press, while
|
* event is shifted. pressBy(0.5) is the same as press, while
|
||||||
* pressBy(1/3) shifts each event by a third of its timespan.
|
* pressBy(1/3) shifts each event by a third of its timespan.
|
||||||
|
|||||||
@@ -244,8 +244,7 @@ export function repl({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isPattern(pattern)) {
|
if (!isPattern(pattern)) {
|
||||||
const message = `got "${typeof evaluated}" instead of pattern`;
|
pattern = silence;
|
||||||
throw new Error(message + (typeof evaluated === 'function' ? ', did you forget to call a function?' : '.'));
|
|
||||||
}
|
}
|
||||||
logger(`[eval] code updated`);
|
logger(`[eval] code updated`);
|
||||||
pattern = await setPattern(pattern, autostart);
|
pattern = await setPattern(pattern, autostart);
|
||||||
|
|||||||
@@ -586,6 +586,18 @@ describe('Pattern', () => {
|
|||||||
.map((a) => a.value),
|
.map((a) => a.value),
|
||||||
).toStrictEqual(['c', 'b', 'a']);
|
).toStrictEqual(['c', 'b', 'a']);
|
||||||
});
|
});
|
||||||
|
it('Does not reverse the order of cycles', () => {
|
||||||
|
expect(fastcat('a', 'b', 'c', 'd').slow(2).rev().fast(2).sortHapsByPart().firstCycle()).toStrictEqual(
|
||||||
|
fastcat('b', 'a', 'd', 'c').firstCycle(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('revv()', () => {
|
||||||
|
it('Does reverse the order of cycles', () => {
|
||||||
|
expect(fastcat('a', 'b', 'c', 'd').slow(2).revv().fast(2).sortHapsByPart().firstCycle()).toStrictEqual(
|
||||||
|
fastcat('d', 'c', 'b', 'a').firstCycle(),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('sequence()', () => {
|
describe('sequence()', () => {
|
||||||
it('Can work like fastcat', () => {
|
it('Can work like fastcat', () => {
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ export function createFilter(context, start, end, params, cps, cycle) {
|
|||||||
rate = cps * sync;
|
rate = cps * sync;
|
||||||
}
|
}
|
||||||
const hasLFO = [depth, depthfrequency, skew, shape, rate].some((v) => v !== undefined);
|
const hasLFO = [depth, depthfrequency, skew, shape, rate].some((v) => v !== undefined);
|
||||||
|
let lfo;
|
||||||
if (hasLFO) {
|
if (hasLFO) {
|
||||||
depth = depth ?? 1;
|
depth = depth ?? 1;
|
||||||
const time = cycle / cps;
|
const time = cycle / cps;
|
||||||
@@ -255,10 +256,10 @@ export function createFilter(context, start, end, params, cps, cycle) {
|
|||||||
time,
|
time,
|
||||||
curve: 1,
|
curve: 1,
|
||||||
};
|
};
|
||||||
getParamLfo(context, frequencyParam, start, end, lfoValues);
|
lfo = getParamLfo(context, frequencyParam, start, end, lfoValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
return filter;
|
return { filter, lfo };
|
||||||
}
|
}
|
||||||
|
|
||||||
// stays 1 until .5, then fades out
|
// stays 1 until .5, then fades out
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ export function connectToDestination(input, channels) {
|
|||||||
|
|
||||||
function getPhaser(time, end, frequency = 1, depth = 0.5, centerFrequency = 1000, sweep = 2000) {
|
function getPhaser(time, end, frequency = 1, depth = 0.5, centerFrequency = 1000, sweep = 2000) {
|
||||||
const ac = getAudioContext();
|
const ac = getAudioContext();
|
||||||
const lfoGain = getLfo(ac, time, end, { frequency, depth: sweep * 2 });
|
const lfo = getLfo(ac, time, end, { frequency, depth: sweep * 2 });
|
||||||
|
|
||||||
//filters
|
//filters
|
||||||
const numStages = 2; //num of filters in series
|
const numStages = 2; //num of filters in series
|
||||||
@@ -300,14 +300,14 @@ function getPhaser(time, end, frequency = 1, depth = 0.5, centerFrequency = 1000
|
|||||||
filter.frequency.value = centerFrequency + fOffset;
|
filter.frequency.value = centerFrequency + fOffset;
|
||||||
filter.Q.value = 2 - Math.min(Math.max(depth * 2, 0), 1.9);
|
filter.Q.value = 2 - Math.min(Math.max(depth * 2, 0), 1.9);
|
||||||
|
|
||||||
lfoGain.connect(filter.detune);
|
lfo.connect(filter.detune);
|
||||||
fOffset += 282;
|
fOffset += 282;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
filterChain[i - 1].connect(filter);
|
filterChain[i - 1].connect(filter);
|
||||||
}
|
}
|
||||||
filterChain.push(filter);
|
filterChain.push(filter);
|
||||||
}
|
}
|
||||||
return filterChain[filterChain.length - 1];
|
return { phaser: filterChain[filterChain.length - 1], lfo };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilterType(ftype) {
|
function getFilterType(ftype) {
|
||||||
@@ -413,7 +413,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
|||||||
release = 0,
|
release = 0,
|
||||||
|
|
||||||
//phaser
|
//phaser
|
||||||
phaserrate: phaser,
|
phaserrate,
|
||||||
phaserdepth = getDefaultValue('phaserdepth'),
|
phaserdepth = getDefaultValue('phaserdepth'),
|
||||||
phasersweep,
|
phasersweep,
|
||||||
phasercenter,
|
phasercenter,
|
||||||
@@ -560,10 +560,14 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
|||||||
};
|
};
|
||||||
const lpParams = pickAndRename(value, lpMap);
|
const lpParams = pickAndRename(value, lpMap);
|
||||||
lpParams.type = 'lowpass';
|
lpParams.type = 'lowpass';
|
||||||
let lp = () => createFilter(ac, t, end, lpParams, cps, cycle);
|
const lp = () => createFilter(ac, t, end, lpParams, cps, cycle);
|
||||||
chain.push(lp());
|
const { filter: lpf1, lfo: lfo1 } = lp();
|
||||||
|
chain.push(lpf1);
|
||||||
|
lfo1 && audioNodes.push(lfo1);
|
||||||
if (ftype === '24db') {
|
if (ftype === '24db') {
|
||||||
chain.push(lp());
|
const { filter: lpf2, lfo: lfo2 } = lp();
|
||||||
|
chain.push(lpf2);
|
||||||
|
lfo2 && audioNodes.push(lfo2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,10 +593,14 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
|||||||
};
|
};
|
||||||
const hpParams = pickAndRename(value, hpMap);
|
const hpParams = pickAndRename(value, hpMap);
|
||||||
hpParams.type = 'highpass';
|
hpParams.type = 'highpass';
|
||||||
let hp = () => createFilter(ac, t, end, hpParams, cps, cycle);
|
const hp = () => createFilter(ac, t, end, hpParams, cps, cycle);
|
||||||
chain.push(hp());
|
const { filter: hpf1, lfo: lfo1 } = hp();
|
||||||
|
chain.push(hpf1);
|
||||||
|
lfo1 && audioNodes.push(lfo1);
|
||||||
if (ftype === '24db') {
|
if (ftype === '24db') {
|
||||||
chain.push(hp());
|
const { filter: hpf2, lfo: lfo2 } = hp();
|
||||||
|
chain.push(hpf2);
|
||||||
|
lfo2 && audioNodes.push(lfo2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -618,10 +626,14 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
|||||||
};
|
};
|
||||||
const bpParams = pickAndRename(value, bpMap);
|
const bpParams = pickAndRename(value, bpMap);
|
||||||
bpParams.type = 'bandpass';
|
bpParams.type = 'bandpass';
|
||||||
let bp = () => createFilter(ac, t, end, bpParams, cps, cycle);
|
const bp = () => createFilter(ac, t, end, bpParams, cps, cycle);
|
||||||
chain.push(bp());
|
const { filter: bpf1, lfo: lfo1 } = bp();
|
||||||
|
chain.push(bpf1);
|
||||||
|
lfo1 && audioNodes.push(lfo1);
|
||||||
if (ftype === '24db') {
|
if (ftype === '24db') {
|
||||||
chain.push(bp());
|
const { filter: bpf2, lfo: lfo2 } = bp();
|
||||||
|
chain.push(bpf2);
|
||||||
|
lfo2 && audioNodes.push(lfo2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,9 +696,10 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
|||||||
chain.push(panner);
|
chain.push(panner);
|
||||||
}
|
}
|
||||||
// phaser
|
// phaser
|
||||||
if (phaser !== undefined && phaserdepth > 0) {
|
if (phaserrate !== undefined && phaserdepth > 0) {
|
||||||
const phaserFX = getPhaser(t, endWithRelease, phaser, phaserdepth, phasercenter, phasersweep);
|
const { phaser, lfo } = getPhaser(t, endWithRelease, phaserrate, phaserdepth, phasercenter, phasersweep);
|
||||||
chain.push(phaserFX);
|
audioNodes.push(lfo);
|
||||||
|
chain.push(phaser);
|
||||||
}
|
}
|
||||||
|
|
||||||
// last gain
|
// last gain
|
||||||
|
|||||||
@@ -9256,6 +9256,19 @@ exports[`runs examples > example "rev" example index 0 1`] = `
|
|||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "revv" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/2 | note:g ]",
|
||||||
|
"[ 1/2 → 1/1 | note:e ]",
|
||||||
|
"[ 1/1 → 3/2 | note:d ]",
|
||||||
|
"[ 3/2 → 2/1 | note:c ]",
|
||||||
|
"[ 2/1 → 5/2 | note:g ]",
|
||||||
|
"[ 5/2 → 3/1 | note:e ]",
|
||||||
|
"[ 3/1 → 7/2 | note:d ]",
|
||||||
|
"[ 7/2 → 4/1 | note:c ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "ribbon" example index 0 1`] = `
|
exports[`runs examples > example "ribbon" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/1 | note:d ]",
|
"[ 0/1 → 1/1 | note:d ]",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"name": "dbpatch",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csv": "^6.3.11"
|
"csv": "^6.3.11"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user