Compare commits

..

1 Commits

Author SHA1 Message Date
Alex McLean a481a86c3b not quite.. 2025-07-15 17:38:50 +01:00
33 changed files with 60 additions and 182 deletions
+1 -2
View File
@@ -48,7 +48,6 @@
"homepage": "https://strudel.cc",
"dependencies": {
"@strudel/core": "workspace:*",
"@strudel/cyclist": "workspace:*",
"@strudel/mini": "workspace:*",
"@strudel/tonal": "workspace:*",
"@strudel/transpiler": "workspace:*",
@@ -75,4 +74,4 @@
"vitest": "^3.0.4",
"vite-plugin-bundle-audioworklet": "workspace:*"
}
}
}
+1 -2
View File
@@ -13,8 +13,7 @@ import {
lineNumbers,
drawSelection,
} from '@codemirror/view';
import { registerControl } from '@strudel/core';
import { repl } from '@strudel/cyclist';
import { repl, registerControl } from '@strudel/core';
import { Drawer, cleanupDraw } from '@strudel/draw';
import { isAutoCompletionEnabled } from './autocomplete.mjs';
import { isTooltipEnabled } from './tooltip.mjs';
-1
View File
@@ -45,7 +45,6 @@
"@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"
@@ -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 { logger } from '@strudel/core';
import { logger } from './logger.mjs';
export class Cyclist {
constructor({
+8 -1
View File
@@ -7,8 +7,9 @@ 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 };
export { Fraction, controls, createClock };
export * from './controls.mjs';
export * from './hap.mjs';
export * from './pattern.mjs';
@@ -17,7 +18,13 @@ 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 { default as drawLine } from './drawLine.mjs';
// below won't work with runtime.mjs (json import fails)
/* import * as p from './package.json';
@@ -5,10 +5,10 @@ This program is free software: you can redistribute it and/or modify it under th
*/
import { logger } from './logger.mjs';
import { ClockCollator, cycleToSeconds } from '@strudel/core';
import { ClockCollator, cycleToSeconds } from './util.mjs';
export class NeoCyclist {
constructor({ onTrigger, onToggle, getTime }) {
constructor({ onTrigger, onToggle, getTime, latency = 0.1 }) {
this.started = false;
this.cps = 0.5;
this.lastTick = 0; // absolute time when last tick (clock callback) happened
@@ -20,7 +20,7 @@ export class NeoCyclist {
// in order to schedule events consistently.
this.collator = new ClockCollator({ getTargetClockTime: getTime });
this.onToggle = onToggle;
this.latency = 0.1; // fixed trigger time offset
this.latency = latency; // fixed trigger time offset
this.cycle = 0;
this.id = Math.round(Date.now() * Math.random());
this.worker = new SharedWorker(new URL('./clockworker.js', import.meta.url));
@@ -4,7 +4,7 @@ import { evaluate as _evaluate } from './evaluate.mjs';
import { logger } from './logger.mjs';
import { setTime } from './time.mjs';
import { evalScope } from './evaluate.mjs';
import { register, Pattern, isPattern, silence, stack } from '@strudel/core';
import { register, Pattern, isPattern, silence, stack } from './pattern.mjs';
export function repl({
defaultOutput,
@@ -18,6 +18,7 @@ export function repl({
editPattern,
onUpdateState,
sync = false,
latency = 0.1,
setInterval,
clearInterval,
id,
@@ -56,6 +57,7 @@ export function repl({
setInterval,
clearInterval,
beforeStart,
latency,
};
// NeoCyclist uses a shared worker to communicate between instances, which is not supported on mobile chrome
@@ -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 '@strudel/core';
import { register } from './index.mjs';
let synth;
try {
-8
View File
@@ -1,8 +0,0 @@
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 };
-28
View File
@@ -1,28 +0,0 @@
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;
-40
View File
@@ -1,40 +0,0 @@
{
"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"
}
}
-20
View File
@@ -1,20 +0,0 @@
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',
},
});
+1 -2
View File
@@ -4,8 +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 { Pattern, State, TimeSpan } from '@strudel/core';
import { getTime } from '@strudel/cyclist';
import { Pattern, getTime, State, TimeSpan } from '@strudel/core';
export const getDrawContext = (id = 'test-canvas', options) => {
let { contextType = '2d', pixelated = false, pixelRatio = window.devicePixelRatio } = options || {};
+1 -2
View File
@@ -29,8 +29,7 @@
},
"homepage": "https://codeberg.org/uzu/strudel#readme",
"dependencies": {
"@strudel/core": "workspace:*",
"@strudel/cyclist": "workspace:*"
"@strudel/core": "workspace:*"
},
"devDependencies": {
"vite": "^6.0.11"
+1 -2
View File
@@ -1,6 +1,5 @@
import { getDrawContext } from '@strudel/draw';
import { controls, reify } from '@strudel/core';
import { getTime } from '@strudel/cyclist';
import { controls, getTime, reify } from '@strudel/core';
let latestOptions;
let hydra;
-1
View File
@@ -34,7 +34,6 @@
"homepage": "https://codeberg.org/uzu/strudel#readme",
"dependencies": {
"@strudel/core": "workspace:*",
"@strudel/cyclist": "workspace:*",
"@strudel/draw": "workspace:*",
"hydra-synth": "^1.3.29"
},
+14 -3
View File
@@ -1,5 +1,17 @@
import { reify, fast, slow, seq, stepcat, extend, expand, pace, chooseIn, degradeBy, silence } from '@strudel/core';
import { strudelScope } from '@strudel/cyclist';
import {
strudelScope,
reify,
fast,
slow,
seq,
stepcat,
extend,
expand,
pace,
chooseIn,
degradeBy,
silence,
} from '@strudel/core';
import { registerLanguage } from '@strudel/transpiler';
import { MondoRunner } from 'mondolang';
@@ -30,7 +42,6 @@ lib['%'] = pace;
lib['?'] = degradeBy; // todo: default 0.5 not working..
lib[':'] = tail;
lib['..'] = range;
lib['def'] = () => silence;
lib['or'] = (...children) => chooseIn(...children); // always has structure but is cyclewise.. e.g. "s oh*8.dec[.04 | .5]"
//lib['or'] = (...children) => chooseOut(...children); // "s oh*8.dec[.04 | .5]" is better but "dec[.04 | .5].s oh*8" has no struct
-1
View File
@@ -33,7 +33,6 @@
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@strudel/core": "workspace:*",
"@strudel/cyclist": "workspace:*",
"@strudel/transpiler": "workspace:*",
"mondolang": "workspace:*"
},
+1 -1
View File
@@ -17,7 +17,7 @@ const config = {
},
udpClient: {
host: 'localhost', // @param {string} Hostname of udp client for messaging
port: 7771, // @param {number} Port of udp client for messaging
port: 57120, // @param {number} Port of udp client for messaging
},
wsServer: {
host: 'localhost', // @param {string} Hostname of WebSocket server
+1 -1
View File
@@ -1,4 +1,4 @@
import { evaluate as _evaluate } from '@strudel/cyclist';
import { evaluate as _evaluate } from '@strudel/core';
import { transpiler } from './transpiler.mjs';
export * from './transpiler.mjs';
-1
View File
@@ -31,7 +31,6 @@
"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",
-42
View File
@@ -11,9 +11,6 @@ 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
@@ -212,9 +209,6 @@ importers:
'@strudel/core':
specifier: workspace:*
version: link:../core
'@strudel/cyclist':
specifier: workspace:*
version: link:../cyclist
'@strudel/draw':
specifier: workspace:*
version: link:../draw
@@ -258,19 +252,6 @@ 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':
@@ -285,9 +266,6 @@ importers:
'@strudel/core':
specifier: workspace:*
version: link:../core
'@strudel/cyclist':
specifier: workspace:*
version: link:../cyclist
devDependencies:
vite:
specifier: ^6.0.11
@@ -323,9 +301,6 @@ importers:
'@strudel/core':
specifier: workspace:*
version: link:../core
'@strudel/cyclist':
specifier: workspace:*
version: link:../cyclist
'@strudel/draw':
specifier: workspace:*
version: link:../draw
@@ -386,9 +361,6 @@ importers:
'@strudel/core':
specifier: workspace:*
version: link:../core
'@strudel/cyclist':
specifier: workspace:*
version: link:../cyclist
'@strudel/transpiler':
specifier: workspace:*
version: link:../transpiler
@@ -588,9 +560,6 @@ importers:
'@strudel/core':
specifier: workspace:*
version: link:../core
'@strudel/cyclist':
specifier: workspace:*
version: link:../cyclist
'@strudel/mini':
specifier: workspace:*
version: link:../mini
@@ -727,9 +696,6 @@ 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
@@ -2487,9 +2453,6 @@ 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==}
@@ -7694,7 +7657,6 @@ 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==}
@@ -9846,10 +9808,6 @@ 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
+1 -1
View File
@@ -4,7 +4,7 @@
// import * as tunes from './tunes.mjs';
import { evaluate } from '@strudel/transpiler';
import { evalScope } from '@strudel/cyclist';
import { evalScope } from '@strudel/core';
import * as strudel from '@strudel/core';
import * as webaudio from '@strudel/webaudio';
// import gist from '@strudel/core/gist.js';
-1
View File
@@ -26,7 +26,6 @@
"@nanostores/react": "^0.8.4",
"@strudel/codemirror": "workspace:*",
"@strudel/core": "workspace:*",
"@strudel/cyclist": "workspace:*",
"@strudel/csound": "workspace:*",
"@strudel/desktopbridge": "workspace:*",
"@strudel/draw": "workspace:*",
@@ -176,16 +176,3 @@ $ chord <Dm9!3 Db7> # voicing
/>
The `$` sign is an alias for `,` so it will create a stack behind the scenes.
## variables
using the `def` keyword, you can define variables:
<MiniRepl
client:idle
mondo
tune={`
$ def melody [0 1 2 3]
$ n melody # scale C:minor
`}
/>
@@ -108,6 +108,7 @@ export function SettingsTab({ started }) {
audioEngineTarget,
togglePanelTrigger,
maxPolyphony,
latency,
multiChannelOrbits,
isTabIndentationEnabled,
isMultiCursorEnabled,
@@ -165,6 +166,24 @@ export function SettingsTab({ started }) {
value={maxPolyphony ?? ''}
/>
</FormItem>
<FormItem label="Latency">
<Textbox
min={0}
max={Infinity}
onBlur={(e) => {
let v = parseFloat(e.target.value);
v = isNaN(v) ? 0.1 : v;
settingsMap.setKey('latency', v);
}}
onChange={(v) => {
v = parseFloat(v);
settingsMap.setKey('latency', isNaN(v) ? undefined : v);
}}
type="number"
placeholder=""
value={latency ?? 0.1}
/>
</FormItem>
<FormItem>
<Checkbox
label="Multi Channel Orbits"
+2 -1
View File
@@ -37,7 +37,7 @@ import './Repl.css';
import { setInterval, clearInterval } from 'worker-timers';
import { getMetadata } from '../metadata_parser';
const { latestCode, maxPolyphony, audioDeviceName, multiChannelOrbits } = settingsMap.get();
const { latestCode, maxPolyphony, audioDeviceName, multiChannelOrbits, latency } = settingsMap.get();
let modulesLoading, presets, drawContext, clearCanvas, audioReady;
if (typeof window !== 'undefined') {
@@ -73,6 +73,7 @@ export function useReplContext() {
const drawContext = getDrawContext();
const editor = new StrudelMirror({
sync: isSyncEnabled,
latency,
defaultOutput,
getTime,
setInterval,
+1 -2
View File
@@ -1,5 +1,4 @@
import { hash2code, logger } from '@strudel/core';
import { evalScope } from '@strudel/cyclist';
import { evalScope, hash2code, logger } from '@strudel/core';
import { settingPatterns } from '../settings.mjs';
import { setVersionDefaults } from '@strudel/webaudio';
import { getMetadata } from '../metadata_parser';