Compare commits

..

10 Commits

Author SHA1 Message Date
Felix Roos c21bc161d6 some osc helper functions 2024-02-18 20:41:06 +01:00
Felix Roos 8d65092c97 update osc readme 2024-02-15 10:00:01 +01:00
Felix Roos b6a9943b5a use es6 import 2024-02-15 09:59:52 +01:00
Felix Roos a468ddb85b Merge pull request #945 from tidalcycles/cjs-fixes
remove cjs builds
2024-02-08 13:16:15 +01:00
Felix Roos 051bdaccc7 Publish
- @strudel/codemirror@1.0.1
 - @strudel/core@1.0.1
 - @strudel/csound@1.0.1
 - @strudel/hydra@1.0.1
 - @strudel/midi@1.0.1
 - @strudel/mini@1.0.1
 - @strudel/osc@1.0.1
 - @strudel/repl@1.0.1
 - @strudel/serial@1.0.1
 - @strudel/soundfonts@1.0.1
 - superdough@1.0.1
 - @strudel/tonal@1.0.1
 - @strudel/transpiler@1.0.1
 - @strudel/web@1.0.1
 - @strudel/webaudio@1.0.1
 - @strudel/xen@1.0.1
2024-02-08 13:04:25 +01:00
Felix Roos 5dc04d9574 make sure to overwrite main field 2024-02-08 12:36:04 +01:00
Felix Roos 60129413d3 remove cjs builds
+ add type module everywhere
2024-02-08 12:19:11 +01:00
Felix Roos d2bf9370ea Update README.md
add link to usage example for repl package
2024-02-04 23:24:43 +01:00
Felix Roos fd11aa5eec Merge pull request #941 from mhetrick/patch-1
Minor documentation error: Update first-sounds.mdx
2024-02-04 23:15:37 +01:00
Michael Hetrick fb7c2b61d3 Update first-sounds.mdx
Update the tutorial text to reflect that the default cpm setting has changed from 60 to 30.
2024-01-26 07:13:09 -08:00
37 changed files with 109 additions and 104 deletions
+2 -3
View File
@@ -1,11 +1,10 @@
{
"name": "@strudel/codemirror",
"version": "1.0.0",
"version": "1.0.1",
"description": "Codemirror Extensions for Strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+8 -14
View File
@@ -10,8 +10,9 @@ 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/>.
*/
import { timeCat, register, silence } from './pattern.mjs';
import { Pattern, timeCat, register, silence } from './pattern.mjs';
import { rotate, flatten, splitAt, zipWith } from './util.mjs';
import Fraction from './fraction.mjs';
const left = function (n, x) {
const [ons, offs] = n;
@@ -57,7 +58,6 @@ export const bjork = function (ons, steps) {
*
* @memberof Pattern
* @name euclid
* @synonyms euc
* @param {number} pulses the number of onsets / beats
* @param {number} steps the number of steps to fill
* @returns Pattern
@@ -70,7 +70,6 @@ export const bjork = function (ons, steps) {
* Like `euclid`, but has an additional parameter for 'rotating' the resulting sequence.
* @memberof Pattern
* @name euclidRot
* @synonyms eucr
* @param {number} pulses the number of onsets / beats
* @param {number} steps the number of steps to fill
* @param {number} rotation offset in steps
@@ -133,22 +132,18 @@ const _euclidRot = function (pulses, steps, rotation) {
return b;
};
export const euclid = register(['euclid', 'euc'], function (pulses, steps, pat) {
export const euclid = register('euclid', function (pulses, steps, pat) {
return pat.struct(_euclidRot(pulses, steps, 0));
});
export const { euclidrot, euclidRot } = register(
['euclidrot', 'euclidRot', 'eucr'],
function (pulses, steps, rotation, pat) {
return pat.struct(_euclidRot(pulses, steps, rotation));
},
);
export const { euclidrot, euclidRot } = register(['euclidrot', 'euclidRot'], function (pulses, steps, rotation, pat) {
return pat.struct(_euclidRot(pulses, steps, rotation));
});
/**
* Similar to `euclid`, but each pulse is held until the next pulse,
* so there will be no gaps.
* @name euclidLegato
* @synonyms eucl
* @memberof Pattern
* @param {number} pulses the number of onsets / beats
* @param {number} steps the number of steps to fill
@@ -169,7 +164,7 @@ const _euclidLegato = function (pulses, steps, rotation, pat) {
return pat.struct(timeCat(...gapless));
};
export const euclidLegato = register(['euclidLegato', 'eucl'], function (pulses, steps, pat) {
export const euclidLegato = register(['euclidLegato'], function (pulses, steps, pat) {
return _euclidLegato(pulses, steps, 0, pat);
});
@@ -178,7 +173,6 @@ export const euclidLegato = register(['euclidLegato', 'eucl'], function (pulses,
* so there will be no gaps, and has an additional parameter for 'rotating'
* the resulting sequence
* @name euclidLegatoRot
* @synonyms euclr
* @memberof Pattern
* @param {number} pulses the number of onsets / beats
* @param {number} steps the number of steps to fill
@@ -186,6 +180,6 @@ export const euclidLegato = register(['euclidLegato', 'eucl'], function (pulses,
* @example
* note("c3").euclidLegatoRot(3,5,2)
*/
export const euclidLegatoRot = register(['euclidLegatoRot', 'euclr'], function (pulses, steps, rotation, pat) {
export const euclidLegatoRot = register(['euclidLegatoRot'], function (pulses, steps, rotation, pat) {
return _euclidLegato(pulses, steps, rotation, pat);
});
+2 -3
View File
@@ -1,12 +1,11 @@
{
"name": "@strudel/core",
"version": "1.0.0",
"version": "1.0.1",
"description": "Port of Tidal Cycles to JavaScript",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"test": "vitest run",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/csound",
"version": "1.0.0",
"version": "1.0.1",
"description": "csound bindings for strudel",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/hydra",
"version": "1.0.0",
"version": "1.0.1",
"description": "Hydra integration for strudel",
"main": "hydra.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"server": "node server.js",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'hydra.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/midi",
"version": "1.0.0",
"version": "1.0.1",
"description": "Midi API for strudel",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2 -3
View File
@@ -1,12 +1,11 @@
{
"name": "@strudel/mini",
"version": "1.0.0",
"version": "1.0.1",
"description": "Mini notation for strudel",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"test": "vitest run",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -11
View File
@@ -4,18 +4,10 @@ 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:
From the project root:
Make sure you've [set up strudel locally](https://github.com/tidalcycles/strudel/blob/main/CONTRIBUTING.md#project-setup). Then run:
```js
npm run repl
```
and in a seperate shell:
```js
npm run osc
pnpm osc
```
This should give you
@@ -26,7 +18,7 @@ osc server running on port 57121
websocket server running on port 8080
```
Now open Supercollider (with the super dirt startup file)
Now open Supercollider (with the super dirt startup file) or run `sclang`.
Now open the REPL and type:
+26
View File
@@ -8,6 +8,7 @@ import OSC from 'osc-js';
import { logger, parseNumeral, Pattern } from '@strudel/core';
let subs = {};
let connection; // Promise<OSC>
function connect() {
if (!connection) {
@@ -25,6 +26,13 @@ function connect() {
console.log('[osc] disconnected');
reject('OSC connection closed');
});
osc.on('*', (msg) => {
Object.entries(subs).forEach(([route, callback]) => {
if (msg.address.startsWith(route)) {
callback(msg.args, msg);
}
});
});
osc.on('error', (err) => reject(err));
}).catch((err) => {
connection = undefined;
@@ -34,6 +42,24 @@ function connect() {
return connection;
}
export const connectOSC = connect;
export async function sendOSC(...msg) {
const osc = await connect();
const t = Date.now();
const message = new OSC.Message(...msg);
const bundle = new OSC.Bundle([message], t);
bundle.timestamp(t); // workaround for https://github.com/adzialocha/osc-js/issues/60
osc.send(bundle);
}
export function subOSC(route, callback) {
subs[route] = callback;
}
export function unsubOSC(route) {
delete subs[route];
}
/**
*
* Sends each hap as an OSC message, which can be picked up by SuperCollider or any other OSC-enabled software.
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/osc",
"version": "1.0.0",
"version": "1.0.1",
"description": "OSC messaging for strudel",
"main": "osc.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"server": "node server.js",
+1 -1
View File
@@ -4,7 +4,7 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
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/>.
*/
const OSC = require('osc-js');
import OSC from 'osc-js';
const config = {
receiver: 'ws', // @param {string} Where messages sent via 'send' method will be delivered to, 'ws' for Websocket clients, 'udp' for udp client
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'osc.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2
View File
@@ -1,3 +1,5 @@
# @strudel/repl
The Strudel REPL as a web component.
[Usage example](https://github.com/tidalcycles/strudel/blob/main/examples/buildless/web-component-no-iframe.html)
+2 -3
View File
@@ -1,11 +1,10 @@
{
"name": "@strudel/repl",
"version": "1.0.0",
"version": "1.0.1",
"description": "Strudel REPL as a Web Component",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/serial",
"version": "1.0.0",
"version": "1.0.1",
"description": "Webserial API for strudel",
"main": "serial.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'serial.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2 -3
View File
@@ -1,11 +1,10 @@
{
"name": "@strudel/soundfonts",
"version": "1.0.0",
"version": "1.0.1",
"description": "Soundsfont support for strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2 -3
View File
@@ -1,12 +1,11 @@
{
"name": "superdough",
"version": "1.0.0",
"version": "1.0.1",
"description": "simple web audio synth and sampler intended for live coding. inspired by superdirt and webdirt.",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.cjs",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"directories": {
"example": "examples"
+1 -1
View File
@@ -8,7 +8,7 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.cjs' })[ext],
},
rollupOptions: {
+2 -3
View File
@@ -1,11 +1,10 @@
{
"name": "@strudel/tonal",
"version": "1.0.0",
"version": "1.0.1",
"description": "Tonal functions for strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/transpiler",
"version": "1.0.0",
"version": "1.0.1",
"description": "Transpiler for strudel user code. Converts syntactically correct but semantically meaningless JS into evaluatable strudel code.",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2 -3
View File
@@ -1,11 +1,10 @@
{
"name": "@strudel/web",
"version": "1.0.0",
"version": "1.0.1",
"description": "Easy to setup, opiniated bundle of Strudel for the browser.",
"main": "web.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'web.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel/webaudio",
"version": "1.0.0",
"version": "1.0.1",
"description": "Web Audio helpers for Strudel",
"main": "index.mjs",
"type": "module",
@@ -8,8 +8,7 @@
"example": "examples"
},
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"example": "npx parcel examples/repl.html",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/xen",
"version": "1.0.0",
"version": "1.0.1",
"description": "Xenharmonic API for strudel",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+1 -1
View File
@@ -139,7 +139,7 @@ The content of a sequence will be squished into what's called a cycle.
cpm = cycles per minute
By default, the tempo is 60 cycles per minute = 1 cycle per second.
By default, the tempo is 30 cycles per minute = 1 half cycle per second.
</Box>