mirror of
https://codeberg.org/uzu/strudel
synced 2026-08-08 23:48:01 -04:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 77bab433e0 | |||
| f8cc1c2022 | |||
| e0bf9ea4d6 | |||
| 374661eb23 | |||
| df06248c54 | |||
| 27073d6c17 | |||
| f44caf9096 | |||
| ff5b11f5ed | |||
| 719c70a598 | |||
| 7a53f6c021 | |||
| 09d05abd70 | |||
| 3acc364a03 | |||
| b1aba294ad | |||
| 63ac80eb79 | |||
| e19fd24447 | |||
| fe9a91d1e4 | |||
| 860bb58d61 | |||
| d58b3e490b | |||
| 0003ce174e | |||
| 8e0f23e081 | |||
| 71e60ed8de | |||
| e2a29914c7 | |||
| a9a3d491a2 | |||
| a750764f88 | |||
| 5b397009ab | |||
| e68df9e789 | |||
| 4d3bbd5057 | |||
| 94257e81ee | |||
| 006ce9d1da | |||
| 81ca199a96 | |||
| 8d8b8ab99e | |||
| a4f10d5339 | |||
| 33a73c37bc | |||
| 4e6d39666a | |||
| a5b6022506 |
+1
-1
@@ -17,7 +17,7 @@ git remote set-url origin git@codeberg.org:uzu/strudel.git
|
|||||||
|
|
||||||
To get in touch with the contributors, either
|
To get in touch with the contributors, either
|
||||||
|
|
||||||
- [join the Tidal Discord Channel](https://discord.gg/remJ6gQA) and go to the #strudel channel
|
- [join the Tidal Discord Channel](https://discord.com/invite/HGEdXmRkzT) and go to the #strudel channel
|
||||||
- Find related discussions on the [tidal club forum](https://club.tidalcycles.org/)
|
- Find related discussions on the [tidal club forum](https://club.tidalcycles.org/)
|
||||||
|
|
||||||
## Ask a Question
|
## Ask a Question
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ This project is organized into many [packages](./packages), which are also avail
|
|||||||
|
|
||||||
Read more about how to use these in your own project [here](https://strudel.cc/technical-manual/project-start).
|
Read more about how to use these in your own project [here](https://strudel.cc/technical-manual/project-start).
|
||||||
|
|
||||||
You will need to abide by the terms of the [GNU Affero Public Licence v3](LICENSE.md). As such, Strudel code can only be shared within free/open source projects under the same license -- see the license for details.
|
You will need to abide by the terms of the [GNU Affero Public Licence v3](LICENSE). As such, Strudel code can only be shared within free/open source projects under the same license -- see the license for details.
|
||||||
|
|
||||||
Licensing info for the default sound banks can be found over on the [dough-samples](https://github.com/felixroos/dough-samples/blob/main/README.md) repository.
|
Licensing info for the default sound banks can be found over on the [dough-samples](https://github.com/felixroos/dough-samples/blob/main/README.md) repository.
|
||||||
|
|
||||||
|
|||||||
@@ -985,15 +985,31 @@ export const { delayfeedback, delayfb, dfb } = registerControl('delayfeedback',
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', 'dt');
|
export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', 'dt');
|
||||||
/* // TODO: test
|
|
||||||
|
/**
|
||||||
|
* Sets the time of the delay effect in cycles.
|
||||||
|
*
|
||||||
|
* @name delaysync
|
||||||
|
* @param {number | Pattern} cycles delay length in cycles
|
||||||
|
* @synonyms delayt, dt
|
||||||
|
* @example
|
||||||
|
* s("bd bd").delay(.25).delaysync("<1 2 3 5>".div(8))
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const { delaysync } = registerControl('delaysync');
|
||||||
|
|
||||||
|
/**
|
||||||
* Specifies whether delaytime is calculated relative to cps.
|
* Specifies whether delaytime is calculated relative to cps.
|
||||||
*
|
*
|
||||||
* @name lock
|
* @name lock
|
||||||
* @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle.
|
* @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle.
|
||||||
|
* @superdirtOnly
|
||||||
* @example
|
* @example
|
||||||
* s("sd").delay().lock(1).osc()
|
* s("sd").delay().lock(1).osc()
|
||||||
*
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const { lock } = registerControl('lock');
|
export const { lock } = registerControl('lock');
|
||||||
/**
|
/**
|
||||||
* Set detune for stacked voices of supported oscillators
|
* Set detune for stacked voices of supported oscillators
|
||||||
|
|||||||
@@ -869,6 +869,31 @@ export class Pattern {
|
|||||||
console.log(drawLine(this));
|
console.log(drawLine(this));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// methods relating to breaking patterns into subcycles
|
||||||
|
|
||||||
|
// Breaks a pattern into a pattern of patterns, according to the structure of the given binary pattern.
|
||||||
|
unjoin(pieces, func = id) {
|
||||||
|
return pieces.withHap((hap) =>
|
||||||
|
hap.withValue((v) => (v ? func(this.ribbon(hap.whole.begin, hap.whole.duration)) : this)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breaks a pattern into pieces according to the structure of a given pattern.
|
||||||
|
* True values in the given pattern cause the corresponding subcycle of the
|
||||||
|
* source pattern to be looped, and for an (optional) given function to be
|
||||||
|
* applied. False values result in the corresponding part of the source pattern
|
||||||
|
* to be played unchanged.
|
||||||
|
* @name into
|
||||||
|
* @memberof Pattern
|
||||||
|
* @example
|
||||||
|
* sound("bd sd ht lt").into("1 0", hurry(2))
|
||||||
|
*/
|
||||||
|
into(pieces, func) {
|
||||||
|
return this.unjoin(pieces, func).innerJoin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@@ -2494,6 +2519,37 @@ export const { fastchunk, fastChunk } = register(
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like `chunk`, but the function is applied to a looped subcycle of the source pattern.
|
||||||
|
* @name chunkInto
|
||||||
|
* @synonym chunkinto
|
||||||
|
* @memberof Pattern
|
||||||
|
* @example
|
||||||
|
* sound("bd sd ht lt bd - cp lt").chunkInto(4, hurry(2))
|
||||||
|
* .bank("tr909")
|
||||||
|
*/
|
||||||
|
export const { chunkinto, chunkInto } = register(['chunkinto', 'chunkInto'], function (n, func, pat) {
|
||||||
|
return pat.into(fastcat(true, ...Array(n - 1).fill(false))._iterback(n), func);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like `chunkInto`, but moves backwards through the chunks.
|
||||||
|
* @name chunkBackInto
|
||||||
|
* @synonym chunkbackinto
|
||||||
|
* @memberof Pattern
|
||||||
|
* @example
|
||||||
|
* sound("bd sd ht lt bd - cp lt").chunkInto(4, hurry(2))
|
||||||
|
* .bank("tr909")
|
||||||
|
*/
|
||||||
|
export const { chunkbackinto, chunkBackInto } = register(['chunkbackinto', 'chunkBackInto'], function (n, func, pat) {
|
||||||
|
return pat.into(
|
||||||
|
fastcat(true, ...Array(n - 1).fill(false))
|
||||||
|
._iter(n)
|
||||||
|
._early(1),
|
||||||
|
func,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// TODO - redefine elsewhere in terms of mask
|
// TODO - redefine elsewhere in terms of mask
|
||||||
export const bypass = register(
|
export const bypass = register(
|
||||||
'bypass',
|
'bypass',
|
||||||
|
|||||||
@@ -114,8 +114,9 @@ export function repl({
|
|||||||
* all(x => x.pianoroll())
|
* all(x => x.pianoroll())
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
|
let allTransforms = [];
|
||||||
const all = function (transform) {
|
const all = function (transform) {
|
||||||
allTransform = transform;
|
allTransforms.push(transform);
|
||||||
return silence;
|
return silence;
|
||||||
};
|
};
|
||||||
/** Applies a function to each of the running patterns separately. This is intended for future use with upcoming 'stepwise' features. See `all` for a version that applies the function to all the patterns stacked together into a single pattern.
|
/** Applies a function to each of the running patterns separately. This is intended for future use with upcoming 'stepwise' features. See `all` for a version that applies the function to all the patterns stacked together into a single pattern.
|
||||||
@@ -191,6 +192,7 @@ export function repl({
|
|||||||
await injectPatternMethods();
|
await injectPatternMethods();
|
||||||
setTime(() => scheduler.now()); // TODO: refactor?
|
setTime(() => scheduler.now()); // TODO: refactor?
|
||||||
await beforeEval?.({ code });
|
await beforeEval?.({ code });
|
||||||
|
allTransforms = []; // reset all transforms
|
||||||
shouldHush && hush();
|
shouldHush && hush();
|
||||||
|
|
||||||
if (mondo) {
|
if (mondo) {
|
||||||
@@ -207,8 +209,10 @@ export function repl({
|
|||||||
} else if (eachTransform) {
|
} else if (eachTransform) {
|
||||||
pattern = eachTransform(pattern);
|
pattern = eachTransform(pattern);
|
||||||
}
|
}
|
||||||
if (allTransform) {
|
if (allTransforms.length) {
|
||||||
pattern = allTransform(pattern);
|
for (let i in allTransforms) {
|
||||||
|
pattern = allTransforms[i](pattern);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!isPattern(pattern)) {
|
if (!isPattern(pattern)) {
|
||||||
const message = `got "${typeof evaluated}" instead of pattern`;
|
const message = `got "${typeof evaluated}" instead of pattern`;
|
||||||
|
|||||||
@@ -1271,4 +1271,39 @@ describe('Pattern', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('unjoin', () => {
|
||||||
|
it('destructures a pattern into subcycles', () => {
|
||||||
|
sameFirst(
|
||||||
|
fastcat('a', 'b', 'c', 'd')
|
||||||
|
.unjoin(fastcat(true, fastcat(true, true)))
|
||||||
|
.fmap(fast(2))
|
||||||
|
.join(),
|
||||||
|
fastcat('a', 'b', 'a', 'b', 'c', 'c', 'd', 'd'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('into', () => {
|
||||||
|
it('applies a function to subcycles of a pattern', () => {
|
||||||
|
sameFirst(
|
||||||
|
fastcat('a', 'b', 'c', 'd').into(fastcat(fastcat('true', 'true'), 'true'), fast(2)),
|
||||||
|
fastcat('a', 'a', 'b', 'b', 'c', 'd', 'c', 'd'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('chunkinto', () => {
|
||||||
|
it('chunks into subcycles', () => {
|
||||||
|
sameFirst(
|
||||||
|
fastcat('a', 'b', 'c').chunkInto(3, fast(2)).fast(3),
|
||||||
|
fastcat(fastcat('a', 'a'), 'b', 'c', 'a', fastcat('b', 'b'), 'c', 'a', 'b', fastcat('c', 'c')),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('chunkbackinto', () => {
|
||||||
|
it('chunks into subcycles backwards', () => {
|
||||||
|
sameFirst(
|
||||||
|
fastcat('a', 'b', 'c').chunkBackInto(3, fast(2)).fast(3),
|
||||||
|
fastcat('a', 'b', fastcat('c', 'c'), 'a', fastcat('b', 'b'), 'c', fastcat('a', 'a'), 'b', 'c'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ This program is free software: you can redistribute it and/or modify it under th
|
|||||||
import './feedbackdelay.mjs';
|
import './feedbackdelay.mjs';
|
||||||
import './reverb.mjs';
|
import './reverb.mjs';
|
||||||
import './vowel.mjs';
|
import './vowel.mjs';
|
||||||
import { clamp, nanFallback, _mod } from './util.mjs';
|
import { clamp, nanFallback, _mod, cycleToSeconds } from './util.mjs';
|
||||||
import workletsUrl from './worklets.mjs?audioworklet';
|
import workletsUrl from './worklets.mjs?audioworklet';
|
||||||
import { createFilter, gainNode, getCompressor, getWorklet } from './helpers.mjs';
|
import { createFilter, gainNode, getCompressor, getWorklet } from './helpers.mjs';
|
||||||
import { map } from 'nanostores';
|
import { map } from 'nanostores';
|
||||||
@@ -143,7 +143,7 @@ const defaultDefaultValues = {
|
|||||||
delay: 0,
|
delay: 0,
|
||||||
byteBeatExpression: '0',
|
byteBeatExpression: '0',
|
||||||
delayfeedback: 0.5,
|
delayfeedback: 0.5,
|
||||||
delaytime: 0.25,
|
delaysync: 3 / 16,
|
||||||
orbit: 1,
|
orbit: 1,
|
||||||
i: 1,
|
i: 1,
|
||||||
velocity: 1,
|
velocity: 1,
|
||||||
@@ -450,7 +450,7 @@ function mapChannelNumbers(channels) {
|
|||||||
return (Array.isArray(channels) ? channels : [channels]).map((ch) => ch - 1);
|
return (Array.isArray(channels) ? channels : [channels]).map((ch) => ch - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const superdough = async (value, t, hapDuration, cps) => {
|
export const superdough = async (value, t, hapDuration, cps = 0.5) => {
|
||||||
const ac = getAudioContext();
|
const ac = getAudioContext();
|
||||||
t = typeof t === 'string' && t.startsWith('=') ? Number(t.slice(1)) : ac.currentTime + t;
|
t = typeof t === 'string' && t.startsWith('=') ? Number(t.slice(1)) : ac.currentTime + t;
|
||||||
let { stretch } = value;
|
let { stretch } = value;
|
||||||
@@ -528,7 +528,8 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
vowel,
|
vowel,
|
||||||
delay = getDefaultValue('delay'),
|
delay = getDefaultValue('delay'),
|
||||||
delayfeedback = getDefaultValue('delayfeedback'),
|
delayfeedback = getDefaultValue('delayfeedback'),
|
||||||
delaytime = getDefaultValue('delaytime'),
|
delaysync = getDefaultValue('delaysync'),
|
||||||
|
delaytime,
|
||||||
orbit = getDefaultValue('orbit'),
|
orbit = getDefaultValue('orbit'),
|
||||||
room,
|
room,
|
||||||
roomfade,
|
roomfade,
|
||||||
@@ -547,6 +548,8 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
compressorRelease,
|
compressorRelease,
|
||||||
} = value;
|
} = value;
|
||||||
|
|
||||||
|
delaytime = delaytime ?? cycleToSeconds(delaysync, cps);
|
||||||
|
|
||||||
const orbitChannels = mapChannelNumbers(
|
const orbitChannels = mapChannelNumbers(
|
||||||
multiChannelOrbits && orbit > 0 ? [orbit * 2 - 1, orbit * 2] : getDefaultValue('channels'),
|
multiChannelOrbits && orbit > 0 ? [orbit * 2 - 1, orbit * 2] : getDefaultValue('channels'),
|
||||||
);
|
);
|
||||||
@@ -725,8 +728,8 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
// delay
|
// delay
|
||||||
let delaySend;
|
let delaySend;
|
||||||
if (delay > 0 && delaytime > 0 && delayfeedback > 0) {
|
if (delay > 0 && delaytime > 0 && delayfeedback > 0) {
|
||||||
const delyNode = getDelay(orbit, delaytime, delayfeedback, t, orbitChannels);
|
const delayNode = getDelay(orbit, delaytime, delayfeedback, t, orbitChannels);
|
||||||
delaySend = effectSend(post, delyNode, delay);
|
delaySend = effectSend(post, delayNode, delay);
|
||||||
audioNodes.push(delaySend);
|
audioNodes.push(delaySend);
|
||||||
}
|
}
|
||||||
// reverb
|
// reverb
|
||||||
|
|||||||
@@ -68,3 +68,7 @@ export const _mod = (n, m) => ((n % m) + m) % m;
|
|||||||
export const getSoundIndex = (n, numSounds) => {
|
export const getSoundIndex = (n, numSounds) => {
|
||||||
return _mod(Math.round(nanFallback(n, 0)), numSounds);
|
return _mod(Math.round(nanFallback(n, 0)), numSounds);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function cycleToSeconds(cycle, cps) {
|
||||||
|
return cycle / cps;
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,6 +37,13 @@ describe('tonal', () => {
|
|||||||
.firstCycleValues.map((h) => h.note),
|
.firstCycleValues.map((h) => h.note),
|
||||||
).toEqual(['C3', 'D3', 'E3']);
|
).toEqual(['C3', 'D3', 'E3']);
|
||||||
});
|
});
|
||||||
|
it('scale without tonic', () => {
|
||||||
|
expect(
|
||||||
|
n(seq(0, 1, 2))
|
||||||
|
.scale('major')
|
||||||
|
.firstCycleValues.map((h) => h.note),
|
||||||
|
).toEqual(['C3', 'D3', 'E3']);
|
||||||
|
});
|
||||||
it('scale with mininotation colon', () => {
|
it('scale with mininotation colon', () => {
|
||||||
expect(
|
expect(
|
||||||
n(seq(0, 1, 2))
|
n(seq(0, 1, 2))
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ function scaleStep(step, scale) {
|
|||||||
scale = scale.replaceAll(':', ' ');
|
scale = scale.replaceAll(':', ' ');
|
||||||
step = Math.ceil(step);
|
step = Math.ceil(step);
|
||||||
let { intervals, tonic, empty } = Scale.get(scale);
|
let { intervals, tonic, empty } = Scale.get(scale);
|
||||||
if ((empty && isNote(scale)) || (!empty && !tonic)) {
|
if ((empty && isNote(scale)) || (empty && !tonic)) {
|
||||||
throw new Error(`incomplete scale. Make sure to use ":" instead of spaces, example: .scale("C:major")`);
|
throw new Error(`incomplete scale. Make sure to use ":" instead of spaces, example: .scale("C:major")`);
|
||||||
} else if (empty) {
|
} else if (empty) {
|
||||||
throw new Error(`invalid scale "${scale}"`);
|
throw new Error(`invalid scale "${scale}"`);
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ const hap2value = (hap) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const webaudioOutputTrigger = (t, hap, ct, cps) => superdough(hap2value(hap), t - ct, hap.duration / cps, cps);
|
export const webaudioOutputTrigger = (t, hap, ct, cps) => superdough(hap2value(hap), t - ct, hap.duration / cps, cps);
|
||||||
// uses more precise, absolute t if available, see https://codeberg.org/uzu/strudel/pulls/1004
|
// uses more precise, absolute t if available, see https://github.com/tidalcycles/strudel/pull/1004
|
||||||
export const webaudioOutput = (hap, deadline, hapDuration, cps, t) =>
|
export const webaudioOutput = (hap, deadline, hapDuration, cps, t) => {
|
||||||
superdough(hap2value(hap), t ? `=${t}` : deadline, hapDuration);
|
return superdough(hap2value(hap), t ? `=${t}` : deadline, hapDuration, cps);
|
||||||
|
};
|
||||||
|
|
||||||
Pattern.prototype.webaudio = function () {
|
Pattern.prototype.webaudio = function () {
|
||||||
return this.onTrigger(webaudioOutputTrigger);
|
return this.onTrigger(webaudioOutputTrigger);
|
||||||
|
|||||||
@@ -1889,6 +1889,86 @@ exports[`runs examples > example "chunkBack" example index 0 1`] = `
|
|||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "chunkBackInto" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/16 | s:bd speed:2 bank:tr909 ]",
|
||||||
|
"[ 1/16 → 1/8 | s:sd speed:2 bank:tr909 ]",
|
||||||
|
"[ 1/8 → 3/16 | s:bd speed:2 bank:tr909 ]",
|
||||||
|
"[ 3/16 → 1/4 | s:sd speed:2 bank:tr909 ]",
|
||||||
|
"[ 1/4 → 3/8 | s:ht bank:tr909 ]",
|
||||||
|
"[ 3/8 → 1/2 | s:lt bank:tr909 ]",
|
||||||
|
"[ 1/2 → 5/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 3/4 → 7/8 | s:cp bank:tr909 ]",
|
||||||
|
"[ 7/8 → 1/1 | s:lt bank:tr909 ]",
|
||||||
|
"[ 1/1 → 9/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 9/8 → 5/4 | s:sd bank:tr909 ]",
|
||||||
|
"[ 5/4 → 21/16 | s:ht speed:2 bank:tr909 ]",
|
||||||
|
"[ 21/16 → 11/8 | s:lt speed:2 bank:tr909 ]",
|
||||||
|
"[ 11/8 → 23/16 | s:ht speed:2 bank:tr909 ]",
|
||||||
|
"[ 23/16 → 3/2 | s:lt speed:2 bank:tr909 ]",
|
||||||
|
"[ 3/2 → 13/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 7/4 → 15/8 | s:cp bank:tr909 ]",
|
||||||
|
"[ 15/8 → 2/1 | s:lt bank:tr909 ]",
|
||||||
|
"[ 2/1 → 17/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 17/8 → 9/4 | s:sd bank:tr909 ]",
|
||||||
|
"[ 9/4 → 19/8 | s:ht bank:tr909 ]",
|
||||||
|
"[ 19/8 → 5/2 | s:lt bank:tr909 ]",
|
||||||
|
"[ 5/2 → 41/16 | s:bd speed:2 bank:tr909 ]",
|
||||||
|
"[ 21/8 → 43/16 | s:bd speed:2 bank:tr909 ]",
|
||||||
|
"[ 11/4 → 23/8 | s:cp bank:tr909 ]",
|
||||||
|
"[ 23/8 → 3/1 | s:lt bank:tr909 ]",
|
||||||
|
"[ 3/1 → 25/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 25/8 → 13/4 | s:sd bank:tr909 ]",
|
||||||
|
"[ 13/4 → 27/8 | s:ht bank:tr909 ]",
|
||||||
|
"[ 27/8 → 7/2 | s:lt bank:tr909 ]",
|
||||||
|
"[ 7/2 → 29/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 15/4 → 61/16 | s:cp speed:2 bank:tr909 ]",
|
||||||
|
"[ 61/16 → 31/8 | s:lt speed:2 bank:tr909 ]",
|
||||||
|
"[ 31/8 → 63/16 | s:cp speed:2 bank:tr909 ]",
|
||||||
|
"[ 63/16 → 4/1 | s:lt speed:2 bank:tr909 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "chunkInto" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/16 | s:bd speed:2 bank:tr909 ]",
|
||||||
|
"[ 1/16 → 1/8 | s:sd speed:2 bank:tr909 ]",
|
||||||
|
"[ 1/8 → 3/16 | s:bd speed:2 bank:tr909 ]",
|
||||||
|
"[ 3/16 → 1/4 | s:sd speed:2 bank:tr909 ]",
|
||||||
|
"[ 1/4 → 3/8 | s:ht bank:tr909 ]",
|
||||||
|
"[ 3/8 → 1/2 | s:lt bank:tr909 ]",
|
||||||
|
"[ 1/2 → 5/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 3/4 → 7/8 | s:cp bank:tr909 ]",
|
||||||
|
"[ 7/8 → 1/1 | s:lt bank:tr909 ]",
|
||||||
|
"[ 1/1 → 9/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 9/8 → 5/4 | s:sd bank:tr909 ]",
|
||||||
|
"[ 5/4 → 21/16 | s:ht speed:2 bank:tr909 ]",
|
||||||
|
"[ 21/16 → 11/8 | s:lt speed:2 bank:tr909 ]",
|
||||||
|
"[ 11/8 → 23/16 | s:ht speed:2 bank:tr909 ]",
|
||||||
|
"[ 23/16 → 3/2 | s:lt speed:2 bank:tr909 ]",
|
||||||
|
"[ 3/2 → 13/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 7/4 → 15/8 | s:cp bank:tr909 ]",
|
||||||
|
"[ 15/8 → 2/1 | s:lt bank:tr909 ]",
|
||||||
|
"[ 2/1 → 17/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 17/8 → 9/4 | s:sd bank:tr909 ]",
|
||||||
|
"[ 9/4 → 19/8 | s:ht bank:tr909 ]",
|
||||||
|
"[ 19/8 → 5/2 | s:lt bank:tr909 ]",
|
||||||
|
"[ 5/2 → 41/16 | s:bd speed:2 bank:tr909 ]",
|
||||||
|
"[ 21/8 → 43/16 | s:bd speed:2 bank:tr909 ]",
|
||||||
|
"[ 11/4 → 23/8 | s:cp bank:tr909 ]",
|
||||||
|
"[ 23/8 → 3/1 | s:lt bank:tr909 ]",
|
||||||
|
"[ 3/1 → 25/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 25/8 → 13/4 | s:sd bank:tr909 ]",
|
||||||
|
"[ 13/4 → 27/8 | s:ht bank:tr909 ]",
|
||||||
|
"[ 27/8 → 7/2 | s:lt bank:tr909 ]",
|
||||||
|
"[ 7/2 → 29/8 | s:bd bank:tr909 ]",
|
||||||
|
"[ 15/4 → 61/16 | s:cp speed:2 bank:tr909 ]",
|
||||||
|
"[ 61/16 → 31/8 | s:lt speed:2 bank:tr909 ]",
|
||||||
|
"[ 31/8 → 63/16 | s:cp speed:2 bank:tr909 ]",
|
||||||
|
"[ 63/16 → 4/1 | s:lt speed:2 bank:tr909 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "clip" example index 0 1`] = `
|
exports[`runs examples > example "clip" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/4 | note:c s:piano clip:0.5 ]",
|
"[ 0/1 → 1/4 | note:c s:piano clip:0.5 ]",
|
||||||
@@ -2505,6 +2585,19 @@ exports[`runs examples > example "delayfeedback" example index 0 1`] = `
|
|||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "delaysync" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/2 | s:bd delay:0.25 delaysync:0.125 ]",
|
||||||
|
"[ 1/2 → 1/1 | s:bd delay:0.25 delaysync:0.125 ]",
|
||||||
|
"[ 1/1 → 3/2 | s:bd delay:0.25 delaysync:0.25 ]",
|
||||||
|
"[ 3/2 → 2/1 | s:bd delay:0.25 delaysync:0.25 ]",
|
||||||
|
"[ 2/1 → 5/2 | s:bd delay:0.25 delaysync:0.375 ]",
|
||||||
|
"[ 5/2 → 3/1 | s:bd delay:0.25 delaysync:0.375 ]",
|
||||||
|
"[ 3/1 → 7/2 | s:bd delay:0.25 delaysync:0.625 ]",
|
||||||
|
"[ 7/2 → 4/1 | s:bd delay:0.25 delaysync:0.625 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "delaytime" example index 0 1`] = `
|
exports[`runs examples > example "delaytime" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/2 | s:bd delay:0.25 delaytime:0.125 ]",
|
"[ 0/1 → 1/2 | s:bd delay:0.25 delaytime:0.125 ]",
|
||||||
@@ -4391,6 +4484,35 @@ exports[`runs examples > example "inside" example index 0 1`] = `
|
|||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "into" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/8 | s:bd speed:2 ]",
|
||||||
|
"[ 1/8 → 1/4 | s:sd speed:2 ]",
|
||||||
|
"[ 1/4 → 3/8 | s:bd speed:2 ]",
|
||||||
|
"[ 3/8 → 1/2 | s:sd speed:2 ]",
|
||||||
|
"[ 1/2 → 3/4 | s:ht ]",
|
||||||
|
"[ 3/4 → 1/1 | s:lt ]",
|
||||||
|
"[ 1/1 → 9/8 | s:bd speed:2 ]",
|
||||||
|
"[ 9/8 → 5/4 | s:sd speed:2 ]",
|
||||||
|
"[ 5/4 → 11/8 | s:bd speed:2 ]",
|
||||||
|
"[ 11/8 → 3/2 | s:sd speed:2 ]",
|
||||||
|
"[ 3/2 → 7/4 | s:ht ]",
|
||||||
|
"[ 7/4 → 2/1 | s:lt ]",
|
||||||
|
"[ 2/1 → 17/8 | s:bd speed:2 ]",
|
||||||
|
"[ 17/8 → 9/4 | s:sd speed:2 ]",
|
||||||
|
"[ 9/4 → 19/8 | s:bd speed:2 ]",
|
||||||
|
"[ 19/8 → 5/2 | s:sd speed:2 ]",
|
||||||
|
"[ 5/2 → 11/4 | s:ht ]",
|
||||||
|
"[ 11/4 → 3/1 | s:lt ]",
|
||||||
|
"[ 3/1 → 25/8 | s:bd speed:2 ]",
|
||||||
|
"[ 25/8 → 13/4 | s:sd speed:2 ]",
|
||||||
|
"[ 13/4 → 27/8 | s:bd speed:2 ]",
|
||||||
|
"[ 27/8 → 7/2 | s:sd speed:2 ]",
|
||||||
|
"[ 7/2 → 15/4 | s:ht ]",
|
||||||
|
"[ 15/4 → 4/1 | s:lt ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "invert" example index 0 1`] = `
|
exports[`runs examples > example "invert" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/8 | s:bd ]",
|
"[ 0/1 → 1/8 | s:bd ]",
|
||||||
@@ -5016,6 +5138,15 @@ exports[`runs examples > example "linger" example index 0 1`] = `
|
|||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "lock" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/1 | delay:{s:sd} lock:1 ]",
|
||||||
|
"[ 1/1 → 2/1 | delay:{s:sd} lock:1 ]",
|
||||||
|
"[ 2/1 → 3/1 | delay:{s:sd} lock:1 ]",
|
||||||
|
"[ 3/1 → 4/1 | delay:{s:sd} lock:1 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "loop" example index 0 1`] = `
|
exports[`runs examples > example "loop" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/1 | s:casio loop:1 ]",
|
"[ 0/1 → 1/1 | s:casio loop:1 ]",
|
||||||
|
|||||||
@@ -21,7 +21,11 @@ export function Reference() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry.name.includes(search) || (entry.synonyms?.some((s) => s.includes(search)) ?? false);
|
const lowCaseSearch = search.toLowerCase();
|
||||||
|
return (
|
||||||
|
entry.name.toLowerCase().includes(lowCaseSearch) ||
|
||||||
|
(entry.synonyms?.some((s) => s.includes(lowCaseSearch)) ?? false)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}, [search]);
|
}, [search]);
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export function WelcomeTab({ context }) {
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{/* To learn more about what this all means, check out the{' '} */}
|
{/* To learn more about what this all means, check out the{' '} */}
|
||||||
To get started, check out the
|
To get started, check out the{' '}
|
||||||
<a href={`${baseNoTrailing}/workshop/getting-started/`} target="_blank">
|
<a href={`${baseNoTrailing}/workshop/getting-started/`} target="_blank">
|
||||||
interactive tutorial
|
interactive tutorial
|
||||||
</a>
|
</a>
|
||||||
@@ -43,7 +43,7 @@ export function WelcomeTab({ context }) {
|
|||||||
</a>
|
</a>
|
||||||
. You can find the source code at{' '}
|
. You can find the source code at{' '}
|
||||||
<a href="https://codeberg.org/uzu/strudel" target="_blank">
|
<a href="https://codeberg.org/uzu/strudel" target="_blank">
|
||||||
github
|
codeberg
|
||||||
</a>
|
</a>
|
||||||
. You can also find <a href="https://github.com/felixroos/dough-samples/blob/main/README.md">licensing info</a>{' '}
|
. You can also find <a href="https://github.com/felixroos/dough-samples/blob/main/README.md">licensing info</a>{' '}
|
||||||
for the default sound banks there. Please consider to{' '}
|
for the default sound banks there. Please consider to{' '}
|
||||||
|
|||||||
Reference in New Issue
Block a user