add docs for OSC target

This commit is contained in:
Jade (Rose) Rowland 2024-08-31 23:38:23 -04:00
parent 8befa4382b
commit 11a07df120
6 changed files with 33 additions and 27 deletions

View File

@ -1,20 +1,12 @@
import { parseNumeral, Pattern, ClockCollator } from '@strudel/core';
import { Pattern, ClockCollator } from '@strudel/core';
import { parseControlsFromHap } from 'node_modules/@strudel/osc/osc.mjs';
import { Invoke } from './utils.mjs';
const collator = new ClockCollator({});
export async function oscTriggerTauri(t_deprecate, hap, currentTime, cps = 1, targetTime) {
hap.ensureObjectValue();
const cycle = hap.wholeOrPart().begin.valueOf();
const delta = hap.duration.valueOf();
const controls = Object.assign({}, { cps, cycle, delta }, hap.value);
// make sure n and note are numbers
controls.n && (controls.n = parseNumeral(controls.n));
controls.note && (controls.note = parseNumeral(controls.note));
const controls = parseControlsFromHap(hap, cps);
const params = [];
const timestamp = collator.calculateTimestamp(currentTime, targetTime);
Object.keys(controls).forEach((key) => {

View File

@ -34,11 +34,8 @@ function connect() {
return connection;
}
const collator = new ClockCollator({});
export async function oscTrigger(t_deprecate, hap, currentTime, cps = 1, targetTime) {
export function parseControlsFromHap(hap, cps) {
hap.ensureObjectValue();
const osc = await connect();
const cycle = hap.wholeOrPart().begin.valueOf();
const delta = hap.duration.valueOf();
const controls = Object.assign({}, { cps, cycle, delta }, hap.value);
@ -53,9 +50,19 @@ export async function oscTrigger(t_deprecate, hap, currentTime, cps = 1, targetT
}
controls.bank && (controls.s = controls.bank + controls.s);
controls.roomsize && (controls.size = parseNumeral(controls.roomsize));
const keyvals = Object.entries(controls).flat();
const ts = Math.round(collator.calculateTimestamp(currentTime, targetTime) * 1000);
const channels = controls.channels;
channels != undefined && (controls.channels = JSON.stringify(channels));
return controls;
}
const collator = new ClockCollator({});
export async function oscTrigger(t_deprecate, hap, currentTime, cps = 1, targetTime) {
const osc = await connect();
const controls = parseControlsFromHap(hap, cps);
const keyvals = Object.entries(controls).flat();
const ts = Math.round(collator.calculateTimestamp(currentTime, targetTime) * 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

View File

@ -45,7 +45,7 @@ But you can also control cc messages separately like this:
$: ccv(sine.segment(16).slow(4)).ccn(74).midi()`}
/>
# SuperDirt API
# OSC/SuperDirt API
In mainline tidal, the actual sound is generated via [SuperDirt](https://github.com/musikinformatik/SuperDirt/), which runs inside SuperCollider.
Strudel also supports using [SuperDirt](https://github.com/musikinformatik/SuperDirt/) as a backend, although it requires some developer tooling to run.
@ -73,16 +73,14 @@ Now you're all set!
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).
Note: if you have the 'Audio Engine Target' in settings set to 'OSC', you do not need to add .osc() to the end of your pattern.
### Pattern.osc
<JsDoc client:idle name="Pattern.osc" h={0} />
## SuperDirt Params
The following functions can be used with [SuperDirt](https://github.com/musikinformatik/SuperDirt/):
`s n note freq channel orbit cutoff resonance hcutoff hresonance bandf bandq djf vowel cut begin end loop fadeTime speed unitA gain amp accelerate crush coarse delay lock leslie lrate lsize pan panspan pansplay room size dry shape squiz waveloss attack decay octave detune tremolodepth`
Please refer to [Tidal Docs](https://tidalcycles.org/) for more info.
<br />

View File

@ -9,7 +9,16 @@ export function AudioEngineTargetSelector({ target, onChange, isDisabled }) {
};
const options = new Map([
[audioEngineTargets.webaudio, audioEngineTargets.webaudio],
[audioEngineTargets.superdirt, 'superdirt (osc)'],
[audioEngineTargets.osc, audioEngineTargets.osc],
]);
return <SelectInput isDisabled={isDisabled} options={options} value={target} onChange={onTargetChange} />;
return (
<div className=' flex flex-col gap-1'>
<SelectInput isDisabled={isDisabled} options={options} value={target} onChange={onTargetChange} />
{target === audioEngineTargets.osc && (
<div>
<p className='text-sm italic'> Events routed to OSC, audio is silenced! See <a className='text-blue-500' href="https://strudel.cc/learn/input-output/">Docs</a></p>
</div>
)}
</div>
);
}

View File

@ -57,7 +57,7 @@ async function getModule(name) {
export function useReplContext() {
const { isSyncEnabled, audioEngineTarget } = useSettings();
const shouldUseWebaudio = audioEngineTarget !== audioEngineTargets.superdirt;
const shouldUseWebaudio = audioEngineTarget !== audioEngineTargets.osc;
const defaultOutput = shouldUseWebaudio ? webaudioOutput : superdirtOutput;
const getTime = shouldUseWebaudio ? getAudioContextCurrentTime : getPerformanceTimeSeconds;

View File

@ -7,7 +7,7 @@ export const defaultAudioDeviceName = 'System Standard';
export const audioEngineTargets = {
webaudio: 'webaudio',
superdirt: 'superdirt',
osc: 'osc',
};
export const defaultSettings = {
@ -33,7 +33,7 @@ export const defaultSettings = {
panelPosition: 'right',
userPatterns: '{}',
audioDeviceName: defaultAudioDeviceName,
audioEngineTarget: audioEngineTargets.webaudio, //webaudio | superdirt
audioEngineTarget: audioEngineTargets.webaudio,
};
let search = null;