From cdc200e1da2f6ff417ff5d2aafcf8f5ef9b7f187 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 16 Mar 2024 03:12:00 +0100 Subject: [PATCH] draw straight line when no analyser is defined yet + add todo for memory leak --- packages/webaudio/scope.mjs | 26 ++++++++++++++++++++++---- packages/widgets/canvas.mjs | 6 ++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/webaudio/scope.mjs b/packages/webaudio/scope.mjs index e4b856f3..c9ee1f33 100644 --- a/packages/webaudio/scope.mjs +++ b/packages/webaudio/scope.mjs @@ -15,13 +15,23 @@ export function drawTimeScope( id = 1, } = {}, ) { - const dataArray = getAnalyzerData('time', id); - ctx.lineWidth = thickness; ctx.strokeStyle = color; + let canvas = ctx.canvas; + + if (!analyser) { + // if analyser is undefined, draw straight line + // it may be undefined when no sound has been played yet + ctx.beginPath(); + let y = pos * canvas.height; + ctx.moveTo(0, y); + ctx.lineTo(canvas.width, y); + ctx.stroke(); + return; + } + const dataArray = getAnalyzerData('time', id); ctx.beginPath(); - let canvas = ctx.canvas; const bufferSize = analyser.frequencyBinCount; let triggerIndex = align @@ -49,6 +59,14 @@ export function drawFrequencyScope( analyser, { color = 'white', scale = 0.25, pos = 0.75, lean = 0.5, min = -150, max = 0, ctx = getDrawContext(), id = 1 } = {}, ) { + if (!analyser) { + ctx.beginPath(); + let y = pos * canvas.height; + ctx.moveTo(0, y); + ctx.lineTo(canvas.width, y); + ctx.stroke(); + return; + } const dataArray = getAnalyzerData('frequency', id); const canvas = ctx.canvas; @@ -119,7 +137,7 @@ Pattern.prototype.tscope = function (config = {}) { return this.analyze(id).draw( () => { clearScreen(config.smear, '0,0,0', config.ctx); - analysers[id] && drawTimeScope(analysers[id], config); + drawTimeScope(analysers[id], config); }, { id }, ); diff --git a/packages/widgets/canvas.mjs b/packages/widgets/canvas.mjs index 14aa8911..d5a705b9 100644 --- a/packages/widgets/canvas.mjs +++ b/packages/widgets/canvas.mjs @@ -25,5 +25,11 @@ registerWidget('twist', (id, options = {}, pat) => { registerWidget('osci', (id, options = {}, pat) => { options = { width: 500, height: 60, pos: 0.5, scale: 1, ...options }; const ctx = getCanvasWidget(id, options).getContext('2d'); + // TODO: find way to clear previous analysers to avoid memory leak + // .scope passes id to Pattern.analyze, which is picked up by superdough + // .. which calls getAnalyserById(analyze), creating a new analyzer (+buffer) for that key + // the id here is the col number where the osci function ends (as passed by the transpiler) + // effectively, this means for each evaluation of .osci on a unique col, a new analyser will be created + // the problem is that the old ones will never get deleted.. this might pile up some memory return pat.scope({ ...options, ctx, id }); });