mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-23 21:47:16 -04:00
Compare commits
95 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d855cf5e8 | |||
| dd04d49c75 | |||
| 34874862ab | |||
| 0361bc629f | |||
| 1fdd87a4f3 | |||
| 16e9aca222 | |||
| 4a3d5ca44f | |||
| 6c0e8a0833 | |||
| 7336ff0ded | |||
| 735f57e276 | |||
| eb4f1f69f6 | |||
| e7e321fe03 | |||
| bf3de368f0 | |||
| d645cc6fe5 | |||
| 6fe11be218 | |||
| cf7fc23981 | |||
| bfdfab0a00 | |||
| edb347e85a | |||
| 63fcce79e0 | |||
| 8defdc424c | |||
| 16b2fc0632 | |||
| d0a544d7a7 | |||
| 9b3c6b9f94 | |||
| 6327e17feb | |||
| 15fe2734e9 | |||
| 1dd1ce254f | |||
| 3ea91adfd6 | |||
| ce5f425142 | |||
| 671a22fc22 | |||
| 976955dae3 | |||
| a6ad58a375 | |||
| 681eed3d0e | |||
| 81a9811803 | |||
| 72b582c605 | |||
| 2f0891d4e5 | |||
| a7a283a99e | |||
| d9e44dcda6 | |||
| acd5661106 | |||
| b0b2b6a120 | |||
| 664d76cf1b | |||
| a901e2e387 | |||
| 82b14b5292 | |||
| 05bcd5e32f | |||
| 077556e7cb | |||
| 4cc2de9b7e | |||
| b0c0a393a1 | |||
| 168269a839 | |||
| 34771f03d4 | |||
| 504fe9ed40 | |||
| caf6686d01 | |||
| c063fb6b1c | |||
| e3680b96de | |||
| 688e275e0c | |||
| 2e33569786 | |||
| 46fe6d3c4d | |||
| 9220b95677 | |||
| 5b27b19972 | |||
| db413881db | |||
| 77bab433e0 | |||
| f8cc1c2022 | |||
| e0bf9ea4d6 | |||
| 374661eb23 | |||
| df06248c54 | |||
| 27073d6c17 | |||
| f44caf9096 | |||
| ff5b11f5ed | |||
| 719c70a598 | |||
| 7a53f6c021 | |||
| 09d05abd70 | |||
| 3acc364a03 | |||
| e19fd24447 | |||
| fe9a91d1e4 | |||
| 1b7fbecf50 | |||
| 117cf7e18a | |||
| ae15bb7274 | |||
| 94257e81ee | |||
| 006ce9d1da | |||
| bee8c81254 | |||
| 8ad48e1633 | |||
| 4a181d5b33 | |||
| d5ab6b7211 | |||
| 4ba9d47bff | |||
| c6c5a3035c | |||
| e024ae2142 | |||
| 19df19375d | |||
| cba96049a3 | |||
| 1509ff1793 | |||
| 6a33032da7 | |||
| 6c05a4eb7b | |||
| 16472b59dd | |||
| 7df663e87d | |||
| 3159f66560 | |||
| 0d900c0134 | |||
| 66a27a609c | |||
| 496d60dc1c |
@@ -150,6 +150,7 @@ Important: Always publish with `pnpm`, as `npm` does not support overriding main
|
|||||||
|
|
||||||
|
|
||||||
## useful commands
|
## useful commands
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
#regenerate the test snapshots (ex: when updating or creating new pattern functions)
|
#regenerate the test snapshots (ex: when updating or creating new pattern functions)
|
||||||
pnpm snapshot
|
pnpm snapshot
|
||||||
@@ -160,6 +161,81 @@ pnpm run osc
|
|||||||
#build the standalone version
|
#build the standalone version
|
||||||
pnpm tauri build
|
pnpm tauri build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## version tag patching
|
||||||
|
|
||||||
|
here's a little guide on how to patch patterns in the database to prevent breaking old patterns due to breaking changes in newer versions.
|
||||||
|
|
||||||
|
the general tactic is to use `// @version x.y` to tag a pattern with a specific strudel version. when a pattern is evaluated, this metadata will de-activate any breaking changes that came after the specified version.
|
||||||
|
for example, in version 1.1, the default value for `fanchor` was changed from `0.5` to `0`.
|
||||||
|
if play a pattern that was made before that change, sounds that use filter evenlopes can sound very different, so by adding `// @version 1.0` will make it sound like it used to.
|
||||||
|
before releasing a new version with breaking changes, we can edit all patterns in the database, inserting the version tag they were created under:
|
||||||
|
|
||||||
|
as an example, to release version 1.2, do the following:
|
||||||
|
|
||||||
|
1. get date range
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# get date of last version:
|
||||||
|
git log -1 --format=%aI @strudel/core@1.1.0
|
||||||
|
# 2024-05-31T23:07:26+02:00
|
||||||
|
|
||||||
|
# get date of current version:
|
||||||
|
git log -1 --format=%aI @strudel/core@1.2.0
|
||||||
|
# 2025-05-01T12:39:24+02:00
|
||||||
|
# might also use todays timestamp if version is not yet released
|
||||||
|
```
|
||||||
|
|
||||||
|
now we know, all patterns between these 2 dates have to receive a version tag (unless they already have one).
|
||||||
|
|
||||||
|
2. get patterns in question
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT *
|
||||||
|
FROM code_v1
|
||||||
|
WHERE code NOT LIKE '%@version%'
|
||||||
|
AND created_at > '2024-05-31T23:07:26+02:00'
|
||||||
|
AND created_at < '2025-05-01T12:39:24+02:00'
|
||||||
|
ORDER BY created_at ASC;
|
||||||
|
```
|
||||||
|
|
||||||
|
this gives us all unversioned patterns that were saved between 1.1.0 and 1.2.0. in this case, it's 9373 patterns!
|
||||||
|
|
||||||
|
3. insert version tags
|
||||||
|
|
||||||
|
we are now ready to insert the version tag to these patterns.
|
||||||
|
before updating thousands of patterns, it's probably a good idea to test if a single one gets udpated:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
UPDATE code_v1
|
||||||
|
SET code = code || E'\n// @version 1.1'
|
||||||
|
WHERE hash = 'Ns2sMB40yIw4';
|
||||||
|
```
|
||||||
|
|
||||||
|
after [verifying](https://strudel.cc/?Ns2sMB40yIw4) that the version tag has been added, let's insert it everywhere:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
UPDATE code_v1
|
||||||
|
SET code = code || E'\n// @version 1.1'
|
||||||
|
WHERE code NOT LIKE '%@version%'
|
||||||
|
AND created_at > '2024-05-31T23:07:26+02:00'
|
||||||
|
AND created_at < '2025-05-01T12:39:24+02:00'
|
||||||
|
```
|
||||||
|
|
||||||
|
4. verify
|
||||||
|
|
||||||
|
we can verify that the edits worked by querying all patterns that contain the new version tag:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT *
|
||||||
|
FROM code_v1
|
||||||
|
WHERE code LIKE '%@version 1.1%'
|
||||||
|
AND created_at > '2024-05-31T23:07:26+02:00'
|
||||||
|
AND created_at < '2025-05-01T12:39:24+02:00'
|
||||||
|
ORDER BY created_at ASC;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Have Fun
|
## Have Fun
|
||||||
|
|
||||||
Remember to have fun, and that this project is driven by the passion of volunteers!
|
Remember to have fun, and that this project is driven by the passion of volunteers!
|
||||||
|
|||||||
@@ -38,13 +38,7 @@ Licensing info for the default sound banks can be found over on the [dough-sampl
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
There are many ways to contribute to this project! See [contribution guide](./CONTRIBUTING.md).
|
There are many ways to contribute to this project! See [contribution guide](./CONTRIBUTING.md). You can find the full list of contributors [here](https://codeberg.org/uzu/strudel/activity/contributors).
|
||||||
|
|
||||||
<a href="https://codeberg.org/uzu/strudel/activity/contributors">
|
|
||||||
<img src="https://contrib.rocks/image?repo=tidalcycles/strudel" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
Made with [contrib.rocks](https://contrib.rocks).
|
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
jsdoc-synonyms.js - Add support for @synonym tag
|
jsdoc-synonyms.js - Add support for @synonyms tag
|
||||||
Copyright (C) 2023 Strudel contributors - see <https://codeberg.org/uzu/strudel/activity/contributors>
|
Copyright (C) 2023 Strudel contributors - see <https://codeberg.org/uzu/strudel/activity/contributors>
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { closeBrackets } from '@codemirror/autocomplete';
|
import { closeBrackets } from '@codemirror/autocomplete';
|
||||||
export { toggleComment, toggleBlockComment, toggleLineComment, toggleBlockCommentByLine } from '@codemirror/commands';
|
export { toggleComment, toggleBlockComment, toggleLineComment, toggleBlockCommentByLine } from '@codemirror/commands';
|
||||||
// import { search, highlightSelectionMatches } from '@codemirror/search';
|
// import { search, highlightSelectionMatches } from '@codemirror/search';
|
||||||
import { history } from '@codemirror/commands';
|
import { history, indentWithTab } from '@codemirror/commands';
|
||||||
import { javascript } from '@codemirror/lang-javascript';
|
import { javascript } from '@codemirror/lang-javascript';
|
||||||
import { defaultHighlightStyle, syntaxHighlighting, bracketMatching } from '@codemirror/language';
|
import { defaultHighlightStyle, syntaxHighlighting, bracketMatching } from '@codemirror/language';
|
||||||
import { Compartment, EditorState, Prec } from '@codemirror/state';
|
import { Compartment, EditorState, Prec } from '@codemirror/state';
|
||||||
@@ -37,6 +37,14 @@ const extensions = {
|
|||||||
isActiveLineHighlighted: (on) => (on ? [highlightActiveLine(), highlightActiveLineGutter()] : []),
|
isActiveLineHighlighted: (on) => (on ? [highlightActiveLine(), highlightActiveLineGutter()] : []),
|
||||||
isFlashEnabled,
|
isFlashEnabled,
|
||||||
keybindings,
|
keybindings,
|
||||||
|
isTabIndentationEnabled: (on) => (on ? keymap.of([indentWithTab]) : []),
|
||||||
|
isMultiCursorEnabled: (on) =>
|
||||||
|
on
|
||||||
|
? [
|
||||||
|
EditorState.allowMultipleSelections.of(true),
|
||||||
|
EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey),
|
||||||
|
]
|
||||||
|
: [],
|
||||||
};
|
};
|
||||||
const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()]));
|
const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()]));
|
||||||
|
|
||||||
@@ -51,6 +59,8 @@ export const defaultSettings = {
|
|||||||
isFlashEnabled: true,
|
isFlashEnabled: true,
|
||||||
isTooltipEnabled: false,
|
isTooltipEnabled: false,
|
||||||
isLineWrappingEnabled: false,
|
isLineWrappingEnabled: false,
|
||||||
|
isTabIndentationEnabled: false,
|
||||||
|
isMultiCursorEnabled: false,
|
||||||
theme: 'strudelTheme',
|
theme: 'strudelTheme',
|
||||||
fontFamily: 'monospace',
|
fontFamily: 'monospace',
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ const vscodeExtension = (options) => [vscodePlugin].concat(options ?? []);
|
|||||||
const keymaps = {
|
const keymaps = {
|
||||||
vim,
|
vim,
|
||||||
emacs,
|
emacs,
|
||||||
|
codemirror: () => keymap.of(defaultKeymap),
|
||||||
vscode: vscodeExtension,
|
vscode: vscodeExtension,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function keybindings(name) {
|
export function keybindings(name) {
|
||||||
const active = keymaps[name];
|
const active = keymaps[name];
|
||||||
return [keymap.of(defaultKeymap), keymap.of(historyKeymap), active ? active() : []];
|
return [active ? active() : [], keymap.of(historyKeymap)];
|
||||||
// keymap.of(searchKeymap),
|
|
||||||
}
|
}
|
||||||
|
|||||||
+113
-14
@@ -444,6 +444,78 @@ export const { crush } = registerControl('crush');
|
|||||||
*/
|
*/
|
||||||
export const { coarse } = registerControl('coarse');
|
export const { coarse } = registerControl('coarse');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* modulate the amplitude of a sound with a continuous waveform
|
||||||
|
*
|
||||||
|
* @name tremolo
|
||||||
|
* @synonyms trem
|
||||||
|
* @param {number | Pattern} speed modulation speed in HZ
|
||||||
|
* @example
|
||||||
|
* note("d d d# d".fast(4)).s("supersaw").tremolo("<3 2 100> ").tremoloskew("<.5>")
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const { tremolo } = registerControl(['tremolo', 'tremolodepth', 'tremoloskew', 'tremolophase'], 'trem');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* modulate the amplitude of a sound with a continuous waveform
|
||||||
|
*
|
||||||
|
* @name tremolosync
|
||||||
|
* @synonyms tremsync
|
||||||
|
* @param {number | Pattern} cycles modulation speed in cycles
|
||||||
|
* @example
|
||||||
|
* note("d d d# d".fast(4)).s("supersaw").tremolosync("4").tremoloskew("<1 .5 0>")
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const { tremolosync } = registerControl(
|
||||||
|
['tremolosync', 'tremolodepth', 'tremoloskew', 'tremolophase'],
|
||||||
|
'tremsync',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* depth of amplitude modulation
|
||||||
|
*
|
||||||
|
* @name tremolodepth
|
||||||
|
* @synonyms tremdepth
|
||||||
|
* @param {number | Pattern} depth
|
||||||
|
* @example
|
||||||
|
* note("a1 a1 a#1 a1".fast(4)).s("pulse").tremsync(4).tremolodepth("<1 2 .7>")
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const { tremolodepth } = registerControl('tremolodepth', 'tremdepth');
|
||||||
|
/**
|
||||||
|
* alter the shape of the modulation waveform
|
||||||
|
*
|
||||||
|
* @name tremoloskew
|
||||||
|
* @synonyms tremskew
|
||||||
|
* @param {number | Pattern} amount between 0 & 1, the shape of the waveform
|
||||||
|
* @example
|
||||||
|
* note("{f a c e}%16").s("sawtooth").tremsync(4).tremoloskew("<.5 0 1>")
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const { tremoloskew } = registerControl('tremoloskew', 'tremskew');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* alter the phase of the modulation waveform
|
||||||
|
*
|
||||||
|
* @name tremolophase
|
||||||
|
* @synonyms tremphase
|
||||||
|
* @param {number | Pattern} offset the offset in cycles of the modulation
|
||||||
|
* @example
|
||||||
|
* note("{f a c e}%16").s("sawtooth").tremsync(4).tremolophase("<0 .25 .66>")
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const { tremolophase } = registerControl('tremolophase', 'tremphase');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shape of amplitude modulation
|
||||||
|
*
|
||||||
|
* @name tremoloshape
|
||||||
|
* @param {number | Pattern} shape tri | square | sine | saw | ramp
|
||||||
|
* @example
|
||||||
|
* note("{f g c d}%16").tremsync(4).tremoloshape("<sine tri square>").s("sawtooth")
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const { tremoloshape } = registerControl('tremoloshape', 'tremshape');
|
||||||
/**
|
/**
|
||||||
* filter overdrive for supported filter types
|
* filter overdrive for supported filter types
|
||||||
*
|
*
|
||||||
@@ -453,6 +525,30 @@ export const { coarse } = registerControl('coarse');
|
|||||||
* note("{f g g c d a a#}%16".sub(17)).s("supersaw").lpenv(8).lpf(150).lpq(.8).ftype('ladder').drive("<.5 4>")
|
* note("{f g g c d a a#}%16".sub(17)).s("supersaw").lpenv(8).lpf(150).lpq(.8).ftype('ladder').drive("<.5 4>")
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO: SUPRADOUGH implement post orbit "pump" sidechain effect
|
||||||
|
// /**
|
||||||
|
// * modulate the amplitude of an orbit to create a "sidechain" like effect
|
||||||
|
// *
|
||||||
|
// * @name pump
|
||||||
|
// * @param {number | Pattern} speed modulation speed in cycles
|
||||||
|
// * @example
|
||||||
|
// * note("{f g c d}%16").s("sawtooth").pump(".25:.75")
|
||||||
|
// *
|
||||||
|
// */
|
||||||
|
// export const { pump } = registerControl(['pump', 'pumpdepth']);
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * modulate the amplitude of an orbit to create a "sidechain" like effect
|
||||||
|
// *
|
||||||
|
// * @name pumpdepth
|
||||||
|
// * @param {number | Pattern} depth depth of modulation from 0 to 1
|
||||||
|
// * @example
|
||||||
|
// * note("{f g c d}%16").s("sawtooth").pump(".25").depth("<.25 .5 .75 1>")
|
||||||
|
// *
|
||||||
|
// */
|
||||||
|
// export const { pumpdepth } = registerControl('pumpdepth');
|
||||||
|
|
||||||
export const { drive } = registerControl('drive');
|
export const { drive } = registerControl('drive');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -985,15 +1081,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
|
||||||
@@ -1545,18 +1657,6 @@ export const { density } = registerControl('density');
|
|||||||
// ['modwheel'],
|
// ['modwheel'],
|
||||||
export const { expression } = registerControl('expression');
|
export const { expression } = registerControl('expression');
|
||||||
export const { sustainpedal } = registerControl('sustainpedal');
|
export const { sustainpedal } = registerControl('sustainpedal');
|
||||||
/* // TODO: doesn't seem to do anything
|
|
||||||
*
|
|
||||||
* Tremolo Audio DSP effect
|
|
||||||
*
|
|
||||||
* @name tremolodepth
|
|
||||||
* @param {number | Pattern} depth between 0 and 1
|
|
||||||
* @example
|
|
||||||
* n("0,4,7").tremolodepth("<0 .3 .6 .9>").osc()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export const { tremolodepth, tremdp } = registerControl('tremolodepth', 'tremdp');
|
|
||||||
export const { tremolorate, tremr } = registerControl('tremolorate', 'tremr');
|
|
||||||
|
|
||||||
export const { fshift } = registerControl('fshift');
|
export const { fshift } = registerControl('fshift');
|
||||||
export const { fshiftnote } = registerControl('fshiftnote');
|
export const { fshiftnote } = registerControl('fshiftnote');
|
||||||
@@ -1633,7 +1733,6 @@ export const { zmod } = registerControl('zmod');
|
|||||||
// like crush but scaled differently
|
// like crush but scaled differently
|
||||||
export const { zcrush } = registerControl('zcrush');
|
export const { zcrush } = registerControl('zcrush');
|
||||||
export const { zdelay } = registerControl('zdelay');
|
export const { zdelay } = registerControl('zdelay');
|
||||||
export const { tremolo } = registerControl('tremolo');
|
|
||||||
export const { zzfx } = registerControl('zzfx');
|
export const { zzfx } = registerControl('zzfx');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export class Cyclist {
|
|||||||
// the following line is dumb and only here for backwards compatibility
|
// the following line is dumb and only here for backwards compatibility
|
||||||
// see https://codeberg.org/uzu/strudel/pulls/1004
|
// see https://codeberg.org/uzu/strudel/pulls/1004
|
||||||
const deadline = targetTime - phase;
|
const deadline = targetTime - phase;
|
||||||
|
// this onTrigger has another signature
|
||||||
onTrigger?.(hap, deadline, duration, this.cps, targetTime);
|
onTrigger?.(hap, deadline, duration, this.cps, targetTime);
|
||||||
if (hap.value.cps !== undefined && this.cps != hap.value.cps) {
|
if (hap.value.cps !== undefined && this.cps != hap.value.cps) {
|
||||||
this.cps = hap.value.cps;
|
this.cps = hap.value.cps;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ export class NeoCyclist {
|
|||||||
constructor({ onTrigger, onToggle, getTime }) {
|
constructor({ onTrigger, onToggle, getTime }) {
|
||||||
this.started = false;
|
this.started = false;
|
||||||
this.cps = 0.5;
|
this.cps = 0.5;
|
||||||
this.lastTick = 0; // absolute time when last tick (clock callback) happened
|
|
||||||
this.getTime = getTime; // get absolute time
|
this.getTime = getTime; // get absolute time
|
||||||
this.time_at_last_tick_message = 0;
|
this.time_at_last_tick_message = 0;
|
||||||
// the clock of the worker and the audio context clock can drift apart over time
|
// the clock of the worker and the audio context clock can drift apart over time
|
||||||
|
|||||||
@@ -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
|
||||||
|
* @synonyms 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
|
||||||
|
* @synonyms 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',
|
||||||
@@ -2509,7 +2565,7 @@ export const bypass = register(
|
|||||||
* Loops the pattern inside an `offset` for `cycles`.
|
* Loops the pattern inside an `offset` for `cycles`.
|
||||||
* If you think of the entire span of time in cycles as a ribbon, you can cut a single piece and loop it.
|
* If you think of the entire span of time in cycles as a ribbon, you can cut a single piece and loop it.
|
||||||
* @name ribbon
|
* @name ribbon
|
||||||
* @synonym rib
|
* @synonyms rib
|
||||||
* @param {number} offset start point of loop in cycles
|
* @param {number} offset start point of loop in cycles
|
||||||
* @param {number} cycles loop length in cycles
|
* @param {number} cycles loop length in cycles
|
||||||
* @example
|
* @example
|
||||||
@@ -3207,7 +3263,7 @@ export const slice = register(
|
|||||||
* s("bd!8").onTriggerTime((hap) => {console.info(hap)})
|
* s("bd!8").onTriggerTime((hap) => {console.info(hap)})
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.onTriggerTime = function (func) {
|
Pattern.prototype.onTriggerTime = function (func) {
|
||||||
return this.onTrigger((t_deprecate, hap, currentTime, cps = 1, targetTime) => {
|
return this.onTrigger((hap, currentTime, _cps, targetTime) => {
|
||||||
const diff = targetTime - currentTime;
|
const diff = targetTime - currentTime;
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
func(hap);
|
func(hap);
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ export function repl({
|
|||||||
export const getTrigger =
|
export const getTrigger =
|
||||||
({ getTime, defaultOutput }) =>
|
({ getTime, defaultOutput }) =>
|
||||||
async (hap, deadline, duration, cps, t) => {
|
async (hap, deadline, duration, cps, t) => {
|
||||||
|
// ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger)
|
||||||
// TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004
|
// TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004
|
||||||
try {
|
try {
|
||||||
if (!hap.context.onTrigger || !hap.context.dominantTrigger) {
|
if (!hap.context.onTrigger || !hap.context.dominantTrigger) {
|
||||||
@@ -252,7 +253,7 @@ export const getTrigger =
|
|||||||
}
|
}
|
||||||
if (hap.context.onTrigger) {
|
if (hap.context.onTrigger) {
|
||||||
// call signature of output / onTrigger is different...
|
// call signature of output / onTrigger is different...
|
||||||
await hap.context.onTrigger(getTime() + deadline, hap, getTime(), cps, t);
|
await hap.context.onTrigger(hap, getTime(), cps, t);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger(`[cyclist] error: ${err.message}`, 'error');
|
logger(`[cyclist] error: ${err.message}`, 'error');
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ export const randrun = (n) => {
|
|||||||
const rands = timeToRands(t.floor().add(0.5), n);
|
const rands = timeToRands(t.floor().add(0.5), n);
|
||||||
const nums = rands
|
const nums = rands
|
||||||
.map((n, i) => [n, i])
|
.map((n, i) => [n, i])
|
||||||
.sort((a, b) => a[0] > b[0] - a[0] < b[0])
|
.sort((a, b) => (a[0] > b[0]) - (a[0] < b[0]))
|
||||||
.map((x) => x[1]);
|
.map((x) => x[1]);
|
||||||
const i = t.cyclePos().mul(n).floor() % n;
|
const i = t.cyclePos().mul(n).floor() % n;
|
||||||
return nums[i];
|
return nums[i];
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ function triggerSpeech(words, lang, voice) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const speak = register('speak', function (lang, voice, pat) {
|
export const speak = register('speak', function (lang, voice, pat) {
|
||||||
return pat.onTrigger((_, hap) => {
|
return pat.onTrigger((hap) => {
|
||||||
triggerSpeech(hap.value, lang, voice);
|
triggerSpeech(hap.value, lang, voice);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export const csound = register('csound', (instrument, pat) => {
|
|||||||
instrument = instrument || 'triangle';
|
instrument = instrument || 'triangle';
|
||||||
init(); // not async to support csound inside other patterns + to be able to call pattern methods after it
|
init(); // not async to support csound inside other patterns + to be able to call pattern methods after it
|
||||||
// TODO: find a alternative way to wait for csound to load (to wait with first time playback)
|
// TODO: find a alternative way to wait for csound to load (to wait with first time playback)
|
||||||
return pat.onTrigger((time_deprecate, hap, currentTime, _cps, targetTime) => {
|
return pat.onTrigger((hap, currentTime, _cps, targetTime) => {
|
||||||
if (!_csound) {
|
if (!_csound) {
|
||||||
logger('[csound] not loaded yet', 'warning');
|
logger('[csound] not loaded yet', 'warning');
|
||||||
return;
|
return;
|
||||||
@@ -142,7 +142,7 @@ export const csoundm = register('csoundm', (instrument, pat) => {
|
|||||||
p1 = `"${instrument}"`;
|
p1 = `"${instrument}"`;
|
||||||
}
|
}
|
||||||
init(); // not async to support csound inside other patterns + to be able to call pattern methods after it
|
init(); // not async to support csound inside other patterns + to be able to call pattern methods after it
|
||||||
return pat.onTrigger((tidal_time, hap) => {
|
return pat.onTrigger((hap, currentTime, _cps, targetTime) => {
|
||||||
if (!_csound) {
|
if (!_csound) {
|
||||||
logger('[csound] not loaded yet', 'warning');
|
logger('[csound] not loaded yet', 'warning');
|
||||||
return;
|
return;
|
||||||
@@ -151,7 +151,7 @@ export const csoundm = register('csoundm', (instrument, pat) => {
|
|||||||
throw new Error('csound only support objects as hap values');
|
throw new Error('csound only support objects as hap values');
|
||||||
}
|
}
|
||||||
// Time in seconds counting from now.
|
// Time in seconds counting from now.
|
||||||
const p2 = tidal_time - getAudioContext().currentTime;
|
const p2 = targetTime - currentTime;
|
||||||
const p3 = hap.duration.valueOf() + 0;
|
const p3 = hap.duration.valueOf() + 0;
|
||||||
const frequency = getFrequency(hap);
|
const frequency = getFrequency(hap);
|
||||||
let { gain = 1, velocity = 0.9 } = hap.value;
|
let { gain = 1, velocity = 0.9 } = hap.value;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const OFF_MESSAGE = 0x80;
|
|||||||
const CC_MESSAGE = 0xb0;
|
const CC_MESSAGE = 0xb0;
|
||||||
|
|
||||||
Pattern.prototype.midi = function (output) {
|
Pattern.prototype.midi = function (output) {
|
||||||
return this.onTrigger((time_deprecate, hap, currentTime, cps, targetTime) => {
|
return this.onTrigger((hap, currentTime, cps, targetTime) => {
|
||||||
let { note, nrpnn, nrpv, ccn, ccv, velocity = 0.9, gain = 1 } = hap.value;
|
let { note, nrpnn, nrpv, ccn, ccv, velocity = 0.9, gain = 1 } = hap.value;
|
||||||
//magic number to get audio engine to line up, can probably be calculated somehow
|
//magic number to get audio engine to line up, can probably be calculated somehow
|
||||||
const latencyMs = 34;
|
const latencyMs = 34;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Invoke } from './utils.mjs';
|
|||||||
|
|
||||||
const collator = new ClockCollator({});
|
const collator = new ClockCollator({});
|
||||||
|
|
||||||
export async function oscTriggerTauri(t_deprecate, hap, currentTime, cps = 1, targetTime) {
|
export async function oscTriggerTauri(hap, currentTime, cps = 1, targetTime) {
|
||||||
const controls = parseControlsFromHap(hap, cps);
|
const controls = parseControlsFromHap(hap, cps);
|
||||||
const params = [];
|
const params = [];
|
||||||
const timestamp = collator.calculateTimestamp(currentTime, targetTime);
|
const timestamp = collator.calculateTimestamp(currentTime, targetTime);
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ Pattern.prototype.midi = function (midiport, options = {}) {
|
|||||||
logger(`Midi device disconnected! Available: ${getMidiDeviceNamesString(outputs)}`),
|
logger(`Midi device disconnected! Available: ${getMidiDeviceNamesString(outputs)}`),
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.onTrigger((time_deprecate, hap, currentTime, cps, targetTime) => {
|
return this.onTrigger((hap, currentTime, cps, targetTime) => {
|
||||||
if (!WebMidi.enabled) {
|
if (!WebMidi.enabled) {
|
||||||
logger('Midi not enabled');
|
logger('Midi not enabled');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ lib['%'] = pace;
|
|||||||
lib['?'] = degradeBy; // todo: default 0.5 not working..
|
lib['?'] = degradeBy; // todo: default 0.5 not working..
|
||||||
lib[':'] = tail;
|
lib[':'] = tail;
|
||||||
lib['..'] = range;
|
lib['..'] = range;
|
||||||
|
lib['def'] = () => silence;
|
||||||
lib['or'] = (...children) => chooseIn(...children); // always has structure but is cyclewise.. e.g. "s oh*8.dec[.04 | .5]"
|
lib['or'] = (...children) => chooseIn(...children); // always has structure but is cyclewise.. e.g. "s oh*8.dec[.04 | .5]"
|
||||||
//lib['or'] = (...children) => chooseOut(...children); // "s oh*8.dec[.04 | .5]" is better but "dec[.04 | .5].s oh*8" has no struct
|
//lib['or'] = (...children) => chooseOut(...children); // "s oh*8.dec[.04 | .5]" is better but "dec[.04 | .5].s oh*8" has no struct
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export function parseControlsFromHap(hap, cps) {
|
|||||||
|
|
||||||
const collator = new ClockCollator({});
|
const collator = new ClockCollator({});
|
||||||
|
|
||||||
export async function oscTrigger(t_deprecate, hap, currentTime, cps = 1, targetTime) {
|
export async function oscTrigger(hap, currentTime, cps = 1, targetTime) {
|
||||||
const osc = await connect();
|
const osc = await connect();
|
||||||
const controls = parseControlsFromHap(hap, cps);
|
const controls = parseControlsFromHap(hap, cps);
|
||||||
const keyvals = Object.entries(controls).flat();
|
const keyvals = Object.entries(controls).flat();
|
||||||
|
|||||||
@@ -537,7 +537,7 @@ export default {
|
|||||||
],
|
],
|
||||||
gm_synth_bass_1: [
|
gm_synth_bass_1: [
|
||||||
// Synth Bass 1: Bass
|
// Synth Bass 1: Bass
|
||||||
'0380_Aspirin_sf2_file',
|
// '0380_Aspirin_sf2_file', // broken in safari https://codeberg.org/uzu/strudel/issues/1384
|
||||||
'0380_Chaos_sf2_file',
|
'0380_Chaos_sf2_file',
|
||||||
'0380_FluidR3_GM_sf2_file',
|
'0380_FluidR3_GM_sf2_file',
|
||||||
// 0380_GeneralUserGS_sf2_file // laut
|
// 0380_GeneralUserGS_sf2_file // laut
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { getAudioContext, registerSound } from '@strudel/webaudio';
|
|||||||
import { loadSoundfont as _loadSoundfont, startPresetNote } from 'sfumato';
|
import { loadSoundfont as _loadSoundfont, startPresetNote } from 'sfumato';
|
||||||
|
|
||||||
Pattern.prototype.soundfont = function (sf, n = 0) {
|
Pattern.prototype.soundfont = function (sf, n = 0) {
|
||||||
return this.onTrigger((time_deprecate, h, ct, cps, targetTime) => {
|
return this.onTrigger((h, ct, cps, targetTime) => {
|
||||||
const ctx = getAudioContext();
|
const ctx = getAudioContext();
|
||||||
const note = getPlayableNoteValue(h);
|
const note = getPlayableNoteValue(h);
|
||||||
const preset = sf.presets[n % sf.presets.length];
|
const preset = sf.presets[n % sf.presets.length];
|
||||||
|
|||||||
@@ -74,6 +74,6 @@ export const dough = async (code) => {
|
|||||||
worklet.node.connect(ac.destination);
|
worklet.node.connect(ac.destination);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function doughTrigger(time_deprecate, hap, currentTime, cps, targetTime) {
|
export function doughTrigger(hap, currentTime, cps, targetTime) {
|
||||||
window.postMessage({ time: targetTime, dough: hap.value, currentTime, duration: hap.duration, cps });
|
window.postMessage({ time: targetTime, dough: hap.value, currentTime, duration: hap.duration, cps });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, secondsToCycle } 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';
|
||||||
@@ -28,6 +28,13 @@ export function setMultiChannelOrbits(bool) {
|
|||||||
multiChannelOrbits = bool == true;
|
multiChannelOrbits = bool == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getModulationShapeInput(val) {
|
||||||
|
if (typeof val === 'number') {
|
||||||
|
return val % 5;
|
||||||
|
}
|
||||||
|
return { tri: 0, triangle: 0, sine: 1, ramp: 2, saw: 3, square: 4 }[val] ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
export const soundMap = map();
|
export const soundMap = map();
|
||||||
|
|
||||||
export function registerSound(key, onTrigger, data = {}) {
|
export function registerSound(key, onTrigger, data = {}) {
|
||||||
@@ -126,7 +133,7 @@ export const getAudioDevices = async () => {
|
|||||||
return devicesMap;
|
return devicesMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultDefaultValues = {
|
let defaultDefaultValues = {
|
||||||
s: 'triangle',
|
s: 'triangle',
|
||||||
gain: 0.8,
|
gain: 0.8,
|
||||||
postgain: 1,
|
postgain: 1,
|
||||||
@@ -143,13 +150,24 @@ 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,
|
||||||
fft: 8,
|
fft: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const defaultDefaultDefaultValues = Object.freeze({ ...defaultDefaultValues });
|
||||||
|
|
||||||
|
export function setDefault(control, value) {
|
||||||
|
// const main = getControlName(control); // we cant do this because superdough is independent of strudel/core
|
||||||
|
defaultDefaultValues[control] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetDefaults() {
|
||||||
|
defaultDefaultValues = { ...defaultDefaultDefaultValues };
|
||||||
|
}
|
||||||
|
|
||||||
let defaultControls = new Map(Object.entries(defaultDefaultValues));
|
let defaultControls = new Map(Object.entries(defaultDefaultValues));
|
||||||
|
|
||||||
export function setDefaultValue(key, value) {
|
export function setDefaultValue(key, value) {
|
||||||
@@ -325,9 +343,31 @@ function getDelay(orbit, delaytime, delayfeedback, t, channels) {
|
|||||||
return delays[orbit];
|
return delays[orbit];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLfo(audioContext, time, end, properties = {}) {
|
export function getLfo(audioContext, begin, end, properties = {}) {
|
||||||
|
const { shape = 0, ...props } = properties;
|
||||||
|
const { dcoffset = -0.5, depth = 1 } = properties;
|
||||||
return getWorklet(audioContext, 'lfo-processor', {
|
return getWorklet(audioContext, 'lfo-processor', {
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
|
depth,
|
||||||
|
skew: 0,
|
||||||
|
phaseoffset: 0,
|
||||||
|
time: begin,
|
||||||
|
begin,
|
||||||
|
end,
|
||||||
|
shape: getModulationShapeInput(shape),
|
||||||
|
dcoffset,
|
||||||
|
min: dcoffset - depth * 0.5,
|
||||||
|
max: dcoffset + depth * 0.5,
|
||||||
|
curve: 1,
|
||||||
|
...props,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSyncedLfo(audioContext, time, end, cps, cycle, properties = {}) {
|
||||||
|
const frequency = cycle / cps;
|
||||||
|
|
||||||
|
return getWorklet(audioContext, 'lfo-processor', {
|
||||||
|
frequency,
|
||||||
depth: 1,
|
depth: 1,
|
||||||
skew: 0,
|
skew: 0,
|
||||||
phaseoffset: 0,
|
phaseoffset: 0,
|
||||||
@@ -450,9 +490,10 @@ 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, cycle = 0.5) => {
|
||||||
|
// new: t is always expected to be the absolute target onset time
|
||||||
const ac = getAudioContext();
|
const ac = getAudioContext();
|
||||||
t = typeof t === 'string' && t.startsWith('=') ? Number(t.slice(1)) : ac.currentTime + t;
|
|
||||||
let { stretch } = value;
|
let { stretch } = value;
|
||||||
if (stretch != null) {
|
if (stretch != null) {
|
||||||
//account for phase vocoder latency
|
//account for phase vocoder latency
|
||||||
@@ -478,6 +519,12 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
}
|
}
|
||||||
// destructure
|
// destructure
|
||||||
let {
|
let {
|
||||||
|
tremolo,
|
||||||
|
tremolosync,
|
||||||
|
tremolodepth = 1,
|
||||||
|
tremoloskew,
|
||||||
|
tremolophase = 0,
|
||||||
|
tremoloshape,
|
||||||
s = getDefaultValue('s'),
|
s = getDefaultValue('s'),
|
||||||
bank,
|
bank,
|
||||||
source,
|
source,
|
||||||
@@ -487,6 +534,7 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
// filters
|
// filters
|
||||||
fanchor = getDefaultValue('fanchor'),
|
fanchor = getDefaultValue('fanchor'),
|
||||||
drive = 0.69,
|
drive = 0.69,
|
||||||
|
release = 0,
|
||||||
// low pass
|
// low pass
|
||||||
cutoff,
|
cutoff,
|
||||||
lpenv,
|
lpenv,
|
||||||
@@ -519,6 +567,7 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
phasercenter,
|
phasercenter,
|
||||||
//
|
//
|
||||||
coarse,
|
coarse,
|
||||||
|
|
||||||
crush,
|
crush,
|
||||||
shape,
|
shape,
|
||||||
shapevol = getDefaultValue('shapevol'),
|
shapevol = getDefaultValue('shapevol'),
|
||||||
@@ -528,7 +577,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 +597,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'),
|
||||||
);
|
);
|
||||||
@@ -558,8 +610,11 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
distortvol = applyGainCurve(distortvol);
|
distortvol = applyGainCurve(distortvol);
|
||||||
delay = applyGainCurve(delay);
|
delay = applyGainCurve(delay);
|
||||||
velocity = applyGainCurve(velocity);
|
velocity = applyGainCurve(velocity);
|
||||||
|
tremolodepth = applyGainCurve(tremolodepth);
|
||||||
gain *= velocity; // velocity currently only multiplies with gain. it might do other things in the future
|
gain *= velocity; // velocity currently only multiplies with gain. it might do other things in the future
|
||||||
|
|
||||||
|
const end = t + hapDuration;
|
||||||
|
const endWithRelease = end + release;
|
||||||
const chainID = Math.round(Math.random() * 1000000);
|
const chainID = Math.round(Math.random() * 1000000);
|
||||||
|
|
||||||
// oldest audio nodes will be destroyed if maximum polyphony is exceeded
|
// oldest audio nodes will be destroyed if maximum polyphony is exceeded
|
||||||
@@ -634,7 +689,7 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
lprelease,
|
lprelease,
|
||||||
lpenv,
|
lpenv,
|
||||||
t,
|
t,
|
||||||
t + hapDuration,
|
end,
|
||||||
fanchor,
|
fanchor,
|
||||||
ftype,
|
ftype,
|
||||||
drive,
|
drive,
|
||||||
@@ -658,7 +713,7 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
hprelease,
|
hprelease,
|
||||||
hpenv,
|
hpenv,
|
||||||
t,
|
t,
|
||||||
t + hapDuration,
|
end,
|
||||||
fanchor,
|
fanchor,
|
||||||
);
|
);
|
||||||
chain.push(hp());
|
chain.push(hp());
|
||||||
@@ -669,20 +724,7 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
|
|
||||||
if (bandf !== undefined) {
|
if (bandf !== undefined) {
|
||||||
let bp = () =>
|
let bp = () =>
|
||||||
createFilter(
|
createFilter(ac, 'bandpass', bandf, bandq, bpattack, bpdecay, bpsustain, bprelease, bpenv, t, end, fanchor);
|
||||||
ac,
|
|
||||||
'bandpass',
|
|
||||||
bandf,
|
|
||||||
bandq,
|
|
||||||
bpattack,
|
|
||||||
bpdecay,
|
|
||||||
bpsustain,
|
|
||||||
bprelease,
|
|
||||||
bpenv,
|
|
||||||
t,
|
|
||||||
t + hapDuration,
|
|
||||||
fanchor,
|
|
||||||
);
|
|
||||||
chain.push(bp());
|
chain.push(bp());
|
||||||
if (ftype === '24db') {
|
if (ftype === '24db') {
|
||||||
chain.push(bp());
|
chain.push(bp());
|
||||||
@@ -700,6 +742,33 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
shape !== undefined && chain.push(getWorklet(ac, 'shape-processor', { shape, postgain: shapevol }));
|
shape !== undefined && chain.push(getWorklet(ac, 'shape-processor', { shape, postgain: shapevol }));
|
||||||
distort !== undefined && chain.push(getWorklet(ac, 'distort-processor', { distort, postgain: distortvol }));
|
distort !== undefined && chain.push(getWorklet(ac, 'distort-processor', { distort, postgain: distortvol }));
|
||||||
|
|
||||||
|
if (tremolosync != null) {
|
||||||
|
tremolo = cps * tremolosync;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tremolo !== undefined) {
|
||||||
|
// Allow clipping of modulator for more dynamic possiblities, and to prevent speaker overload
|
||||||
|
// EX: a triangle waveform will clip like this /-\ when the depth is above 1
|
||||||
|
const gain = Math.max(1 - tremolodepth, 0);
|
||||||
|
const amGain = new GainNode(ac, { gain });
|
||||||
|
|
||||||
|
const time = cycle / cps;
|
||||||
|
const lfo = getLfo(ac, t, endWithRelease, {
|
||||||
|
skew: tremoloskew ?? (tremoloshape != null ? 0.5 : 1),
|
||||||
|
frequency: tremolo,
|
||||||
|
depth: tremolodepth,
|
||||||
|
time,
|
||||||
|
dcoffset: 0,
|
||||||
|
shape: tremoloshape,
|
||||||
|
phaseoffset: tremolophase,
|
||||||
|
min: 0,
|
||||||
|
max: 1,
|
||||||
|
curve: 1.5,
|
||||||
|
});
|
||||||
|
lfo.connect(amGain.gain);
|
||||||
|
chain.push(amGain);
|
||||||
|
}
|
||||||
|
|
||||||
compressorThreshold !== undefined &&
|
compressorThreshold !== undefined &&
|
||||||
chain.push(
|
chain.push(
|
||||||
getCompressor(ac, compressorThreshold, compressorRatio, compressorKnee, compressorAttack, compressorRelease),
|
getCompressor(ac, compressorThreshold, compressorRatio, compressorKnee, compressorAttack, compressorRelease),
|
||||||
@@ -713,7 +782,7 @@ export const superdough = async (value, t, hapDuration, cps) => {
|
|||||||
}
|
}
|
||||||
// phaser
|
// phaser
|
||||||
if (phaser !== undefined && phaserdepth > 0) {
|
if (phaser !== undefined && phaserdepth > 0) {
|
||||||
const phaserFX = getPhaser(t, t + hapDuration, phaser, phaserdepth, phasercenter, phasersweep);
|
const phaserFX = getPhaser(t, endWithRelease, phaser, phaserdepth, phasercenter, phasersweep);
|
||||||
chain.push(phaserFX);
|
chain.push(phaserFX);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,8 +794,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
|
||||||
|
|||||||
@@ -121,7 +121,10 @@ export function registerSynthSounds() {
|
|||||||
const gainAdjustment = 1 / Math.sqrt(voices);
|
const gainAdjustment = 1 / Math.sqrt(voices);
|
||||||
getPitchEnvelope(o.parameters.get('detune'), value, begin, holdend);
|
getPitchEnvelope(o.parameters.get('detune'), value, begin, holdend);
|
||||||
const vibratoOscillator = getVibratoOscillator(o.parameters.get('detune'), value, begin);
|
const vibratoOscillator = getVibratoOscillator(o.parameters.get('detune'), value, begin);
|
||||||
const fm = applyFM(o.parameters.get('frequency'), value, begin);
|
// const fm = applyFM(o.parameters.get('frequency'), value, begin);
|
||||||
|
// https://codeberg.org/uzu/strudel/issues/1428
|
||||||
|
// if you think about re-enabling this, please test with fm > 1 first
|
||||||
|
// it's like 10x gain, so it's really dangerous
|
||||||
let envGain = gainNode(1);
|
let envGain = gainNode(1);
|
||||||
envGain = o.connect(envGain);
|
envGain = o.connect(envGain);
|
||||||
|
|
||||||
@@ -133,7 +136,7 @@ export function registerSynthSounds() {
|
|||||||
destroyAudioWorkletNode(o);
|
destroyAudioWorkletNode(o);
|
||||||
envGain.disconnect();
|
envGain.disconnect();
|
||||||
onended();
|
onended();
|
||||||
fm?.stop();
|
// fm?.stop();
|
||||||
vibratoOscillator?.stop();
|
vibratoOscillator?.stop();
|
||||||
},
|
},
|
||||||
begin,
|
begin,
|
||||||
|
|||||||
@@ -68,3 +68,11 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function secondsToCycle(t, cps) {
|
||||||
|
return t * cps;
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ function polyBlep(phase, dt) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// The order is important for dough integration
|
||||||
const waveshapes = {
|
const waveshapes = {
|
||||||
tri(phase, skew = 0.5) {
|
tri(phase, skew = 0.5) {
|
||||||
const x = 1 - skew;
|
const x = 1 - skew;
|
||||||
@@ -85,6 +85,7 @@ const waveShapeNames = Object.keys(waveshapes);
|
|||||||
class LFOProcessor extends AudioWorkletProcessor {
|
class LFOProcessor extends AudioWorkletProcessor {
|
||||||
static get parameterDescriptors() {
|
static get parameterDescriptors() {
|
||||||
return [
|
return [
|
||||||
|
{ name: 'begin', defaultValue: 0 },
|
||||||
{ name: 'time', defaultValue: 0 },
|
{ name: 'time', defaultValue: 0 },
|
||||||
{ name: 'end', defaultValue: 0 },
|
{ name: 'end', defaultValue: 0 },
|
||||||
{ name: 'frequency', defaultValue: 0.5 },
|
{ name: 'frequency', defaultValue: 0.5 },
|
||||||
@@ -92,7 +93,10 @@ class LFOProcessor extends AudioWorkletProcessor {
|
|||||||
{ name: 'depth', defaultValue: 1 },
|
{ name: 'depth', defaultValue: 1 },
|
||||||
{ name: 'phaseoffset', defaultValue: 0 },
|
{ name: 'phaseoffset', defaultValue: 0 },
|
||||||
{ name: 'shape', defaultValue: 0 },
|
{ name: 'shape', defaultValue: 0 },
|
||||||
|
{ name: 'curve', defaultValue: 1 },
|
||||||
{ name: 'dcoffset', defaultValue: 0 },
|
{ name: 'dcoffset', defaultValue: 0 },
|
||||||
|
{ name: 'min', defaultValue: 0 },
|
||||||
|
{ name: 'max', defaultValue: 1 },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,10 +113,14 @@ class LFOProcessor extends AudioWorkletProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
process(inputs, outputs, parameters) {
|
process(inputs, outputs, parameters) {
|
||||||
|
const begin = parameters['begin'][0];
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
if (currentTime >= parameters.end[0]) {
|
if (currentTime >= parameters.end[0]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (currentTime <= begin) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const output = outputs[0];
|
const output = outputs[0];
|
||||||
const frequency = parameters['frequency'][0];
|
const frequency = parameters['frequency'][0];
|
||||||
@@ -121,6 +129,9 @@ class LFOProcessor extends AudioWorkletProcessor {
|
|||||||
const depth = parameters['depth'][0];
|
const depth = parameters['depth'][0];
|
||||||
const skew = parameters['skew'][0];
|
const skew = parameters['skew'][0];
|
||||||
const phaseoffset = parameters['phaseoffset'][0];
|
const phaseoffset = parameters['phaseoffset'][0];
|
||||||
|
const min = parameters['min'][0];
|
||||||
|
const max = parameters['max'][0];
|
||||||
|
const curve = parameters['curve'][0];
|
||||||
|
|
||||||
const dcoffset = parameters['dcoffset'][0];
|
const dcoffset = parameters['dcoffset'][0];
|
||||||
const shape = waveShapeNames[parameters['shape'][0]];
|
const shape = waveShapeNames[parameters['shape'][0]];
|
||||||
@@ -135,7 +146,7 @@ class LFOProcessor extends AudioWorkletProcessor {
|
|||||||
for (let n = 0; n < blockSize; n++) {
|
for (let n = 0; n < blockSize; n++) {
|
||||||
for (let i = 0; i < output.length; i++) {
|
for (let i = 0; i < output.length; i++) {
|
||||||
const modval = (waveshapes[shape](this.phase, skew) + dcoffset) * depth;
|
const modval = (waveshapes[shape](this.phase, skew) + dcoffset) * depth;
|
||||||
output[i][n] = modval;
|
output[i][n] = clamp(Math.pow(modval, curve), min, max);
|
||||||
}
|
}
|
||||||
this.incrementPhase(dt);
|
this.incrementPhase(dt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,13 +15,10 @@ const hap2value = (hap) => {
|
|||||||
return hap.value;
|
return hap.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
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://github.com/tidalcycles/strudel/pull/1004
|
||||||
// uses more precise, absolute t if available, see https://codeberg.org/uzu/strudel/pulls/1004
|
// TODO: refactor output callbacks to eliminate deadline
|
||||||
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, hapDuration, cps, hap.whole?.begin.valueOf());
|
||||||
|
|
||||||
Pattern.prototype.webaudio = function () {
|
|
||||||
return this.onTrigger(webaudioOutputTrigger);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function webaudioRepl(options = {}) {
|
export function webaudioRepl(options = {}) {
|
||||||
|
|||||||
@@ -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 ]",
|
||||||
@@ -8682,46 +8813,46 @@ exports[`runs examples > example "shrink" example index 3 1`] = `
|
|||||||
|
|
||||||
exports[`runs examples > example "shuffle" example index 0 1`] = `
|
exports[`runs examples > example "shuffle" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/4 | note:c s:piano ]",
|
"[ 0/1 → 1/4 | note:e s:piano ]",
|
||||||
"[ 1/4 → 1/2 | note:d s:piano ]",
|
"[ 1/4 → 1/2 | note:d s:piano ]",
|
||||||
"[ 1/2 → 3/4 | note:e s:piano ]",
|
"[ 1/2 → 3/4 | note:f s:piano ]",
|
||||||
"[ 3/4 → 1/1 | note:f s:piano ]",
|
"[ 3/4 → 1/1 | note:c s:piano ]",
|
||||||
"[ 1/1 → 5/4 | note:c s:piano ]",
|
"[ 1/1 → 5/4 | note:e s:piano ]",
|
||||||
"[ 5/4 → 3/2 | note:d s:piano ]",
|
"[ 5/4 → 3/2 | note:c s:piano ]",
|
||||||
"[ 3/2 → 7/4 | note:e s:piano ]",
|
"[ 3/2 → 7/4 | note:f s:piano ]",
|
||||||
"[ 7/4 → 2/1 | note:f s:piano ]",
|
"[ 7/4 → 2/1 | note:d s:piano ]",
|
||||||
"[ 2/1 → 9/4 | note:c s:piano ]",
|
"[ 2/1 → 9/4 | note:d s:piano ]",
|
||||||
"[ 9/4 → 5/2 | note:d s:piano ]",
|
"[ 9/4 → 5/2 | note:c s:piano ]",
|
||||||
"[ 5/2 → 11/4 | note:e s:piano ]",
|
"[ 5/2 → 11/4 | note:e s:piano ]",
|
||||||
"[ 11/4 → 3/1 | note:f s:piano ]",
|
"[ 11/4 → 3/1 | note:f s:piano ]",
|
||||||
"[ 3/1 → 13/4 | note:c s:piano ]",
|
"[ 3/1 → 13/4 | note:c s:piano ]",
|
||||||
"[ 13/4 → 7/2 | note:d s:piano ]",
|
"[ 13/4 → 7/2 | note:e s:piano ]",
|
||||||
"[ 7/2 → 15/4 | note:e s:piano ]",
|
"[ 7/2 → 15/4 | note:f s:piano ]",
|
||||||
"[ 15/4 → 4/1 | note:f s:piano ]",
|
"[ 15/4 → 4/1 | note:d s:piano ]",
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "shuffle" example index 1 1`] = `
|
exports[`runs examples > example "shuffle" example index 1 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/8 | note:c s:piano ]",
|
"[ 0/1 → 1/8 | note:e s:piano ]",
|
||||||
"[ 1/8 → 1/4 | note:d s:piano ]",
|
"[ 1/8 → 1/4 | note:d s:piano ]",
|
||||||
"[ 1/4 → 3/8 | note:e s:piano ]",
|
"[ 1/4 → 3/8 | note:f s:piano ]",
|
||||||
"[ 3/8 → 1/2 | note:f s:piano ]",
|
"[ 3/8 → 1/2 | note:c s:piano ]",
|
||||||
"[ 1/2 → 1/1 | note:g s:piano ]",
|
"[ 1/2 → 1/1 | note:g s:piano ]",
|
||||||
"[ 1/1 → 9/8 | note:c s:piano ]",
|
"[ 1/1 → 9/8 | note:e s:piano ]",
|
||||||
"[ 9/8 → 5/4 | note:d s:piano ]",
|
"[ 9/8 → 5/4 | note:c s:piano ]",
|
||||||
"[ 5/4 → 11/8 | note:e s:piano ]",
|
"[ 5/4 → 11/8 | note:f s:piano ]",
|
||||||
"[ 11/8 → 3/2 | note:f s:piano ]",
|
"[ 11/8 → 3/2 | note:d s:piano ]",
|
||||||
"[ 3/2 → 2/1 | note:g s:piano ]",
|
"[ 3/2 → 2/1 | note:g s:piano ]",
|
||||||
"[ 2/1 → 17/8 | note:c s:piano ]",
|
"[ 2/1 → 17/8 | note:d s:piano ]",
|
||||||
"[ 17/8 → 9/4 | note:d s:piano ]",
|
"[ 17/8 → 9/4 | note:c s:piano ]",
|
||||||
"[ 9/4 → 19/8 | note:e s:piano ]",
|
"[ 9/4 → 19/8 | note:e s:piano ]",
|
||||||
"[ 19/8 → 5/2 | note:f s:piano ]",
|
"[ 19/8 → 5/2 | note:f s:piano ]",
|
||||||
"[ 5/2 → 3/1 | note:g s:piano ]",
|
"[ 5/2 → 3/1 | note:g s:piano ]",
|
||||||
"[ 3/1 → 25/8 | note:c s:piano ]",
|
"[ 3/1 → 25/8 | note:c s:piano ]",
|
||||||
"[ 25/8 → 13/4 | note:d s:piano ]",
|
"[ 25/8 → 13/4 | note:e s:piano ]",
|
||||||
"[ 13/4 → 27/8 | note:e s:piano ]",
|
"[ 13/4 → 27/8 | note:f s:piano ]",
|
||||||
"[ 27/8 → 7/2 | note:f s:piano ]",
|
"[ 27/8 → 7/2 | note:d s:piano ]",
|
||||||
"[ 7/2 → 4/1 | note:g s:piano ]",
|
"[ 7/2 → 4/1 | note:g s:piano ]",
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
@@ -9979,6 +10110,420 @@ exports[`runs examples > example "transpose" example index 1 1`] = `
|
|||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "tremolo" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/16 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/16 → 1/8 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/8 → 3/16 | note:d# s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 3/16 → 1/4 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/4 → 5/16 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 5/16 → 3/8 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 3/8 → 7/16 | note:d# s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 7/16 → 1/2 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/2 → 9/16 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 9/16 → 5/8 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 5/8 → 11/16 | note:d# s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 11/16 → 3/4 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 3/4 → 13/16 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 13/16 → 7/8 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 7/8 → 15/16 | note:d# s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 15/16 → 1/1 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/1 → 17/16 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 17/16 → 9/8 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 9/8 → 19/16 | note:d# s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 19/16 → 5/4 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 5/4 → 21/16 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 21/16 → 11/8 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 11/8 → 23/16 | note:d# s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 23/16 → 3/2 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 3/2 → 25/16 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 25/16 → 13/8 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 13/8 → 27/16 | note:d# s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 27/16 → 7/4 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 7/4 → 29/16 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 29/16 → 15/8 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 15/8 → 31/16 | note:d# s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 31/16 → 2/1 | note:d s:supersaw tremolo:2 tremoloskew:0.5 ]",
|
||||||
|
"[ 2/1 → 33/16 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 33/16 → 17/8 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 17/8 → 35/16 | note:d# s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 35/16 → 9/4 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 9/4 → 37/16 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 37/16 → 19/8 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 19/8 → 39/16 | note:d# s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 39/16 → 5/2 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 5/2 → 41/16 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 41/16 → 21/8 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 21/8 → 43/16 | note:d# s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 43/16 → 11/4 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 11/4 → 45/16 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 45/16 → 23/8 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 23/8 → 47/16 | note:d# s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 47/16 → 3/1 | note:d s:supersaw tremolo:100 tremoloskew:0.5 ]",
|
||||||
|
"[ 3/1 → 49/16 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 49/16 → 25/8 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 25/8 → 51/16 | note:d# s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 51/16 → 13/4 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 13/4 → 53/16 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 53/16 → 27/8 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 27/8 → 55/16 | note:d# s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 55/16 → 7/2 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 7/2 → 57/16 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 57/16 → 29/8 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 29/8 → 59/16 | note:d# s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 59/16 → 15/4 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 15/4 → 61/16 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 61/16 → 31/8 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 31/8 → 63/16 | note:d# s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
"[ 63/16 → 4/1 | note:d s:supersaw tremolo:3 tremoloskew:0.5 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "tremolodepth" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/16 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 1/16 → 1/8 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 1/8 → 3/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 3/16 → 1/4 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 1/4 → 5/16 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 5/16 → 3/8 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 3/8 → 7/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 7/16 → 1/2 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 1/2 → 9/16 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 9/16 → 5/8 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 5/8 → 11/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 11/16 → 3/4 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 3/4 → 13/16 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 13/16 → 7/8 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 7/8 → 15/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 15/16 → 1/1 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 1/1 → 17/16 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 17/16 → 9/8 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 9/8 → 19/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 19/16 → 5/4 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 5/4 → 21/16 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 21/16 → 11/8 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 11/8 → 23/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 23/16 → 3/2 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 3/2 → 25/16 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 25/16 → 13/8 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 13/8 → 27/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 27/16 → 7/4 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 7/4 → 29/16 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 29/16 → 15/8 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 15/8 → 31/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 31/16 → 2/1 | note:a1 s:pulse tremolosync:4 tremolodepth:2 ]",
|
||||||
|
"[ 2/1 → 33/16 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 33/16 → 17/8 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 17/8 → 35/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 35/16 → 9/4 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 9/4 → 37/16 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 37/16 → 19/8 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 19/8 → 39/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 39/16 → 5/2 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 5/2 → 41/16 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 41/16 → 21/8 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 21/8 → 43/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 43/16 → 11/4 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 11/4 → 45/16 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 45/16 → 23/8 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 23/8 → 47/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 47/16 → 3/1 | note:a1 s:pulse tremolosync:4 tremolodepth:0.7 ]",
|
||||||
|
"[ 3/1 → 49/16 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 49/16 → 25/8 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 25/8 → 51/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 51/16 → 13/4 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 13/4 → 53/16 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 53/16 → 27/8 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 27/8 → 55/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 55/16 → 7/2 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 7/2 → 57/16 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 57/16 → 29/8 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 29/8 → 59/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 59/16 → 15/4 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 15/4 → 61/16 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 61/16 → 31/8 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 31/8 → 63/16 | note:a#1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
"[ 63/16 → 4/1 | note:a1 s:pulse tremolosync:4 tremolodepth:1 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "tremolophase" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/16 | note:f s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 1/16 → 1/8 | note:a s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 1/8 → 3/16 | note:c s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 3/16 → 1/4 | note:e s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 1/4 → 5/16 | note:f s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 5/16 → 3/8 | note:a s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 3/8 → 7/16 | note:c s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 7/16 → 1/2 | note:e s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 1/2 → 9/16 | note:f s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 9/16 → 5/8 | note:a s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 5/8 → 11/16 | note:c s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 11/16 → 3/4 | note:e s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 3/4 → 13/16 | note:f s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 13/16 → 7/8 | note:a s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 7/8 → 15/16 | note:c s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 15/16 → 1/1 | note:e s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 1/1 → 17/16 | note:f s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 17/16 → 9/8 | note:a s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 9/8 → 19/16 | note:c s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 19/16 → 5/4 | note:e s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 5/4 → 21/16 | note:f s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 21/16 → 11/8 | note:a s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 11/8 → 23/16 | note:c s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 23/16 → 3/2 | note:e s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 3/2 → 25/16 | note:f s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 25/16 → 13/8 | note:a s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 13/8 → 27/16 | note:c s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 27/16 → 7/4 | note:e s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 7/4 → 29/16 | note:f s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 29/16 → 15/8 | note:a s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 15/8 → 31/16 | note:c s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 31/16 → 2/1 | note:e s:sawtooth tremolosync:4 tremolophase:0.25 ]",
|
||||||
|
"[ 2/1 → 33/16 | note:f s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 33/16 → 17/8 | note:a s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 17/8 → 35/16 | note:c s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 35/16 → 9/4 | note:e s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 9/4 → 37/16 | note:f s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 37/16 → 19/8 | note:a s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 19/8 → 39/16 | note:c s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 39/16 → 5/2 | note:e s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 5/2 → 41/16 | note:f s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 41/16 → 21/8 | note:a s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 21/8 → 43/16 | note:c s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 43/16 → 11/4 | note:e s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 11/4 → 45/16 | note:f s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 45/16 → 23/8 | note:a s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 23/8 → 47/16 | note:c s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 47/16 → 3/1 | note:e s:sawtooth tremolosync:4 tremolophase:0.66 ]",
|
||||||
|
"[ 3/1 → 49/16 | note:f s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 49/16 → 25/8 | note:a s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 25/8 → 51/16 | note:c s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 51/16 → 13/4 | note:e s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 13/4 → 53/16 | note:f s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 53/16 → 27/8 | note:a s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 27/8 → 55/16 | note:c s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 55/16 → 7/2 | note:e s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 7/2 → 57/16 | note:f s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 57/16 → 29/8 | note:a s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 29/8 → 59/16 | note:c s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 59/16 → 15/4 | note:e s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 15/4 → 61/16 | note:f s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 61/16 → 31/8 | note:a s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 31/8 → 63/16 | note:c s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
"[ 63/16 → 4/1 | note:e s:sawtooth tremolosync:4 tremolophase:0 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "tremoloshape" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/16 | note:f tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 1/16 → 1/8 | note:g tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 1/8 → 3/16 | note:c tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 3/16 → 1/4 | note:d tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 1/4 → 5/16 | note:f tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 5/16 → 3/8 | note:g tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 3/8 → 7/16 | note:c tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 7/16 → 1/2 | note:d tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 1/2 → 9/16 | note:f tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 9/16 → 5/8 | note:g tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 5/8 → 11/16 | note:c tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 11/16 → 3/4 | note:d tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 3/4 → 13/16 | note:f tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 13/16 → 7/8 | note:g tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 7/8 → 15/16 | note:c tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 15/16 → 1/1 | note:d tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 1/1 → 17/16 | note:f tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 17/16 → 9/8 | note:g tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 9/8 → 19/16 | note:c tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 19/16 → 5/4 | note:d tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 5/4 → 21/16 | note:f tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 21/16 → 11/8 | note:g tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 11/8 → 23/16 | note:c tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 23/16 → 3/2 | note:d tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 3/2 → 25/16 | note:f tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 25/16 → 13/8 | note:g tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 13/8 → 27/16 | note:c tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 27/16 → 7/4 | note:d tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 7/4 → 29/16 | note:f tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 29/16 → 15/8 | note:g tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 15/8 → 31/16 | note:c tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 31/16 → 2/1 | note:d tremolosync:4 tremoloshape:tri s:sawtooth ]",
|
||||||
|
"[ 2/1 → 33/16 | note:f tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 33/16 → 17/8 | note:g tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 17/8 → 35/16 | note:c tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 35/16 → 9/4 | note:d tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 9/4 → 37/16 | note:f tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 37/16 → 19/8 | note:g tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 19/8 → 39/16 | note:c tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 39/16 → 5/2 | note:d tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 5/2 → 41/16 | note:f tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 41/16 → 21/8 | note:g tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 21/8 → 43/16 | note:c tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 43/16 → 11/4 | note:d tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 11/4 → 45/16 | note:f tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 45/16 → 23/8 | note:g tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 23/8 → 47/16 | note:c tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 47/16 → 3/1 | note:d tremolosync:4 tremoloshape:square s:sawtooth ]",
|
||||||
|
"[ 3/1 → 49/16 | note:f tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 49/16 → 25/8 | note:g tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 25/8 → 51/16 | note:c tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 51/16 → 13/4 | note:d tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 13/4 → 53/16 | note:f tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 53/16 → 27/8 | note:g tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 27/8 → 55/16 | note:c tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 55/16 → 7/2 | note:d tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 7/2 → 57/16 | note:f tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 57/16 → 29/8 | note:g tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 29/8 → 59/16 | note:c tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 59/16 → 15/4 | note:d tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 15/4 → 61/16 | note:f tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 61/16 → 31/8 | note:g tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 31/8 → 63/16 | note:c tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
"[ 63/16 → 4/1 | note:d tremolosync:4 tremoloshape:sine s:sawtooth ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "tremoloskew" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/16 → 1/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/8 → 3/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 3/16 → 1/4 | note:e s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/4 → 5/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 5/16 → 3/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 3/8 → 7/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 7/16 → 1/2 | note:e s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/2 → 9/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 9/16 → 5/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 5/8 → 11/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 11/16 → 3/4 | note:e s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 3/4 → 13/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 13/16 → 7/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 7/8 → 15/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 15/16 → 1/1 | note:e s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 1/1 → 17/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 17/16 → 9/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 9/8 → 19/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 19/16 → 5/4 | note:e s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 5/4 → 21/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 21/16 → 11/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 11/8 → 23/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 23/16 → 3/2 | note:e s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 3/2 → 25/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 25/16 → 13/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 13/8 → 27/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 27/16 → 7/4 | note:e s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 7/4 → 29/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 29/16 → 15/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 15/8 → 31/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 31/16 → 2/1 | note:e s:sawtooth tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 2/1 → 33/16 | note:f s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 33/16 → 17/8 | note:a s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 17/8 → 35/16 | note:c s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 35/16 → 9/4 | note:e s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 9/4 → 37/16 | note:f s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 37/16 → 19/8 | note:a s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 19/8 → 39/16 | note:c s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 39/16 → 5/2 | note:e s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 5/2 → 41/16 | note:f s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 41/16 → 21/8 | note:a s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 21/8 → 43/16 | note:c s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 43/16 → 11/4 | note:e s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 11/4 → 45/16 | note:f s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 45/16 → 23/8 | note:a s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 23/8 → 47/16 | note:c s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 47/16 → 3/1 | note:e s:sawtooth tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 3/1 → 49/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 49/16 → 25/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 25/8 → 51/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 51/16 → 13/4 | note:e s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 13/4 → 53/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 53/16 → 27/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 27/8 → 55/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 55/16 → 7/2 | note:e s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 7/2 → 57/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 57/16 → 29/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 29/8 → 59/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 59/16 → 15/4 | note:e s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 15/4 → 61/16 | note:f s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 61/16 → 31/8 | note:a s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 31/8 → 63/16 | note:c s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 63/16 → 4/1 | note:e s:sawtooth tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "tremolosync" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/16 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 1/16 → 1/8 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 1/8 → 3/16 | note:d# s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 3/16 → 1/4 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 1/4 → 5/16 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 5/16 → 3/8 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 3/8 → 7/16 | note:d# s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 7/16 → 1/2 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 1/2 → 9/16 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 9/16 → 5/8 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 5/8 → 11/16 | note:d# s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 11/16 → 3/4 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 3/4 → 13/16 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 13/16 → 7/8 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 7/8 → 15/16 | note:d# s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 15/16 → 1/1 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 1/1 → 17/16 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 17/16 → 9/8 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 9/8 → 19/16 | note:d# s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 19/16 → 5/4 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 5/4 → 21/16 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 21/16 → 11/8 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 11/8 → 23/16 | note:d# s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 23/16 → 3/2 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 3/2 → 25/16 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 25/16 → 13/8 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 13/8 → 27/16 | note:d# s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 27/16 → 7/4 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 7/4 → 29/16 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 29/16 → 15/8 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 15/8 → 31/16 | note:d# s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 31/16 → 2/1 | note:d s:supersaw tremolosync:4 tremoloskew:0.5 ]",
|
||||||
|
"[ 2/1 → 33/16 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 33/16 → 17/8 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 17/8 → 35/16 | note:d# s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 35/16 → 9/4 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 9/4 → 37/16 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 37/16 → 19/8 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 19/8 → 39/16 | note:d# s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 39/16 → 5/2 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 5/2 → 41/16 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 41/16 → 21/8 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 21/8 → 43/16 | note:d# s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 43/16 → 11/4 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 11/4 → 45/16 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 45/16 → 23/8 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 23/8 → 47/16 | note:d# s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 47/16 → 3/1 | note:d s:supersaw tremolosync:4 tremoloskew:0 ]",
|
||||||
|
"[ 3/1 → 49/16 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 49/16 → 25/8 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 25/8 → 51/16 | note:d# s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 51/16 → 13/4 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 13/4 → 53/16 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 53/16 → 27/8 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 27/8 → 55/16 | note:d# s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 55/16 → 7/2 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 7/2 → 57/16 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 57/16 → 29/8 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 29/8 → 59/16 | note:d# s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 59/16 → 15/4 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 15/4 → 61/16 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 61/16 → 31/8 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 31/8 → 63/16 | note:d# s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
"[ 63/16 → 4/1 | note:d s:supersaw tremolosync:4 tremoloskew:1 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "tri" example index 0 1`] = `
|
exports[`runs examples > example "tri" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/8 | note:C3 ]",
|
"[ 0/1 → 1/8 | note:C3 ]",
|
||||||
|
|||||||
@@ -359,28 +359,6 @@ stack(
|
|||||||
"[~ [0 ~]] 0 [~ [4 ~]] 4".sub(7).restart(scales).scale(scales).early(.25)
|
"[~ [0 ~]] 0 [~ [4 ~]] 4".sub(7).restart(scales).scale(scales).early(.25)
|
||||||
).note().piano().slow(2)`;
|
).note().piano().slow(2)`;
|
||||||
|
|
||||||
/*
|
|
||||||
export const customTrigger = `// licensed with CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
||||||
// by Felix Roos
|
|
||||||
stack(
|
|
||||||
freq("55 [110,165] 110 [220,275]".mul("<1 <3/4 2/3>>").struct("x(3,8)").layer(x=>x.mul("1.006,.995"))),
|
|
||||||
freq("440(5,8)".clip(.18).mul("<1 3/4 2 2/3>")).gain(perlin.range(.2,.8))
|
|
||||||
).s("<sawtooth square>/2")
|
|
||||||
.onTrigger((t,hap,ct)=>{
|
|
||||||
const ac = Tone.getContext().rawContext;
|
|
||||||
t = ac.currentTime + t - ct;
|
|
||||||
const { freq, s, gain = 1 } = hap.value;
|
|
||||||
const master = ac.createGain();
|
|
||||||
master.gain.value = 0.1 * gain;
|
|
||||||
master.connect(ac.destination);
|
|
||||||
const o = ac.createOscillator();
|
|
||||||
o.type = s || 'triangle';
|
|
||||||
o.frequency.value = Number(freq);
|
|
||||||
o.connect(master);
|
|
||||||
o.start(t);
|
|
||||||
o.stop(t + hap.duration);
|
|
||||||
}).stack(s("bd(3,8),hh*4,~ sd").webdirt())`; */
|
|
||||||
|
|
||||||
export const swimmingWithSoundfonts = `// Koji Kondo - Swimming (Super Mario World)
|
export const swimmingWithSoundfonts = `// Koji Kondo - Swimming (Super Mario World)
|
||||||
stack(
|
stack(
|
||||||
n(
|
n(
|
||||||
|
|||||||
@@ -647,7 +647,6 @@
|
|||||||
"evaluate"
|
"evaluate"
|
||||||
],
|
],
|
||||||
"/packages/webaudio/webaudio.mjs": [
|
"/packages/webaudio/webaudio.mjs": [
|
||||||
"webaudioOutputTrigger",
|
|
||||||
"webaudioOutput",
|
"webaudioOutput",
|
||||||
"webaudioRepl"
|
"webaudioRepl"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ Diese Kombinationen von Buchstaben stehen für verschiedene Teile eines Schlagze
|
|||||||
- `mt` = **m**iddle tom
|
- `mt` = **m**iddle tom
|
||||||
- `ht` = **h**igh tom
|
- `ht` = **h**igh tom
|
||||||
- `rd` = **r**i**d**e cymbal
|
- `rd` = **r**i**d**e cymbal
|
||||||
- `rd` = **cr**ash cymbal
|
- `cr` = **cr**ash cymbal
|
||||||
|
|
||||||
Probier verschiedene Sounds aus!
|
Probier verschiedene Sounds aus!
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,34 @@ Each filter has 2 parameters:
|
|||||||
|
|
||||||
<JsDoc client:idle name="vowel" h={0} />
|
<JsDoc client:idle name="vowel" h={0} />
|
||||||
|
|
||||||
|
# Amplitude Modulation
|
||||||
|
|
||||||
|
Amplitude modulation changes the amplitude (gain) periodically over time.
|
||||||
|
|
||||||
|
## am
|
||||||
|
|
||||||
|
<JsDoc client:idle name="am" h={0} />
|
||||||
|
|
||||||
|
## tremolosync
|
||||||
|
|
||||||
|
<JsDoc client:idle name="tremolosync" h={0} />
|
||||||
|
|
||||||
|
## tremolodepth
|
||||||
|
|
||||||
|
<JsDoc client:idle name="tremolodepth" h={0} />
|
||||||
|
|
||||||
|
## tremoloskew
|
||||||
|
|
||||||
|
<JsDoc client:idle name="tremoloskew" h={0} />
|
||||||
|
|
||||||
|
## tremolophase
|
||||||
|
|
||||||
|
<JsDoc client:idle name="tremolophase" h={0} />
|
||||||
|
|
||||||
|
## tremoloshape
|
||||||
|
|
||||||
|
<JsDoc client:idle name="tremoloshape" h={0} />
|
||||||
|
|
||||||
# Amplitude Envelope
|
# Amplitude Envelope
|
||||||
|
|
||||||
The amplitude [envelope](<https://en.wikipedia.org/wiki/Envelope_(music)>) controls the dynamic contour of a sound.
|
The amplitude [envelope](<https://en.wikipedia.org/wiki/Envelope_(music)>) controls the dynamic contour of a sound.
|
||||||
|
|||||||
@@ -176,3 +176,16 @@ $ chord <Dm9!3 Db7> # voicing
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
The `$` sign is an alias for `,` so it will create a stack behind the scenes.
|
The `$` sign is an alias for `,` so it will create a stack behind the scenes.
|
||||||
|
|
||||||
|
## variables
|
||||||
|
|
||||||
|
using the `def` keyword, you can define variables:
|
||||||
|
|
||||||
|
<MiniRepl
|
||||||
|
client:idle
|
||||||
|
mondo
|
||||||
|
tune={`
|
||||||
|
$ def melody [0 1 2 3]
|
||||||
|
$ n melody # scale C:minor
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
|||||||
@@ -163,6 +163,21 @@ The last section could be written as:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Please note that browsers will often cache `strudel.json` on first load, and keep using the cached
|
||||||
|
version even if the orginal has been updated. If this bites you (for example while developing a new
|
||||||
|
sample pack), you can force the browser to download a new copy by i.e. changing capitalization of one
|
||||||
|
character in the URL, or adding a URL attribute, such as:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
samples('https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/strudel.json?version=2');
|
||||||
|
```
|
||||||
|
|
||||||
|
that gets ignored by GitHub (but changes the URL, forcing the browser to reload every time we increase
|
||||||
|
the version number).
|
||||||
|
|
||||||
|
It is also possible, of course, to just remove it from cache (deleting cache in browser Privacy settings,
|
||||||
|
or from the dev console if you're technically minded, or by using a cache deleting extension).
|
||||||
|
|
||||||
## Github Shortcut
|
## Github Shortcut
|
||||||
|
|
||||||
Because loading samples from github is common, there is a shortcut:
|
Because loading samples from github is common, there is a shortcut:
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ Or using 2 beats per cycle:
|
|||||||
s("bd sd, hh*4")`}
|
s("bd sd, hh*4")`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
You can use the `setcps` method to set the global tempo in cycles per second. `setcpm(x)` is the same as `setcps(x / 60)`.
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
|
|
||||||
To set a specific bpm, use `setcpm(bpm/bpc)`
|
To set a specific bpm, use `setcpm(bpm/bpc)`
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ export function SettingsTab({ started }) {
|
|||||||
togglePanelTrigger,
|
togglePanelTrigger,
|
||||||
maxPolyphony,
|
maxPolyphony,
|
||||||
multiChannelOrbits,
|
multiChannelOrbits,
|
||||||
|
isTabIndentationEnabled,
|
||||||
|
isMultiCursorEnabled,
|
||||||
} = useSettings();
|
} = useSettings();
|
||||||
const shouldAlwaysSync = isUdels();
|
const shouldAlwaysSync = isUdels();
|
||||||
const canChangeAudioDevice = AudioContext.prototype.setSinkId != null;
|
const canChangeAudioDevice = AudioContext.prototype.setSinkId != null;
|
||||||
@@ -262,6 +264,16 @@ export function SettingsTab({ started }) {
|
|||||||
onChange={(cbEvent) => settingsMap.setKey('isLineWrappingEnabled', cbEvent.target.checked)}
|
onChange={(cbEvent) => settingsMap.setKey('isLineWrappingEnabled', cbEvent.target.checked)}
|
||||||
value={isLineWrappingEnabled}
|
value={isLineWrappingEnabled}
|
||||||
/>
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label="Enable Tab indentation"
|
||||||
|
onChange={(cbEvent) => settingsMap.setKey('isTabIndentationEnabled', cbEvent.target.checked)}
|
||||||
|
value={isTabIndentationEnabled}
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label="Enable Multi-Cursor (Cmd/Ctrl+Click)"
|
||||||
|
onChange={(cbEvent) => settingsMap.setKey('isMultiCursorEnabled', cbEvent.target.checked)}
|
||||||
|
value={isMultiCursorEnabled}
|
||||||
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label="Enable flashing on evaluation"
|
label="Enable flashing on evaluation"
|
||||||
onChange={(cbEvent) => settingsMap.setKey('isFlashEnabled', cbEvent.target.checked)}
|
onChange={(cbEvent) => settingsMap.setKey('isFlashEnabled', cbEvent.target.checked)}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
resetGlobalEffects,
|
resetGlobalEffects,
|
||||||
resetLoadedSounds,
|
resetLoadedSounds,
|
||||||
initAudioOnFirstClick,
|
initAudioOnFirstClick,
|
||||||
|
resetDefaults,
|
||||||
} from '@strudel/webaudio';
|
} from '@strudel/webaudio';
|
||||||
import { setVersionDefaultsFrom } from './util.mjs';
|
import { setVersionDefaultsFrom } from './util.mjs';
|
||||||
import { StrudelMirror, defaultSettings } from '@strudel/codemirror';
|
import { StrudelMirror, defaultSettings } from '@strudel/codemirror';
|
||||||
@@ -181,6 +182,7 @@ export function useReplContext() {
|
|||||||
|
|
||||||
const resetEditor = async () => {
|
const resetEditor = async () => {
|
||||||
(await getModule('@strudel/tonal'))?.resetVoicings();
|
(await getModule('@strudel/tonal'))?.resetVoicings();
|
||||||
|
resetDefaults();
|
||||||
resetGlobalEffects();
|
resetGlobalEffects();
|
||||||
clearCanvas();
|
clearCanvas();
|
||||||
clearHydra();
|
clearHydra();
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ export const defaultSettings = {
|
|||||||
isSyncEnabled: false,
|
isSyncEnabled: false,
|
||||||
isLineWrappingEnabled: false,
|
isLineWrappingEnabled: false,
|
||||||
isPatternHighlightingEnabled: true,
|
isPatternHighlightingEnabled: true,
|
||||||
|
isTabIndentationEnabled: false,
|
||||||
|
isMultiCursorEnabled: false,
|
||||||
theme: 'strudelTheme',
|
theme: 'strudelTheme',
|
||||||
fontFamily: 'monospace',
|
fontFamily: 'monospace',
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
@@ -77,6 +79,8 @@ export function useSettings() {
|
|||||||
isLineWrappingEnabled: parseBoolean(state.isLineWrappingEnabled),
|
isLineWrappingEnabled: parseBoolean(state.isLineWrappingEnabled),
|
||||||
isFlashEnabled: parseBoolean(state.isFlashEnabled),
|
isFlashEnabled: parseBoolean(state.isFlashEnabled),
|
||||||
isSyncEnabled: isUdels() ? true : parseBoolean(state.isSyncEnabled),
|
isSyncEnabled: isUdels() ? true : parseBoolean(state.isSyncEnabled),
|
||||||
|
isTabIndentationEnabled: parseBoolean(state.isTabIndentationEnabled),
|
||||||
|
isMultiCursorEnabled: parseBoolean(state.isMultiCursorEnabled),
|
||||||
fontSize: Number(state.fontSize),
|
fontSize: Number(state.fontSize),
|
||||||
panelPosition: state.activeFooter !== '' && !isUdels() ? state.panelPosition : 'bottom', // <-- keep this 'bottom' where it is!
|
panelPosition: state.activeFooter !== '' && !isUdels() ? state.panelPosition : 'bottom', // <-- keep this 'bottom' where it is!
|
||||||
isPanelPinned: parseBoolean(state.isPanelPinned),
|
isPanelPinned: parseBoolean(state.isPanelPinned),
|
||||||
|
|||||||
Reference in New Issue
Block a user