@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.
package/cppsrc/odinroom.cpp
CHANGED
|
@@ -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 (
|
|
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
|
-
|
|
625
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
-
//
|
|
202
|
-
const buffer = Buffer.from(data.samples16
|
|
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
|
}
|