mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-14 07:08:30 +00:00
Merge branch 'tidalcycles:main' into phaser
This commit is contained in:
commit
c89f91215c
@ -83,7 +83,7 @@ Please report any problems you've had with the setup instructions!
|
||||
|
||||
To make sure the code changes only where it should, we are using prettier to unify the code style.
|
||||
|
||||
- You can format all files at once by running `pnpm prettier` from the project root
|
||||
- You can format all files at once by running `pnpm codeformat` from the project root
|
||||
- Run `pnpm format-check` from the project root to check if all files are well formatted
|
||||
|
||||
If you use VSCode, you can
|
||||
|
||||
@ -47,7 +47,7 @@ If you want to automatically deploy your site on push, go to `deploy.yml` and ch
|
||||
## running locally
|
||||
|
||||
- install dependencies with `npm run setup`
|
||||
- run dev server with `npm run repl` and open `http://localhost:3000/strudel/swatch/`
|
||||
- run dev server with `npm run repl` and open `http://localhost:4321/strudel/swatch/`
|
||||
|
||||
## tests fail?
|
||||
|
||||
|
||||
@ -1318,6 +1318,17 @@ generic_params.forEach(([names, ...aliases]) => {
|
||||
controls.createParams = (...names) =>
|
||||
names.reduce((acc, name) => Object.assign(acc, { [name]: controls.createParam(name) }), {});
|
||||
|
||||
/**
|
||||
* ADSR envelope: Combination of Attack, Decay, Sustain, and Release.
|
||||
*
|
||||
* @name adsr
|
||||
* @param {number | Pattern} time attack time in seconds
|
||||
* @param {number | Pattern} time decay time in seconds
|
||||
* @param {number | Pattern} gain sustain level (0 to 1)
|
||||
* @param {number | Pattern} time release time in seconds
|
||||
* @example
|
||||
* note("<c3 bb2 f3 eb3>").sound("sawtooth").lpf(600).adsr(".1:.1:.5:.2")
|
||||
*/
|
||||
controls.adsr = register('adsr', (adsr, pat) => {
|
||||
adsr = !Array.isArray(adsr) ? [adsr] : adsr;
|
||||
const [attack, decay, sustain, release] = adsr;
|
||||
|
||||
@ -2100,23 +2100,43 @@ export const { iterBack, iterback } = register(['iterBack', 'iterback'], functio
|
||||
return _iter(times, pat, true);
|
||||
});
|
||||
|
||||
/**
|
||||
* Repeats each cycle the given number of times.
|
||||
* @name repeatCycles
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* note(irand(12).add(34)).segment(4).repeatCycles(2).s("gm_acoustic_guitar_nylon")
|
||||
*/
|
||||
const _repeatCycles = function (n, pat) {
|
||||
return slowcat(...Array(n).fill(pat));
|
||||
};
|
||||
|
||||
const { repeatCycles } = register('repeatCycles', _repeatCycles);
|
||||
|
||||
/**
|
||||
* Divides a pattern into a given number of parts, then cycles through those parts in turn, applying the given function to each part in turn (one part per cycle).
|
||||
* @name chunk
|
||||
* @synonyms slowChunk, slowchunk
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "0 1 2 3".chunk(4, x=>x.add(7)).scale('A minor').note()
|
||||
*/
|
||||
const _chunk = function (n, func, pat, back = false) {
|
||||
const _chunk = function (n, func, pat, back = false, fast = false) {
|
||||
const binary = Array(n - 1).fill(false);
|
||||
binary.unshift(true);
|
||||
const binary_pat = _iter(n, sequence(...binary), back);
|
||||
// Invert the 'back' because we want to shift the pattern forwards,
|
||||
// and so time backwards
|
||||
const binary_pat = _iter(n, sequence(...binary), !back);
|
||||
if (!fast) {
|
||||
pat = pat.repeatCycles(n);
|
||||
}
|
||||
return pat.when(binary_pat, func);
|
||||
};
|
||||
|
||||
export const chunk = register('chunk', function (n, func, pat) {
|
||||
return _chunk(n, func, pat, false);
|
||||
const { chunk, slowchunk, slowChunk } = register(['chunk', 'slowchunk', 'slowChunk'], function (n, func, pat) {
|
||||
return _chunk(n, func, pat, false, false);
|
||||
});
|
||||
|
||||
/**
|
||||
@ -2132,6 +2152,21 @@ export const { chunkBack, chunkback } = register(['chunkBack', 'chunkback'], fun
|
||||
return _chunk(n, func, pat, true);
|
||||
});
|
||||
|
||||
/**
|
||||
* Like `chunk`, but the cycles of the source pattern aren't repeated
|
||||
* for each set of chunks.
|
||||
* @name fastChunk
|
||||
* @synonyms fastchunk
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "<0 8> 1 2 3 4 5 6 7".fastChunk(4, x => x.color('red')).slow(4).scale("C2:major").note()
|
||||
.s("folkharp")
|
||||
*/
|
||||
const { fastchunk, fastChunk } = register(['fastchunk', 'fastChunk'], function (n, func, pat) {
|
||||
return _chunk(n, func, pat, false, true);
|
||||
});
|
||||
|
||||
// TODO - redefine elsewhere in terms of mask
|
||||
export const bypass = register('bypass', function (on, pat) {
|
||||
on = Boolean(parseInt(on));
|
||||
@ -2357,3 +2392,29 @@ export const ref = (accessor) =>
|
||||
pure(1)
|
||||
.withValue(() => reify(accessor()))
|
||||
.innerJoin();
|
||||
|
||||
let fadeGain = (p) => (p < 0.5 ? 1 : 1 - (p - 0.5) / 0.5);
|
||||
|
||||
/**
|
||||
* Cross-fades between left and right from 0 to 1:
|
||||
* - 0 = (full left, no right)
|
||||
* - .5 = (both equal)
|
||||
* - 1 = (no left, full right)
|
||||
*
|
||||
* @name xfade
|
||||
* @example
|
||||
* xfade(s("bd*2"), "<0 .25 .5 .75 1>", s("hh*8"))
|
||||
*/
|
||||
export let xfade = (a, pos, b) => {
|
||||
pos = reify(pos);
|
||||
a = reify(a);
|
||||
b = reify(b);
|
||||
let gaina = pos.fmap((v) => ({ gain: fadeGain(v) }));
|
||||
let gainb = pos.fmap((v) => ({ gain: fadeGain(1 - v) }));
|
||||
return stack(a.mul(gaina), b.mul(gainb));
|
||||
};
|
||||
|
||||
// the prototype version is actually flipped so left/right makes sense
|
||||
Pattern.prototype.xfade = function (pos, b) {
|
||||
return xfade(this, pos, b);
|
||||
};
|
||||
|
||||
@ -1003,4 +1003,23 @@ describe('Pattern', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('chunk', () => {
|
||||
it('Processes each cycle of the source pattern multiple times, once for each chunk', () => {
|
||||
expect(sequence(0, 1, 2, 3).slow(2).chunk(2, add(10)).fast(4).firstCycleValues).toStrictEqual([
|
||||
10, 1, 0, 11, 12, 3, 2, 13,
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe('fastChunk', () => {
|
||||
it('Unlike chunk, cycles of the source pattern proceed cycle-by-cycle', () => {
|
||||
expect(sequence(0, 1, 2, 3).slow(2).fastChunk(2, add(10)).fast(4).firstCycleValues).toStrictEqual([
|
||||
10, 1, 2, 13, 10, 1, 2, 13,
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe('repeatCycles', () => {
|
||||
it('Repeats each cycle of the source pattern the given number of times', () => {
|
||||
expect(slowcat(0, 1).repeatCycles(2).fast(6).firstCycleValues).toStrictEqual([0, 0, 1, 1, 0, 0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -33,12 +33,17 @@
|
||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.6.0",
|
||||
"@codemirror/commands": "^6.0.0",
|
||||
"@codemirror/lang-javascript": "^6.1.7",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/lint": "^6.0.0",
|
||||
"@codemirror/search": "^6.0.0",
|
||||
"@codemirror/state": "^6.2.0",
|
||||
"@codemirror/view": "^6.10.0",
|
||||
"@lezer/highlight": "^1.1.4",
|
||||
"@replit/codemirror-emacs": "^6.0.1",
|
||||
"@replit/codemirror-vim": "^6.0.14",
|
||||
"@replit/codemirror-vscode-keymap": "^6.0.2",
|
||||
"@strudel.cycles/core": "workspace:*",
|
||||
"@strudel.cycles/transpiler": "workspace:*",
|
||||
"@strudel.cycles/webaudio": "workspace:*",
|
||||
|
||||
@ -26,7 +26,6 @@ export function Autocomplete({ doc }) {
|
||||
<pre
|
||||
className="cursor-pointer"
|
||||
onMouseDown={(e) => {
|
||||
console.log('ola!');
|
||||
navigator.clipboard.writeText(example);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
import { autocompletion } from '@codemirror/autocomplete';
|
||||
import { Prec } from '@codemirror/state';
|
||||
import { javascript, javascriptLanguage } from '@codemirror/lang-javascript';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
import { ViewPlugin, EditorView, keymap } from '@codemirror/view';
|
||||
import { emacs } from '@replit/codemirror-emacs';
|
||||
import { vim } from '@replit/codemirror-vim';
|
||||
import { vscodeKeymap } from '@replit/codemirror-vscode-keymap';
|
||||
import _CodeMirror from '@uiw/react-codemirror';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import strudelTheme from '../themes/strudel-theme';
|
||||
import { strudelAutocomplete } from './Autocomplete';
|
||||
import { strudelTooltip } from './Tooltip';
|
||||
import {
|
||||
highlightExtension,
|
||||
flashField,
|
||||
@ -31,6 +34,7 @@ export default function CodeMirror({
|
||||
keybindings,
|
||||
isLineNumbersDisplayed,
|
||||
isAutoCompletionEnabled,
|
||||
isTooltipEnabled,
|
||||
isLineWrappingEnabled,
|
||||
fontSize = 18,
|
||||
fontFamily = 'monospace',
|
||||
@ -61,11 +65,25 @@ export default function CodeMirror({
|
||||
[onSelectionChange],
|
||||
);
|
||||
|
||||
const vscodePlugin = ViewPlugin.fromClass(
|
||||
class {
|
||||
constructor(view) {}
|
||||
},
|
||||
{
|
||||
provide: (plugin) => {
|
||||
return Prec.highest(keymap.of([...vscodeKeymap]));
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const vscodeExtension = (options) => [vscodePlugin].concat(options ?? []);
|
||||
|
||||
const extensions = useMemo(() => {
|
||||
let _extensions = [...staticExtensions];
|
||||
let bindings = {
|
||||
vim,
|
||||
emacs,
|
||||
vscode: vscodeExtension,
|
||||
};
|
||||
|
||||
if (bindings[keybindings]) {
|
||||
@ -78,12 +96,18 @@ export default function CodeMirror({
|
||||
_extensions.push(autocompletion({ override: [] }));
|
||||
}
|
||||
|
||||
if (isTooltipEnabled) {
|
||||
_extensions.push(strudelTooltip);
|
||||
}
|
||||
|
||||
_extensions.push([keymap.of({})]);
|
||||
|
||||
if (isLineWrappingEnabled) {
|
||||
_extensions.push(EditorView.lineWrapping);
|
||||
}
|
||||
|
||||
return _extensions;
|
||||
}, [keybindings, isAutoCompletionEnabled, isLineWrappingEnabled]);
|
||||
}, [keybindings, isAutoCompletionEnabled, isTooltipEnabled, isLineWrappingEnabled]);
|
||||
|
||||
const basicSetup = useMemo(() => ({ lineNumbers: isLineNumbersDisplayed }), [isLineNumbersDisplayed]);
|
||||
|
||||
|
||||
69
packages/react/src/components/Tooltip.jsx
Normal file
69
packages/react/src/components/Tooltip.jsx
Normal file
@ -0,0 +1,69 @@
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { hoverTooltip } from '@codemirror/view';
|
||||
import jsdoc from '../../../../doc.json';
|
||||
import { Autocomplete } from './Autocomplete';
|
||||
|
||||
const getDocLabel = (doc) => doc.name || doc.longname;
|
||||
|
||||
let ctrlDown = false;
|
||||
|
||||
// Record Control key event to trigger or block the tooltip depending on the state
|
||||
window.addEventListener(
|
||||
'keyup',
|
||||
function (e) {
|
||||
if (e.key == 'Control') {
|
||||
ctrlDown = false;
|
||||
}
|
||||
},
|
||||
true,
|
||||
);
|
||||
|
||||
window.addEventListener(
|
||||
'keydown',
|
||||
function (e) {
|
||||
if (e.key == 'Control') {
|
||||
ctrlDown = true;
|
||||
}
|
||||
},
|
||||
true,
|
||||
);
|
||||
|
||||
export const strudelTooltip = hoverTooltip(
|
||||
(view, pos, side) => {
|
||||
// Word selection from CodeMirror Hover Tooltip example https://codemirror.net/examples/tooltip/#hover-tooltips
|
||||
let { from, to, text } = view.state.doc.lineAt(pos);
|
||||
let start = pos,
|
||||
end = pos;
|
||||
while (start > from && /\w/.test(text[start - from - 1])) {
|
||||
start--;
|
||||
}
|
||||
while (end < to && /\w/.test(text[end - from])) {
|
||||
end++;
|
||||
}
|
||||
if ((start == pos && side < 0) || (end == pos && side > 0)) {
|
||||
return null;
|
||||
}
|
||||
let word = text.slice(start - from, end - from);
|
||||
// Get entry from Strudel documentation
|
||||
let entry = jsdoc.docs.filter((doc) => getDocLabel(doc) === word)[0];
|
||||
if (!entry) {
|
||||
return null;
|
||||
}
|
||||
if (!ctrlDown) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
pos: start,
|
||||
end,
|
||||
above: false,
|
||||
arrow: true,
|
||||
create(view) {
|
||||
let dom = document.createElement('div');
|
||||
dom.className = 'strudel-tooltip';
|
||||
createRoot(dom).render(<Autocomplete doc={entry} />);
|
||||
return { dom };
|
||||
},
|
||||
};
|
||||
},
|
||||
{ hoverTime: 10 },
|
||||
);
|
||||
@ -28,3 +28,7 @@
|
||||
footer {
|
||||
z-index: 0 !important;
|
||||
}
|
||||
|
||||
.strudel-tooltip {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
@ -162,9 +162,17 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option
|
||||
if (handler) {
|
||||
return handler(sampleMap);
|
||||
}
|
||||
if (sampleMap.startsWith('bubo:')) {
|
||||
const [_, repo] = sampleMap.split(':');
|
||||
sampleMap = `github:Bubobubobubobubo/dough-${repo}`;
|
||||
}
|
||||
if (sampleMap.startsWith('github:')) {
|
||||
let [_, path] = sampleMap.split('github:');
|
||||
path = path.endsWith('/') ? path.slice(0, -1) : path;
|
||||
if (path.split('/').length === 2) {
|
||||
// assume main as default branch if none set
|
||||
path += '/main';
|
||||
}
|
||||
sampleMap = `https://raw.githubusercontent.com/${path}/strudel.json`;
|
||||
}
|
||||
if (sampleMap.startsWith('shabda:')) {
|
||||
|
||||
@ -3,7 +3,7 @@ import { analyser, getAnalyzerData } from 'superdough';
|
||||
|
||||
export function drawTimeScope(
|
||||
analyser,
|
||||
{ align = true, color = 'white', thickness = 3, scale = 0.25, pos = 0.75, next = 1, trigger = 0 } = {},
|
||||
{ align = true, color = 'white', thickness = 3, scale = 0.25, pos = 0.75, trigger = 0 } = {},
|
||||
) {
|
||||
const ctx = getDrawContext();
|
||||
const dataArray = getAnalyzerData('time');
|
||||
@ -22,10 +22,9 @@ export function drawTimeScope(
|
||||
|
||||
const sliceWidth = (canvas.width * 1.0) / bufferSize;
|
||||
let x = 0;
|
||||
|
||||
for (let i = triggerIndex; i < bufferSize; i++) {
|
||||
const v = dataArray[i] + 1;
|
||||
const y = (1 - (scale * (v - 1) + pos)) * canvas.height;
|
||||
const y = (pos - scale * (v - 1)) * canvas.height;
|
||||
|
||||
if (i === 0) {
|
||||
ctx.moveTo(x, y);
|
||||
@ -71,6 +70,18 @@ function clearScreen(smear = 0, smearRGB = `0,0,0`) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an oscilloscope for the frequency domain of the audio signal.
|
||||
* @name fscope
|
||||
* @param {string} color line color as hex or color name. defaults to white.
|
||||
* @param {number} scale scales the y-axis. Defaults to 0.25
|
||||
* @param {number} pos y-position relative to screen height. 0 = top, 1 = bottom of screen
|
||||
* @param {number} lean y-axis alignment where 0 = top and 1 = bottom
|
||||
* @param {number} min min value
|
||||
* @param {number} max max value
|
||||
* @example
|
||||
* s("sawtooth").fscope()
|
||||
*/
|
||||
Pattern.prototype.fscope = function (config = {}) {
|
||||
return this.analyze(1).draw(() => {
|
||||
clearScreen(config.smear);
|
||||
@ -78,6 +89,20 @@ Pattern.prototype.fscope = function (config = {}) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an oscilloscope for the time domain of the audio signal.
|
||||
* @name scope
|
||||
* @synonyms tscope
|
||||
* @param {object} config optional config with options:
|
||||
* @param {boolean} align if 1, the scope will be aligned to the first zero crossing. defaults to 1
|
||||
* @param {string} color line color as hex or color name. defaults to white.
|
||||
* @param {number} thickness line thickness. defaults to 3
|
||||
* @param {number} scale scales the y-axis. Defaults to 0.25
|
||||
* @param {number} pos y-position relative to screen height. 0 = top, 1 = bottom of screen
|
||||
* @param {number} trigger amplitude value that is used to align the scope. defaults to 0.
|
||||
* @example
|
||||
* s("sawtooth").scope()
|
||||
*/
|
||||
Pattern.prototype.tscope = function (config = {}) {
|
||||
return this.analyze(1).draw(() => {
|
||||
clearScreen(config.smear);
|
||||
|
||||
2692
pnpm-lock.yaml
generated
2692
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
91
src-tauri/Cargo.lock
generated
91
src-tauri/Cargo.lock
generated
@ -1727,6 +1727,17 @@ dependencies = [
|
||||
"objc_exception",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc-foundation"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
|
||||
dependencies = [
|
||||
"block",
|
||||
"objc",
|
||||
"objc_id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc_exception"
|
||||
version = "0.1.2"
|
||||
@ -2190,6 +2201,30 @@ version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
||||
|
||||
[[package]]
|
||||
name = "rfd"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0149778bd99b6959285b0933288206090c50e2327f47a9c463bfdbf45c8823ea"
|
||||
dependencies = [
|
||||
"block",
|
||||
"dispatch",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gtk-sys",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"objc",
|
||||
"objc-foundation",
|
||||
"objc_id",
|
||||
"raw-window-handle",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"windows 0.37.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rosc"
|
||||
version = "0.10.1"
|
||||
@ -2696,6 +2731,7 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"rand 0.8.5",
|
||||
"raw-window-handle",
|
||||
"rfd",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -3251,6 +3287,18 @@ dependencies = [
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.87"
|
||||
@ -3406,6 +3454,19 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647"
|
||||
dependencies = [
|
||||
"windows_aarch64_msvc 0.37.0",
|
||||
"windows_i686_gnu 0.37.0",
|
||||
"windows_i686_msvc 0.37.0",
|
||||
"windows_x86_64_gnu 0.37.0",
|
||||
"windows_x86_64_msvc 0.37.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.39.0"
|
||||
@ -3512,6 +3573,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.39.0"
|
||||
@ -3530,6 +3597,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.39.0"
|
||||
@ -3548,6 +3621,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.39.0"
|
||||
@ -3566,6 +3645,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.39.0"
|
||||
@ -3596,6 +3681,12 @@ version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.39.0"
|
||||
|
||||
@ -17,7 +17,7 @@ tauri-build = { version = "1.4.0", features = [] }
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tauri = { version = "1.4.0", features = ["fs-all"] }
|
||||
tauri = { version = "1.4.0", features = [ "dialog-all", "clipboard-write-text", "fs-all"] }
|
||||
midir = "0.9.1"
|
||||
tokio = { version = "1.29.0", features = ["full"] }
|
||||
rosc = "0.10.1"
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"build": {
|
||||
"beforeBuildCommand": "npm run build",
|
||||
"beforeDevCommand": "npm run dev",
|
||||
"devPath": "http://localhost:3000",
|
||||
"devPath": "http://localhost:4321",
|
||||
"distDir": "../website/dist",
|
||||
"withGlobalTauri": true
|
||||
},
|
||||
@ -13,6 +13,12 @@
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
"dialog": {
|
||||
"all": true
|
||||
},
|
||||
"clipboard": {
|
||||
"writeText": true
|
||||
},
|
||||
"all": false,
|
||||
"fs": {
|
||||
"all": true,
|
||||
|
||||
@ -633,6 +633,15 @@ exports[`runs examples > example "addVoicings" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "adsr" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | note:c3 s:sawtooth cutoff:600 ]",
|
||||
"[ 1/1 → 2/1 | note:bb2 s:sawtooth cutoff:600 ]",
|
||||
"[ 2/1 → 3/1 | note:f3 s:sawtooth cutoff:600 ]",
|
||||
"[ 3/1 → 4/1 | note:eb3 s:sawtooth cutoff:600 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "almostAlways" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | s:hh speed:0.5 ]",
|
||||
@ -1106,27 +1115,6 @@ exports[`runs examples > example "chop" example index 0 1`] = `
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "chunk" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:A4 ]",
|
||||
"[ 1/4 → 1/2 | note:B3 ]",
|
||||
"[ 1/2 → 3/4 | note:C4 ]",
|
||||
"[ 3/4 → 1/1 | note:D4 ]",
|
||||
"[ 1/1 → 5/4 | note:A3 ]",
|
||||
"[ 5/4 → 3/2 | note:B3 ]",
|
||||
"[ 3/2 → 7/4 | note:C4 ]",
|
||||
"[ 7/4 → 2/1 | note:D5 ]",
|
||||
"[ 2/1 → 9/4 | note:A3 ]",
|
||||
"[ 9/4 → 5/2 | note:B3 ]",
|
||||
"[ 5/2 → 11/4 | note:C5 ]",
|
||||
"[ 11/4 → 3/1 | note:D4 ]",
|
||||
"[ 3/1 → 13/4 | note:A3 ]",
|
||||
"[ 13/4 → 7/2 | note:B4 ]",
|
||||
"[ 7/2 → 15/4 | note:C4 ]",
|
||||
"[ 15/4 → 4/1 | note:D4 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "chunkBack" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:A4 ]",
|
||||
"[ 1/4 → 1/2 | note:B3 ]",
|
||||
@ -1147,6 +1135,27 @@ exports[`runs examples > example "chunkBack" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "chunkBack" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:A4 ]",
|
||||
"[ 1/4 → 1/2 | note:B3 ]",
|
||||
"[ 1/2 → 3/4 | note:C4 ]",
|
||||
"[ 3/4 → 1/1 | note:D4 ]",
|
||||
"[ 1/1 → 5/4 | note:A3 ]",
|
||||
"[ 5/4 → 3/2 | note:B3 ]",
|
||||
"[ 3/2 → 7/4 | note:C4 ]",
|
||||
"[ 7/4 → 2/1 | note:D5 ]",
|
||||
"[ 2/1 → 9/4 | note:A3 ]",
|
||||
"[ 9/4 → 5/2 | note:B3 ]",
|
||||
"[ 5/2 → 11/4 | note:C5 ]",
|
||||
"[ 11/4 → 3/1 | note:D4 ]",
|
||||
"[ 3/1 → 13/4 | note:A3 ]",
|
||||
"[ 13/4 → 7/2 | note:B4 ]",
|
||||
"[ 7/2 → 15/4 | note:C4 ]",
|
||||
"[ 15/4 → 4/1 | note:D4 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "clip" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:c s:piano clip:0.5 ]",
|
||||
@ -1848,6 +1857,19 @@ exports[`runs examples > example "fast" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fastChunk" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | note:C2 s:folkharp ]",
|
||||
"[ 1/2 → 1/1 | note:D2 s:folkharp ]",
|
||||
"[ 1/1 → 3/2 | note:E2 s:folkharp ]",
|
||||
"[ 3/2 → 2/1 | note:F2 s:folkharp ]",
|
||||
"[ 2/1 → 5/2 | note:G2 s:folkharp ]",
|
||||
"[ 5/2 → 3/1 | note:A2 s:folkharp ]",
|
||||
"[ 3/1 → 7/2 | note:B2 s:folkharp ]",
|
||||
"[ 7/2 → 4/1 | note:C3 s:folkharp ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fastGap" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd ]",
|
||||
@ -2121,6 +2143,15 @@ exports[`runs examples > example "freq" example index 1 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fscope" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 1/1 → 2/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 2/1 → 3/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 3/1 → 4/1 | s:sawtooth analyze:1 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "ftype" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | note:c2 s:sawtooth cutoff:500 bpenv:4 ftype:12db ]",
|
||||
@ -3275,6 +3306,23 @@ exports[`runs examples > example "perlin" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "pick" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | note:g ]",
|
||||
"[ 1/2 → 1/1 | note:a ]",
|
||||
"[ 1/1 → 3/2 | note:e ]",
|
||||
"[ 3/2 → 2/1 | note:f ]",
|
||||
"[ 2/1 → 9/4 | note:f ]",
|
||||
"[ 9/4 → 5/2 | note:g ]",
|
||||
"[ 5/2 → 11/4 | note:f ]",
|
||||
"[ 11/4 → 3/1 | note:g ]",
|
||||
"[ 3/1 → 13/4 | note:g ]",
|
||||
"[ 13/4 → 7/2 | note:a ]",
|
||||
"[ 7/2 → 15/4 | note:c ]",
|
||||
"[ 15/4 → 4/1 | note:d ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "ply" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd ]",
|
||||
@ -3620,6 +3668,27 @@ exports[`runs examples > example "release" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "repeatCycles" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:42 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 1/4 → 1/2 | note:38 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 1/2 → 3/4 | note:35 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 3/4 → 1/1 | note:38 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 1/1 → 5/4 | note:42 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 5/4 → 3/2 | note:38 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 3/2 → 7/4 | note:35 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 7/4 → 2/1 | note:38 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 2/1 → 9/4 | note:42 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 9/4 → 5/2 | note:36 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 5/2 → 11/4 | note:39 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 11/4 → 3/1 | note:41 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 3/1 → 13/4 | note:42 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 13/4 → 7/2 | note:36 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 7/2 → 15/4 | note:39 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 15/4 → 4/1 | note:41 s:gm_acoustic_guitar_nylon ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "reset" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:hh ]",
|
||||
@ -4175,6 +4244,15 @@ exports[`runs examples > example "scaleTranspose" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "scope" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 1/1 → 2/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 2/1 → 3/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 3/1 → 4/1 | s:sawtooth analyze:1 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "segment" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/24 | note:40.25 ]",
|
||||
@ -4612,6 +4690,25 @@ exports[`runs examples > example "square" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "squeeze" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | note:g ]",
|
||||
"[ 1/1 → 2/1 | note:a ]",
|
||||
"[ 2/1 → 17/8 | note:f ]",
|
||||
"[ 17/8 → 9/4 | note:g ]",
|
||||
"[ 9/4 → 19/8 | note:f ]",
|
||||
"[ 19/8 → 5/2 | note:g ]",
|
||||
"[ 5/2 → 21/8 | note:f ]",
|
||||
"[ 21/8 → 11/4 | note:g ]",
|
||||
"[ 11/4 → 23/8 | note:f ]",
|
||||
"[ 23/8 → 3/1 | note:g ]",
|
||||
"[ 3/1 → 13/4 | note:g ]",
|
||||
"[ 13/4 → 7/2 | note:a ]",
|
||||
"[ 7/2 → 15/4 | note:c ]",
|
||||
"[ 15/4 → 4/1 | note:d ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "squiz" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | squiz:2 s:bd ]",
|
||||
@ -5156,6 +5253,51 @@ exports[`runs examples > example "withValue" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "xfade" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | s:hh gain:0 ]",
|
||||
"[ 0/1 → 1/2 | s:bd gain:1 ]",
|
||||
"[ 1/8 → 1/4 | s:hh gain:0 ]",
|
||||
"[ 1/4 → 3/8 | s:hh gain:0 ]",
|
||||
"[ 3/8 → 1/2 | s:hh gain:0 ]",
|
||||
"[ 1/2 → 5/8 | s:hh gain:0 ]",
|
||||
"[ 1/2 → 1/1 | s:bd gain:1 ]",
|
||||
"[ 5/8 → 3/4 | s:hh gain:0 ]",
|
||||
"[ 3/4 → 7/8 | s:hh gain:0 ]",
|
||||
"[ 7/8 → 1/1 | s:hh gain:0 ]",
|
||||
"[ 1/1 → 9/8 | s:hh gain:0.5 ]",
|
||||
"[ 1/1 → 3/2 | s:bd gain:1 ]",
|
||||
"[ 9/8 → 5/4 | s:hh gain:0.5 ]",
|
||||
"[ 5/4 → 11/8 | s:hh gain:0.5 ]",
|
||||
"[ 11/8 → 3/2 | s:hh gain:0.5 ]",
|
||||
"[ 3/2 → 13/8 | s:hh gain:0.5 ]",
|
||||
"[ 3/2 → 2/1 | s:bd gain:1 ]",
|
||||
"[ 13/8 → 7/4 | s:hh gain:0.5 ]",
|
||||
"[ 7/4 → 15/8 | s:hh gain:0.5 ]",
|
||||
"[ 15/8 → 2/1 | s:hh gain:0.5 ]",
|
||||
"[ 2/1 → 17/8 | s:hh gain:1 ]",
|
||||
"[ 2/1 → 5/2 | s:bd gain:1 ]",
|
||||
"[ 17/8 → 9/4 | s:hh gain:1 ]",
|
||||
"[ 9/4 → 19/8 | s:hh gain:1 ]",
|
||||
"[ 19/8 → 5/2 | s:hh gain:1 ]",
|
||||
"[ 5/2 → 21/8 | s:hh gain:1 ]",
|
||||
"[ 5/2 → 3/1 | s:bd gain:1 ]",
|
||||
"[ 21/8 → 11/4 | s:hh gain:1 ]",
|
||||
"[ 11/4 → 23/8 | s:hh gain:1 ]",
|
||||
"[ 23/8 → 3/1 | s:hh gain:1 ]",
|
||||
"[ 3/1 → 25/8 | s:hh gain:1 ]",
|
||||
"[ 3/1 → 7/2 | s:bd gain:0.5 ]",
|
||||
"[ 25/8 → 13/4 | s:hh gain:1 ]",
|
||||
"[ 13/4 → 27/8 | s:hh gain:1 ]",
|
||||
"[ 27/8 → 7/2 | s:hh gain:1 ]",
|
||||
"[ 7/2 → 29/8 | s:hh gain:1 ]",
|
||||
"[ 7/2 → 4/1 | s:bd gain:0.5 ]",
|
||||
"[ 29/8 → 15/4 | s:hh gain:1 ]",
|
||||
"[ 15/4 → 31/8 | s:hh gain:1 ]",
|
||||
"[ 31/8 → 4/1 | s:hh gain:1 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "zoom" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/6 | s:hh ]",
|
||||
|
||||
@ -56,7 +56,7 @@ All commands are run from the root of the project, from a terminal:
|
||||
| Command | Action |
|
||||
| :--------------------- | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:3000` |
|
||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
|
||||
@ -50,6 +50,7 @@ export default defineConfig({
|
||||
mdx(options),
|
||||
tailwind(),
|
||||
AstroPWA({
|
||||
experimental: { directoryAndTrailingSlashHandler: true },
|
||||
registerType: 'autoUpdate',
|
||||
injectRegister: 'auto',
|
||||
workbox: {
|
||||
|
||||
@ -13,9 +13,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/client-search": "^4.17.0",
|
||||
"@astrojs/mdx": "^0.19.0",
|
||||
"@astrojs/react": "^2.1.1",
|
||||
"@astrojs/tailwind": "^3.1.1",
|
||||
"@astrojs/mdx": "^1.1.3",
|
||||
"@astrojs/react": "^3.0.4",
|
||||
"@astrojs/tailwind": "^5.0.2",
|
||||
"@docsearch/css": "^3.3.4",
|
||||
"@docsearch/react": "^3.3.4",
|
||||
"@headlessui/react": "^1.7.14",
|
||||
@ -45,7 +45,7 @@
|
||||
"@types/react": "^18.2.0",
|
||||
"@types/react-dom": "^18.2.1",
|
||||
"@uiw/codemirror-themes-all": "^4.19.16",
|
||||
"astro": "^2.3.2",
|
||||
"astro": "^3.4.2",
|
||||
"canvas": "^2.11.2",
|
||||
"claviature": "^0.1.0",
|
||||
"fraction.js": "^4.2.0",
|
||||
@ -60,7 +60,7 @@
|
||||
"tailwindcss": "^3.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vite-pwa/astro": "file:vite-pwa-astro-0.1.3.tgz",
|
||||
"@vite-pwa/astro": "^0.1.4",
|
||||
"html-escaper": "^3.0.3",
|
||||
"vite-plugin-pwa": "^0.16.5",
|
||||
"workbox-window": "^7.0.0"
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
.cm-activeLine,
|
||||
.cm-activeLineGutter {
|
||||
.mini-repl .cm-activeLine,
|
||||
.mini-repl .cm-activeLineGutter {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.cm-theme {
|
||||
.mini-repl .cm-theme {
|
||||
background-color: var(--background);
|
||||
border: 1px solid var(--lineHighlight);
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.cm-scroller {
|
||||
.mini-repl .cm-scroller {
|
||||
font-family: inherit !important;
|
||||
}
|
||||
|
||||
.cm-gutters {
|
||||
.mini-repl .cm-gutters {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cm-cursorLayer {
|
||||
.mini-repl .cm-cursorLayer {
|
||||
animation-name: inherit !important;
|
||||
}
|
||||
|
||||
.cm-cursor {
|
||||
.mini-repl .cm-cursor {
|
||||
border-left: 2px solid currentcolor !important;
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ export function MiniRepl({
|
||||
.catch((err) => console.error(err));
|
||||
}, []);
|
||||
return Repl ? (
|
||||
<div className="mb-4">
|
||||
<div className="mb-4 mini-repl">
|
||||
<Repl
|
||||
tune={tune}
|
||||
hideOutsideView={true}
|
||||
|
||||
@ -277,7 +277,7 @@ Das haben wir bisher gelernt:
|
||||
| Schneller | \* | <MiniRepl hideHeader client:visible tune={`sound("bd sd*2 cp*3")`} /> |
|
||||
| Parallel | , | <MiniRepl hideHeader client:visible tune={`sound("bd*2, hh*2 [hh oh]")`} /> |
|
||||
|
||||
Die mit Apostrophen umgebene Mini-Notation benutzt man normalerweise in eine sogenannten Funktion.
|
||||
Die mit Apostrophen umgebene Mini-Notation benutzt man normalerweise in einer sogenannten Funktion.
|
||||
Die folgenden Funktionen haben wir bereits gesehen:
|
||||
|
||||
| Name | Description | Example |
|
||||
|
||||
@ -60,4 +60,12 @@ import { JsDoc } from '../../docs/JsDoc';
|
||||
|
||||
<JsDoc client:idle name="invert" h={0} />
|
||||
|
||||
## pick
|
||||
|
||||
<JsDoc client:idle name="pick" h={0} />
|
||||
|
||||
## squeeze
|
||||
|
||||
<JsDoc client:idle name="squeeze" h={0} />
|
||||
|
||||
After Conditional Modifiers, let's see what [Accumulation Modifiers](/learn/accumulation) have to offer.
|
||||
|
||||
@ -82,6 +82,10 @@ Strudel uses ADSR envelopes, which are probably the most common way to describe
|
||||
|
||||
<JsDoc client:idle name="release" h={0} />
|
||||
|
||||
## adsr
|
||||
|
||||
<JsDoc client:idle name="adsr" h={0} />
|
||||
|
||||
# Filter Envelope
|
||||
|
||||
Each filter can receive an additional filter envelope controlling the cutoff value dynamically. It uses an ADSR envelope similar to the one used for amplitude. There is an additional parameter to control the depth of the filter modulation: `lpenv`|`hpenv`|`bpenv`. This allows you to play subtle or huge filter modulations just the same by only increasing or decreasing the depth.
|
||||
@ -152,6 +156,10 @@ There is one filter envelope for each filter type and thus one set of envelope f
|
||||
|
||||
<JsDoc client:idle name="postgain" h={0} />
|
||||
|
||||
## xfade
|
||||
|
||||
<JsDoc client:idle name="xfade" h={0} />
|
||||
|
||||
# Panning
|
||||
|
||||
## jux
|
||||
|
||||
@ -13,7 +13,7 @@ Just like [Tidal Cycles](https://tidalcycles.org/), Strudel uses a so called "Mi
|
||||
## Note
|
||||
|
||||
This page just explains the entirety of the Mini-Notation syntax.
|
||||
If you are just getting started with Strudel, you can learn the basics of the Mini-Notation in a more practical manner in the [workshop](http://localhost:3000/workshop/first-sounds).
|
||||
If you are just getting started with Strudel, you can learn the basics of the Mini-Notation in a more practical manner in the [workshop](/workshop/first-sounds).
|
||||
After that, you can come back here if you want to understand every little detail.
|
||||
|
||||
## Example
|
||||
|
||||
@ -106,7 +106,7 @@ You can find a [list of available effects here](./learn/effects).
|
||||
|
||||
### Sampler
|
||||
|
||||
Strudel's sampler supports [a subset](http://127.0.0.1:3000/learn/samples) of Superdirt's sampler.
|
||||
Strudel's sampler supports [a subset](/learn/samples) of Superdirt's sampler.
|
||||
Also, samples are always loaded from a URL rather than from the disk, although [that might be possible in the future](https://github.com/tidalcycles/strudel/issues/118).
|
||||
|
||||
## Evaluation
|
||||
|
||||
@ -9,7 +9,7 @@ The docs page is built ontop of astro's [docs site](https://github.com/withastro
|
||||
|
||||
## Adding a new Docs Page
|
||||
|
||||
1. add a `.mdx` file in a path under `website/src/pages/`, e.g. [website/src/pages/learn/code.mdx](https://raw.githubusercontent.com/tidalcycles/strudel/main/website/src/pages/learn/code.mdx) will be available under https://strudel.cc/learn/code (or locally under `http://localhost:3000/learn/code`)
|
||||
1. add a `.mdx` file in a path under `website/src/pages/`, e.g. [website/src/pages/learn/code.mdx](https://raw.githubusercontent.com/tidalcycles/strudel/main/website/src/pages/learn/code.mdx) will be available under https://strudel.cc/learn/code (or locally under `http://localhost:4321/learn/code`)
|
||||
2. make sure to copy the top part of another existing docs page. Adjust the title accordingly
|
||||
3. To add a link to the sidebar, add a new entry to `SIDEBAR` to [`config.ts`](https://github.com/tidalcycles/strudel/blob/main/website/src/config.ts)
|
||||
|
||||
|
||||
@ -385,6 +385,7 @@ function SettingsTab({ scheduler }) {
|
||||
keybindings,
|
||||
isLineNumbersDisplayed,
|
||||
isAutoCompletionEnabled,
|
||||
isTooltipEnabled,
|
||||
isLineWrappingEnabled,
|
||||
fontSize,
|
||||
fontFamily,
|
||||
@ -436,7 +437,7 @@ function SettingsTab({ scheduler }) {
|
||||
<ButtonGroup
|
||||
value={keybindings}
|
||||
onChange={(keybindings) => settingsMap.setKey('keybindings', keybindings)}
|
||||
items={{ codemirror: 'Codemirror', vim: 'Vim', emacs: 'Emacs' }}
|
||||
items={{ codemirror: 'Codemirror', vim: 'Vim', emacs: 'Emacs', vscode: 'VSCode' }}
|
||||
></ButtonGroup>
|
||||
</FormItem>
|
||||
<FormItem label="Panel Position">
|
||||
@ -457,6 +458,11 @@ function SettingsTab({ scheduler }) {
|
||||
onChange={(cbEvent) => settingsMap.setKey('isAutoCompletionEnabled', cbEvent.target.checked)}
|
||||
value={isAutoCompletionEnabled}
|
||||
/>
|
||||
<Checkbox
|
||||
label="Enable tooltips on Ctrl and hover"
|
||||
onChange={(cbEvent) => settingsMap.setKey('isTooltipEnabled', cbEvent.target.checked)}
|
||||
value={isTooltipEnabled}
|
||||
/>
|
||||
<Checkbox
|
||||
label="Enable line wrapping"
|
||||
onChange={(cbEvent) => settingsMap.setKey('isLineWrappingEnabled', cbEvent.target.checked)}
|
||||
|
||||
@ -3,17 +3,31 @@ const visibleFunctions = jsdocJson.docs
|
||||
.filter(({ name, description }) => name && !name.startsWith('_') && !!description)
|
||||
.sort((a, b) => /* a.meta.filename.localeCompare(b.meta.filename) + */ a.name.localeCompare(b.name));
|
||||
|
||||
const getInnerText = (html) => {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = html;
|
||||
return div.textContent || div.innerText || '';
|
||||
};
|
||||
|
||||
export function Reference() {
|
||||
return (
|
||||
<div className="flex h-full w-full pt-2 text-foreground overflow-hidden">
|
||||
<div className="w-42 flex-none h-full overflow-y-auto overflow-x-hidden pr-4">
|
||||
{visibleFunctions.map((entry, i) => (
|
||||
<a key={i} className="cursor-pointer block hover:bg-lineHighlight py-1 px-4" href={`#doc-${i}`}>
|
||||
<a
|
||||
key={i}
|
||||
className="cursor-pointer block hover:bg-lineHighlight py-1 px-4"
|
||||
onClick={() => {
|
||||
const el = document.getElementById(`doc-${i}`);
|
||||
const container = document.getElementById('reference-container');
|
||||
container.scrollTo(0, el.offsetTop);
|
||||
}}
|
||||
>
|
||||
{entry.name} {/* <span className="text-gray-600">{entry.meta.filename}</span> */}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<div className="break-normal w-full h-full overflow-auto pl-4 flex relative">
|
||||
<div className="break-normal w-full h-full overflow-auto pl-4 flex relative" id="reference-container">
|
||||
<div className="prose dark:prose-invert max-w-full pr-4">
|
||||
<h2>API Reference</h2>
|
||||
<p>
|
||||
@ -24,8 +38,14 @@ export function Reference() {
|
||||
<section key={i}>
|
||||
<h3 id={`doc-${i}`}>{entry.name}</h3>
|
||||
{/* <small>{entry.meta.filename}</small> */}
|
||||
|
||||
<p dangerouslySetInnerHTML={{ __html: entry.description }}></p>
|
||||
<ul>
|
||||
{entry.params?.map(({ name, type, description }, i) => (
|
||||
<li key={i}>
|
||||
{name} : {type.names?.join(' | ')} {description ? <> - {getInnerText(description)}</> : ''}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{entry.examples?.map((example, j) => (
|
||||
<pre key={j}>{example}</pre>
|
||||
))}
|
||||
|
||||
@ -23,6 +23,7 @@ import { settingPatterns } from '../settings.mjs';
|
||||
import { code2hash, hash2code } from './helpers.mjs';
|
||||
import { isTauri } from '../tauri.mjs';
|
||||
import { useWidgets } from '@strudel.cycles/react/src/hooks/useWidgets.mjs';
|
||||
import { writeText } from '@tauri-apps/api/clipboard';
|
||||
|
||||
const { latestCode } = settingsMap.get();
|
||||
|
||||
@ -125,6 +126,7 @@ export function Repl({ embedded = false }) {
|
||||
fontFamily,
|
||||
isLineNumbersDisplayed,
|
||||
isAutoCompletionEnabled,
|
||||
isTooltipEnabled,
|
||||
isLineWrappingEnabled,
|
||||
panelPosition,
|
||||
isZen,
|
||||
@ -270,7 +272,11 @@ export function Repl({ embedded = false }) {
|
||||
if (!error) {
|
||||
setLastShared(activeCode || code);
|
||||
// copy shareUrl to clipboard
|
||||
await navigator.clipboard.writeText(shareUrl);
|
||||
if (isTauri()) {
|
||||
await writeText(shareUrl);
|
||||
} else {
|
||||
await navigator.clipboard.writeText(shareUrl);
|
||||
}
|
||||
const message = `Link copied to clipboard: ${shareUrl}`;
|
||||
alert(message);
|
||||
// alert(message);
|
||||
@ -330,6 +336,7 @@ export function Repl({ embedded = false }) {
|
||||
keybindings={keybindings}
|
||||
isLineNumbersDisplayed={isLineNumbersDisplayed}
|
||||
isAutoCompletionEnabled={isAutoCompletionEnabled}
|
||||
isTooltipEnabled={isTooltipEnabled}
|
||||
isLineWrappingEnabled={isLineWrappingEnabled}
|
||||
fontSize={fontSize}
|
||||
fontFamily={fontFamily}
|
||||
|
||||
@ -7,6 +7,7 @@ export const defaultSettings = {
|
||||
keybindings: 'codemirror',
|
||||
isLineNumbersDisplayed: true,
|
||||
isAutoCompletionEnabled: false,
|
||||
isTooltipEnabled: false,
|
||||
isLineWrappingEnabled: false,
|
||||
theme: 'strudelTheme',
|
||||
fontFamily: 'monospace',
|
||||
@ -26,6 +27,7 @@ export function useSettings() {
|
||||
isZen: [true, 'true'].includes(state.isZen) ? true : false,
|
||||
isLineNumbersDisplayed: [true, 'true'].includes(state.isLineNumbersDisplayed) ? true : false,
|
||||
isAutoCompletionEnabled: [true, 'true'].includes(state.isAutoCompletionEnabled) ? true : false,
|
||||
isTooltipEnabled: [true, 'true'].includes(state.isTooltipEnabled) ? true : false,
|
||||
isLineWrappingEnabled: [true, 'true'].includes(state.isLineWrappingEnabled) ? true : false,
|
||||
fontSize: Number(state.fontSize),
|
||||
panelPosition: state.activeFooter !== '' ? state.panelPosition : 'bottom',
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user