mirror of
https://codeberg.org/uzu/strudel
synced 2026-09-16 18:56:57 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4603a34f7c | |||
| 30977019cc |
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
jsdoc-synonyms.js - Add support for @synonyms tag
|
||||
jsdoc-synonyms.js - Add support for @synonym tag
|
||||
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/>.
|
||||
*/
|
||||
|
||||
+2
-1
@@ -48,6 +48,7 @@
|
||||
"homepage": "https://strudel.cc",
|
||||
"dependencies": {
|
||||
"@strudel/core": "workspace:*",
|
||||
"@strudel/cyclist": "workspace:*",
|
||||
"@strudel/mini": "workspace:*",
|
||||
"@strudel/tonal": "workspace:*",
|
||||
"@strudel/transpiler": "workspace:*",
|
||||
@@ -74,4 +75,4 @@
|
||||
"vitest": "^3.0.4",
|
||||
"vite-plugin-bundle-audioworklet": "workspace:*"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ import {
|
||||
lineNumbers,
|
||||
drawSelection,
|
||||
} from '@codemirror/view';
|
||||
import { repl, registerControl } from '@strudel/core';
|
||||
import { registerControl } from '@strudel/core';
|
||||
import { repl } from '@strudel/cyclist';
|
||||
import { Drawer, cleanupDraw } from '@strudel/draw';
|
||||
import { isAutoCompletionEnabled } from './autocomplete.mjs';
|
||||
import { isTooltipEnabled } from './tooltip.mjs';
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"@replit/codemirror-vim": "^6.2.1",
|
||||
"@replit/codemirror-vscode-keymap": "^6.0.2",
|
||||
"@strudel/core": "workspace:*",
|
||||
"@strudel/cyclist": "workspace:*",
|
||||
"@strudel/draw": "workspace:*",
|
||||
"@strudel/transpiler": "workspace:*",
|
||||
"nanostores": "^0.11.3"
|
||||
|
||||
+13
-96
@@ -444,78 +444,6 @@ export const { crush } = registerControl('crush');
|
||||
*/
|
||||
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
|
||||
*
|
||||
@@ -525,30 +453,6 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape');
|
||||
* 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');
|
||||
|
||||
/**
|
||||
@@ -1657,6 +1561,18 @@ export const { density } = registerControl('density');
|
||||
// ['modwheel'],
|
||||
export const { expression } = registerControl('expression');
|
||||
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 { fshiftnote } = registerControl('fshiftnote');
|
||||
@@ -1733,6 +1649,7 @@ export const { zmod } = registerControl('zmod');
|
||||
// like crush but scaled differently
|
||||
export const { zcrush } = registerControl('zcrush');
|
||||
export const { zdelay } = registerControl('zdelay');
|
||||
export const { tremolo } = registerControl('tremolo');
|
||||
export const { zzfx } = registerControl('zzfx');
|
||||
|
||||
/**
|
||||
|
||||
+1
-10
@@ -7,9 +7,8 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
import * as controls from './controls.mjs'; // legacy
|
||||
export * from './euclid.mjs';
|
||||
import Fraction from './fraction.mjs';
|
||||
import createClock from './zyklus.mjs';
|
||||
import { logger } from './logger.mjs';
|
||||
export { Fraction, controls, createClock };
|
||||
export { Fraction, controls };
|
||||
export * from './controls.mjs';
|
||||
export * from './hap.mjs';
|
||||
export * from './pattern.mjs';
|
||||
@@ -18,15 +17,7 @@ export * from './pick.mjs';
|
||||
export * from './state.mjs';
|
||||
export * from './timespan.mjs';
|
||||
export * from './util.mjs';
|
||||
export * from './speak.mjs';
|
||||
export * from './evaluate.mjs';
|
||||
export * from './repl.mjs';
|
||||
export * from './cyclist.mjs';
|
||||
export * from './logger.mjs';
|
||||
export * from './time.mjs';
|
||||
export * from './ui.mjs';
|
||||
export * from './ui.mjs';
|
||||
export * from './idbutils.mjs'
|
||||
export { default as drawLine } from './drawLine.mjs';
|
||||
// below won't work with runtime.mjs (json import fails)
|
||||
/* import * as p from './package.json';
|
||||
|
||||
@@ -4,12 +4,6 @@ let debounce = 1000,
|
||||
lastMessage,
|
||||
lastTime;
|
||||
|
||||
export function errorLogger(e, origin = 'cyclist') {
|
||||
//TODO: add some kind of debug flag that enables this while in dev mode
|
||||
// console.error(e)
|
||||
logger(`[${origin}] error: ${e.message}`);
|
||||
}
|
||||
|
||||
export function logger(message, type, data = {}) {
|
||||
let t = performance.now();
|
||||
if (lastMessage === message && t - lastTime < debounce) {
|
||||
|
||||
@@ -2522,7 +2522,7 @@ export const { fastchunk, fastChunk } = register(
|
||||
/**
|
||||
* Like `chunk`, but the function is applied to a looped subcycle of the source pattern.
|
||||
* @name chunkInto
|
||||
* @synonyms chunkinto
|
||||
* @synonym chunkinto
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* sound("bd sd ht lt bd - cp lt").chunkInto(4, hurry(2))
|
||||
@@ -2535,7 +2535,7 @@ export const { chunkinto, chunkInto } = register(['chunkinto', 'chunkInto'], fun
|
||||
/**
|
||||
* Like `chunkInto`, but moves backwards through the chunks.
|
||||
* @name chunkBackInto
|
||||
* @synonyms chunkbackinto
|
||||
* @synonym chunkbackinto
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* sound("bd sd ht lt bd - cp lt").chunkInto(4, hurry(2))
|
||||
@@ -2565,7 +2565,7 @@ export const bypass = register(
|
||||
* 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.
|
||||
* @name ribbon
|
||||
* @synonyms rib
|
||||
* @synonym rib
|
||||
* @param {number} offset start point of loop in cycles
|
||||
* @param {number} cycles loop length in cycles
|
||||
* @example
|
||||
|
||||
@@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
*/
|
||||
|
||||
import createClock from './zyklus.mjs';
|
||||
import { errorLogger, logger } from './logger.mjs';
|
||||
import { logger } from '@strudel/core';
|
||||
|
||||
export class Cyclist {
|
||||
constructor({
|
||||
@@ -76,7 +76,7 @@ export class Cyclist {
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
errorLogger(e);
|
||||
logger(`[cyclist] error: ${e.message}`);
|
||||
onError?.(e);
|
||||
}
|
||||
},
|
||||
@@ -0,0 +1,8 @@
|
||||
export * from './speak.mjs';
|
||||
export * from './evaluate.mjs';
|
||||
export * from './repl.mjs';
|
||||
export * from './cyclist.mjs';
|
||||
export * from './time.mjs';
|
||||
export * from './ui.mjs';
|
||||
import createClock from './zyklus.mjs';
|
||||
export { createClock };
|
||||
@@ -0,0 +1,28 @@
|
||||
export const logKey = 'strudel.log';
|
||||
|
||||
let debounce = 1000,
|
||||
lastMessage,
|
||||
lastTime;
|
||||
|
||||
export function logger(message, type, data = {}) {
|
||||
let t = performance.now();
|
||||
if (lastMessage === message && t - lastTime < debounce) {
|
||||
return;
|
||||
}
|
||||
lastMessage = message;
|
||||
lastTime = t;
|
||||
console.log(`%c${message}`, 'background-color: black;color:white;border-radius:15px');
|
||||
if (typeof document !== 'undefined' && typeof CustomEvent !== 'undefined') {
|
||||
document.dispatchEvent(
|
||||
new CustomEvent(logKey, {
|
||||
detail: {
|
||||
message,
|
||||
type,
|
||||
data,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
logger.key = logKey;
|
||||
@@ -5,12 +5,13 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
*/
|
||||
|
||||
import { logger } from './logger.mjs';
|
||||
import { ClockCollator, cycleToSeconds } from './util.mjs';
|
||||
import { ClockCollator, cycleToSeconds } from '@strudel/core';
|
||||
|
||||
export class NeoCyclist {
|
||||
constructor({ onTrigger, onToggle, getTime }) {
|
||||
this.started = false;
|
||||
this.cps = 0.5;
|
||||
this.lastTick = 0; // absolute time when last tick (clock callback) happened
|
||||
this.getTime = getTime; // get absolute time
|
||||
this.time_at_last_tick_message = 0;
|
||||
// the clock of the worker and the audio context clock can drift apart over time
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@strudel/cyclist",
|
||||
"version": "1.2.2",
|
||||
"description": "Event Scheduler for Strudel",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
"publishConfig": {
|
||||
"main": "dist/index.mjs"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
"bench": "vitest bench",
|
||||
"build": "vite build",
|
||||
"prepublishOnly": "pnpm build"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://codeberg.org/uzu/strudel.git"
|
||||
},
|
||||
"keywords": [
|
||||
"tidalcycles",
|
||||
"strudel",
|
||||
"pattern",
|
||||
"livecoding",
|
||||
"algorave"
|
||||
],
|
||||
"author": "Alex McLean <alex@slab.org> (https://slab.org)",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"bugs": {
|
||||
"url": "https://codeberg.org/uzu/strudel/issues"
|
||||
},
|
||||
"homepage": "https://strudel.cc",
|
||||
"dependencies": {
|
||||
"@strudel/core": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^6.0.11",
|
||||
"vitest": "^3.0.4"
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { NeoCyclist } from './neocyclist.mjs';
|
||||
import { Cyclist } from './cyclist.mjs';
|
||||
import { evaluate as _evaluate } from './evaluate.mjs';
|
||||
import { errorLogger, logger } from './logger.mjs';
|
||||
import { logger } from './logger.mjs';
|
||||
import { setTime } from './time.mjs';
|
||||
import { evalScope } from './evaluate.mjs';
|
||||
import { register, Pattern, isPattern, silence, stack } from './pattern.mjs';
|
||||
import { register, Pattern, isPattern, silence, stack } from '@strudel/core';
|
||||
|
||||
export function repl({
|
||||
defaultOutput,
|
||||
@@ -256,6 +256,6 @@ export const getTrigger =
|
||||
await hap.context.onTrigger(hap, getTime(), cps, t);
|
||||
}
|
||||
} catch (err) {
|
||||
errorLogger(err, 'getTrigger');
|
||||
logger(`[cyclist] error: ${err.message}`, 'error');
|
||||
}
|
||||
};
|
||||
@@ -4,7 +4,7 @@ Copyright (C) 2022 Strudel contributors - see <https://codeberg.org/uzu/strudel/
|
||||
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/>.
|
||||
*/
|
||||
|
||||
import { register } from './index.mjs';
|
||||
import { register } from '@strudel/core';
|
||||
|
||||
let synth;
|
||||
try {
|
||||
@@ -0,0 +1,20 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import { dependencies } from './package.json';
|
||||
import { resolve } from 'path';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
base: './',
|
||||
plugins: [],
|
||||
build: {
|
||||
lib: {
|
||||
entry: resolve(__dirname, 'index.mjs'),
|
||||
formats: ['es'],
|
||||
fileName: (ext) => ({ es: 'index.mjs' })[ext],
|
||||
},
|
||||
rollupOptions: {
|
||||
external: [...Object.keys(dependencies)],
|
||||
},
|
||||
target: 'esnext',
|
||||
},
|
||||
});
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://codeberg.org/uzu/strudel/
|
||||
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/>.
|
||||
*/
|
||||
|
||||
import { Pattern, getTime, State, TimeSpan } from '@strudel/core';
|
||||
import { Pattern, State, TimeSpan } from '@strudel/core';
|
||||
import { getTime } from '@strudel/cyclist';
|
||||
|
||||
export const getDrawContext = (id = 'test-canvas', options) => {
|
||||
let { contextType = '2d', pixelated = false, pixelRatio = window.devicePixelRatio } = options || {};
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
},
|
||||
"homepage": "https://codeberg.org/uzu/strudel#readme",
|
||||
"dependencies": {
|
||||
"@strudel/core": "workspace:*"
|
||||
"@strudel/core": "workspace:*",
|
||||
"@strudel/cyclist": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^6.0.11"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { getDrawContext } from '@strudel/draw';
|
||||
import { controls, getTime, reify } from '@strudel/core';
|
||||
import { controls, reify } from '@strudel/core';
|
||||
import { getTime } from '@strudel/cyclist';
|
||||
|
||||
let latestOptions;
|
||||
let hydra;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"homepage": "https://codeberg.org/uzu/strudel#readme",
|
||||
"dependencies": {
|
||||
"@strudel/core": "workspace:*",
|
||||
"@strudel/cyclist": "workspace:*",
|
||||
"@strudel/draw": "workspace:*",
|
||||
"hydra-synth": "^1.3.29"
|
||||
},
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
import {
|
||||
strudelScope,
|
||||
reify,
|
||||
fast,
|
||||
slow,
|
||||
seq,
|
||||
stepcat,
|
||||
extend,
|
||||
expand,
|
||||
pace,
|
||||
chooseIn,
|
||||
degradeBy,
|
||||
silence,
|
||||
} from '@strudel/core';
|
||||
import { reify, fast, slow, seq, stepcat, extend, expand, pace, chooseIn, degradeBy, silence } from '@strudel/core';
|
||||
import { strudelScope } from '@strudel/cyclist';
|
||||
import { registerLanguage } from '@strudel/transpiler';
|
||||
import { MondoRunner } from 'mondolang';
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||
"dependencies": {
|
||||
"@strudel/core": "workspace:*",
|
||||
"@strudel/cyclist": "workspace:*",
|
||||
"@strudel/transpiler": "workspace:*",
|
||||
"mondolang": "workspace:*"
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@ const config = {
|
||||
},
|
||||
udpClient: {
|
||||
host: 'localhost', // @param {string} Hostname of udp client for messaging
|
||||
port: 57120, // @param {number} Port of udp client for messaging
|
||||
port: 7771, // @param {number} Port of udp client for messaging
|
||||
},
|
||||
wsServer: {
|
||||
host: 'localhost', // @param {string} Hostname of WebSocket server
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './repl-component.mjs';
|
||||
export * from './prebake.mjs';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { noteToMidi, valueToMidi, Pattern, evalScope,registerSamplesFromDB } from '@strudel/core';
|
||||
import { aliasBank, registerSynthSounds, registerZZFXSounds, samples, } from '@strudel/webaudio';
|
||||
import { noteToMidi, valueToMidi, Pattern, evalScope } from '@strudel/core';
|
||||
import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio';
|
||||
import * as core from '@strudel/core';
|
||||
|
||||
export async function prebake() {
|
||||
@@ -28,7 +28,6 @@ export async function prebake() {
|
||||
modulesLoading,
|
||||
registerSynthSounds(),
|
||||
registerZZFXSounds(),
|
||||
registerSamplesFromDB(),
|
||||
//registerSoundfonts(),
|
||||
// need dynamic import here, because importing @strudel/soundfonts fails on server:
|
||||
// => getting "window is not defined", as soon as "@strudel/soundfonts" is imported statically
|
||||
@@ -37,10 +36,9 @@ export async function prebake() {
|
||||
samples(`${ds}/tidal-drum-machines.json`),
|
||||
samples(`${ds}/piano.json`),
|
||||
samples(`${ds}/Dirt-Samples.json`),
|
||||
samples(`https://raw.githubusercontent.com/tidalcycles/uzu-drumkit/main/strudel.json`),
|
||||
samples(`${ds}/EmuSP12.json`),
|
||||
samples(`${ds}/vcsl.json`),
|
||||
samples(`${ds}/mridangam.json`),
|
||||
registerSamplesFromDB(),
|
||||
]);
|
||||
|
||||
aliasBank(`${ts}/tidal-drum-machines-alias.json`);
|
||||
|
||||
@@ -216,63 +216,50 @@ function getSamplesPrefixHandler(url) {
|
||||
*/
|
||||
|
||||
export const samples = async (sampleMap, baseUrl = sampleMap._base || '', options = {}) => {
|
||||
|
||||
if (typeof sampleMap === 'string') {
|
||||
const base = sampleMap.split('/').slice(0, -1).join('/');
|
||||
const savedJSON = localStorage.getItem(sampleMap)
|
||||
if (savedJSON) {
|
||||
const json = JSON.parse(savedJSON)
|
||||
samples(json, baseUrl || json._base || base, options)
|
||||
} else {
|
||||
|
||||
|
||||
// check if custom prefix handler
|
||||
const handler = getSamplesPrefixHandler(sampleMap);
|
||||
if (handler) {
|
||||
return handler(sampleMap);
|
||||
}
|
||||
sampleMap = resolveSpecialPaths(sampleMap);
|
||||
if (sampleMap.startsWith('github:')) {
|
||||
sampleMap = githubPath(sampleMap, 'strudel.json');
|
||||
}
|
||||
if (sampleMap.startsWith('local:')) {
|
||||
sampleMap = `http://localhost:5432`;
|
||||
}
|
||||
if (sampleMap.startsWith('shabda:')) {
|
||||
let [_, path] = sampleMap.split('shabda:');
|
||||
sampleMap = `https://shabda.ndre.gr/${path}.json?strudel=1`;
|
||||
}
|
||||
if (sampleMap.startsWith('shabda/speech')) {
|
||||
let [_, path] = sampleMap.split('shabda/speech');
|
||||
path = path.startsWith('/') ? path.substring(1) : path;
|
||||
let [params, words] = path.split(':');
|
||||
let gender = 'f';
|
||||
let language = 'en-GB';
|
||||
if (params) {
|
||||
[language, gender] = params.split('/');
|
||||
}
|
||||
sampleMap = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`;
|
||||
}
|
||||
if (typeof fetch !== 'function') {
|
||||
// not a browser
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof fetch === 'undefined') {
|
||||
// skip fetch when in node / testing
|
||||
return;
|
||||
}
|
||||
return fetch(sampleMap)
|
||||
.then((res) => res.json())
|
||||
.then((json) => {
|
||||
localStorage.setItem(sampleMap, JSON.stringify(json))
|
||||
samples(json, baseUrl || json._base || base, options)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
throw new Error(`error loading "${sampleMap}"`);
|
||||
});
|
||||
// check if custom prefix handler
|
||||
const handler = getSamplesPrefixHandler(sampleMap);
|
||||
if (handler) {
|
||||
return handler(sampleMap);
|
||||
}
|
||||
sampleMap = resolveSpecialPaths(sampleMap);
|
||||
if (sampleMap.startsWith('github:')) {
|
||||
sampleMap = githubPath(sampleMap, 'strudel.json');
|
||||
}
|
||||
if (sampleMap.startsWith('local:')) {
|
||||
sampleMap = `http://localhost:5432`;
|
||||
}
|
||||
if (sampleMap.startsWith('shabda:')) {
|
||||
let [_, path] = sampleMap.split('shabda:');
|
||||
sampleMap = `https://shabda.ndre.gr/${path}.json?strudel=1`;
|
||||
}
|
||||
if (sampleMap.startsWith('shabda/speech')) {
|
||||
let [_, path] = sampleMap.split('shabda/speech');
|
||||
path = path.startsWith('/') ? path.substring(1) : path;
|
||||
let [params, words] = path.split(':');
|
||||
let gender = 'f';
|
||||
let language = 'en-GB';
|
||||
if (params) {
|
||||
[language, gender] = params.split('/');
|
||||
}
|
||||
sampleMap = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`;
|
||||
}
|
||||
if (typeof fetch !== 'function') {
|
||||
// not a browser
|
||||
return;
|
||||
}
|
||||
const base = sampleMap.split('/').slice(0, -1).join('/');
|
||||
if (typeof fetch === 'undefined') {
|
||||
// skip fetch when in node / testing
|
||||
return;
|
||||
}
|
||||
return fetch(sampleMap)
|
||||
.then((res) => res.json())
|
||||
.then((json) => samples(json, baseUrl || json._base || base, options))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
throw new Error(`error loading "${sampleMap}"`);
|
||||
});
|
||||
}
|
||||
const { prebake, tag } = options;
|
||||
processSampleMap(
|
||||
|
||||
@@ -7,7 +7,7 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
import './feedbackdelay.mjs';
|
||||
import './reverb.mjs';
|
||||
import './vowel.mjs';
|
||||
import { clamp, nanFallback, _mod, cycleToSeconds, secondsToCycle } from './util.mjs';
|
||||
import { clamp, nanFallback, _mod, cycleToSeconds } from './util.mjs';
|
||||
import workletsUrl from './worklets.mjs?audioworklet';
|
||||
import { createFilter, gainNode, getCompressor, getWorklet } from './helpers.mjs';
|
||||
import { map } from 'nanostores';
|
||||
@@ -28,13 +28,6 @@ export function setMultiChannelOrbits(bool) {
|
||||
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 function registerSound(key, onTrigger, data = {}) {
|
||||
@@ -343,33 +336,9 @@ function getDelay(orbit, delaytime, delayfeedback, t, channels) {
|
||||
return delays[orbit];
|
||||
}
|
||||
|
||||
export function getLfo(audioContext, begin, end, properties = {}) {
|
||||
const { shape = 0, ...props } = properties;
|
||||
const { dcoffset = -0.5, depth = 1 } = properties;
|
||||
const lfoprops = {
|
||||
frequency: 1,
|
||||
depth,
|
||||
skew: 0.5,
|
||||
phaseoffset: 0,
|
||||
time: begin,
|
||||
begin,
|
||||
end,
|
||||
shape: getModulationShapeInput(shape),
|
||||
dcoffset,
|
||||
min: dcoffset * depth,
|
||||
max: dcoffset * depth + depth,
|
||||
curve: 1,
|
||||
...props,
|
||||
};
|
||||
|
||||
return getWorklet(audioContext, 'lfo-processor', lfoprops);
|
||||
}
|
||||
|
||||
export function getSyncedLfo(audioContext, time, end, cps, cycle, properties = {}) {
|
||||
const frequency = cycle / cps;
|
||||
|
||||
export function getLfo(audioContext, time, end, properties = {}) {
|
||||
return getWorklet(audioContext, 'lfo-processor', {
|
||||
frequency,
|
||||
frequency: 1,
|
||||
depth: 1,
|
||||
skew: 0,
|
||||
phaseoffset: 0,
|
||||
@@ -492,10 +461,9 @@ function mapChannelNumbers(channels) {
|
||||
return (Array.isArray(channels) ? channels : [channels]).map((ch) => ch - 1);
|
||||
}
|
||||
|
||||
export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) => {
|
||||
export const superdough = async (value, t, hapDuration, cps = 0.5) => {
|
||||
// new: t is always expected to be the absolute target onset time
|
||||
const ac = getAudioContext();
|
||||
|
||||
let { stretch } = value;
|
||||
if (stretch != null) {
|
||||
//account for phase vocoder latency
|
||||
@@ -521,12 +489,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
}
|
||||
// destructure
|
||||
let {
|
||||
tremolo,
|
||||
tremolosync,
|
||||
tremolodepth = 1,
|
||||
tremoloskew,
|
||||
tremolophase = 0,
|
||||
tremoloshape,
|
||||
s = getDefaultValue('s'),
|
||||
bank,
|
||||
source,
|
||||
@@ -536,7 +498,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
// filters
|
||||
fanchor = getDefaultValue('fanchor'),
|
||||
drive = 0.69,
|
||||
release = 0,
|
||||
// low pass
|
||||
cutoff,
|
||||
lpenv,
|
||||
@@ -569,7 +530,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
phasercenter,
|
||||
//
|
||||
coarse,
|
||||
|
||||
crush,
|
||||
shape,
|
||||
shapevol = getDefaultValue('shapevol'),
|
||||
@@ -612,11 +572,8 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
distortvol = applyGainCurve(distortvol);
|
||||
delay = applyGainCurve(delay);
|
||||
velocity = applyGainCurve(velocity);
|
||||
tremolodepth = applyGainCurve(tremolodepth);
|
||||
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);
|
||||
|
||||
// oldest audio nodes will be destroyed if maximum polyphony is exceeded
|
||||
@@ -691,7 +648,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
lprelease,
|
||||
lpenv,
|
||||
t,
|
||||
end,
|
||||
t + hapDuration,
|
||||
fanchor,
|
||||
ftype,
|
||||
drive,
|
||||
@@ -715,7 +672,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
hprelease,
|
||||
hpenv,
|
||||
t,
|
||||
end,
|
||||
t + hapDuration,
|
||||
fanchor,
|
||||
);
|
||||
chain.push(hp());
|
||||
@@ -726,7 +683,20 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
|
||||
if (bandf !== undefined) {
|
||||
let bp = () =>
|
||||
createFilter(ac, 'bandpass', bandf, bandq, bpattack, bpdecay, bpsustain, bprelease, bpenv, t, end, fanchor);
|
||||
createFilter(
|
||||
ac,
|
||||
'bandpass',
|
||||
bandf,
|
||||
bandq,
|
||||
bpattack,
|
||||
bpdecay,
|
||||
bpsustain,
|
||||
bprelease,
|
||||
bpenv,
|
||||
t,
|
||||
t + hapDuration,
|
||||
fanchor,
|
||||
);
|
||||
chain.push(bp());
|
||||
if (ftype === '24db') {
|
||||
chain.push(bp());
|
||||
@@ -744,33 +714,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
shape !== undefined && chain.push(getWorklet(ac, 'shape-processor', { shape, postgain: shapevol }));
|
||||
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 &&
|
||||
chain.push(
|
||||
getCompressor(ac, compressorThreshold, compressorRatio, compressorKnee, compressorAttack, compressorRelease),
|
||||
@@ -784,7 +727,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
}
|
||||
// phaser
|
||||
if (phaser !== undefined && phaserdepth > 0) {
|
||||
const phaserFX = getPhaser(t, endWithRelease, phaser, phaserdepth, phasercenter, phasersweep);
|
||||
const phaserFX = getPhaser(t, t + hapDuration, phaser, phaserdepth, phasercenter, phasersweep);
|
||||
chain.push(phaserFX);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,3 @@ export const getSoundIndex = (n, 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;
|
||||
}
|
||||
}
|
||||
// The order is important for dough integration
|
||||
|
||||
const waveshapes = {
|
||||
tri(phase, skew = 0.5) {
|
||||
const x = 1 - skew;
|
||||
@@ -81,12 +81,10 @@ function getParamValue(block, param) {
|
||||
}
|
||||
return param[0];
|
||||
}
|
||||
|
||||
const waveShapeNames = Object.keys(waveshapes);
|
||||
class LFOProcessor extends AudioWorkletProcessor {
|
||||
static get parameterDescriptors() {
|
||||
return [
|
||||
{ name: 'begin', defaultValue: 0 },
|
||||
{ name: 'time', defaultValue: 0 },
|
||||
{ name: 'end', defaultValue: 0 },
|
||||
{ name: 'frequency', defaultValue: 0.5 },
|
||||
@@ -94,10 +92,7 @@ class LFOProcessor extends AudioWorkletProcessor {
|
||||
{ name: 'depth', defaultValue: 1 },
|
||||
{ name: 'phaseoffset', defaultValue: 0 },
|
||||
{ name: 'shape', defaultValue: 0 },
|
||||
{ name: 'curve', defaultValue: 1 },
|
||||
{ name: 'dcoffset', defaultValue: 0 },
|
||||
{ name: 'min', defaultValue: 0 },
|
||||
{ name: 'max', defaultValue: 1 },
|
||||
];
|
||||
}
|
||||
|
||||
@@ -114,14 +109,10 @@ class LFOProcessor extends AudioWorkletProcessor {
|
||||
}
|
||||
|
||||
process(inputs, outputs, parameters) {
|
||||
const begin = parameters['begin'][0];
|
||||
// eslint-disable-next-line no-undef
|
||||
if (currentTime >= parameters.end[0]) {
|
||||
return false;
|
||||
}
|
||||
if (currentTime <= begin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const output = outputs[0];
|
||||
const frequency = parameters['frequency'][0];
|
||||
@@ -131,11 +122,7 @@ class LFOProcessor extends AudioWorkletProcessor {
|
||||
const skew = parameters['skew'][0];
|
||||
const phaseoffset = parameters['phaseoffset'][0];
|
||||
|
||||
const curve = parameters['curve'][0];
|
||||
|
||||
const dcoffset = parameters['dcoffset'][0];
|
||||
const min = parameters['min'][0];
|
||||
const max = parameters['max'][0];
|
||||
const shape = waveShapeNames[parameters['shape'][0]];
|
||||
|
||||
const blockSize = output[0].length ?? 0;
|
||||
@@ -147,9 +134,8 @@ class LFOProcessor extends AudioWorkletProcessor {
|
||||
const dt = frequency / sampleRate;
|
||||
for (let n = 0; n < blockSize; n++) {
|
||||
for (let i = 0; i < output.length; i++) {
|
||||
let modval = (waveshapes[shape](this.phase, skew) + dcoffset) * depth;
|
||||
modval = Math.pow(modval, curve);
|
||||
output[i][n] = clamp(modval, min, max);
|
||||
const modval = (waveshapes[shape](this.phase, skew) + dcoffset) * depth;
|
||||
output[i][n] = modval;
|
||||
}
|
||||
this.incrementPhase(dt);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { evaluate as _evaluate } from '@strudel/core';
|
||||
import { evaluate as _evaluate } from '@strudel/cyclist';
|
||||
import { transpiler } from './transpiler.mjs';
|
||||
export * from './transpiler.mjs';
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"homepage": "https://codeberg.org/uzu/strudel#readme",
|
||||
"dependencies": {
|
||||
"@strudel/core": "workspace:*",
|
||||
"@strudel/cyclist": "workspace:*",
|
||||
"@strudel/mini": "workspace:*",
|
||||
"acorn": "^8.14.0",
|
||||
"escodegen": "^2.1.0",
|
||||
|
||||
@@ -17,8 +17,8 @@ const hap2value = (hap) => {
|
||||
|
||||
// uses more precise, absolute t if available, see https://github.com/tidalcycles/strudel/pull/1004
|
||||
// TODO: refactor output callbacks to eliminate deadline
|
||||
export const webaudioOutput = (hap, _deadline, hapDuration, cps, t) => {
|
||||
return superdough(hap2value(hap), t, hapDuration, cps, hap.whole?.begin.valueOf());
|
||||
export const webaudioOutput = (hap, deadline, hapDuration, cps, t) => {
|
||||
return superdough(hap2value(hap), t, hapDuration, cps);
|
||||
};
|
||||
|
||||
export function webaudioRepl(options = {}) {
|
||||
|
||||
Generated
+42
@@ -11,6 +11,9 @@ importers:
|
||||
'@strudel/core':
|
||||
specifier: workspace:*
|
||||
version: link:packages/core
|
||||
'@strudel/cyclist':
|
||||
specifier: workspace:*
|
||||
version: link:packages/cyclist
|
||||
'@strudel/mini':
|
||||
specifier: workspace:*
|
||||
version: link:packages/mini
|
||||
@@ -209,6 +212,9 @@ importers:
|
||||
'@strudel/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
'@strudel/cyclist':
|
||||
specifier: workspace:*
|
||||
version: link:../cyclist
|
||||
'@strudel/draw':
|
||||
specifier: workspace:*
|
||||
version: link:../draw
|
||||
@@ -252,6 +258,19 @@ importers:
|
||||
specifier: ^6.0.11
|
||||
version: 6.0.11(@types/node@22.10.10)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0)
|
||||
|
||||
packages/cyclist:
|
||||
dependencies:
|
||||
'@strudel/core':
|
||||
specifier: '*'
|
||||
version: 1.2.2
|
||||
devDependencies:
|
||||
vite:
|
||||
specifier: ^6.0.11
|
||||
version: 6.0.11(@types/node@22.10.10)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0)
|
||||
vitest:
|
||||
specifier: ^3.0.4
|
||||
version: 3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0)
|
||||
|
||||
packages/desktopbridge:
|
||||
dependencies:
|
||||
'@strudel/core':
|
||||
@@ -266,6 +285,9 @@ importers:
|
||||
'@strudel/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
'@strudel/cyclist':
|
||||
specifier: workspace:*
|
||||
version: link:../cyclist
|
||||
devDependencies:
|
||||
vite:
|
||||
specifier: ^6.0.11
|
||||
@@ -301,6 +323,9 @@ importers:
|
||||
'@strudel/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
'@strudel/cyclist':
|
||||
specifier: workspace:*
|
||||
version: link:../cyclist
|
||||
'@strudel/draw':
|
||||
specifier: workspace:*
|
||||
version: link:../draw
|
||||
@@ -361,6 +386,9 @@ importers:
|
||||
'@strudel/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
'@strudel/cyclist':
|
||||
specifier: workspace:*
|
||||
version: link:../cyclist
|
||||
'@strudel/transpiler':
|
||||
specifier: workspace:*
|
||||
version: link:../transpiler
|
||||
@@ -560,6 +588,9 @@ importers:
|
||||
'@strudel/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
'@strudel/cyclist':
|
||||
specifier: workspace:*
|
||||
version: link:../cyclist
|
||||
'@strudel/mini':
|
||||
specifier: workspace:*
|
||||
version: link:../mini
|
||||
@@ -696,6 +727,9 @@ importers:
|
||||
'@strudel/csound':
|
||||
specifier: workspace:*
|
||||
version: link:../packages/csound
|
||||
'@strudel/cyclist':
|
||||
specifier: workspace:*
|
||||
version: link:../packages/cyclist
|
||||
'@strudel/desktopbridge':
|
||||
specifier: workspace:*
|
||||
version: link:../packages/desktopbridge
|
||||
@@ -2453,6 +2487,9 @@ packages:
|
||||
'@sinclair/typebox@0.27.8':
|
||||
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
|
||||
|
||||
'@strudel/core@1.2.2':
|
||||
resolution: {integrity: sha512-rPFAwV7Emz85HyKwfVVn+2cNOHCGBbWw6XImv0elnzRiXxKWMdmZfuSL3xgpheEg9WUgacgmzJL9kbvfCitGtA==}
|
||||
|
||||
'@supabase/auth-js@2.67.3':
|
||||
resolution: {integrity: sha512-NJDaW8yXs49xMvWVOkSIr8j46jf+tYHV0wHhrwOaLLMZSFO4g6kKAf+MfzQ2RaD06OCUkUHIzctLAxjTgEVpzw==}
|
||||
|
||||
@@ -7657,6 +7694,7 @@ packages:
|
||||
|
||||
workbox-google-analytics@7.0.0:
|
||||
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
|
||||
deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
|
||||
|
||||
workbox-navigation-preload@7.0.0:
|
||||
resolution: {integrity: sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA==}
|
||||
@@ -9808,6 +9846,10 @@ snapshots:
|
||||
|
||||
'@sinclair/typebox@0.27.8': {}
|
||||
|
||||
'@strudel/core@1.2.2':
|
||||
dependencies:
|
||||
fraction.js: 5.2.1
|
||||
|
||||
'@supabase/auth-js@2.67.3':
|
||||
dependencies:
|
||||
'@supabase/node-fetch': 2.6.15
|
||||
|
||||
@@ -10110,420 +10110,6 @@ 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`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | note:C3 ]",
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
// import * as tunes from './tunes.mjs';
|
||||
import { evaluate } from '@strudel/transpiler';
|
||||
import { evalScope } from '@strudel/core';
|
||||
import { evalScope } from '@strudel/cyclist';
|
||||
import * as strudel from '@strudel/core';
|
||||
import * as webaudio from '@strudel/webaudio';
|
||||
// import gist from '@strudel/core/gist.js';
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"@nanostores/react": "^0.8.4",
|
||||
"@strudel/codemirror": "workspace:*",
|
||||
"@strudel/core": "workspace:*",
|
||||
"@strudel/cyclist": "workspace:*",
|
||||
"@strudel/csound": "workspace:*",
|
||||
"@strudel/desktopbridge": "workspace:*",
|
||||
"@strudel/draw": "workspace:*",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"_base": "https://raw.githubusercontent.com/ritchse/tidal-drum-machines/main/machines/EmuSP12/",
|
||||
"bd": ["emusp12-bd/Bassdrum-01.wav","emusp12-bd/Bassdrum-02.wav","emusp12-bd/Bassdrum-03.wav","emusp12-bd/Bassdrum-04.wav","emusp12-bd/Bassdrum-05.wav","emusp12-bd/Bassdrum-06.wav","emusp12-bd/Bassdrum-07.wav","emusp12-bd/Bassdrum-08.wav","emusp12-bd/Bassdrum-09.wav","emusp12-bd/Bassdrum-10.wav","emusp12-bd/Bassdrum-11.wav","emusp12-bd/Bassdrum-12.wav","emusp12-bd/Bassdrum-13.wav","emusp12-bd/Bassdrum-14.wav"],
|
||||
"cb": ["emusp12-cb/Cowbell.wav"],
|
||||
"cp": ["emusp12-cp/Clap.wav"],
|
||||
"cr": ["emusp12-cr/Crash.wav"],
|
||||
"hh": ["emusp12-hh/Hat Closed-01.wav","emusp12-hh/Hat Closed-02.wav"],
|
||||
"ht": ["emusp12-ht/Tom H-01.wav","emusp12-ht/Tom H-02.wav","emusp12-ht/Tom H-03.wav","emusp12-ht/Tom H-04.wav","emusp12-ht/Tom H-05.wav","emusp12-ht/Tom H-06.wav"],
|
||||
"lt": ["emusp12-lt/Tom L-01.wav","emusp12-lt/Tom L-02.wav","emusp12-lt/Tom L-03.wav","emusp12-lt/Tom L-04.wav","emusp12-lt/Tom L-05.wav","emusp12-lt/Tom L-06.wav"],
|
||||
"misc": ["emusp12-misc/Metal-01.wav","emusp12-misc/Metal-02.wav","emusp12-misc/Metal-03.wav","emusp12-misc/Scratch.wav","emusp12-misc/Shot-01.wav","emusp12-misc/Shot-02.wav","emusp12-misc/Shot-03.wav"],
|
||||
"mt": ["emusp12-mt/Tom M-01.wav","emusp12-mt/Tom M-02.wav","emusp12-mt/Tom M-03.wav","emusp12-mt/Tom M-05.wav"],
|
||||
"oh": ["emusp12-oh/Hhopen1.wav"],
|
||||
"perc": ["emusp12-perc/Blow1.wav"],
|
||||
"rd": ["emusp12-rd/Ride.wav"],
|
||||
"rim": ["emusp12-rim/zRim Shot-01.wav","emusp12-rim/zRim Shot-02.wav"],
|
||||
"sd": ["emusp12-sd/Snaredrum-01.wav","emusp12-sd/Snaredrum-02.wav","emusp12-sd/Snaredrum-03.wav","emusp12-sd/Snaredrum-04.wav","emusp12-sd/Snaredrum-05.wav","emusp12-sd/Snaredrum-06.wav","emusp12-sd/Snaredrum-07.wav","emusp12-sd/Snaredrum-08.wav","emusp12-sd/Snaredrum-09.wav","emusp12-sd/Snaredrum-10.wav","emusp12-sd/Snaredrum-11.wav","emusp12-sd/Snaredrum-12.wav","emusp12-sd/Snaredrum-13.wav","emusp12-sd/Snaredrum-14.wav","emusp12-sd/Snaredrum-15.wav","emusp12-sd/Snaredrum-16.wav","emusp12-sd/Snaredrum-17.wav","emusp12-sd/Snaredrum-18.wav","emusp12-sd/Snaredrum-19.wav","emusp12-sd/Snaredrum-20.wav","emusp12-sd/Snaredrum-21.wav"]
|
||||
}
|
||||
@@ -57,34 +57,6 @@ Each filter has 2 parameters:
|
||||
|
||||
<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
|
||||
|
||||
The amplitude [envelope](<https://en.wikipedia.org/wiki/Envelope_(music)>) controls the dynamic contour of a sound.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Fragment, useEffect } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { readDir, dir, playFile } from '../../files.mjs';
|
||||
import { isAudioFile } from '@strudel/core';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { isAudioFile, readDir, dir, playFile } from '../../files.mjs';
|
||||
|
||||
export function FilesTab() {
|
||||
const [path, setPath] = useState([]);
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { registerSamplesFromDB, uploadSamplesToDB, userSamplesDBConfig } from '@strudel/core';
|
||||
import { registerSamplesFromDB, uploadSamplesToDB, userSamplesDBConfig } from '../../idbutils.mjs';
|
||||
|
||||
//choose a directory to locally import samples
|
||||
export default function ImportSoundsButton({ onComplete }) {
|
||||
|
||||
@@ -125,7 +125,7 @@ function UserPatterns({ context }) {
|
||||
style={{ display: 'none' }}
|
||||
type="file"
|
||||
multiple
|
||||
accept="text/plain,text/x-markdown,application/json"
|
||||
accept="text/plain,application/json"
|
||||
onChange={(e) => importPatterns(e.target.files)}
|
||||
/>
|
||||
import
|
||||
|
||||
@@ -75,7 +75,8 @@ export const walkFileTree = (node, fn) => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const isAudioFile = (filename) =>
|
||||
['wav', 'mp3', 'flac', 'ogg', 'm4a', 'aac'].includes(filename.split('.').slice(-1)[0]);
|
||||
|
||||
function uint8ArrayToDataURL(uint8Array) {
|
||||
const blob = new Blob([uint8Array], { type: 'audio/*' });
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { registerSound, onTriggerSample } from '@strudel/webaudio';
|
||||
import { isAudioFile } from './files.mjs';
|
||||
import { logger } from '@strudel/core';
|
||||
|
||||
//utilites for writing and reading to the indexdb
|
||||
|
||||
|
||||
export const isAudioFile = (filename) =>
|
||||
['wav', 'mp3', 'flac', 'ogg', 'm4a', 'aac'].includes(filename.split('.').slice(-1)[0]);
|
||||
|
||||
export const userSamplesDBConfig = {
|
||||
dbName: 'samples',
|
||||
table: 'usersamples',
|
||||
+141
-146
@@ -1,158 +1,153 @@
|
||||
import { Pattern, noteToMidi, valueToMidi } from '@strudel/core';
|
||||
import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio';
|
||||
import { registerSamplesFromDB } from '@strudel/core'
|
||||
import { registerSamplesFromDB } from './idbutils.mjs';
|
||||
import './piano.mjs';
|
||||
import './files.mjs';
|
||||
|
||||
const { BASE_URL } = import.meta.env;
|
||||
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;
|
||||
|
||||
// export async function prebake() {
|
||||
// // https://archive.org/details/SalamanderGrandPianoV3
|
||||
// // License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm
|
||||
|
||||
|
||||
// await Promise.all([
|
||||
// registerSynthSounds(),
|
||||
// registerZZFXSounds(),
|
||||
// registerSamplesFromDB(),
|
||||
// //registerSoundfonts(),
|
||||
// // need dynamic import here, because importing @strudel/soundfonts fails on server:
|
||||
// // => getting "window is not defined", as soon as "@strudel/soundfonts" is imported statically
|
||||
// // seems to be a problem with soundfont2
|
||||
// import('@strudel/soundfonts').then(({ registerSoundfonts }) => registerSoundfonts()),
|
||||
// samples(`${baseNoTrailing}/piano.json`, undefined, { prebake: true }),
|
||||
// // https://github.com/sgossner/VCSL/
|
||||
// // https://api.github.com/repositories/126427031/contents/
|
||||
// // LICENSE: CC0 general-purpose
|
||||
// samples(`${baseNoTrailing}/vcsl.json`, 'github:sgossner/VCSL/master/', { prebake: true }),
|
||||
// samples(`${baseNoTrailing}/tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/', {
|
||||
// prebake: true,
|
||||
// tag: 'drum-machines',
|
||||
// }),
|
||||
// samples(`https://raw.githubusercontent.com/tidalcycles/uzu-drumkit/main/strudel.json`, undefined, {
|
||||
// prebake: true,
|
||||
// tag: 'drum-machines',
|
||||
// }),
|
||||
// samples(`${baseNoTrailing}/mridangam.json`, undefined, { prebake: true, tag: 'drum-machines' }),
|
||||
// samples(
|
||||
// {
|
||||
// casio: ['casio/high.wav', 'casio/low.wav', 'casio/noise.wav'],
|
||||
// crow: ['crow/000_crow.wav', 'crow/001_crow2.wav', 'crow/002_crow3.wav', 'crow/003_crow4.wav'],
|
||||
// insect: [
|
||||
// 'insect/000_everglades_conehead.wav',
|
||||
// 'insect/001_robust_shieldback.wav',
|
||||
// 'insect/002_seashore_meadow_katydid.wav',
|
||||
// ],
|
||||
// wind: [
|
||||
// 'wind/000_wind1.wav',
|
||||
// 'wind/001_wind10.wav',
|
||||
// 'wind/002_wind2.wav',
|
||||
// 'wind/003_wind3.wav',
|
||||
// 'wind/004_wind4.wav',
|
||||
// 'wind/005_wind5.wav',
|
||||
// 'wind/006_wind6.wav',
|
||||
// 'wind/007_wind7.wav',
|
||||
// 'wind/008_wind8.wav',
|
||||
// 'wind/009_wind9.wav',
|
||||
// ],
|
||||
// jazz: [
|
||||
// 'jazz/000_BD.wav',
|
||||
// 'jazz/001_CB.wav',
|
||||
// 'jazz/002_FX.wav',
|
||||
// 'jazz/003_HH.wav',
|
||||
// 'jazz/004_OH.wav',
|
||||
// 'jazz/005_P1.wav',
|
||||
// 'jazz/006_P2.wav',
|
||||
// 'jazz/007_SN.wav',
|
||||
// ],
|
||||
// metal: [
|
||||
// 'metal/000_0.wav',
|
||||
// 'metal/001_1.wav',
|
||||
// 'metal/002_2.wav',
|
||||
// 'metal/003_3.wav',
|
||||
// 'metal/004_4.wav',
|
||||
// 'metal/005_5.wav',
|
||||
// 'metal/006_6.wav',
|
||||
// 'metal/007_7.wav',
|
||||
// 'metal/008_8.wav',
|
||||
// 'metal/009_9.wav',
|
||||
// ],
|
||||
// east: [
|
||||
// 'east/000_nipon_wood_block.wav',
|
||||
// 'east/001_ohkawa_mute.wav',
|
||||
// 'east/002_ohkawa_open.wav',
|
||||
// 'east/003_shime_hi.wav',
|
||||
// 'east/004_shime_hi_2.wav',
|
||||
// 'east/005_shime_mute.wav',
|
||||
// 'east/006_taiko_1.wav',
|
||||
// 'east/007_taiko_2.wav',
|
||||
// 'east/008_taiko_3.wav',
|
||||
// ],
|
||||
// space: [
|
||||
// 'space/000_0.wav',
|
||||
// 'space/001_1.wav',
|
||||
// 'space/002_11.wav',
|
||||
// 'space/003_12.wav',
|
||||
// 'space/004_13.wav',
|
||||
// 'space/005_14.wav',
|
||||
// 'space/006_15.wav',
|
||||
// 'space/007_16.wav',
|
||||
// 'space/008_17.wav',
|
||||
// 'space/009_18.wav',
|
||||
// 'space/010_2.wav',
|
||||
// 'space/011_3.wav',
|
||||
// 'space/012_4.wav',
|
||||
// 'space/013_5.wav',
|
||||
// 'space/014_6.wav',
|
||||
// 'space/015_7.wav',
|
||||
// 'space/016_8.wav',
|
||||
// 'space/017_9.wav',
|
||||
// ],
|
||||
// numbers: [
|
||||
// 'numbers/0.wav',
|
||||
// 'numbers/1.wav',
|
||||
// 'numbers/2.wav',
|
||||
// 'numbers/3.wav',
|
||||
// 'numbers/4.wav',
|
||||
// 'numbers/5.wav',
|
||||
// 'numbers/6.wav',
|
||||
// 'numbers/7.wav',
|
||||
// 'numbers/8.wav',
|
||||
// ],
|
||||
// num: [
|
||||
// 'num/00.wav',
|
||||
// 'num/01.wav',
|
||||
// 'num/02.wav',
|
||||
// 'num/03.wav',
|
||||
// 'num/04.wav',
|
||||
// 'num/05.wav',
|
||||
// 'num/06.wav',
|
||||
// 'num/07.wav',
|
||||
// 'num/08.wav',
|
||||
// 'num/09.wav',
|
||||
// 'num/10.wav',
|
||||
// 'num/11.wav',
|
||||
// 'num/12.wav',
|
||||
// 'num/13.wav',
|
||||
// 'num/14.wav',
|
||||
// 'num/15.wav',
|
||||
// 'num/16.wav',
|
||||
// 'num/17.wav',
|
||||
// 'num/18.wav',
|
||||
// 'num/19.wav',
|
||||
// 'num/20.wav',
|
||||
// ],
|
||||
// },
|
||||
// 'github:tidalcycles/dirt-samples',
|
||||
// {
|
||||
// prebake: true,
|
||||
// },
|
||||
// ),
|
||||
// ]);
|
||||
export async function prebake() {
|
||||
// https://archive.org/details/SalamanderGrandPianoV3
|
||||
// License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm
|
||||
await Promise.all([
|
||||
registerSynthSounds(),
|
||||
registerZZFXSounds(),
|
||||
registerSamplesFromDB(),
|
||||
//registerSoundfonts(),
|
||||
// need dynamic import here, because importing @strudel/soundfonts fails on server:
|
||||
// => getting "window is not defined", as soon as "@strudel/soundfonts" is imported statically
|
||||
// seems to be a problem with soundfont2
|
||||
import('@strudel/soundfonts').then(({ registerSoundfonts }) => registerSoundfonts()),
|
||||
samples(`${baseNoTrailing}/piano.json`, undefined, { prebake: true }),
|
||||
// https://github.com/sgossner/VCSL/
|
||||
// https://api.github.com/repositories/126427031/contents/
|
||||
// LICENSE: CC0 general-purpose
|
||||
samples(`${baseNoTrailing}/vcsl.json`, 'github:sgossner/VCSL/master/', { prebake: true }),
|
||||
samples(`${baseNoTrailing}/tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/', {
|
||||
prebake: true,
|
||||
tag: 'drum-machines',
|
||||
}),
|
||||
samples(`${baseNoTrailing}/EmuSP12.json`, undefined, { prebake: true, tag: 'drum-machines' }),
|
||||
samples(`${baseNoTrailing}/mridangam.json`, undefined, { prebake: true, tag: 'drum-machines' }),
|
||||
samples(
|
||||
{
|
||||
casio: ['casio/high.wav', 'casio/low.wav', 'casio/noise.wav'],
|
||||
crow: ['crow/000_crow.wav', 'crow/001_crow2.wav', 'crow/002_crow3.wav', 'crow/003_crow4.wav'],
|
||||
insect: [
|
||||
'insect/000_everglades_conehead.wav',
|
||||
'insect/001_robust_shieldback.wav',
|
||||
'insect/002_seashore_meadow_katydid.wav',
|
||||
],
|
||||
wind: [
|
||||
'wind/000_wind1.wav',
|
||||
'wind/001_wind10.wav',
|
||||
'wind/002_wind2.wav',
|
||||
'wind/003_wind3.wav',
|
||||
'wind/004_wind4.wav',
|
||||
'wind/005_wind5.wav',
|
||||
'wind/006_wind6.wav',
|
||||
'wind/007_wind7.wav',
|
||||
'wind/008_wind8.wav',
|
||||
'wind/009_wind9.wav',
|
||||
],
|
||||
jazz: [
|
||||
'jazz/000_BD.wav',
|
||||
'jazz/001_CB.wav',
|
||||
'jazz/002_FX.wav',
|
||||
'jazz/003_HH.wav',
|
||||
'jazz/004_OH.wav',
|
||||
'jazz/005_P1.wav',
|
||||
'jazz/006_P2.wav',
|
||||
'jazz/007_SN.wav',
|
||||
],
|
||||
metal: [
|
||||
'metal/000_0.wav',
|
||||
'metal/001_1.wav',
|
||||
'metal/002_2.wav',
|
||||
'metal/003_3.wav',
|
||||
'metal/004_4.wav',
|
||||
'metal/005_5.wav',
|
||||
'metal/006_6.wav',
|
||||
'metal/007_7.wav',
|
||||
'metal/008_8.wav',
|
||||
'metal/009_9.wav',
|
||||
],
|
||||
east: [
|
||||
'east/000_nipon_wood_block.wav',
|
||||
'east/001_ohkawa_mute.wav',
|
||||
'east/002_ohkawa_open.wav',
|
||||
'east/003_shime_hi.wav',
|
||||
'east/004_shime_hi_2.wav',
|
||||
'east/005_shime_mute.wav',
|
||||
'east/006_taiko_1.wav',
|
||||
'east/007_taiko_2.wav',
|
||||
'east/008_taiko_3.wav',
|
||||
],
|
||||
space: [
|
||||
'space/000_0.wav',
|
||||
'space/001_1.wav',
|
||||
'space/002_11.wav',
|
||||
'space/003_12.wav',
|
||||
'space/004_13.wav',
|
||||
'space/005_14.wav',
|
||||
'space/006_15.wav',
|
||||
'space/007_16.wav',
|
||||
'space/008_17.wav',
|
||||
'space/009_18.wav',
|
||||
'space/010_2.wav',
|
||||
'space/011_3.wav',
|
||||
'space/012_4.wav',
|
||||
'space/013_5.wav',
|
||||
'space/014_6.wav',
|
||||
'space/015_7.wav',
|
||||
'space/016_8.wav',
|
||||
'space/017_9.wav',
|
||||
],
|
||||
numbers: [
|
||||
'numbers/0.wav',
|
||||
'numbers/1.wav',
|
||||
'numbers/2.wav',
|
||||
'numbers/3.wav',
|
||||
'numbers/4.wav',
|
||||
'numbers/5.wav',
|
||||
'numbers/6.wav',
|
||||
'numbers/7.wav',
|
||||
'numbers/8.wav',
|
||||
],
|
||||
num: [
|
||||
'num/00.wav',
|
||||
'num/01.wav',
|
||||
'num/02.wav',
|
||||
'num/03.wav',
|
||||
'num/04.wav',
|
||||
'num/05.wav',
|
||||
'num/06.wav',
|
||||
'num/07.wav',
|
||||
'num/08.wav',
|
||||
'num/09.wav',
|
||||
'num/10.wav',
|
||||
'num/11.wav',
|
||||
'num/12.wav',
|
||||
'num/13.wav',
|
||||
'num/14.wav',
|
||||
'num/15.wav',
|
||||
'num/16.wav',
|
||||
'num/17.wav',
|
||||
'num/18.wav',
|
||||
'num/19.wav',
|
||||
'num/20.wav',
|
||||
],
|
||||
},
|
||||
'github:tidalcycles/dirt-samples',
|
||||
{
|
||||
prebake: true,
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
// aliasBank(`${baseNoTrailing}/tidal-drum-machines-alias.json`);
|
||||
// }
|
||||
aliasBank(`${baseNoTrailing}/tidal-drum-machines-alias.json`);
|
||||
}
|
||||
|
||||
const maxPan = noteToMidi('C8');
|
||||
const panwidth = (pan, width) => pan * width + (1 - width) / 2;
|
||||
|
||||
@@ -31,7 +31,7 @@ import {
|
||||
import { superdirtOutput } from '@strudel/osc/superdirtoutput';
|
||||
import { audioEngineTargets } from '../settings.mjs';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { prebake } from '../../../packages/repl/prebake.mjs'
|
||||
import { prebake } from './prebake.mjs';
|
||||
import { getRandomTune, initCode, loadModules, shareCode } from './util.mjs';
|
||||
import './Repl.css';
|
||||
import { setInterval, clearInterval } from 'worker-timers';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { evalScope, hash2code, logger } from '@strudel/core';
|
||||
import { hash2code, logger } from '@strudel/core';
|
||||
import { evalScope } from '@strudel/cyclist';
|
||||
import { settingPatterns } from '../settings.mjs';
|
||||
import { setVersionDefaults } from '@strudel/webaudio';
|
||||
import { getMetadata } from '../metadata_parser';
|
||||
|
||||
@@ -197,7 +197,7 @@ export async function importPatterns(fileList) {
|
||||
if (file.type === 'application/json') {
|
||||
const userPatterns = userPattern.getAll();
|
||||
setUserPatterns({ ...userPatterns, ...parseJSON(content) });
|
||||
} else if (['text/x-markdown', 'text/plain'].includes(file.type)) {
|
||||
} else if (file.type === 'text/plain') {
|
||||
const id = file.name.replace(/\.[^/.]+$/, '');
|
||||
userPattern.update(id, { code: content });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user