@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.55 → 1.0.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -351,26 +351,48 @@ class MLNoiseSuppressor {
351
351
  this.processingNode = this.audioContext.createScriptProcessor(bufferSize, 1, 1);
352
352
  let frameCount = 0;
353
353
  const startTime = performance.now();
354
+ // Double-buffering for async ML processing
355
+ // We store the PREVIOUS processed result and output it in the NEXT callback
356
+ // This adds one buffer of latency but ensures we never output zeros
357
+ let previousProcessedBuffer = null;
358
+ let processingInFlight = false;
354
359
  // Process audio frames with ML model
355
- this.processingNode.onaudioprocess = async (event) => {
360
+ // IMPORTANT: onaudioprocess is synchronous! We use double-buffering to handle async ML
361
+ this.processingNode.onaudioprocess = (event) => {
356
362
  const inputData = event.inputBuffer.getChannelData(0);
357
363
  const outputData = event.outputBuffer.getChannelData(0);
358
364
  frameCount++;
359
- try {
360
- // Process with BiLSTM model
361
- const processed = await this.processAudio(new Float32Array(inputData));
362
- outputData.set(processed);
363
- // Log performance every ~4 seconds
364
- if (frameCount % 100 === 0) {
365
- const elapsed = (performance.now() - startTime) / 1000;
366
- const fps = frameCount / elapsed;
367
- console.log(`🎤 [ML] BiLSTM: ${frameCount} frames @ ${fps.toFixed(1)} fps`);
368
- }
365
+ // OUTPUT: Use previously processed audio (or passthrough if not ready yet)
366
+ if (previousProcessedBuffer) {
367
+ outputData.set(previousProcessedBuffer);
369
368
  }
370
- catch (error) {
371
- // On error, pass through original audio
369
+ else {
370
+ // First frame or ML not ready - pass through original audio
372
371
  outputData.set(inputData);
373
372
  }
373
+ // PROCESS: Start async ML processing for the NEXT frame
374
+ // Only start new processing if previous one is complete
375
+ if (!processingInFlight) {
376
+ processingInFlight = true;
377
+ const inputCopy = new Float32Array(inputData);
378
+ // Fire-and-forget async processing
379
+ this.processAudio(inputCopy)
380
+ .then((processed) => {
381
+ previousProcessedBuffer = processed;
382
+ processingInFlight = false;
383
+ })
384
+ .catch((error) => {
385
+ // On error, store the original audio for passthrough
386
+ previousProcessedBuffer = inputCopy;
387
+ processingInFlight = false;
388
+ });
389
+ }
390
+ // Log performance every ~4 seconds
391
+ if (frameCount % 100 === 0) {
392
+ const elapsed = (performance.now() - startTime) / 1000;
393
+ const fps = frameCount / elapsed;
394
+ console.log(`🎤 [ML] BiLSTM: ${frameCount} frames @ ${fps.toFixed(1)} fps`);
395
+ }
374
396
  };
375
397
  // Connect: source -> highpass -> BiLSTM processor -> destination
376
398
  source.connect(this.highPassFilter);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newgameplusinc/odyssey-audio-video-sdk-dev",
3
- "version": "1.0.55",
3
+ "version": "1.0.56",
4
4
  "description": "Odyssey Spatial Audio & Video SDK using MediaSoup for real-time communication with AI-powered noise suppression",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",