@4players/odin-nodejs 0.7.4 → 0.8.0
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/binding.gyp +60 -58
- package/cppsrc/odinclient.cpp +10 -1
- package/cppsrc/odinmedia.cpp +1 -1
- package/cppsrc/odinroom.cpp +3 -26
- package/cppsrc/odinroom.h +0 -1
- package/libs/bin/linux/arm64/libodin_static.a +0 -0
- package/libs/bin/linux/ia32/libodin_static.a +0 -0
- package/libs/bin/linux/x64/libodin_static.a +0 -0
- package/libs/bin/macos/arm64/libodin_static.a +0 -0
- package/libs/bin/macos/x64/libodin_static.a +0 -0
- package/libs/bin/windows/arm64/odin_static.lib +0 -0
- package/libs/bin/windows/ia32/odin_static.lib +0 -0
- package/libs/bin/windows/x64/odin_static.lib +0 -0
- package/libs/include/odin.h +106 -102
- package/odin.media.d.ts +3 -2
- package/odin.room.d.ts +0 -6
- package/package.json +2 -2
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/darwin-x64/node.napi.node +0 -0
- package/tests/sending-audio/index.js +30 -13
- package/prebuilds/linux-x64/node.napi.node +0 -0
package/binding.gyp
CHANGED
|
@@ -1,61 +1,63 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"<(module_root_dir)/libs/include"
|
|
26
|
-
],
|
|
27
|
-
}],
|
|
28
|
-
["OS=='win'", {
|
|
29
|
-
"defines": [
|
|
30
|
-
"_HAS_EXCEPTIONS=1"
|
|
31
|
-
],
|
|
32
|
-
"msvs_settings": {
|
|
33
|
-
"VCCLCompilerTool": {
|
|
34
|
-
"ExceptionHandling": 1
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
'runtime_library': [
|
|
38
|
-
"<(module_root_dir)/libs/bin/windows/<(target_arch)/odin_static.lib"
|
|
39
|
-
],
|
|
40
|
-
'include_dirs': [
|
|
41
|
-
"<!@(node -p \"require('node-addon-api').include\")",
|
|
42
|
-
"<(module_root_dir)/libs/include"
|
|
43
|
-
],
|
|
44
|
-
}],
|
|
45
|
-
["OS=='mac'", {
|
|
46
|
-
'xcode_settings': {
|
|
47
|
-
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
|
|
48
|
-
'CLANG_CXX_LIBRARY': 'libc++',
|
|
49
|
-
'MACOSX_DEPLOYMENT_TARGET': '10.12',
|
|
50
|
-
},
|
|
51
|
-
'libraries': [
|
|
52
|
-
"<(module_root_dir)/libs/bin/macos/<(target_arch)/libodin_static.a"
|
|
53
|
-
],
|
|
54
|
-
'include_dirs': [
|
|
55
|
-
"<!@(node -p \"require('node-addon-api').include\")",
|
|
56
|
-
"<(module_root_dir)/libs/include"
|
|
57
|
-
],
|
|
58
|
-
}],
|
|
2
|
+
"targets": [
|
|
3
|
+
{
|
|
4
|
+
"target_name": "odin",
|
|
5
|
+
"sources": [
|
|
6
|
+
"cppsrc/binding.cpp",
|
|
7
|
+
"cppsrc/odinbindings.cpp",
|
|
8
|
+
"cppsrc/odinclient.cpp",
|
|
9
|
+
"cppsrc/odinroom.cpp",
|
|
10
|
+
"cppsrc/odinmedia.cpp",
|
|
11
|
+
"cppsrc/utilities.cpp"
|
|
12
|
+
],
|
|
13
|
+
"include_dirs": [
|
|
14
|
+
"<!@(node -p \"require('node-addon-api').include\")",
|
|
15
|
+
"<(module_root_dir)/libs/include"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": [
|
|
18
|
+
"<!(node -p \"require('node-addon-api').gyp\")"
|
|
19
|
+
],
|
|
20
|
+
"conditions": [
|
|
21
|
+
["OS=='linux'", {
|
|
22
|
+
"libraries": [
|
|
23
|
+
"-L<(module_root_dir)/libs/bin/linux/<(target_arch)",
|
|
24
|
+
"-lodin_static"
|
|
59
25
|
]
|
|
60
|
-
|
|
26
|
+
}],
|
|
27
|
+
["OS=='mac'", {
|
|
28
|
+
"libraries": [
|
|
29
|
+
"-L<(module_root_dir)/libs/bin/macos/<(target_arch)",
|
|
30
|
+
"-lodin_static",
|
|
31
|
+
]
|
|
32
|
+
}],
|
|
33
|
+
["OS=='win'", {
|
|
34
|
+
"msvs_settings": {
|
|
35
|
+
"VCCLCompilerTool": {
|
|
36
|
+
"AdditionalOptions": [ "/MD" ],
|
|
37
|
+
},
|
|
38
|
+
"VCLinkerTool": {
|
|
39
|
+
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
"libraries": [
|
|
43
|
+
"<(module_root_dir)/libs/bin/windows/<(target_arch)/odin_static.lib",
|
|
44
|
+
"-lws2_32",
|
|
45
|
+
"-lbcrypt",
|
|
46
|
+
"-lucrt",
|
|
47
|
+
"-lvcruntime",
|
|
48
|
+
"-lwinmm",
|
|
49
|
+
"-lntdll"
|
|
50
|
+
]
|
|
51
|
+
}]
|
|
52
|
+
],
|
|
53
|
+
"defines": [ "NAPI_DISABLE_CPP_EXCEPTIONS" ],
|
|
54
|
+
"cflags!": [ "-fno-exceptions" ],
|
|
55
|
+
"cflags_cc!": [ "-fno-exceptions" ],
|
|
56
|
+
"xcode_settings": {
|
|
57
|
+
"GCC_ENABLE_CPP_EXCEPTIONS": "NO",
|
|
58
|
+
"CLANG_CXX_LIBRARY": "libc++",
|
|
59
|
+
"MACOSX_DEPLOYMENT_TARGET": "10.12",
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
]
|
|
61
63
|
}
|
package/cppsrc/odinclient.cpp
CHANGED
|
@@ -72,7 +72,12 @@ OdinClient::OdinClient(const Napi::CallbackInfo& info) : Napi::ObjectWrap<OdinCl
|
|
|
72
72
|
printf("Odin NodeJS Addon: Initializing Odin runtime (%s) with sample rate %f and %d channels\n", ODIN_VERSION, _sampleRate, _numChannels);
|
|
73
73
|
#endif
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
// Create a OdinAudioStreamConfig struct to configure the audio stream
|
|
76
|
+
OdinAudioStreamConfig config;
|
|
77
|
+
config.sample_rate = _sampleRate;
|
|
78
|
+
config.channel_count = _numChannels;
|
|
79
|
+
|
|
80
|
+
odin_startup_ex(ODIN_VERSION, config);
|
|
76
81
|
}
|
|
77
82
|
|
|
78
83
|
/**
|
|
@@ -141,6 +146,8 @@ Napi::Value OdinClient::CreateRoom(const Napi::CallbackInfo &info) {
|
|
|
141
146
|
if (!generator)
|
|
142
147
|
{
|
|
143
148
|
Napi::TypeError::New(env, "Failed to initialize token generator, invalid access key").ThrowAsJavaScriptException();
|
|
149
|
+
odin_token_generator_destroy(generator);
|
|
150
|
+
return env.Undefined();
|
|
144
151
|
}
|
|
145
152
|
|
|
146
153
|
/*
|
|
@@ -151,6 +158,8 @@ Napi::Value OdinClient::CreateRoom(const Napi::CallbackInfo &info) {
|
|
|
151
158
|
if (odin_is_error(error))
|
|
152
159
|
{
|
|
153
160
|
Napi::TypeError::New(env, "Creating access token failed").ThrowAsJavaScriptException();
|
|
161
|
+
odin_token_generator_destroy(generator);
|
|
162
|
+
return env.Undefined();
|
|
154
163
|
}
|
|
155
164
|
|
|
156
165
|
/*
|
package/cppsrc/odinmedia.cpp
CHANGED
|
@@ -232,7 +232,7 @@ void OdinMedia::SendData(const Napi::CallbackInfo &info) {
|
|
|
232
232
|
Napi::Float32Array array = info[0].As<Napi::Float32Array>();
|
|
233
233
|
|
|
234
234
|
#ifdef DEBUG
|
|
235
|
-
printf("
|
|
235
|
+
printf("Sent %d bytes of audio data\n", (int)array.ElementLength());
|
|
236
236
|
#endif
|
|
237
237
|
|
|
238
238
|
OdinReturnCode result = odin_audio_push_data(_mediaStreamHandle, array.Data(), array.ElementLength());
|
package/cppsrc/odinroom.cpp
CHANGED
|
@@ -331,7 +331,6 @@ Napi::Object OdinRoom::Init(Napi::Env env, Napi::Object exports) {
|
|
|
331
331
|
Napi::Function func = DefineClass(env, "OdinRoom", {
|
|
332
332
|
InstanceMethod<&OdinRoom::Join>("join", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
333
333
|
InstanceMethod<&OdinRoom::UpdatePeerUserData>("updateOwnUserData", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
334
|
-
InstanceMethod<&OdinRoom::UpdateRoomUserData>("updateRoomUserData", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
335
334
|
InstanceMethod<&OdinRoom::SendMessage>("sendMessage", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
336
335
|
InstanceMethod<&OdinRoom::SetEventListener>("setEventListener", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
337
336
|
InstanceMethod<&OdinRoom::AddEventListener>("addEventListener", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
@@ -381,7 +380,7 @@ void OdinRoom::Join(const Napi::CallbackInfo &info) {
|
|
|
381
380
|
|
|
382
381
|
if (info.Length() > 1) {
|
|
383
382
|
Napi::Uint8Array data = info[1].As<Napi::Uint8Array>();
|
|
384
|
-
OdinReturnCode error =
|
|
383
|
+
OdinReturnCode error = odin_room_update_peer_user_data(_roomHandle, data.Data(), data.ByteLength());
|
|
385
384
|
if (odin_is_error(error))
|
|
386
385
|
{
|
|
387
386
|
Napi::TypeError::New(env, "Setting initial room peer data failed").ThrowAsJavaScriptException();
|
|
@@ -475,7 +474,7 @@ void OdinRoom::UpdatePeerUserData(const Napi::CallbackInfo &info) {
|
|
|
475
474
|
|
|
476
475
|
Napi::Uint8Array data = info[0].As<Napi::Uint8Array>();
|
|
477
476
|
|
|
478
|
-
OdinReturnCode error =
|
|
477
|
+
OdinReturnCode error = odin_room_update_peer_user_data(_roomHandle, data.Data(), data.ByteLength());
|
|
479
478
|
|
|
480
479
|
if (odin_is_error(error))
|
|
481
480
|
{
|
|
@@ -483,28 +482,6 @@ void OdinRoom::UpdatePeerUserData(const Napi::CallbackInfo &info) {
|
|
|
483
482
|
}
|
|
484
483
|
}
|
|
485
484
|
|
|
486
|
-
/**
|
|
487
|
-
* Updates the room user data. Requires an array of bytes as a parameter.
|
|
488
|
-
* @param info
|
|
489
|
-
* @return
|
|
490
|
-
*/
|
|
491
|
-
void OdinRoom::UpdateRoomUserData(const Napi::CallbackInfo &info) {
|
|
492
|
-
Napi::Env env = info.Env();
|
|
493
|
-
|
|
494
|
-
if (info.Length() != 1 || !info[0].IsTypedArray()) {
|
|
495
|
-
Napi::TypeError::New(env, "Data as byte array expected").ThrowAsJavaScriptException();
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
Napi::Uint8Array data = info[0].As<Napi::Uint8Array>();
|
|
499
|
-
|
|
500
|
-
OdinReturnCode error = odin_room_update_user_data(_roomHandle, OdinUserDataTarget_Room, data.Data(), data.ByteLength());
|
|
501
|
-
|
|
502
|
-
if (odin_is_error(error))
|
|
503
|
-
{
|
|
504
|
-
OdinUtilities::ThrowNapiException(env, error, "Failed to update room user data");
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
485
|
/**
|
|
509
486
|
* Sends a message to the room. Requires an array of bytes as a parameter and optinally a list of peer ids to send to.
|
|
510
487
|
* Please note: If the list is NULL the message will be sent to all peers in the room. If the list is not NULL the message
|
|
@@ -544,7 +521,7 @@ void OdinRoom::SendMessage(const Napi::CallbackInfo &info) {
|
|
|
544
521
|
|
|
545
522
|
if (odin_is_error(error))
|
|
546
523
|
{
|
|
547
|
-
OdinUtilities::ThrowNapiException(env, error, "Failed to
|
|
524
|
+
OdinUtilities::ThrowNapiException(env, error, "Failed to send message");
|
|
548
525
|
}
|
|
549
526
|
}
|
|
550
527
|
|
package/cppsrc/odinroom.h
CHANGED
|
@@ -47,7 +47,6 @@ private:
|
|
|
47
47
|
void Close(const Napi::CallbackInfo& info);
|
|
48
48
|
void Join(const Napi::CallbackInfo& info);
|
|
49
49
|
void UpdatePeerUserData(const Napi::CallbackInfo &info);
|
|
50
|
-
void UpdateRoomUserData(const Napi::CallbackInfo &info);
|
|
51
50
|
void SendMessage(const Napi::CallbackInfo &info);
|
|
52
51
|
void SetEventListener(const Napi::CallbackInfo &info);
|
|
53
52
|
void AddEventListener(const Napi::CallbackInfo &info);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/libs/include/odin.h
CHANGED
|
@@ -10,23 +10,7 @@
|
|
|
10
10
|
#include <stdint.h>
|
|
11
11
|
#include <stdlib.h>
|
|
12
12
|
|
|
13
|
-
#define ODIN_VERSION "1.4
|
|
14
|
-
|
|
15
|
-
#define Frame_SAMPLE_RATE 48000
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Supported channel layouts in audio functions.
|
|
19
|
-
*/
|
|
20
|
-
typedef enum OdinChannelLayout {
|
|
21
|
-
/**
|
|
22
|
-
* Samples are sequential
|
|
23
|
-
*/
|
|
24
|
-
OdinChannelLayout_Mono,
|
|
25
|
-
/**
|
|
26
|
-
* Channels are interleaved
|
|
27
|
-
*/
|
|
28
|
-
OdinChannelLayout_Stereo,
|
|
29
|
-
} OdinChannelLayout;
|
|
13
|
+
#define ODIN_VERSION "1.6.4"
|
|
30
14
|
|
|
31
15
|
/**
|
|
32
16
|
* Known types of a media stream.
|
|
@@ -134,25 +118,11 @@ typedef enum OdinTokenAudience {
|
|
|
134
118
|
} OdinTokenAudience;
|
|
135
119
|
|
|
136
120
|
/**
|
|
137
|
-
*
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
*/
|
|
143
|
-
OdinUserDataTarget_Peer,
|
|
144
|
-
/**
|
|
145
|
-
* Global user data for the room
|
|
146
|
-
*/
|
|
147
|
-
OdinUserDataTarget_Room,
|
|
148
|
-
} OdinUserDataTarget;
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* A pointer to a local ODIN token generator used to generate signed room tokens based based on an
|
|
152
|
-
* access key. Please note, that access keys are your the unique authentication keys to be used to
|
|
153
|
-
* generate room tokens for accessing the ODIN server network. For your own security, we strongly
|
|
154
|
-
* recommend that you _NEVER_ put an access key in your client code and generate room tokens on a
|
|
155
|
-
* server.
|
|
121
|
+
* A pointer to a local ODIN token generator, employed for generating signed room tokens predicated
|
|
122
|
+
* on an access key. Be aware that access keys serve as your unique authentication keys, requisite
|
|
123
|
+
* for generating room tokens to access the ODIN server network. To ensure your security, it's
|
|
124
|
+
* strongly recommended that you _NEVER_ embed an access key within your client code, and instead
|
|
125
|
+
* generate room tokens on a server.
|
|
156
126
|
*/
|
|
157
127
|
typedef struct OdinTokenGenerator OdinTokenGenerator;
|
|
158
128
|
|
|
@@ -164,6 +134,20 @@ typedef struct OdinTokenGenerator OdinTokenGenerator;
|
|
|
164
134
|
*/
|
|
165
135
|
typedef uint32_t OdinReturnCode;
|
|
166
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Audio stream configuration.
|
|
139
|
+
*/
|
|
140
|
+
typedef struct OdinAudioStreamConfig {
|
|
141
|
+
/**
|
|
142
|
+
* The number of samples per second in hertz (between 8000 and 192000)
|
|
143
|
+
*/
|
|
144
|
+
uint32_t sample_rate;
|
|
145
|
+
/**
|
|
146
|
+
* The number of channels for the new audio stream (between 1 and 2)
|
|
147
|
+
*/
|
|
148
|
+
uint8_t channel_count;
|
|
149
|
+
} OdinAudioStreamConfig;
|
|
150
|
+
|
|
167
151
|
/**
|
|
168
152
|
* Internal handle identifier for an ODIN room to interact with.
|
|
169
153
|
*/
|
|
@@ -491,20 +475,6 @@ typedef struct OdinApmConfig {
|
|
|
491
475
|
bool gain_controller;
|
|
492
476
|
} OdinApmConfig;
|
|
493
477
|
|
|
494
|
-
/**
|
|
495
|
-
* Audio stream configuration.
|
|
496
|
-
*/
|
|
497
|
-
typedef struct OdinAudioStreamConfig {
|
|
498
|
-
/**
|
|
499
|
-
* The number of samples per second in hertz (between 8000 and 192000)
|
|
500
|
-
*/
|
|
501
|
-
uint32_t sample_rate;
|
|
502
|
-
/**
|
|
503
|
-
* The number of channels for the new audio stream (between 1 and 2)
|
|
504
|
-
*/
|
|
505
|
-
uint8_t channel_count;
|
|
506
|
-
} OdinAudioStreamConfig;
|
|
507
|
-
|
|
508
478
|
/**
|
|
509
479
|
* Audio stream statistics.
|
|
510
480
|
*/
|
|
@@ -583,30 +553,30 @@ size_t odin_error_format(OdinReturnCode error, char *buf, size_t buf_len);
|
|
|
583
553
|
bool odin_is_error(OdinReturnCode code);
|
|
584
554
|
|
|
585
555
|
/**
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
* and shutdown
|
|
589
|
-
*
|
|
556
|
+
* Initializes the internal ODIN client runtime with optimized settings for audio output, ensuring
|
|
557
|
+
* the correct API header file is employed. This operation is ref-counted, necessitating paired
|
|
558
|
+
* invocations of startup and shutdown within your application. The majority of the API functions
|
|
559
|
+
* hinge on an active ODIN runtime, with the sole exception of `access_key` and `token_generator`
|
|
560
|
+
* related functions.
|
|
590
561
|
*
|
|
591
|
-
* Note:
|
|
562
|
+
* Note: Utilize `ODIN_VERSION` to supply the `version` argument.
|
|
592
563
|
*/
|
|
593
564
|
bool odin_startup(const char *version);
|
|
594
565
|
|
|
595
566
|
/**
|
|
596
|
-
*
|
|
597
|
-
* for audio output. This is ref-counted
|
|
598
|
-
* application.
|
|
567
|
+
* Initializes the internal ODIN client runtime, permitting the specification of sample rate and
|
|
568
|
+
* channel layout for audio output. This operation is ref-counted, necessitating paired invocations
|
|
569
|
+
* of startup and shutdown within your application.
|
|
599
570
|
*
|
|
600
|
-
* Note:
|
|
571
|
+
* Note: Ensure consistent settings are used on successive invocations of this function.
|
|
601
572
|
*/
|
|
602
|
-
bool odin_startup_ex(const char *version,
|
|
603
|
-
uint32_t output_sample_rate,
|
|
604
|
-
enum OdinChannelLayout output_channel_layout);
|
|
573
|
+
bool odin_startup_ex(const char *version, struct OdinAudioStreamConfig output_config);
|
|
605
574
|
|
|
606
575
|
/**
|
|
607
|
-
*
|
|
608
|
-
* the application.
|
|
609
|
-
*
|
|
576
|
+
* Shuts down the internal ODIN runtime. It is advisable to invoke this function prior to
|
|
577
|
+
* terminating the application. Post invocation, all `odin_*` methods will cease to function
|
|
578
|
+
* immediately, provided the internal ref-count has descended to zero. Refer to `odin_startup`
|
|
579
|
+
* for additional details.
|
|
610
580
|
*/
|
|
611
581
|
void odin_shutdown(void);
|
|
612
582
|
|
|
@@ -639,13 +609,13 @@ OdinReturnCode odin_room_set_event_callback(OdinRoomHandle room,
|
|
|
639
609
|
void *extra_data);
|
|
640
610
|
|
|
641
611
|
/**
|
|
642
|
-
* Sets the scaling
|
|
643
|
-
*
|
|
644
|
-
* a unit circle
|
|
645
|
-
*
|
|
646
|
-
*
|
|
612
|
+
* Sets the scaling factor for coordinates supplied to `odin_room_update_position`, facilitating
|
|
613
|
+
* adaptation to your game's unique coordinate system requirements. Peers are visible to each other
|
|
614
|
+
* only within a unit circle of radius `1.0`. When altering a peer's position, ensure the position
|
|
615
|
+
* is scaled such that the maximum distance remains one or less. This scaling can be performed
|
|
616
|
+
* manually or by specifying the multiplicative scale here.
|
|
647
617
|
*
|
|
648
|
-
* Note:
|
|
618
|
+
* Note: It's crucial to maintain consistent scaling across all client applications.
|
|
649
619
|
*/
|
|
650
620
|
OdinReturnCode odin_room_set_position_scale(OdinRoomHandle room, float scale);
|
|
651
621
|
|
|
@@ -679,28 +649,26 @@ OdinReturnCode odin_room_peer_id(OdinRoomHandle room, uint64_t *out_peer_id);
|
|
|
679
649
|
OdinReturnCode odin_room_connection_stats(OdinRoomHandle room, struct OdinConnectionStats *stats);
|
|
680
650
|
|
|
681
651
|
/**
|
|
682
|
-
* Updates the custom user data for
|
|
683
|
-
*
|
|
684
|
-
* individual peer and even globally for the room if needed.
|
|
652
|
+
* Updates the custom user data for your own peer. All user data is synced automatically, which
|
|
653
|
+
* allows storing of arbitrary information for each individual peer.
|
|
685
654
|
*
|
|
686
655
|
* Note: Use this before calling `odin_room_join` to set initial peer user data upon connect.
|
|
687
656
|
*/
|
|
688
|
-
OdinReturnCode
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
size_t user_data_length);
|
|
657
|
+
OdinReturnCode odin_room_update_peer_user_data(OdinRoomHandle room,
|
|
658
|
+
const uint8_t *user_data,
|
|
659
|
+
size_t user_data_length);
|
|
692
660
|
|
|
693
661
|
/**
|
|
694
|
-
* Updates the
|
|
695
|
-
*
|
|
696
|
-
* based on unit circles with a radius of `1.0`. This is
|
|
697
|
-
*
|
|
698
|
-
*
|
|
699
|
-
*
|
|
662
|
+
* Updates the three-dimensional position of the current peer within the specified `OdinRoomHandle`.
|
|
663
|
+
* The server utilizes the provided coordinates to perform automatic culling among peers in the same
|
|
664
|
+
* room, based on unit circles with a radius of `1.0`. This feature is particularly beneficial in
|
|
665
|
+
* scenarios involving a large number of peers within the same room, enabling peers to interact or
|
|
666
|
+
* 'see' each other only when in close proximity. To modify the distance sensitivity for position
|
|
667
|
+
* updates, use `odin_room_set_position_scale`.
|
|
700
668
|
*
|
|
701
669
|
* Note: Use this before calling `odin_room_join` to set the initial peer position upon connect.
|
|
702
670
|
*/
|
|
703
|
-
OdinReturnCode odin_room_update_position(OdinRoomHandle room, float x, float y);
|
|
671
|
+
OdinReturnCode odin_room_update_position(OdinRoomHandle room, float x, float y, float z);
|
|
704
672
|
|
|
705
673
|
/**
|
|
706
674
|
* Sends arbitrary data to a list of target peers over the ODIN server. If `NULL` is specified, the
|
|
@@ -725,12 +693,12 @@ OdinReturnCode odin_room_add_media(OdinRoomHandle room, OdinMediaStreamHandle me
|
|
|
725
693
|
OdinReturnCode odin_room_configure_apm(OdinRoomHandle room, struct OdinApmConfig config);
|
|
726
694
|
|
|
727
695
|
/**
|
|
728
|
-
* Creates a new audio stream, which can be added to a room and send data over it.
|
|
696
|
+
* Creates a new audio input stream, which can be added to a room and send data over it.
|
|
729
697
|
*/
|
|
730
698
|
OdinMediaStreamHandle odin_audio_stream_create(struct OdinAudioStreamConfig config);
|
|
731
699
|
|
|
732
700
|
/**
|
|
733
|
-
* Creates a new video stream, which can be added to a room and send data over it.
|
|
701
|
+
* Creates a new video input stream, which can be added to a room and send data over it.
|
|
734
702
|
*
|
|
735
703
|
* Note: Video streams are not supported yet.
|
|
736
704
|
*/
|
|
@@ -760,21 +728,45 @@ OdinReturnCode odin_media_stream_peer_id(OdinMediaStreamHandle stream, uint64_t
|
|
|
760
728
|
*/
|
|
761
729
|
enum OdinMediaStreamType odin_media_stream_type(OdinMediaStreamHandle stream);
|
|
762
730
|
|
|
731
|
+
/**
|
|
732
|
+
* Instructs the server to pause the specified `OdinMediaStreamHandle`, ceasing the reception of
|
|
733
|
+
* data. This operation essentially communicates a server-side mute request from the client, thus
|
|
734
|
+
* indicating a desire to halt packet reception for this media stream.
|
|
735
|
+
*/
|
|
736
|
+
OdinReturnCode odin_media_stream_pause(OdinMediaStreamHandle stream);
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* Instructs the server to resume the specified output `OdinMediaStreamHandle`, re-initiating the
|
|
740
|
+
* reception of data. This operation essentially communicates a server-side unmute request from the
|
|
741
|
+
* client, indicating a desire to restart packet reception for this media stream.
|
|
742
|
+
*/
|
|
743
|
+
OdinReturnCode odin_media_stream_resume(OdinMediaStreamHandle stream);
|
|
744
|
+
|
|
763
745
|
/**
|
|
764
746
|
* Sends data to the audio stream. The data has to be interleaved [-1, 1] float data.
|
|
765
747
|
*/
|
|
766
748
|
OdinReturnCode odin_audio_push_data(OdinMediaStreamHandle stream, const float *buf, size_t buf_len);
|
|
767
749
|
|
|
768
750
|
/**
|
|
769
|
-
* Reads audio data from the specified `OdinMediaStreamHandle`. This will return audio data in
|
|
770
|
-
*
|
|
771
|
-
*
|
|
772
|
-
* Note: `out_channel_layout` is reserved for future use.
|
|
751
|
+
* Reads audio data from the specified `OdinMediaStreamHandle`. This will return audio data in the
|
|
752
|
+
* format specified when calling `odin_startup_ex` or 48 kHz interleaved by default.
|
|
773
753
|
*/
|
|
774
754
|
OdinReturnCode odin_audio_read_data(OdinMediaStreamHandle stream,
|
|
775
755
|
float *out_buffer,
|
|
776
756
|
size_t out_buffer_len);
|
|
777
757
|
|
|
758
|
+
/**
|
|
759
|
+
* Returns the number of samples available in the audio buffer of an output `OdinMediaStreamHandle`.
|
|
760
|
+
*/
|
|
761
|
+
OdinReturnCode odin_audio_data_len(OdinMediaStreamHandle stream);
|
|
762
|
+
|
|
763
|
+
/**
|
|
764
|
+
* Resets the specified `OdinMediaStreamHandle` to its initial state, restoring it to its default
|
|
765
|
+
* configuration. This operation resets the internal Opus encoder/decoder, ensuring a clean state.
|
|
766
|
+
* Additionally, it clears internal buffers, providing a fresh start.
|
|
767
|
+
*/
|
|
768
|
+
OdinReturnCode odin_audio_reset(OdinMediaStreamHandle stream);
|
|
769
|
+
|
|
778
770
|
/**
|
|
779
771
|
* Retrieves statistics for the specified `OdinMediaStreamHandle`.
|
|
780
772
|
*
|
|
@@ -784,9 +776,9 @@ OdinReturnCode odin_audio_stats(OdinMediaStreamHandle stream, struct OdinAudioSt
|
|
|
784
776
|
|
|
785
777
|
/**
|
|
786
778
|
* Reads up to `out_buffer_len` samples from the given streams and mixes them into the `out_buffer`.
|
|
787
|
-
* All audio streams will be read based on
|
|
788
|
-
* accordingly. After the call the `out_buffer_len` will contain
|
|
789
|
-
* actually been read and mixed into `out_buffer`.
|
|
779
|
+
* All audio streams will be read based on the sample rate you chose when initializing the ODIN runtime
|
|
780
|
+
* so make sure to allocate the buffer accordingly. After the call the `out_buffer_len` will contain
|
|
781
|
+
* the amount of samples that have actually been read and mixed into `out_buffer`.
|
|
790
782
|
*
|
|
791
783
|
* If enabled this will also apply any audio processing to the output stream and feed back required
|
|
792
784
|
* data to the internal audio processing pipeline which requires a final mix.
|
|
@@ -803,6 +795,17 @@ OdinReturnCode odin_audio_mix_streams(OdinRoomHandle room,
|
|
|
803
795
|
*/
|
|
804
796
|
OdinReturnCode odin_audio_process_reverse(OdinRoomHandle room, float *buffer, size_t buffer_len);
|
|
805
797
|
|
|
798
|
+
/**
|
|
799
|
+
* Sets the delay estimate for the reverse stream used in the ODIN echo cancellation. This function
|
|
800
|
+
* is important in scenarios where the audio output and the audio input are not synchronized. An
|
|
801
|
+
* accurate delay value ensures that the echo canceller can correctly align the two audio streams,
|
|
802
|
+
* resulting in effective echo cancellation.
|
|
803
|
+
*
|
|
804
|
+
* Improper delay values may lead to poor echo cancellation and thus degrade the quality of the
|
|
805
|
+
* audio communication.
|
|
806
|
+
*/
|
|
807
|
+
OdinReturnCode odin_audio_set_stream_delay(OdinRoomHandle room, uint64_t delay_ms);
|
|
808
|
+
|
|
806
809
|
/**
|
|
807
810
|
* Creates a new ODIN resampler instance. This is intended for situations where your audio pipeline
|
|
808
811
|
* doesn't support 48 kHz.
|
|
@@ -834,28 +837,29 @@ OdinReturnCode odin_resampler_process(OdinResamplerHandle resampler,
|
|
|
834
837
|
OdinReturnCode odin_resampler_destroy(OdinResamplerHandle resampler);
|
|
835
838
|
|
|
836
839
|
/**
|
|
837
|
-
* Creates a new access key
|
|
838
|
-
* long Base64
|
|
840
|
+
* Creates a new access key crucial for signing tokens, facilitating access to an ODIN server. An
|
|
841
|
+
* access key is a 44-character long Base64 String, embodying a version identifier, random bytes,
|
|
842
|
+
* and a checksum.
|
|
839
843
|
*/
|
|
840
844
|
OdinReturnCode odin_access_key_generate(char *buf, size_t buf_len);
|
|
841
845
|
|
|
842
846
|
/**
|
|
843
|
-
*
|
|
844
|
-
*
|
|
847
|
+
* Extracts the key ID from a specified access key. The key ID is embedded in room tokens, enabling
|
|
848
|
+
* the identification of the corresponding public key required for verification.
|
|
845
849
|
*/
|
|
846
850
|
OdinReturnCode odin_access_key_id(const char *access_key, char *out_key_id, size_t out_key_id_len);
|
|
847
851
|
|
|
848
852
|
/**
|
|
849
|
-
*
|
|
850
|
-
* curve
|
|
853
|
+
* Extracts the public key from a specified access key. The public key, derived from the Ed25519
|
|
854
|
+
* curve, must be shared with _4Players_ to enable verification of a generated room token.
|
|
851
855
|
*/
|
|
852
856
|
OdinReturnCode odin_access_key_public_key(const char *access_key,
|
|
853
857
|
char *out_public_key,
|
|
854
858
|
size_t out_public_key_len);
|
|
855
859
|
|
|
856
860
|
/**
|
|
857
|
-
*
|
|
858
|
-
* curve
|
|
861
|
+
* Extracts the private key from a specified access key. The private key, rooted in the Ed25519
|
|
862
|
+
* curve, is utilized to sign a generated room token for accessing the ODIN network.
|
|
859
863
|
*/
|
|
860
864
|
OdinReturnCode odin_access_key_secret_key(const char *access_key,
|
|
861
865
|
char *out_secret_key,
|
package/odin.media.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {OdinRoom} from "./odin.room";
|
|
1
|
+
import {OdinAPMSettings, OdinRoom} from "./odin.room";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The OdinMedia class. Represents a local media stream added to the room - i.e. a microphone, another audio stream like files.
|
|
@@ -10,8 +10,9 @@ export declare class OdinMedia {
|
|
|
10
10
|
* @param room - The room to add the media to.
|
|
11
11
|
* @param sampleRate - The sample rate of the audio stream (between 8000 and 48000)
|
|
12
12
|
* @param channelCount - The number of channels of the audio stream (1 or 2)
|
|
13
|
+
* @param options - Optional configuration options for Odin Audio Processing Module (APM).
|
|
13
14
|
*/
|
|
14
|
-
constructor(room: OdinRoom, sampleRate: number, channelCount: number);
|
|
15
|
+
constructor(room: OdinRoom, sampleRate: number, channelCount: number, options?: OdinAPMSettings);
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Closes the local audio stream and removed the media from the room
|
package/odin.room.d.ts
CHANGED
|
@@ -445,12 +445,6 @@ export declare class OdinRoom {
|
|
|
445
445
|
*/
|
|
446
446
|
updateOwnUserData(userData: Uint8Array): void;
|
|
447
447
|
|
|
448
|
-
/**
|
|
449
|
-
* Updates the room user data (for all peers)
|
|
450
|
-
* @param userData - The new user data to set.
|
|
451
|
-
*/
|
|
452
|
-
updateRoomUserData(userData: Uint8Array): void;
|
|
453
|
-
|
|
454
448
|
/**
|
|
455
449
|
* Closes the room and disconnects from the server.
|
|
456
450
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4players/odin-nodejs",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.8.0",
|
|
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",
|
|
7
7
|
"scripts": {
|
|
Binary file
|
|
Binary file
|
|
@@ -21,7 +21,7 @@ const userData = {
|
|
|
21
21
|
version: "0.1"
|
|
22
22
|
}
|
|
23
23
|
const data = new TextEncoder().encode(JSON.stringify(userData));
|
|
24
|
-
const odinClient = new OdinClient(accessKey,
|
|
24
|
+
const odinClient = new OdinClient(accessKey, 48000, 2);
|
|
25
25
|
const room = odinClient.createRoom(roomName, userName);
|
|
26
26
|
|
|
27
27
|
// Join the room
|
|
@@ -30,9 +30,7 @@ room.join("gateway.odin.4players.io", data);
|
|
|
30
30
|
// Send a message to the room
|
|
31
31
|
const message = {
|
|
32
32
|
kind: 'message',
|
|
33
|
-
payload:
|
|
34
|
-
text: 'Hello, I am a music bot and will stream some music to you.'
|
|
35
|
-
}
|
|
33
|
+
payload: 'Hello, I am a music bot and will stream some music to you.'
|
|
36
34
|
}
|
|
37
35
|
room.sendMessage(new TextEncoder().encode(JSON.stringify(message)));
|
|
38
36
|
|
|
@@ -41,29 +39,48 @@ const sendMusic = async (media) => {
|
|
|
41
39
|
// Prepare our MP3 decoder and load the sample file
|
|
42
40
|
const audioBuffer = await decode(fs.readFileSync('./santa.mp3'));
|
|
43
41
|
|
|
44
|
-
// Print our some info about the audio file
|
|
45
|
-
console.log(audioBuffer);
|
|
46
|
-
|
|
47
42
|
// Create a stream that will match the settings of the file
|
|
48
|
-
const audioBufferStream = new AudioBufferStream({
|
|
43
|
+
const audioBufferStream = new AudioBufferStream({
|
|
44
|
+
channels: audioBuffer.numberOfChannels,
|
|
45
|
+
sampleRate: audioBuffer.sampleRate,
|
|
46
|
+
float: true,
|
|
47
|
+
bitDepth: 32,
|
|
48
|
+
chunkLength: 960 // 960 bytes every 20ms - might be doubled (1920) depending on the sample rate
|
|
49
|
+
});
|
|
49
50
|
|
|
50
|
-
//
|
|
51
|
+
// Create a queue to store the chunks of audio data
|
|
52
|
+
const queue = [];
|
|
53
|
+
|
|
54
|
+
// Whenever the stream has data, add it to the queue
|
|
51
55
|
audioBufferStream.on('data', (data) => {
|
|
52
|
-
const floats = new Float32Array(new Uint8Array(data).buffer)
|
|
53
|
-
|
|
56
|
+
const floats = new Float32Array(new Uint8Array(data).buffer);
|
|
57
|
+
queue.push(floats);
|
|
54
58
|
});
|
|
55
59
|
|
|
60
|
+
// Start a timer to send audio data at regular intervals
|
|
61
|
+
const interval = setInterval(() => {
|
|
62
|
+
if (queue.length > 0) {
|
|
63
|
+
const chunk = queue.shift();
|
|
64
|
+
media.sendAudioData(chunk);
|
|
65
|
+
} else {
|
|
66
|
+
// If there's no more data to send, stop the timer
|
|
67
|
+
clearInterval(interval);
|
|
68
|
+
audioBufferStream.end();
|
|
69
|
+
console.log("Audio finished");
|
|
70
|
+
}
|
|
71
|
+
}, 20); // Send a chunk every 20ms
|
|
72
|
+
|
|
56
73
|
audioBufferStream.write(audioBuffer);
|
|
57
74
|
}
|
|
58
75
|
|
|
59
76
|
// Create a media stream in the room - it will return an OdinMedia instance that we can use to send data to ODIN
|
|
60
|
-
const media = room.createAudioStream(
|
|
77
|
+
const media = room.createAudioStream(48000, 2);
|
|
61
78
|
console.log(media);
|
|
62
79
|
console.log("MEDIA-ID:", media.id);
|
|
63
80
|
|
|
64
81
|
// Start the stream and send the music to ODIN
|
|
65
82
|
sendMusic(media).then(() => {
|
|
66
|
-
console.log("
|
|
83
|
+
console.log("Started sending audio");
|
|
67
84
|
});
|
|
68
85
|
|
|
69
86
|
// Wait until the user presses a key to stop
|
|
Binary file
|