@4players/odin-nodejs 0.11.2 → 0.11.3

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.
@@ -588,7 +588,7 @@ void OdinRoomWrapper::HandleAudioData() {
588
588
  OdinDecoder* decoder = pair.second;
589
589
  bool silent = false;
590
590
  OdinError rc = odin_decoder_pop(decoder, _audioSamplesBuffer, 1920, &silent);
591
- if (!odin_is_error(rc) && !silent) {
591
+ if (rc == ODIN_ERROR_SUCCESS && !silent) {
592
592
  // Double-check _started before calling callback
593
593
  // This prevents calling a released ThreadSafeFunction
594
594
  if (_started && _audioDataReceivedEventListener) {
@@ -621,8 +621,10 @@ void OdinRoomWrapper::HandleAudioData() {
621
621
  Napi::Object obj = Napi::Object::New(env);
622
622
  obj.Set("mediaId", samples->MediaId);
623
623
  obj.Set("peerId", (double)samples->PeerId);
624
- obj.Set("samples16", Napi::Buffer<short>::New(env, samples->Data, samples->Len));
625
- obj.Set("samples32", Napi::Buffer<float>::New(env, samples->OriginalData, samples->Len));
624
+ // Must use Copy(), not New(). New() wraps the pointer without copying.
625
+ // Since we delete samples below, New() would leave JS holding a dangling pointer.
626
+ obj.Set("samples16", Napi::Buffer<short>::Copy(env, samples->Data, samples->Len));
627
+ obj.Set("samples32", Napi::Buffer<float>::Copy(env, samples->OriginalData, samples->Len));
626
628
  jsCallback.Call({obj});
627
629
  } catch (...) {
628
630
  // Exception in audio callback - silently ignore
@@ -642,7 +644,11 @@ void OdinRoomWrapper::HandleAudioData() {
642
644
  }
643
645
  }
644
646
  }
645
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
647
+ // Sleep must match the decoder frame size (1920 stereo samples @ 48kHz = 20ms).
648
+ // A shorter sleep (e.g. 10ms) polls faster than audio arrives, causing the
649
+ // decoder's jitter buffer to produce PLC (Packet Loss Concealment) frames that
650
+ // stretch and distort the audio stream.
651
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
646
652
  }
647
653
  }
648
654
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4players/odin-nodejs",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "NodeJS bindings for the ODIN SDK. Use for AI enhanced human interactions, content moderation and audio processing features in a backend.",
5
5
  "main": "index.cjs",
6
6
  "types": "index.d.ts",
Binary file
Binary file
@@ -198,8 +198,8 @@ async function run() {
198
198
  // Write audio samples to the recording
199
199
  const recorder = fileRecorder[mediaId];
200
200
  if (recorder && data.samples16) {
201
- // Convert Int16Array to Buffer and write to WAV file
202
- const buffer = Buffer.from(data.samples16.buffer, data.samples16.byteOffset, data.samples16.byteLength);
201
+ // Copy audio data into a new buffer for safe async WAV writing
202
+ const buffer = Buffer.from(data.samples16);
203
203
  recorder.wavEncoder.write(buffer);
204
204
  recorder.sampleCount += data.samples16.length;
205
205
  }