Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131// AC Buffer Writer for Max for Live// Writes incoming samples to buffer~ objects for playback via wave~
autowatch = 1;inlets = 1;outlets = 2;
// Ring buffer settings - 1 second at 48kHzvar BUFFER_SIZE_MS = 1000;var sampleRate = 48000;var bufferSizeSamples = 48000;
// Write positionvar writePos = 0;
// Buffer referencesvar leftBuf = null;var rightBuf = null;
var debugCount = 0;var initialized = false;var totalSamplesWritten = 0;
function initBuffers() { if (initialized) return; leftBuf = new Buffer("acleft"); rightBuf = new Buffer("acright"); if (leftBuf && rightBuf) { // Get actual buffer size bufferSizeSamples = leftBuf.framecount(); post("AC Buffer Writer: Buffers found! Size: " + bufferSizeSamples + " frames\n"); // Clear buffers leftBuf.send("clear"); rightBuf.send("clear"); initialized = true; outlet(0, "initialized", bufferSizeSamples); } else { post("AC Buffer Writer: Waiting for buffers...\n"); }}
// Called by route: first arg is count, rest is alternating L/R samplesfunction list() { var args = arrayfromargs(arguments); if (args.length < 1) return; // Initialize on first message if (!initialized) { initBuffers(); if (!initialized) return; } var numSamples = args[0]; // Debug: show what we received if (totalSamplesWritten === 0) { post("AC Buffer: First samples! count=" + numSamples + " args.length=" + args.length + "\n"); } // Validate data if (args.length < 1 + numSamples * 2) { post("AC Buffer: Not enough args! Need " + (1 + numSamples * 2) + " got " + args.length + "\n"); return; } // Write samples to buffers using poke for (var i = 0; i < numSamples; i++) { var leftSample = args[1 + i]; var rightSample = args[1 + numSamples + i]; // poke(channel, frame, value) leftBuf.poke(1, writePos, leftSample); rightBuf.poke(1, writePos, rightSample); writePos++; if (writePos >= bufferSizeSamples) { writePos = 0; } } totalSamplesWritten += numSamples; // Debug every 50 messages debugCount++; if (debugCount % 50 === 0) { post("AC Buffer: wrote " + numSamples + " @ pos " + writePos + " (total: " + totalSamplesWritten + ")\n"); }}
// Handle dictionary input (from node.script JSON output)function anything() { var msg = messagename; var args = arrayfromargs(arguments); // Debug incoming message type debugCount++; if (debugCount <= 5) { post("AC Buffer: msg='" + msg + "' args.length=" + args.length + "\n"); } // Initialize on first message if (!initialized) { initBuffers(); if (!initialized) return; } // Handle "samples" message from route object if (msg === "samples") { // Args should be: numSamples, left[0], left[1], ..., right[0], right[1], ... // Already handled by list() via route, but also handle here list.apply(this, args); }}
function bang() { initBuffers(); post("AC Buffer Writer: bang received, initialized=" + initialized + "\n");}
function loadbang() { post("AC Buffer Writer: loadbang\n"); // Defer initialization to let buffers load first var task = new Task(initBuffers); task.schedule(500);}