mirror of
https://codeberg.org/uzu/strudel
synced 2026-09-05 22:58:09 -04:00
strudel cli poc
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import repl from 'repl';
|
||||
import { evalScope, evaluate } from '@strudel.cycles/eval';
|
||||
import { AudioContext } from 'web-audio-api';
|
||||
import Speaker from 'speaker';
|
||||
import controls from '@strudel.cycles/core/controls.mjs';
|
||||
import { prepareSamples, playBuffer } from './sampler.js';
|
||||
import { randomHeadline } from './headline.js';
|
||||
|
||||
/*
|
||||
This is just a POC of how a strudel cli / repl could look like
|
||||
*/
|
||||
|
||||
// setup audio
|
||||
const context = new AudioContext();
|
||||
context.outStream = new Speaker({
|
||||
channels: context.format.numberOfChannels,
|
||||
bitDepth: context.format.bitDepth,
|
||||
sampleRate: context.sampleRate,
|
||||
});
|
||||
console.log('now loading samples..');
|
||||
const buffers = await prepareSamples(context, './samples/');
|
||||
console.log('');
|
||||
|
||||
// scheduler
|
||||
let tick = 0;
|
||||
const slice = 0.5;
|
||||
const latency = 1;
|
||||
/* console.log('latency', latency);
|
||||
console.log('querying every', slice, 's'); */
|
||||
const offset = context.currentTime + latency;
|
||||
let pattern;
|
||||
setInterval(() => {
|
||||
if (pattern) {
|
||||
try {
|
||||
pattern
|
||||
.queryArc(tick * slice, ++tick * slice)
|
||||
.filter((hap) => hap.hasOnset())
|
||||
.forEach((hap) => {
|
||||
const t = hap.whole.begin.valueOf() + offset;
|
||||
const { s, n } = hap.value;
|
||||
const bank = buffers[s];
|
||||
if (bank?.length) {
|
||||
const index = (n ?? 0) % bank.length;
|
||||
playBuffer(context, bank[index], t);
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('query error', err);
|
||||
}
|
||||
}
|
||||
}, slice * 1000);
|
||||
|
||||
await evalScope(controls, import('@strudel.cycles/core'), import('@strudel.cycles/mini'));
|
||||
console.log(`${randomHeadline()}
|
||||
|
||||
welcome to the experimental strudel cli <3
|
||||
|
||||
available samples: ${Object.entries(buffers)
|
||||
.map(([key, samples]) => `${key} (${samples.length})`)
|
||||
.join(', ')}
|
||||
you can add samples to the samples folder (.wav, .ogg, .mp3)
|
||||
|
||||
please enter a pattern, e.g. s("bd(3,8),~ sd,hh(3,8,1)")
|
||||
`);
|
||||
// repl
|
||||
repl.start({
|
||||
prompt: '>>>',
|
||||
eval: async function myEval(cmd, context, filename, callback) {
|
||||
try {
|
||||
pattern = (await evaluate(cmd)).pattern;
|
||||
} catch (err) {
|
||||
console.error('query error', err.message);
|
||||
}
|
||||
callback(null);
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user