From 9052ff71e61934e3f6d639df8b7ee19099c6bec3 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 1 Dec 2022 12:34:26 +0100 Subject: [PATCH] get rid of csound warning on reevaluation: - only compile on init, use evalCode after - pull presets into csd file - use custom logging --- packages/csound/csound.mjs | 61 +++++++++++++++++-------- packages/csound/{csd.mjs => sounds.csd} | 39 ++++++---------- 2 files changed, 55 insertions(+), 45 deletions(-) rename packages/csound/{csd.mjs => sounds.csd} (63%) diff --git a/packages/csound/csound.mjs b/packages/csound/csound.mjs index ab80dd6f..03a539dc 100644 --- a/packages/csound/csound.mjs +++ b/packages/csound/csound.mjs @@ -1,7 +1,7 @@ import { getFrequency, logger, Pattern } from '@strudel.cycles/core'; import { Csound } from '@csound/browser'; // TODO: use dynamic import for code splitting.. -import { csd } from './csd.mjs'; import { getAudioContext } from '@strudel.cycles/webaudio'; +import csd from './sounds.csd?raw'; let csoundLoader, _csound; @@ -30,30 +30,53 @@ Pattern.prototype._csound = function (instrument) { gain, // p5: gain ]; const msg = `i ${params.join(' ')}`; - // console.log('msg', msg); _csound.inputMessage(msg); - // _csound.readScore(msg); // slower alternative - // even slower alternative: - /* const code = `schedule(${params.join(', ')})`; - _csound.evalCode(code); */ }); }; // initializes csound + can be used to reevaluate given instrument code export async function csound(code = '') { - code = csd(code); - let isInit = false; - if (!csoundLoader) { - isInit = true; - csoundLoader = (async () => { - _csound = await Csound({ audioContext: getAudioContext() }); - await _csound.setOption('-m0'); - await _csound.compileCsdText(code); - await _csound.start(); - })(); - } + csoundLoader = csoundLoader || init(); await csoundLoader; - !isInit && (await _csound?.compileCsdText(code)); + code && (await _csound?.evalCode(`${code}`)); + // ^ ^ + // wrapping in backticks makes sure it works when calling as templated function +} + +Pattern.prototype.define('csound', (a, pat) => pat.csound(a), { composable: false, patternified: true }); + +function eventLogger(type, args) { + const [msg] = args; + if ( + type === 'message' && + (['[commit: HEAD]'].includes(msg) || + msg.startsWith('--Csound version') || + msg.startsWith('libsndfile') || + msg.startsWith('sr =') || + msg.startsWith('0dBFS') || + msg.startsWith('audio buffered') || + msg.startsWith('writing') || + msg.startsWith('SECTION 1:')) + ) { + // ignore + return; + } + let logType = 'info'; + if (msg.startsWith('error:')) { + logType = 'error'; + } + logger(`[csound] ${msg || ''}`, logType); +} + +async function init() { + _csound = await Csound({ audioContext: getAudioContext() }); + _csound.removeAllListeners('message'); + ['message'].forEach((k) => _csound.on(k, (...args) => eventLogger(k, args))); + await _csound.setOption('-m0'); // see -m flag https://csound.com/docs/manual/CommandFlags.html + await _csound.setOption('--sample-accurate'); + await _csound.compileCsdText(csd); + await _csound.start(); + return _csound; } // experimental: allows using jsx to eval csound @@ -68,5 +91,3 @@ export function CsInstruments(text) { } return csound(text); } - -Pattern.prototype.define('csound', (a, pat) => pat.csound(a), { composable: false, patternified: true }); diff --git a/packages/csound/csd.mjs b/packages/csound/sounds.csd similarity index 63% rename from packages/csound/csd.mjs rename to packages/csound/sounds.csd index 67adbb3e..aafea9a4 100644 --- a/packages/csound/csd.mjs +++ b/packages/csound/sounds.csd @@ -1,9 +1,4 @@ -export function csd(code = '') { - return ` - --o dac --port=10000 --sample-accurate - sr=48000 ksmps=64 @@ -36,25 +31,19 @@ instr organ endin instr triangle - iduration = p3 - ifreq = p4 - igain = p5 - ioct = octcps(ifreq) - - asig = vco2(igain, ifreq, 12, .5) - - ; amp envelope - iattack = .001 - irelease = .05 - asig *= linsegr:a(0, iattack, 1, iduration, 1, irelease, 0) - - out(asig, asig) - + iduration = p3 + ifreq = p4 + igain = p5 + ioct = octcps(ifreq) + + asig = vco2(igain, ifreq, 12, .5) + + ; amp envelope + iattack = .001 + irelease = .05 + asig *= linsegr:a(0, iattack, 1, iduration, 1, irelease, 0) + + out(asig, asig) endin - -${code} - - -`; -} + \ No newline at end of file