From 5445f0812fe1b7147aeb4866d15114afe56f809c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 12:41:46 +0200 Subject: [PATCH 01/14] configurable port for osc bridge + add bin field --- packages/osc/package.json | 1 + packages/osc/server.js | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index d5a27232..6e8a3394 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -3,6 +3,7 @@ "version": "1.2.4", "description": "OSC messaging for strudel", "main": "osc.mjs", + "bin": "./server.mjs", "type": "module", "publishConfig": { "main": "dist/index.mjs" diff --git a/packages/osc/server.js b/packages/osc/server.js index 75fc5b1c..c727e65f 100644 --- a/packages/osc/server.js +++ b/packages/osc/server.js @@ -6,6 +6,19 @@ This program is free software: you can redistribute it and/or modify it under th import OSC from 'osc-js'; +const args = process.argv.slice(2); +function getArgValue(flag) { + const i = args.indexOf(flag); + if (i !== -1) { + const nextIsFlag = args[i + 1]?.startsWith('--') ?? true; + if (nextIsFlag) return true; + return args[i + 1]; + } +} + +let udpClientPort = Number(getArgValue('--port')) || 57120; +// dirt = 7771 + const config = { receiver: 'ws', // @param {string} Where messages sent via 'send' method will be delivered to, 'ws' for Websocket clients, 'udp' for udp client udpServer: { @@ -17,7 +30,7 @@ const config = { }, udpClient: { host: 'localhost', // @param {string} Hostname of udp client for messaging - port: 57120, // @param {number} Port of udp client for messaging + port: udpClientPort, // @param {number} Port of udp client for messaging }, wsServer: { host: 'localhost', // @param {string} Hostname of WebSocket server From 820744dc27a80e70a14fab0110c5219ff3c22cc7 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 12:42:11 +0200 Subject: [PATCH 02/14] bump osc to 1.2.5 --- packages/osc/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index 6e8a3394..bf7fb474 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.4", + "version": "1.2.5", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.mjs", From 5d7c6c3e4b29e22ded1ecb07ce52bd03a994920c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 12:47:41 +0200 Subject: [PATCH 03/14] fix: add node shebang + bump osc to 1.2.6 --- packages/osc/package.json | 2 +- packages/osc/server.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index bf7fb474..ad0d383f 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.5", + "version": "1.2.6", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.mjs", diff --git a/packages/osc/server.js b/packages/osc/server.js index c727e65f..4d87862c 100644 --- a/packages/osc/server.js +++ b/packages/osc/server.js @@ -1,3 +1,5 @@ +#!/usr/bin/env node + /* server.js - Copyright (C) 2022 Strudel contributors - see From aba594b72ab9c1591167b4f73088c4539f40bfd8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 12:52:42 +0200 Subject: [PATCH 04/14] fix: bin field --- packages/osc/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index ad0d383f..239acda1 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,9 +1,9 @@ { "name": "@strudel/osc", - "version": "1.2.6", + "version": "1.2.7", "description": "OSC messaging for strudel", "main": "osc.mjs", - "bin": "./server.mjs", + "bin": "./server.js", "type": "module", "publishConfig": { "main": "dist/index.mjs" From 28d7e0e489440beec0fedfbbf1a676d78bd63a73 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 13:39:28 +0200 Subject: [PATCH 05/14] export osc function to be able to do all(osc) --- packages/osc/osc.mjs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/osc/osc.mjs b/packages/osc/osc.mjs index 8262e556..fe069152 100644 --- a/packages/osc/osc.mjs +++ b/packages/osc/osc.mjs @@ -6,7 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th import OSC from 'osc-js'; -import { logger, parseNumeral, Pattern, isNote, noteToMidi, ClockCollator } from '@strudel/core'; +import { logger, parseNumeral, register, isNote, noteToMidi, ClockCollator } from '@strudel/core'; let connection; // Promise function connect() { @@ -81,6 +81,4 @@ export async function oscTrigger(hap, currentTime, cps = 1, targetTime) { * @memberof Pattern * @returns Pattern */ -Pattern.prototype.osc = function () { - return this.onTrigger(oscTrigger); -}; +export const osc = register('osc', (pat) => pat.onTrigger(oscTrigger)); From cdb623cb66484843915e35fc2a7de2e3e029c71e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 13:39:35 +0200 Subject: [PATCH 06/14] overhaul osc readme --- packages/osc/README.md | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/osc/README.md b/packages/osc/README.md index 3dc65e16..d5ee60fb 100644 --- a/packages/osc/README.md +++ b/packages/osc/README.md @@ -4,36 +4,35 @@ OSC output for strudel patterns! Currently only tested with super collider / sup ## Usage -OSC will only work if you run the REPL locally + the OSC server besides it: +Assuming you have [node.js](https://nodejs.org/) installed, you can run the osc bridge server via: -From the project root: - -```js -npm run repl +```sh +npx @strudel/osc ``` -and in a seperate shell: - -```js -npm run osc -``` - -This should give you +You should see something like: ```log osc client running on port 57120 -osc server running on port 57121 +osc server running on port 7771 websocket server running on port 8080 ``` -Now open Supercollider (with the super dirt startup file) +By default it will use port 57120 for the osc client, which is what [superdirt](https://github.com/musikinformatik/SuperDirt) uses. You can change it via the `--port` option: -Now open the REPL and type: - -```js -s(" hh").osc() +```sh +npx @strudel/osc --port 7771 # classic dirt ``` -or just [click here](https://strudel.cc/#cygiPGJkIHNkPiBoaCIpLm9zYygp)... +To test it in strudel, you have can use `all(osc)` to send all events through osc: + +```js +$: s("bd*4") + +all(osc) +``` + + +[open in repl](hhttps://strudel.cc/#JDogcygiYmQqNCIpCgphbGwob3NjKQ%3D%3D) You can read more about [how to use Superdirt with Strudel the Tutorial](https://strudel.cc/learn/input-output/#superdirt-api) From 663229ecde6e6cff0a9aa71386e2fa3e6fe10a51 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 13:50:02 +0200 Subject: [PATCH 07/14] bump osc to 1.2.8 --- packages/osc/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index 239acda1..4244c2c6 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.7", + "version": "1.2.8", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.js", From 91ad3d729fb60f04e6dcc58f1286236e398cf331 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 20:36:40 +0200 Subject: [PATCH 08/14] feat: osc add --debug flag to log messages + log errors --- packages/osc/server.js | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/osc/server.js b/packages/osc/server.js index 4d87862c..2571c49d 100644 --- a/packages/osc/server.js +++ b/packages/osc/server.js @@ -19,7 +19,7 @@ function getArgValue(flag) { } let udpClientPort = Number(getArgValue('--port')) || 57120; -// dirt = 7771 +let debug = Number(getArgValue('--debug')) || 0; const config = { receiver: 'ws', // @param {string} Where messages sent via 'send' method will be delivered to, 'ws' for Websocket clients, 'udp' for udp client @@ -42,8 +42,34 @@ const config = { const osc = new OSC({ plugin: new OSC.BridgePlugin(config) }); -osc.open(); // start a WebSocket server on port 8080 +if (debug) { + osc.on('*', (message) => { + const { address, args } = message; + let str = ''; + for (let i = 0; i < args.length; i += 2) { + str += `${args[i]}: ${args[i + 1]} `; + } + console.log(`${address} ${str}`); + }); +} + +osc.on('error', (message) => { + if (message.toString().includes('EADDRINUSE')) { + console.log(`------ ERROR ------- +osc server already running! to stop it: +1. run "lsof -ti :57121 | xargs kill -9" (macos / linux) +2. re-run the osc server +`); + } else { + console.log(message); + } +}); + +osc.open(); console.log('osc client running on port', config.udpClient.port); console.log('osc server running on port', config.udpServer.port); console.log('websocket server running on port', config.wsServer.port); +if (debug) { + console.log('debug logs enabled. incoming messages will appear below'); +} From a25f7637968c0036e527254973fec59edc1cb52d Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 20:37:19 +0200 Subject: [PATCH 09/14] docs: add --debug flag to readme --- packages/osc/README.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/osc/README.md b/packages/osc/README.md index d5ee60fb..0a7bfedc 100644 --- a/packages/osc/README.md +++ b/packages/osc/README.md @@ -14,16 +14,28 @@ You should see something like: ```log osc client running on port 57120 -osc server running on port 7771 +osc server running on port 57121 websocket server running on port 8080 ``` +### --port + By default it will use port 57120 for the osc client, which is what [superdirt](https://github.com/musikinformatik/SuperDirt) uses. You can change it via the `--port` option: ```sh npx @strudel/osc --port 7771 # classic dirt ``` +### --debug + +To log all incoming osc messages, add the `--debug` flag: + +```sh +npx @strudel/osc --debug +``` + +## Usage in Strudel + To test it in strudel, you have can use `all(osc)` to send all events through osc: ```js @@ -32,7 +44,6 @@ $: s("bd*4") all(osc) ``` - -[open in repl](hhttps://strudel.cc/#JDogcygiYmQqNCIpCgphbGwob3NjKQ%3D%3D) +[open in repl](https://strudel.cc/#JDogcygiYmQqNCIpCgphbGwob3NjKQ%3D%3D) You can read more about [how to use Superdirt with Strudel the Tutorial](https://strudel.cc/learn/input-output/#superdirt-api) From c54fa7d2665569006b71aff9019ea17aac9dd725 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 20:39:05 +0200 Subject: [PATCH 10/14] chore: bump osc to 1.2.8 --- packages/osc/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index 4244c2c6..92aa30bf 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.8", + "version": "1.2.9", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.js", From 1c3e07afd3c4fac5367b5afd18dfe4242a72c18c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 20:40:25 +0200 Subject: [PATCH 11/14] fix: rephrase error message + bump to 1.2.10 --- packages/osc/package.json | 2 +- packages/osc/server.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index 92aa30bf..bc828d79 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.9", + "version": "1.2.10", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.js", diff --git a/packages/osc/server.js b/packages/osc/server.js index 2571c49d..d7ec21c4 100644 --- a/packages/osc/server.js +++ b/packages/osc/server.js @@ -56,7 +56,7 @@ if (debug) { osc.on('error', (message) => { if (message.toString().includes('EADDRINUSE')) { console.log(`------ ERROR ------- -osc server already running! to stop it: +a server is already running on port 57121! to stop it: 1. run "lsof -ti :57121 | xargs kill -9" (macos / linux) 2. re-run the osc server `); From 8833d623f71f89df51b79a4f8467456f72daa278 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Sep 2025 16:06:28 +0200 Subject: [PATCH 12/14] fix: all function in mondo --- packages/mondough/mondough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index e409d5a3..66918327 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -85,7 +85,7 @@ function evaluator(node, scope) { let pat; if (type === 'plain' && typeof variable !== 'undefined') { // some function names are not patternable, so we skip reification here - if (['!', 'extend', '@', 'expand', 'square', 'angle'].includes(value)) { + if (['!', 'extend', '@', 'expand', 'square', 'angle', 'all'].includes(value)) { return variable; } pat = reify(variable); From 86248328cc2be957da71566aeb671f69a10ccabe Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Sep 2025 16:09:10 +0200 Subject: [PATCH 13/14] fix: mondo setcps / setcpm --- packages/core/repl.mjs | 17 +++++++++++++++-- packages/mondough/mondough.mjs | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 47231af4..23c5b25e 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -85,7 +85,17 @@ export function repl({ const start = () => scheduler.start(); const pause = () => scheduler.pause(); const toggle = () => scheduler.toggle(); - const setCps = (cps) => scheduler.setCps(cps); + const setCps = (cps) => { + scheduler.setCps(unpure(cps)); + return silence; + }; + + function unpure(pat) { + if (pat._Pattern) { + return pat.__pure; + } + return pat; + } /** * Changes the global tempo to the given cycles per minute @@ -97,7 +107,10 @@ export function repl({ * setcpm(140/4) // =140 bpm in 4/4 * $: s("bd*4,[- sd]*2").bank('tr707') */ - const setCpm = (cpm) => scheduler.setCps(cpm / 60); + const setCpm = (cpm) => { + scheduler.setCps(unpure(cpm) / 60); + return silence; + }; // TODO - not documented as jsdoc examples as the test framework doesn't simulate enough context for `each` and `all`.. diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index 66918327..b7ee8378 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -85,7 +85,7 @@ function evaluator(node, scope) { let pat; if (type === 'plain' && typeof variable !== 'undefined') { // some function names are not patternable, so we skip reification here - if (['!', 'extend', '@', 'expand', 'square', 'angle', 'all'].includes(value)) { + if (['!', 'extend', '@', 'expand', 'square', 'angle', 'all', 'setcpm', 'setcps'].includes(value)) { return variable; } pat = reify(variable); From 452827630b2ea1949674e645835a960bb1ae1be1 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Sep 2025 16:13:09 +0200 Subject: [PATCH 14/14] move unpure up --- packages/core/repl.mjs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 23c5b25e..53562f21 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -74,6 +74,14 @@ export function repl({ return silence; }; + // helper to get a patternified pure value out + function unpure(pat) { + if (pat._Pattern) { + return pat.__pure; + } + return pat; + } + const setPattern = async (pattern, autostart = true) => { pattern = editPattern?.(pattern) || pattern; await scheduler.setPattern(pattern, autostart); @@ -90,13 +98,6 @@ export function repl({ return silence; }; - function unpure(pat) { - if (pat._Pattern) { - return pat.__pure; - } - return pat; - } - /** * Changes the global tempo to the given cycles per minute *