From 7250824e6bc9414cd4b2a68befaf31ccd311e77b Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 24 May 2022 22:35:06 +0200 Subject: [PATCH] add superdirt params --- doc.json | 33 +++++++++-- packages/osc/osc.mjs | 12 +++- tutorial/tutorial.mdx | 134 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 7 deletions(-) diff --git a/doc.json b/doc.json index e739c923..caec3b45 100644 --- a/doc.json +++ b/doc.json @@ -3380,6 +3380,29 @@ "___id": "T000002R000906", "___s": true }, + { + "comment": "/**\n *\n * Sends each hap as an OSC message, which can be picked up by SuperCollider or any other OSC-enabled software.\n *\n * @name osc\n * @memberof Pattern\n * @returns Pattern\n */", + "meta": { + "filename": "osc.mjs", + "lineno": 15, + "columnno": 0, + "path": "/home/felix/projects/strudel/packages/osc", + "code": {} + }, + "description": "

Sends each hap as an OSC message, which can be picked up by SuperCollider or any other OSC-enabled software.

", + "name": "osc", + "memberof": "Pattern", + "returns": [ + { + "description": "

Pattern

" + } + ], + "scope": "static", + "longname": "Pattern.osc", + "kind": "member", + "___id": "T000002R002650", + "___s": true + }, { "comment": "/**\n * Change the pitch of each value by the given amount. Expects numbers or note strings as values.\n * The amount can be given as a number of semitones or as a string in interval short notation.\n * If you don't care about enharmonic correctness, just use numbers. Otherwise, pass the interval of\n * the form: ST where S is the degree number and T the type of interval with\n *\n * - M = major\n * - m = minor\n * - P = perfect\n * - A = augmented\n * - d = diminished\n *\n * Examples intervals:\n *\n * - 1P = unison\n * - 3M = major third\n * - 3m = minor third\n * - 4P = perfect fourth\n * - 4A = augmented fourth\n * - 5P = perfect fifth\n * - 5d = diminished fifth\n *\n * @param {string | number} amount Either number of semitones or interval string.\n * @returns Pattern\n * @memberof Pattern\n * @name transpose\n * @example\n * \"c2 c3\".fast(2).transpose(\"<0 -2 5 3>\".slow(2)).transpose(0)\n * @example\n * \"c2 c3\".fast(2).transpose(\"<1P -2M 4P 3m>\".slow(2)).transpose(0)\n */", "meta": { @@ -3416,7 +3439,7 @@ "scope": "static", "longname": "Pattern.transpose", "kind": "member", - "___id": "T000002R003715", + "___id": "T000002R003716", "___s": true }, { @@ -3453,7 +3476,7 @@ "scope": "static", "longname": "Pattern.scaleTranspose", "kind": "member", - "___id": "T000002R003719", + "___id": "T000002R003720", "___s": true }, { @@ -3490,7 +3513,7 @@ "scope": "static", "longname": "Pattern.scale", "kind": "member", - "___id": "T000002R003721", + "___id": "T000002R003722", "___s": true }, { @@ -3527,7 +3550,7 @@ "scope": "static", "longname": "Pattern.voicings", "kind": "member", - "___id": "T000002R003746", + "___id": "T000002R003747", "___s": true }, { @@ -3609,7 +3632,7 @@ "/home/felix/projects/strudel/packages/xen/tunejs.js", "/home/felix/projects/strudel/packages/xen/xen.mjs" ], - "___id": "T000002R014015", + "___id": "T000002R014016", "___s": true } ] diff --git a/packages/osc/osc.mjs b/packages/osc/osc.mjs index 4d4ed55b..e3b12823 100644 --- a/packages/osc/osc.mjs +++ b/packages/osc/osc.mjs @@ -12,17 +12,25 @@ comm.open(); const latency = 0.1; let startedAt = -1; +/** + * + * Sends each hap as an OSC message, which can be picked up by SuperCollider or any other OSC-enabled software. + * + * @name osc + * @memberof Pattern + * @returns Pattern + */ Pattern.prototype.osc = function () { return this._withHap((hap) => { const onTrigger = (time, hap, currentTime, cps, cycle, delta) => { // time should be audio time of onset // currentTime should be current time of audio context (slightly before time) if (startedAt < 0) { - startedAt = Date.now() - (currentTime * 1000); + startedAt = Date.now() - currentTime * 1000; } const controls = Object.assign({}, { cps: cps, cycle: cycle, delta: delta }, hap.value); const keyvals = Object.entries(controls).flat(); - const ts = Math.floor(startedAt + ((time + latency) * 1000)); + const ts = Math.floor(startedAt + (time + latency) * 1000); const message = new OSC.Message('/dirt/play', ...keyvals); const bundle = new OSC.Bundle([message], ts); bundle.timestamp(ts); // workaround for https://github.com/adzialocha/osc-js/issues/60 diff --git a/tutorial/tutorial.mdx b/tutorial/tutorial.mdx index e4d54205..1a3cfba3 100644 --- a/tutorial/tutorial.mdx +++ b/tutorial/tutorial.mdx @@ -728,3 +728,137 @@ The following functions will return a pattern. We will see later what that means {{ 'Pattern.late' | jsdoc }} {{ 'Pattern.rev' | jsdoc }} + +{{ 'Pattern.legato' | jsdoc }} + +## Using Superdirt via OSC + +In mainline tidal, the actual sound is generated via Superdirt, which runs inside Supercollider. +Strudel also supports using Superdirt as a backend, although it requires some developer tooling to run. + +### Getting Started + +Getting Superdirt to work with Strudel, you need to + +1. install SuperCollider + sc3 plugins, see [Tidal Docs](https://tidalcycles.org/docs/) (Install Tidal) for more info. +2. install [node.js](https://nodejs.org/en/) +3. download [Strudel Repo](https://github.com/tidalcycles/strudel/) (or git clone, if you have git installed) +4. run `npm i` in the strudel directory +5. run `npm run osc` to start the osc server, which forwards OSC messages from Strudel REPL to SuperCollider + +Now you're all set! + +### Usage + +1. Start SuperCollider, either using SuperCollider IDE or by running `sclang` in a terminal +2. Open the [Strudel REPL](https://strudel.tidalcycles.org/#cygiYmQgc2QiKS5vc2MoKQ%3D%3D) + +...or test it here: + + + +If you now hear sound, congratulations! If not, you can get help on the [#strudel channel in the TidalCycles discord](https://discord.com/invite/HGEdXmRkzT). + +{{ 'Pattern.osc' | jsdoc }} + +# Superdirt Params + +The following functions are specific to SuperDirt and won't work with other Strudel outputs. + +## Basic Types + +{{ 's' | jsdoc }} + +{{ 'n' | jsdoc }} + +{{ 'freq' | jsdoc }} + +## Filters + +{{ 'cutoff' | jsdoc }} + +{{ 'resonance' | jsdoc }} + +{{ 'hcutoff' | jsdoc }} + +{{ 'hresonance' | jsdoc }} + +{{ 'bandf' | jsdoc }} + +{{ 'bandq' | jsdoc }} + +{{ 'djf' | jsdoc }} + +{{ 'vowel' | jsdoc }} + +## Sample Editing + +{{ 'cut' | jsdoc }} + +{{ 'begin' | jsdoc }} + +{{ 'end' | jsdoc }} + +{{ 'loop' | jsdoc }} + +{{ 'fadeTime' | jsdoc }} + +{{ 'speed' | jsdoc }} + +{{ 'unit' | jsdoc }} + +## Audio Effects + +{{ 'gain' | jsdoc }} + +{{ 'amp' | jsdoc }} + +{{ 'accelerate' | jsdoc }} + +{{ 'crush' | jsdoc }} + +{{ 'coarse' | jsdoc }} + +{{ 'channel' | jsdoc }} + +{{ 'delay' | jsdoc }} + +{{ 'lock' | jsdoc }} + +{{ 'dry' | jsdoc }} + +{{ 'leslie' | jsdoc }} + +{{ 'lrate' | jsdoc }} + +{{ 'lsize' | jsdoc }} + +{{ 'orbit' | jsdoc }} + +{{ 'pan' | jsdoc }} + +{{ 'panspan' | jsdoc }} + +{{ 'pansplay' | jsdoc }} + +{{ 'room' | jsdoc }} + +{{ 'size' | jsdoc }} + +{{ 'shape' | jsdoc }} + +{{ 'squiz' | jsdoc }} + +{{ 'waveloss' | jsdoc }} + +{{ 'attack' | jsdoc }} + +{{ 'decay' | jsdoc }} + +## Synth Effects + +{{ 'octave' | jsdoc }} + +{{ 'detune' | jsdoc }} + +{{ 'tremolodepth' | jsdoc }}