mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-25 06:58:15 -04:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8465517c76 | |||
| 215ab87809 | |||
| e5fe998327 | |||
| 6f75a0a62b | |||
| 0464845262 | |||
| d6ee10e05c | |||
| 36441e7b73 | |||
| 189daa3942 | |||
| d009b9592e | |||
| f7f1bd63e8 | |||
| 7d24e45692 | |||
| f17a4d045f | |||
| 8e1e83f3cf | |||
| 2d64b538e7 | |||
| b717615558 | |||
| 8c4f10464b | |||
| 482ebb695a | |||
| 612efad3eb | |||
| e7839a09a1 | |||
| 3292f88810 | |||
| 03cbe4b6d4 | |||
| 784ee576da | |||
| ee3e1217b4 | |||
| 2eda047108 | |||
| c8cf1dc712 |
@@ -1,68 +1,91 @@
|
|||||||
import jsdoc from '../../doc.json';
|
import jsdoc from '../../doc.json';
|
||||||
// import { javascriptLanguage } from '@codemirror/lang-javascript';
|
|
||||||
import { autocompletion } from '@codemirror/autocomplete';
|
import { autocompletion } from '@codemirror/autocomplete';
|
||||||
import { h } from './html';
|
import { h } from './html';
|
||||||
|
|
||||||
function plaintext(str) {
|
const escapeHtml = (str) => {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.innerText = str;
|
div.innerText = str;
|
||||||
return div.innerHTML;
|
return div.innerHTML;
|
||||||
}
|
};
|
||||||
|
|
||||||
const getDocLabel = (doc) => doc.name || doc.longname;
|
const stripHtml = (html) => {
|
||||||
const getInnerText = (html) => {
|
const div = document.createElement('div');
|
||||||
var div = document.createElement('div');
|
|
||||||
div.innerHTML = html;
|
div.innerHTML = html;
|
||||||
return div.textContent || div.innerText || '';
|
return div.textContent || div.innerText || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Autocomplete({ doc, label }) {
|
const getDocLabel = (doc) => doc.name || doc.longname;
|
||||||
return h`<div class="prose dark:prose-invert max-h-[400px] overflow-auto p-2">
|
|
||||||
<h1 class="pt-0 mt-0">${label || getDocLabel(doc)}</h1>
|
const buildParamsList = (params) =>
|
||||||
${doc.description}
|
params?.length
|
||||||
<ul>
|
? `
|
||||||
${doc.params?.map(
|
<div class="autocomplete-info-params-section">
|
||||||
({ name, type, description }) =>
|
<h4 class="autocomplete-info-section-title">Parameters</h4>
|
||||||
`<li>${name} : ${type.names?.join(' | ')} ${description ? ` - ${getInnerText(description)}` : ''}</li>`,
|
<ul class="autocomplete-info-params-list">
|
||||||
)}
|
${params
|
||||||
</ul>
|
.map(
|
||||||
<div>
|
({ name, type, description }) => `
|
||||||
${doc.examples?.map((example) => `<div><pre>${plaintext(example)}</pre></div>`)}
|
<li class="autocomplete-info-param-item">
|
||||||
</div>
|
<span class="autocomplete-info-param-name">${name}</span>
|
||||||
</div>`[0];
|
<span class="autocomplete-info-param-type">${type.names?.join(' | ')}</span>
|
||||||
/*
|
${description ? `<div class="autocomplete-info-param-desc">${stripHtml(description)}</div>` : ''}
|
||||||
<pre
|
</li>
|
||||||
className="cursor-pointer"
|
`,
|
||||||
onMouseDown={(e) => {
|
)
|
||||||
console.log('ola!');
|
.join('')}
|
||||||
navigator.clipboard.writeText(example);
|
</ul>
|
||||||
e.stopPropagation();
|
</div>
|
||||||
}}
|
`
|
||||||
>
|
: '';
|
||||||
{example}
|
|
||||||
</pre>
|
const buildExamples = (examples) =>
|
||||||
*/
|
examples?.length
|
||||||
}
|
? `
|
||||||
|
<div class="autocomplete-info-examples-section">
|
||||||
|
<h4 class="autocomplete-info-section-title">Examples</h4>
|
||||||
|
${examples
|
||||||
|
.map(
|
||||||
|
(example) => `
|
||||||
|
<pre class="autocomplete-info-example-code">${escapeHtml(example)}</pre>
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
.join('')}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
export const Autocomplete = ({ doc, label }) =>
|
||||||
|
h`
|
||||||
|
<div class="autocomplete-info-tooltip">
|
||||||
|
<h3 class="autocomplete-info-function-name">${label || getDocLabel(doc)}</h3>
|
||||||
|
${doc.description ? `<p class="autocomplete-info-function-description">${doc.description}</p>` : ''}
|
||||||
|
${buildParamsList(doc.params)}
|
||||||
|
${buildExamples(doc.examples)}
|
||||||
|
</div>
|
||||||
|
`[0];
|
||||||
|
|
||||||
|
const isValidDoc = (doc) => {
|
||||||
|
const label = getDocLabel(doc);
|
||||||
|
return label && !label.startsWith('_') && !['package'].includes(doc.kind);
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasExcludedTags = (doc) =>
|
||||||
|
['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag));
|
||||||
|
|
||||||
const jsdocCompletions = jsdoc.docs
|
const jsdocCompletions = jsdoc.docs
|
||||||
.filter(
|
.filter((doc) => isValidDoc(doc) && !hasExcludedTags(doc))
|
||||||
(doc) =>
|
|
||||||
getDocLabel(doc) &&
|
|
||||||
!getDocLabel(doc).startsWith('_') &&
|
|
||||||
!['package'].includes(doc.kind) &&
|
|
||||||
!['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)),
|
|
||||||
)
|
|
||||||
// https://codemirror.net/docs/ref/#autocomplete.Completion
|
// https://codemirror.net/docs/ref/#autocomplete.Completion
|
||||||
.map((doc) /*: Completion */ => ({
|
.map((doc) => ({
|
||||||
label: getDocLabel(doc),
|
label: getDocLabel(doc),
|
||||||
// detail: 'xxx', // An optional short piece of information to show (with a different style) after the label.
|
// detail: 'xxx', // An optional short piece of information to show (with a different style) after the label.
|
||||||
info: () => Autocomplete({ doc }),
|
info: () => Autocomplete({ doc }),
|
||||||
type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type
|
type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const strudelAutocomplete = (context /* : CompletionContext */) => {
|
export const strudelAutocomplete = (context) => {
|
||||||
let word = context.matchBefore(/\w*/);
|
const word = context.matchBefore(/\w*/);
|
||||||
if (word.from == word.to && !context.explicit) return null;
|
if (word.from === word.to && !context.explicit) return null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
from: word.from,
|
from: word.from,
|
||||||
options: jsdocCompletions,
|
options: jsdocCompletions,
|
||||||
@@ -74,11 +97,5 @@ export const strudelAutocomplete = (context /* : CompletionContext */) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function isAutoCompletionEnabled(on) {
|
export const isAutoCompletionEnabled = (enabled) =>
|
||||||
return on
|
enabled ? [autocompletion({ override: [strudelAutocomplete] })] : [];
|
||||||
? [
|
|
||||||
autocompletion({ override: [strudelAutocomplete] }),
|
|
||||||
//javascriptLanguage.data.of({ autocomplete: strudelAutocomplete }),
|
|
||||||
]
|
|
||||||
: []; // autocompletion({ override: [] })
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/codemirror",
|
"name": "@strudel/codemirror",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Codemirror Extensions for Strudel",
|
"description": "Codemirror Extensions for Strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ https://rohandrape.net/?t=hmt
|
|||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { timeCat, register, silence } from './pattern.mjs';
|
import { timeCat, register, silence, stack, pure, _morph } from './pattern.mjs';
|
||||||
import { rotate, flatten, splitAt, zipWith } from './util.mjs';
|
import { rotate, flatten, splitAt, zipWith } from './util.mjs';
|
||||||
import Fraction, { lcm } from './fraction.mjs';
|
import Fraction, { lcm } from './fraction.mjs';
|
||||||
|
|
||||||
@@ -196,3 +196,26 @@ export const euclidLegato = register(['euclidLegato'], function (pulses, steps,
|
|||||||
export const euclidLegatoRot = register(['euclidLegatoRot'], function (pulses, steps, rotation, pat) {
|
export const euclidLegatoRot = register(['euclidLegatoRot'], function (pulses, steps, rotation, pat) {
|
||||||
return _euclidLegato(pulses, steps, rotation, pat);
|
return _euclidLegato(pulses, steps, rotation, pat);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 'euclid' variant with an additional parameter that morphs the resulting
|
||||||
|
* rhythm from 0 (no morphing) to 1 (completely 'even'). For example
|
||||||
|
* `sound("bd").euclidish(3,8,0)` would be the same as
|
||||||
|
* `sound("bd").euclid(3,8)`, and `sound("bd").euclidish(3,8,1)` would be the
|
||||||
|
* same as `sound("bd bd bd")`. `sound("bd").euclidish(3,8,0.5)` would have a
|
||||||
|
* groove somewhere between.
|
||||||
|
* Inspired by the work of Malcom Braff.
|
||||||
|
* @name euclidish
|
||||||
|
* @synonyms eish
|
||||||
|
* @memberof Pattern
|
||||||
|
* @param {number} pulses the number of onsets
|
||||||
|
* @param {number} steps the number of steps to fill
|
||||||
|
* @param {number} groove exists between the extremes of 0 (straight euclidian) and 1 (straight pulse)
|
||||||
|
* @example
|
||||||
|
* sound("hh").euclidish(7,12,sine.slow(8))
|
||||||
|
* .pan(sine.slow(8))
|
||||||
|
*/
|
||||||
|
export const { euclidish, eish } = register(['euclidish', 'eish'], function (pulses, steps, perc, pat) {
|
||||||
|
const morphed = _morph(bjork(pulses, steps), new Array(pulses).fill(1), perc);
|
||||||
|
return pat.struct(morphed).setSteps(steps);
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/core",
|
"name": "@strudel/core",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Port of Tidal Cycles to JavaScript",
|
"description": "Port of Tidal Cycles to JavaScript",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
numeralArgs,
|
numeralArgs,
|
||||||
parseNumeral,
|
parseNumeral,
|
||||||
pairs,
|
pairs,
|
||||||
|
zipWith,
|
||||||
stringifyValues,
|
stringifyValues,
|
||||||
} from './util.mjs';
|
} from './util.mjs';
|
||||||
import drawLine from './drawLine.mjs';
|
import drawLine from './drawLine.mjs';
|
||||||
@@ -3416,3 +3417,69 @@ export const { beat } = register(
|
|||||||
['beat'],
|
['beat'],
|
||||||
__beat((x) => x.innerJoin()),
|
__beat((x) => x.innerJoin()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const _morph = (from, to, by) => {
|
||||||
|
by = Fraction(by);
|
||||||
|
const dur = Fraction(1).div(from.length);
|
||||||
|
const positions = (list) => {
|
||||||
|
const result = [];
|
||||||
|
for (const [pos, value] of list.entries()) {
|
||||||
|
if (value) {
|
||||||
|
result.push([Fraction(pos).div(list.length), value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
const arcs = zipWith(
|
||||||
|
([posa, valuea], [posb, valueb]) => {
|
||||||
|
const b = by.mul(posb - posa).add(posa);
|
||||||
|
const e = b.add(dur);
|
||||||
|
return new TimeSpan(b, e);
|
||||||
|
},
|
||||||
|
positions(from),
|
||||||
|
positions(to),
|
||||||
|
);
|
||||||
|
function query(state) {
|
||||||
|
const cycle = state.span.begin.sam();
|
||||||
|
const cycleArc = state.span.cycleArc();
|
||||||
|
const result = [];
|
||||||
|
for (const whole of arcs) {
|
||||||
|
const part = whole.intersection(cycleArc);
|
||||||
|
if (part !== undefined) {
|
||||||
|
result.push(
|
||||||
|
new Hap(
|
||||||
|
whole.withTime((x) => x.add(cycle)),
|
||||||
|
part.withTime((x) => x.add(cycle)),
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return new Pattern(query).splitQueries();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes two binary rhythms represented as lists of 1s and 0s, and a number
|
||||||
|
* between 0 and 1 that morphs between them. The two lists should contain the same
|
||||||
|
* number of true values.
|
||||||
|
* @example
|
||||||
|
* sound("hh").struct(morph([1,0,1,0,1,0,1,0], // straight rhythm
|
||||||
|
* [1,1,0,1,0,1,0], // wonky rhythm
|
||||||
|
* 0.25 // creates a slightly wonky rhythm
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* @example
|
||||||
|
* sound("hh").struct(morph("1:0:1:0:1:0:1:0", // straight rhythm
|
||||||
|
* "1:1:0:1:0:1:0", // wonky rhythm
|
||||||
|
* sine.slow(8) // slowly morph between the rhythms
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
export const morph = (frompat, topat, bypat) => {
|
||||||
|
frompat = reify(frompat);
|
||||||
|
topat = reify(topat);
|
||||||
|
bypat = reify(bypat);
|
||||||
|
return frompat.innerBind((from) => topat.innerBind((to) => bypat.innerBind((by) => _morph(from, to, by))));
|
||||||
|
};
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export class TimeSpan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
intersection(other) {
|
intersection(other) {
|
||||||
// Intersection of two timespans, returns None if they don't intersect.
|
// Intersection of two timespans, returns undefined if they don't intersect.
|
||||||
const intersect_begin = this.begin.max(other.begin);
|
const intersect_begin = this.begin.max(other.begin);
|
||||||
const intersect_end = this.end.min(other.end);
|
const intersect_end = this.end.min(other.end);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/csound",
|
"name": "@strudel/csound",
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"description": "csound bindings for strudel",
|
"description": "csound bindings for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/draw",
|
"name": "@strudel/draw",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Helpers for drawing with Strudel",
|
"description": "Helpers for drawing with Strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/embed",
|
"name": "@strudel/embed",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"description": "Embeddable Web Component to load a Strudel REPL into an iframe",
|
"description": "Embeddable Web Component to load a Strudel REPL into an iframe",
|
||||||
"main": "embed.js",
|
"main": "embed.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/gamepad",
|
"name": "@strudel/gamepad",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Gamepad Inputs for strudel",
|
"description": "Gamepad Inputs for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/hydra",
|
"name": "@strudel/hydra",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Hydra integration for strudel",
|
"description": "Hydra integration for strudel",
|
||||||
"main": "hydra.mjs",
|
"main": "hydra.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -493,6 +493,9 @@ export async function midin(input) {
|
|||||||
otherInputs?.length ? `Also available: ${getMidiDeviceNamesString(otherInputs)}` : ''
|
otherInputs?.length ? `Also available: ${getMidiDeviceNamesString(otherInputs)}` : ''
|
||||||
}`,
|
}`,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
// ensure refs for this input are initialized
|
||||||
|
if (!refs[input]) {
|
||||||
refs[input] = {};
|
refs[input] = {};
|
||||||
}
|
}
|
||||||
const cc = (cc) => ref(() => refs[input][cc] || 0);
|
const cc = (cc) => ref(() => refs[input][cc] || 0);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/midi",
|
"name": "@strudel/midi",
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"description": "Midi API for strudel",
|
"description": "Midi API for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/mini",
|
"name": "@strudel/mini",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Mini notation for strudel",
|
"description": "Mini notation for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mondolang",
|
"name": "mondolang",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"description": "a language for functional composition that translates to js",
|
"description": "a language for functional composition that translates to js",
|
||||||
"main": "mondo.mjs",
|
"main": "mondo.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/mondo",
|
"name": "@strudel/mondo",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"description": "mondo notation for strudel",
|
"description": "mondo notation for strudel",
|
||||||
"main": "mondough.mjs",
|
"main": "mondough.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/motion",
|
"name": "@strudel/motion",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "DeviceMotion API for strudel",
|
"description": "DeviceMotion API for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/mqtt",
|
"name": "@strudel/mqtt",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "MQTT API for strudel",
|
"description": "MQTT API for strudel",
|
||||||
"main": "mqtt.mjs",
|
"main": "mqtt.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/osc",
|
"name": "@strudel/osc",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "OSC messaging for strudel",
|
"description": "OSC messaging for strudel",
|
||||||
"main": "osc.mjs",
|
"main": "osc.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/reference",
|
"name": "@strudel/reference",
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"description": "Headless reference of all strudel functions",
|
"description": "Headless reference of all strudel functions",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/repl",
|
"name": "@strudel/repl",
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"description": "Strudel REPL as a Web Component",
|
"description": "Strudel REPL as a Web Component",
|
||||||
"module": "index.mjs",
|
"module": "index.mjs",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/serial",
|
"name": "@strudel/serial",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Webserial API for strudel",
|
"description": "Webserial API for strudel",
|
||||||
"main": "serial.mjs",
|
"main": "serial.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/soundfonts",
|
"name": "@strudel/soundfonts",
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"description": "Soundsfont support for strudel",
|
"description": "Soundsfont support for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "superdough",
|
"name": "superdough",
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"description": "simple web audio synth and sampler intended for live coding. inspired by superdirt and webdirt.",
|
"description": "simple web audio synth and sampler intended for live coding. inspired by superdirt and webdirt.",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/tonal",
|
"name": "@strudel/tonal",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Tonal functions for strudel",
|
"description": "Tonal functions for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/transpiler",
|
"name": "@strudel/transpiler",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Transpiler for strudel user code. Converts syntactically correct but semantically meaningless JS into evaluatable strudel code.",
|
"description": "Transpiler for strudel user code. Converts syntactically correct but semantically meaningless JS into evaluatable strudel code.",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/web",
|
"name": "@strudel/web",
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"description": "Easy to setup, opiniated bundle of Strudel for the browser.",
|
"description": "Easy to setup, opiniated bundle of Strudel for the browser.",
|
||||||
"module": "web.mjs",
|
"module": "web.mjs",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/webaudio",
|
"name": "@strudel/webaudio",
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"description": "Web Audio helpers for Strudel",
|
"description": "Web Audio helpers for Strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel/xen",
|
"name": "@strudel/xen",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Xenharmonic API for strudel",
|
"description": "Xenharmonic API for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -3410,6 +3410,39 @@ exports[`runs examples > example "euclidRot" example index 0 1`] = `
|
|||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "euclidish" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/12 | s:hh pan:0.5 ]",
|
||||||
|
"[ 13/84 → 5/21 | s:hh pan:0.5606253170575308 ]",
|
||||||
|
"[ 15/56 → 59/168 | s:hh pan:0.604413082836085 ]",
|
||||||
|
"[ 71/168 → 85/168 | s:hh pan:0.6629314122869361 ]",
|
||||||
|
"[ 97/168 → 37/56 | s:hh pan:0.7190455010067492 ]",
|
||||||
|
"[ 29/42 → 65/84 | s:hh pan:0.7580531369037533 ]",
|
||||||
|
"[ 71/84 → 13/14 | s:hh pan:0.8080762739548087 ]",
|
||||||
|
"[ 1/1 → 13/12 | s:hh pan:0.8535533905932737 ]",
|
||||||
|
"[ 451099417/393511398 → 322594689/262340932 | s:hh pan:0.891768001805729 ]",
|
||||||
|
"[ 335923379/262340932 → 536677685/393511398 | s:hh pan:0.9222657853371297 ]",
|
||||||
|
"[ 1122946175/787022796 → 99044284/65585233 | s:hh pan:0.9501869591788796 ]",
|
||||||
|
"[ 1238122213/787022796 → 651853723/393511398 | s:hh pan:0.9721673436944069 ]",
|
||||||
|
"[ 335923379/196755699 → 469759583/262340932 | s:hh pan:0.9868472639237561 ]",
|
||||||
|
"[ 729434777/393511398 → 1524454787/787022796 | s:hh pan:0.9967009321321423 ]",
|
||||||
|
"[ 2/1 → 25/12 | s:hh pan:1 ]",
|
||||||
|
"[ 15/7 → 187/84 | s:hh pan:0.9968561049466214 ]",
|
||||||
|
"[ 16/7 → 199/84 | s:hh pan:0.9874639560909118 ]",
|
||||||
|
"[ 17/7 → 211/84 | s:hh pan:0.9719416651541839 ]",
|
||||||
|
"[ 18/7 → 223/84 | s:hh pan:0.9504844339512095 ]",
|
||||||
|
"[ 19/7 → 235/84 | s:hh pan:0.9233620996141421 ]",
|
||||||
|
"[ 20/7 → 247/84 | s:hh pan:0.890915741234015 ]",
|
||||||
|
"[ 3/1 → 37/12 | s:hh pan:0.8535533905932737 ]",
|
||||||
|
"[ 1238122213/393511398 → 847276553/262340932 | s:hh pan:0.8106731928589048 ]",
|
||||||
|
"[ 860605243/262340932 → 1323700481/393511398 | s:hh pan:0.7677528833339 ]",
|
||||||
|
"[ 2696991767/787022796 → 230214750/65585233 | s:hh pan:0.7175585019834292 ]",
|
||||||
|
"[ 2812167805/787022796 → 1438876519/393511398 | s:hh pan:0.6644931595798675 ]",
|
||||||
|
"[ 729434777/196755699 → 994441447/262340932 | s:hh pan:0.6139286689554151 ]",
|
||||||
|
"[ 1516457573/393511398 → 3098500379/787022796 | s:hh pan:0.557342689325327 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "every" example index 0 1`] = `
|
exports[`runs examples > example "every" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/4 | note:g3 ]",
|
"[ 0/1 → 1/4 | note:g3 ]",
|
||||||
@@ -6137,6 +6170,48 @@ exports[`runs examples > example "miditouch" example index 0 1`] = `
|
|||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "morph" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/8 | s:hh ]",
|
||||||
|
"[ 25/112 → 39/112 | s:hh ]",
|
||||||
|
"[ 27/56 → 17/28 | s:hh ]",
|
||||||
|
"[ 83/112 → 97/112 | s:hh ]",
|
||||||
|
"[ 1/1 → 9/8 | s:hh ]",
|
||||||
|
"[ 137/112 → 151/112 | s:hh ]",
|
||||||
|
"[ 83/56 → 45/28 | s:hh ]",
|
||||||
|
"[ 195/112 → 209/112 | s:hh ]",
|
||||||
|
"[ 2/1 → 17/8 | s:hh ]",
|
||||||
|
"[ 249/112 → 263/112 | s:hh ]",
|
||||||
|
"[ 139/56 → 73/28 | s:hh ]",
|
||||||
|
"[ 307/112 → 321/112 | s:hh ]",
|
||||||
|
"[ 3/1 → 25/8 | s:hh ]",
|
||||||
|
"[ 361/112 → 375/112 | s:hh ]",
|
||||||
|
"[ 195/56 → 101/28 | s:hh ]",
|
||||||
|
"[ 419/112 → 433/112 | s:hh ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "morph" example index 1 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/8 | s:hh ]",
|
||||||
|
"[ 11/56 → 9/28 | s:hh ]",
|
||||||
|
"[ 13/28 → 33/56 | s:hh ]",
|
||||||
|
"[ 41/56 → 6/7 | s:hh ]",
|
||||||
|
"[ 1/1 → 9/8 | s:hh ]",
|
||||||
|
"[ 303934523/262340932 → 673454279/524681864 | s:hh ]",
|
||||||
|
"[ 188758485/131170466 → 820619173/524681864 | s:hh ]",
|
||||||
|
"[ 451099417/262340932 → 967784067/524681864 | s:hh ]",
|
||||||
|
"[ 2/1 → 17/8 | s:hh ]",
|
||||||
|
"[ 15/7 → 127/56 | s:hh ]",
|
||||||
|
"[ 17/7 → 143/56 | s:hh ]",
|
||||||
|
"[ 19/7 → 159/56 | s:hh ]",
|
||||||
|
"[ 3/1 → 25/8 | s:hh ]",
|
||||||
|
"[ 828616387/262340932 → 1722818007/524681864 | s:hh ]",
|
||||||
|
"[ 451099417/131170466 → 1869982901/524681864 | s:hh ]",
|
||||||
|
"[ 975781281/262340932 → 2017147795/524681864 | s:hh ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "mousex" example index 0 1`] = `
|
exports[`runs examples > example "mousex" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/4 | note:C3 ]",
|
"[ 0/1 → 1/4 | note:C3 ]",
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview --port 3009 --host 0.0.0.0",
|
"preview": "astro preview --port 3009 --host 0.0.0.0",
|
||||||
"astro": "astro",
|
"astro": "astro"
|
||||||
"postinstall": "cp node_modules/hs2js/dist/tree-sitter.wasm public && cp node_modules/hs2js/dist/tree-sitter-haskell.wasm public"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@algolia/client-search": "^5.20.0",
|
"@algolia/client-search": "^5.20.0",
|
||||||
|
|||||||
@@ -34,11 +34,11 @@ import { JsDoc } from '../../docs/JsDoc';
|
|||||||
|
|
||||||
## arp
|
## arp
|
||||||
|
|
||||||
<JsDoc client:idle name="Pattern#arp" h={0} />
|
<JsDoc client:idle name="arp" h={0} />
|
||||||
|
|
||||||
## arpWith 🧪
|
## arpWith 🧪
|
||||||
|
|
||||||
<JsDoc client:idle name="Pattern#arpWith" h={0} />
|
<JsDoc client:idle name="arpWith" h={0} />
|
||||||
|
|
||||||
## struct
|
## struct
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ import { JsDoc } from '../../docs/JsDoc';
|
|||||||
|
|
||||||
## hush
|
## hush
|
||||||
|
|
||||||
<JsDoc client:idle name="hush" h={0} />
|
<JsDoc client:idle name="Pattern#hush" h={0} />
|
||||||
|
|
||||||
## invert
|
## invert
|
||||||
|
|
||||||
|
|||||||
@@ -339,4 +339,18 @@ global effects use the same chain for all events of the same orbit:
|
|||||||
|
|
||||||
<JsDoc client:idle name="phasersweep" h={0} />
|
<JsDoc client:idle name="phasersweep" h={0} />
|
||||||
|
|
||||||
|
## Duck
|
||||||
|
|
||||||
|
### duckorbit
|
||||||
|
|
||||||
|
<JsDoc client:idle name="duckorbit" h={0} />
|
||||||
|
|
||||||
|
### duckattack
|
||||||
|
|
||||||
|
<JsDoc client:idle name="duckattack" h={0} />
|
||||||
|
|
||||||
|
### duckdepth
|
||||||
|
|
||||||
|
<JsDoc client:idle name="duckdepth" h={0} />
|
||||||
|
|
||||||
Next, we'll look at input / output via [MIDI, OSC and other methods](/learn/input-output).
|
Next, we'll look at input / output via [MIDI, OSC and other methods](/learn/input-output).
|
||||||
|
|||||||
@@ -361,6 +361,10 @@ Sampler effects are functions that can be used to change the behaviour of sample
|
|||||||
|
|
||||||
<JsDoc client:idle name="splice" h={0} />
|
<JsDoc client:idle name="splice" h={0} />
|
||||||
|
|
||||||
|
### scrub
|
||||||
|
|
||||||
|
<JsDoc client:idle name="Pattern.scrub" h={0} />{' '}
|
||||||
|
|
||||||
### speed
|
### speed
|
||||||
|
|
||||||
<JsDoc client:idle name="speed" h={0} />
|
<JsDoc client:idle name="speed" h={0} />
|
||||||
|
|||||||
@@ -69,3 +69,133 @@
|
|||||||
text-decoration: underline 0.18rem;
|
text-decoration: underline 0.18rem;
|
||||||
text-underline-offset: 0.22rem;
|
text-underline-offset: 0.22rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Override default styles from the codemirror inline css for autocomplete info tooltip*/
|
||||||
|
.cm-tooltip.cm-completionInfo {
|
||||||
|
padding: 12px !important;
|
||||||
|
padding-bottom: 12px !important;
|
||||||
|
border: 1px solid var(--foreground) !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important;
|
||||||
|
max-width: 500px !important;
|
||||||
|
min-width: 300px !important;
|
||||||
|
max-height: 400px !important;
|
||||||
|
white-space: normal !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
background-color: var(--lineHighlight) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main tooltip container */
|
||||||
|
.autocomplete-info-tooltip {
|
||||||
|
border-radius: 4px !important;
|
||||||
|
color: var(--foreground);
|
||||||
|
font-family: var(--font-family, 'SF Mono', 'Monaco', monospace);
|
||||||
|
font-size: var(--font-size, 13px);
|
||||||
|
line-height: 1.4;
|
||||||
|
max-width: 600px;
|
||||||
|
max-height: 400px;
|
||||||
|
min-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-function-name {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--foreground);
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-function-description {
|
||||||
|
margin: 0 0 12px 0;
|
||||||
|
color: var(--foreground);
|
||||||
|
line-height: 1.5;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-section-title {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--foreground);
|
||||||
|
margin: 16px 0 6px 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-section-title:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-params-section {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-params-list {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-param-item {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: var(--lineBackground);
|
||||||
|
border-radius: 3px;
|
||||||
|
border-left: 2px solid var(--foreground, #555);
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-param-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-param-name {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--variable, var(--foreground));
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-param-type {
|
||||||
|
color: var(--comment);
|
||||||
|
font-size: 12px;
|
||||||
|
background-color: var(--gutterForeground);
|
||||||
|
padding: 1px 4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-param-desc {
|
||||||
|
color: var(--foreground);
|
||||||
|
font-size: 10px;
|
||||||
|
margin-top: 4px;
|
||||||
|
line-height: 1.4;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-examples-section {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-example-code {
|
||||||
|
background: var(--lineBackground);
|
||||||
|
color: var(--foreground);
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-family: var(--font-family, 'SF Mono', 'Monaco', monospace);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin: 4px 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
white-space: pre;
|
||||||
|
border: 1px solid var(--foreground, #3a3a3a);
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-tooltip::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-tooltip::-webkit-scrollbar-track {
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-tooltip::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-info-tooltip::-webkit-scrollbar-thumb:hover {
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user