Add CV visualizer to oscilloscope node

This commit is contained in:
Skyler Lehmkuhl 2025-10-28 20:19:25 -04:00
parent d7dc423fe3
commit d496d796dd
2 changed files with 38 additions and 9 deletions

View File

@ -7034,7 +7034,7 @@ function nodeEditor() {
console.log(`Starting oscilloscope visualization for node ${drawflowNodeId} (backend ID: ${backendNodeId})`); console.log(`Starting oscilloscope visualization for node ${drawflowNodeId} (backend ID: ${backendNodeId})`);
// Wait for DOM to update before starting visualization // Wait for DOM to update before starting visualization
setTimeout(() => { setTimeout(() => {
startOscilloscopeVisualization(drawflowNodeId, currentTrackId, backendNodeId); startOscilloscopeVisualization(drawflowNodeId, currentTrackId, backendNodeId, editor);
}, 100); }, 100);
} }
} }
@ -8131,7 +8131,7 @@ function nodeEditor() {
// For Oscilloscope nodes, start the visualization // For Oscilloscope nodes, start the visualization
if (nodeType === 'Oscilloscope' && serializedNode.id && trackId) { if (nodeType === 'Oscilloscope' && serializedNode.id && trackId) {
startOscilloscopeVisualization(drawflowId, trackId, serializedNode.id); startOscilloscopeVisualization(drawflowId, trackId, serializedNode.id, editor);
} }
resolve(); resolve();
@ -9206,7 +9206,7 @@ const oscilloscopeIntervals = new Map();
const oscilloscopeTimeScales = new Map(); const oscilloscopeTimeScales = new Map();
// Start oscilloscope visualization for a node // Start oscilloscope visualization for a node
function startOscilloscopeVisualization(nodeId, trackId, backendNodeId) { function startOscilloscopeVisualization(nodeId, trackId, backendNodeId, editorRef) {
// Clear any existing interval for this node // Clear any existing interval for this node
stopOscilloscopeVisualization(nodeId); stopOscilloscopeVisualization(nodeId);
@ -9266,17 +9266,17 @@ function startOscilloscopeVisualization(nodeId, trackId, backendNodeId) {
ctx.lineTo(width, height / 2); ctx.lineTo(width, height / 2);
ctx.stroke(); ctx.stroke();
// Draw waveform // Draw audio waveform
if (data && data.length > 0) { if (data && data.audio && data.audio.length > 0) {
ctx.strokeStyle = '#4CAF50'; ctx.strokeStyle = '#4CAF50';
ctx.lineWidth = 2; ctx.lineWidth = 2;
ctx.beginPath(); ctx.beginPath();
const xStep = width / data.length; const xStep = width / data.audio.length;
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.audio.length; i++) {
const x = i * xStep; const x = i * xStep;
// Map sample value from [-1, 1] to canvas height // Map sample value from [-1, 1] to canvas height
const y = height / 2 - (data[i] * height / 2); const y = height / 2 - (data.audio[i] * height / 2);
if (i === 0) { if (i === 0) {
ctx.moveTo(x, y); ctx.moveTo(x, y);
@ -9286,6 +9286,34 @@ function startOscilloscopeVisualization(nodeId, trackId, backendNodeId) {
} }
ctx.stroke(); ctx.stroke();
} }
// Draw CV trace in orange if present and CV input is connected
if (data && data.cv && data.cv.length > 0 && editorRef) {
// Check if CV input (port index 2 = input_3 in drawflow) is connected
const node = editorRef.getNodeFromId(nodeId);
const cvInput = node?.inputs?.input_3;
const isCvConnected = cvInput && cvInput.connections && cvInput.connections.length > 0;
if (isCvConnected) {
ctx.strokeStyle = '#FF9800'; // Orange color
ctx.lineWidth = 2;
ctx.beginPath();
const xStep = width / data.cv.length;
for (let i = 0; i < data.cv.length; i++) {
const x = i * xStep;
// Map CV value from [-1, 1] to canvas height
const y = height / 2 - (data.cv[i] * height / 2);
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
}
}
} catch (error) { } catch (error) {
console.error('Failed to update oscilloscope:', error); console.error('Failed to update oscilloscope:', error);
} }

View File

@ -311,7 +311,8 @@ export const nodeTypes = {
description: 'Visual audio signal monitor (pass-through)', description: 'Visual audio signal monitor (pass-through)',
inputs: [ inputs: [
{ name: 'Audio In', type: SignalType.AUDIO, index: 0 }, { name: 'Audio In', type: SignalType.AUDIO, index: 0 },
{ name: 'V/oct', type: SignalType.CV, index: 1 } { name: 'V/oct', type: SignalType.CV, index: 1 },
{ name: 'CV In', type: SignalType.CV, index: 2 }
], ],
outputs: [ outputs: [
{ name: 'Audio Out', type: SignalType.AUDIO, index: 0 } { name: 'Audio Out', type: SignalType.AUDIO, index: 0 }