mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-25 12:38:35 +00:00
Reinstate slice and splice (#500)
Reinstate slice/splice, fixing up "unit" param using new global cps
This commit is contained in:
parent
fdc4819e39
commit
2d5064bd5b
@ -1415,25 +1415,32 @@ export function register(name, func, patternify = true) {
|
|||||||
const arity = func.length;
|
const arity = func.length;
|
||||||
var pfunc; // the patternified function
|
var pfunc; // the patternified function
|
||||||
|
|
||||||
pfunc = function (...args) {
|
if (patternify) {
|
||||||
args = args.map(reify);
|
pfunc = function (...args) {
|
||||||
const pat = args[args.length - 1];
|
args = args.map(reify);
|
||||||
if (arity === 1) {
|
const pat = args[args.length - 1];
|
||||||
return func(pat);
|
if (arity === 1) {
|
||||||
}
|
return func(pat);
|
||||||
const [left, ...right] = args.slice(0, -1);
|
}
|
||||||
let mapFn = (...args) => {
|
const [left, ...right] = args.slice(0, -1);
|
||||||
// make sure to call func with the correct argument count
|
let mapFn = (...args) => {
|
||||||
// args.length is expected to be <= arity-1
|
// make sure to call func with the correct argument count
|
||||||
// so we set undefined args explicitly undefined
|
// args.length is expected to be <= arity-1
|
||||||
Array(arity - 1)
|
// so we set undefined args explicitly undefined
|
||||||
.fill()
|
Array(arity - 1)
|
||||||
.map((_, i) => args[i] ?? undefined);
|
.fill()
|
||||||
return func(...args, pat);
|
.map((_, i) => args[i] ?? undefined);
|
||||||
|
return func(...args, pat);
|
||||||
|
};
|
||||||
|
mapFn = curry(mapFn, null, arity - 1);
|
||||||
|
return right.reduce((acc, p) => acc.appLeft(p), left.fmap(mapFn)).innerJoin();
|
||||||
};
|
};
|
||||||
mapFn = curry(mapFn, null, arity - 1);
|
} else {
|
||||||
return right.reduce((acc, p) => acc.appLeft(p), left.fmap(mapFn)).innerJoin();
|
pfunc = function (...args) {
|
||||||
};
|
args = args.map(reify);
|
||||||
|
return func(...args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Pattern.prototype[name] = function (...args) {
|
Pattern.prototype[name] = function (...args) {
|
||||||
// For methods that take a single argument (plus 'this'), allow
|
// For methods that take a single argument (plus 'this'), allow
|
||||||
@ -2231,11 +2238,13 @@ const _loopAt = function (factor, pat, cps = 1) {
|
|||||||
* @example
|
* @example
|
||||||
* await samples('github:tidalcycles/Dirt-Samples/master')
|
* await samples('github:tidalcycles/Dirt-Samples/master')
|
||||||
* s("breaks165").slice(8, "0 1 <2 2*2> 3 [4 0] 5 6 7".every(3, rev)).slow(1.5)
|
* s("breaks165").slice(8, "0 1 <2 2*2> 3 [4 0] 5 6 7".every(3, rev)).slow(1.5)
|
||||||
|
*/
|
||||||
|
|
||||||
const slice = register(
|
const slice = register(
|
||||||
'slice',
|
'slice',
|
||||||
function (npat, ipat, opat) {
|
function (npat, ipat, opat) {
|
||||||
return npat.innerBind((n) =>
|
return npat.innerBind((n) =>
|
||||||
ipat.outerBind((i) =>
|
ipat.outerBind((i) =>
|
||||||
opat.outerBind((o) => {
|
opat.outerBind((o) => {
|
||||||
// If it's not an object, assume it's a string and make it a 's' control parameter
|
// If it's not an object, assume it's a string and make it a 's' control parameter
|
||||||
o = o instanceof Object ? o : { s: o };
|
o = o instanceof Object ? o : { s: o };
|
||||||
@ -2248,7 +2257,6 @@ const slice = register(
|
|||||||
},
|
},
|
||||||
false, // turns off auto-patternification
|
false, // turns off auto-patternification
|
||||||
);
|
);
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Works the same as slice, but changes the playback speed of each slice to match the duration of its step.
|
* Works the same as slice, but changes the playback speed of each slice to match the duration of its step.
|
||||||
@ -2258,6 +2266,8 @@ const slice = register(
|
|||||||
* @example
|
* @example
|
||||||
* await samples('github:tidalcycles/Dirt-Samples/master')
|
* await samples('github:tidalcycles/Dirt-Samples/master')
|
||||||
* s("breaks165").splice(8, "0 1 [2 3 0]@2 3 0@2 7").hurry(0.65)
|
* s("breaks165").splice(8, "0 1 [2 3 0]@2 3 0@2 7").hurry(0.65)
|
||||||
|
*/
|
||||||
|
|
||||||
const splice = register(
|
const splice = register(
|
||||||
'splice',
|
'splice',
|
||||||
function (npat, ipat, opat) {
|
function (npat, ipat, opat) {
|
||||||
@ -2273,8 +2283,7 @@ const splice = register(
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
false, // turns off auto-patternification
|
false, // turns off auto-patternification
|
||||||
);
|
);
|
||||||
*/
|
|
||||||
|
|
||||||
const { loopAt, loopat } = register(['loopAt', 'loopat'], function (factor, pat) {
|
const { loopAt, loopat } = register(['loopAt', 'loopat'], function (factor, pat) {
|
||||||
return _loopAt(factor, pat, 1);
|
return _loopAt(factor, pat, 1);
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export function repl({
|
|||||||
onTrigger: async (hap, deadline, duration, cps) => {
|
onTrigger: async (hap, deadline, duration, cps) => {
|
||||||
try {
|
try {
|
||||||
if (!hap.context.onTrigger || !hap.context.dominantTrigger) {
|
if (!hap.context.onTrigger || !hap.context.dominantTrigger) {
|
||||||
await defaultOutput(hap, deadline, duration);
|
await defaultOutput(hap, deadline, duration, cps);
|
||||||
}
|
}
|
||||||
if (hap.context.onTrigger) {
|
if (hap.context.onTrigger) {
|
||||||
// call signature of output / onTrigger is different...
|
// call signature of output / onTrigger is different...
|
||||||
|
|||||||
@ -976,6 +976,7 @@ describe('Pattern', () => {
|
|||||||
sameFirst(n(0, 1).weave(2, s('bd', silence), s(silence, 'sd')), sequence(s('bd').n(0), s('sd').n(1)));
|
sameFirst(n(0, 1).weave(2, s('bd', silence), s(silence, 'sd')), sequence(s('bd').n(0), s('sd').n(1)));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
describe('slice', () => {
|
describe('slice', () => {
|
||||||
it('Can slice a sample', () => {
|
it('Can slice a sample', () => {
|
||||||
sameFirst(
|
sameFirst(
|
||||||
@ -1001,5 +1002,5 @@ describe('Pattern', () => {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});*/
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -191,7 +191,7 @@ function effectSend(input, effect, wet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// export const webaudioOutput = async (t, hap, ct, cps) => {
|
// export const webaudioOutput = async (t, hap, ct, cps) => {
|
||||||
export const webaudioOutput = async (hap, deadline, hapDuration) => {
|
export const webaudioOutput = async (hap, deadline, hapDuration, cps) => {
|
||||||
const ac = getAudioContext();
|
const ac = getAudioContext();
|
||||||
hap.ensureObjectValue();
|
hap.ensureObjectValue();
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ export const webaudioOutput = async (hap, deadline, hapDuration) => {
|
|||||||
bufferSource.playbackRate.value = Math.abs(speed) * bufferSource.playbackRate.value;
|
bufferSource.playbackRate.value = Math.abs(speed) * bufferSource.playbackRate.value;
|
||||||
if (unit === 'c') {
|
if (unit === 'c') {
|
||||||
// are there other units?
|
// are there other units?
|
||||||
bufferSource.playbackRate.value = bufferSource.playbackRate.value * bufferSource.buffer.duration;
|
bufferSource.playbackRate.value = bufferSource.playbackRate.value * bufferSource.buffer.duration * cps;
|
||||||
}
|
}
|
||||||
let duration = soundfont || clip ? hapDuration : bufferSource.buffer.duration / bufferSource.playbackRate.value;
|
let duration = soundfont || clip ? hapDuration : bufferSource.buffer.duration / bufferSource.playbackRate.value;
|
||||||
// "The computation of the offset into the sound is performed using the sound buffer's natural sample rate,
|
// "The computation of the offset into the sound is performed using the sound buffer's natural sample rate,
|
||||||
@ -378,7 +378,7 @@ export const webaudioOutput = async (hap, deadline, hapDuration) => {
|
|||||||
chain[0].onended = () => chain.concat([delaySend, reverbSend]).forEach((n) => n?.disconnect());
|
chain[0].onended = () => chain.concat([delaySend, reverbSend]).forEach((n) => n?.disconnect());
|
||||||
};
|
};
|
||||||
|
|
||||||
export const webaudioOutputTrigger = (t, hap, ct, cps) => webaudioOutput(hap, t - ct, hap.duration / cps);
|
export const webaudioOutputTrigger = (t, hap, ct, cps) => webaudioOutput(hap, t - ct, hap.duration / cps, cps);
|
||||||
|
|
||||||
Pattern.prototype.webaudio = function () {
|
Pattern.prototype.webaudio = function () {
|
||||||
// TODO: refactor (t, hap, ct, cps) to (hap, deadline, duration) ?
|
// TODO: refactor (t, hap, ct, cps) to (hap, deadline, duration) ?
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user