@4players/odin-nodejs 0.7.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.
Files changed (99) hide show
  1. package/.idea/.name +1 -0
  2. package/.idea/jsLibraryMappings.xml +6 -0
  3. package/.idea/misc.xml +4 -0
  4. package/.idea/modules.xml +9 -0
  5. package/.idea/odin-nodejs.iml +8 -0
  6. package/.idea/odin_nodejs.iml +2 -0
  7. package/.idea/php.xml +19 -0
  8. package/.idea/vcs.xml +6 -0
  9. package/CMakeLists.txt +25 -0
  10. package/README.md +53 -0
  11. package/binding.gyp +61 -0
  12. package/build/Makefile +352 -0
  13. package/build/Release/.deps/Release/nothing.a.d +1 -0
  14. package/build/Release/.deps/Release/obj.target/nothing/node_modules/node-addon-api/nothing.o.d +4 -0
  15. package/build/Release/.deps/Release/obj.target/odin/cppsrc/binding.o.d +27 -0
  16. package/build/Release/.deps/Release/obj.target/odin/cppsrc/odinbindings.o.d +24 -0
  17. package/build/Release/.deps/Release/obj.target/odin/cppsrc/odinclient.o.d +24 -0
  18. package/build/Release/.deps/Release/obj.target/odin/cppsrc/odinmedia.o.d +24 -0
  19. package/build/Release/.deps/Release/obj.target/odin/cppsrc/odinroom.o.d +24 -0
  20. package/build/Release/.deps/Release/obj.target/odin/cppsrc/utilities.o.d +21 -0
  21. package/build/Release/.deps/Release/odin.node.d +1 -0
  22. package/build/Release/nothing.a +0 -0
  23. package/build/Release/obj.target/nothing/node_modules/node-addon-api/nothing.o +0 -0
  24. package/build/Release/obj.target/odin/cppsrc/binding.o +0 -0
  25. package/build/Release/obj.target/odin/cppsrc/odinbindings.o +0 -0
  26. package/build/Release/obj.target/odin/cppsrc/odinclient.o +0 -0
  27. package/build/Release/obj.target/odin/cppsrc/odinmedia.o +0 -0
  28. package/build/Release/obj.target/odin/cppsrc/odinroom.o +0 -0
  29. package/build/Release/obj.target/odin/cppsrc/utilities.o +0 -0
  30. package/build/binding.Makefile +6 -0
  31. package/build/gyp-mac-tool +772 -0
  32. package/build/node_modules/node-addon-api/node_api.Makefile +6 -0
  33. package/build/node_modules/node-addon-api/nothing.target.mk +186 -0
  34. package/build/odin.target.mk +201 -0
  35. package/cmake-build-debug/.cmake/api/v1/query/cache-v2 +0 -0
  36. package/cmake-build-debug/.cmake/api/v1/query/cmakeFiles-v1 +0 -0
  37. package/cmake-build-debug/.cmake/api/v1/query/codemodel-v2 +0 -0
  38. package/cmake-build-debug/.cmake/api/v1/query/toolchains-v1 +0 -0
  39. package/cmake-build-debug/.cmake/api/v1/reply/cache-v2-912a6d0c3c2c7ebbadf8.json +1183 -0
  40. package/cmake-build-debug/.cmake/api/v1/reply/cmakeFiles-v1-0825651e80f1fb47890c.json +161 -0
  41. package/cmake-build-debug/.cmake/api/v1/reply/codemodel-v2-bc24edc239de864eb886.json +60 -0
  42. package/cmake-build-debug/.cmake/api/v1/reply/directory-.-Debug-f5ebdc15457944623624.json +14 -0
  43. package/cmake-build-debug/.cmake/api/v1/reply/index-2023-03-18T11-25-22-0179.json +108 -0
  44. package/cmake-build-debug/.cmake/api/v1/reply/target-odin_nodejs-Debug-1ac16802f252a85492c7.json +322 -0
  45. package/cmake-build-debug/.cmake/api/v1/reply/toolchains-v1-b57293a485ebf36c82cc.json +88 -0
  46. package/cmake-build-debug/.ninja_log +1 -0
  47. package/cmake-build-debug/CMakeCache.txt +367 -0
  48. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeCCompiler.cmake +72 -0
  49. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeCXXCompiler.cmake +83 -0
  50. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeDetermineCompilerABI_C.bin +0 -0
  51. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeDetermineCompilerABI_CXX.bin +0 -0
  52. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeSystem.cmake +15 -0
  53. package/cmake-build-debug/CMakeFiles/3.24.2/CompilerIdC/CMakeCCompilerId.c +838 -0
  54. package/cmake-build-debug/CMakeFiles/3.24.2/CompilerIdC/CMakeCCompilerId.o +0 -0
  55. package/cmake-build-debug/CMakeFiles/3.24.2/CompilerIdCXX/CMakeCXXCompilerId.cpp +826 -0
  56. package/cmake-build-debug/CMakeFiles/3.24.2/CompilerIdCXX/CMakeCXXCompilerId.o +0 -0
  57. package/cmake-build-debug/CMakeFiles/CMakeError.log +22 -0
  58. package/cmake-build-debug/CMakeFiles/CMakeOutput.log +250 -0
  59. package/cmake-build-debug/CMakeFiles/TargetDirectories.txt +3 -0
  60. package/cmake-build-debug/CMakeFiles/clion-Debug-log.txt +4 -0
  61. package/cmake-build-debug/CMakeFiles/clion-environment.txt +3 -0
  62. package/cmake-build-debug/CMakeFiles/cmake.check_cache +1 -0
  63. package/cmake-build-debug/CMakeFiles/rules.ninja +74 -0
  64. package/cmake-build-debug/Testing/Temporary/LastTest.log +3 -0
  65. package/cmake-build-debug/build.ninja +205 -0
  66. package/cmake-build-debug/cmake_install.cmake +49 -0
  67. package/cppsrc/binding.cpp +15 -0
  68. package/cppsrc/odinbindings.cpp +58 -0
  69. package/cppsrc/odinbindings.h +9 -0
  70. package/cppsrc/odinclient.cpp +162 -0
  71. package/cppsrc/odinclient.h +17 -0
  72. package/cppsrc/odinmedia.cpp +242 -0
  73. package/cppsrc/odinmedia.h +35 -0
  74. package/cppsrc/odinroom.cpp +738 -0
  75. package/cppsrc/odinroom.h +65 -0
  76. package/cppsrc/utilities.cpp +102 -0
  77. package/cppsrc/utilities.h +175 -0
  78. package/index.cjs +2 -0
  79. package/index.d.ts +5 -0
  80. package/libs/bin/linux/arm64/libodin_static.a +0 -0
  81. package/libs/bin/linux/ia32/libodin_static.a +0 -0
  82. package/libs/bin/linux/x64/libodin_static.a +0 -0
  83. package/libs/bin/macos/arm64/libodin_static.a +0 -0
  84. package/libs/bin/macos/x64/libodin_static.a +0 -0
  85. package/libs/bin/windows/arm64/odin_static.lib +0 -0
  86. package/libs/bin/windows/ia32/odin_static.lib +0 -0
  87. package/libs/bin/windows/x64/odin_static.lib +0 -0
  88. package/libs/include/odin.h +896 -0
  89. package/odin.client.d.ts +22 -0
  90. package/odin.media.d.ts +33 -0
  91. package/odin.room.d.ts +473 -0
  92. package/package.json +50 -0
  93. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  94. package/test.js +211 -0
  95. package/tests/audio-recording/README.md +24 -0
  96. package/tests/audio-recording/index.js +148 -0
  97. package/tests/sending-audio/README.md +20 -0
  98. package/tests/sending-audio/index.js +81 -0
  99. package/tests/sending-audio/santa.mp3 +0 -0
@@ -0,0 +1,242 @@
1
+ //
2
+ // Created by Phillip Schuster on 11.02.23.
3
+ //
4
+
5
+ #include "odinmedia.h"
6
+ #include <string>
7
+ #include <iostream>
8
+ #include <codecvt>
9
+ #include <locale>
10
+
11
+ using namespace std;
12
+
13
+ // Required, otherwise an unknown symbol error comes up
14
+ Napi::FunctionReference *OdinMedia::constructor;
15
+
16
+ /**
17
+ * Returns the media id as string of this room instance
18
+ * @param info
19
+ */
20
+ Napi::Value OdinMedia::MediaId(const Napi::CallbackInfo &info) {
21
+ Napi::Env env = info.Env();
22
+ Napi::HandleScope scope(env);
23
+
24
+ uint16_t out_id;
25
+ OdinReturnCode error = odin_media_stream_media_id(_mediaStreamHandle, &out_id);
26
+ if (odin_is_error(error)) {
27
+ Napi::TypeError::New(env, "Failed to get media id").ThrowAsJavaScriptException();
28
+ }
29
+
30
+ return Napi::Number::New(env, out_id);
31
+ }
32
+
33
+ /**
34
+ * Creates a new OdinMedia instance. Requires an Odin token as a parameter.
35
+ * @param info Napi::CallbackInfo
36
+ */
37
+ OdinMedia::OdinMedia(const Napi::CallbackInfo &info) : Napi::ObjectWrap<OdinMedia>(info) {
38
+ Napi::Env env = info.Env();
39
+ Napi::HandleScope scope(env);
40
+
41
+ // Checking for room instance, sample rate (float) and channels (int)
42
+ if (info.Length() < 3 || !info[0].IsObject() || !info[1].IsNumber() || !info[2].IsNumber()) {
43
+ Napi::TypeError::New(env, "Provide an OdinRoom instance, sample rate and number of channels as number").ThrowAsJavaScriptException();
44
+ }
45
+
46
+ if (info.Length() == 4 && !info[3].IsObject()) {
47
+ Napi::TypeError::New(env, "Options need to be provided as an object").ThrowAsJavaScriptException();
48
+ }
49
+
50
+ _room = Napi::ObjectWrap<OdinRoom>::Unwrap(info[0].As<Napi::Object>());
51
+ _sampleRate = info[1].As<Napi::Number>().Uint32Value();
52
+ _numChannels = info[2].As<Napi::Number>().Int32Value();
53
+
54
+ /*
55
+ * Configure audio processing options for the room
56
+ */
57
+ OdinApmConfig apm_config;
58
+ apm_config.voice_activity_detection = false;
59
+ apm_config.voice_activity_detection_attack_probability = 0.9;
60
+ apm_config.voice_activity_detection_release_probability = 0.8;
61
+ apm_config.volume_gate = false;
62
+ apm_config.volume_gate_attack_loudness = -30;
63
+ apm_config.volume_gate_release_loudness = -40;
64
+ apm_config.echo_canceller = false;
65
+ apm_config.high_pass_filter = false;
66
+ apm_config.pre_amplifier = false;
67
+ apm_config.noise_suppression_level = OdinNoiseSuppressionLevel_Moderate;
68
+ apm_config.transient_suppressor = false;
69
+ apm_config.gain_controller = true;
70
+
71
+ if (info.Length() == 4) {
72
+ Napi::Object options = info[3].As<Napi::Object>();
73
+ if (options.Has("voiceActivityDetection")) {
74
+ apm_config.voice_activity_detection = options.Get("voiceActivityDetection").As<Napi::Boolean>().Value();
75
+ }
76
+ if (options.Has("voiceActivityDetectionAttackProbability")) {
77
+ apm_config.voice_activity_detection_attack_probability = options.Get("voiceActivityDetectionAttackProbability").As<Napi::Number>().DoubleValue();
78
+ }
79
+ if (options.Has("voiceActivityDetectionReleaseProbability")) {
80
+ apm_config.voice_activity_detection_release_probability = options.Get("voiceActivityDetectionReleaseProbability").As<Napi::Number>().DoubleValue();
81
+ }
82
+ if (options.Has("volumeGate")) {
83
+ apm_config.volume_gate = options.Get("volumeGate").As<Napi::Boolean>().Value();
84
+ }
85
+ if (options.Has("volumeGateAttackLoudness")) {
86
+ apm_config.volume_gate_attack_loudness = options.Get("volumeGateAttackLoudness").As<Napi::Number>().DoubleValue();
87
+ }
88
+ if (options.Has("volumeGateReleaseLoudness")) {
89
+ apm_config.volume_gate_release_loudness = options.Get("volumeGateReleaseLoudness").As<Napi::Number>().DoubleValue();
90
+ }
91
+ if (options.Has("echoCanceller")) {
92
+ apm_config.echo_canceller = options.Get("echoCanceller").As<Napi::Boolean>().Value();
93
+ }
94
+ if (options.Has("highPassFilter")) {
95
+ apm_config.high_pass_filter = options.Get("highPassFilter").As<Napi::Boolean>().Value();
96
+ }
97
+ if (options.Has("preAmplifier")) {
98
+ apm_config.pre_amplifier = options.Get("preAmplifier").As<Napi::Boolean>().Value();
99
+ }
100
+ if (options.Has("noiseSuppressionLevel")) {
101
+ apm_config.noise_suppression_level = (OdinNoiseSuppressionLevel) options.Get("noiseSuppressionLevel").As<Napi::Number>().Int32Value();
102
+ }
103
+ if (options.Has("transientSuppressor")) {
104
+ apm_config.transient_suppressor = options.Get("transientSuppressor").As<Napi::Boolean>().Value();
105
+ }
106
+ if (options.Has("gainController")) {
107
+ apm_config.gain_controller = options.Get("gainController").As<Napi::Boolean>().Value();
108
+ }
109
+ }
110
+
111
+ OdinReturnCode error = odin_room_configure_apm(_room->GetRoomHandle(), apm_config);
112
+ if (odin_is_error(error)) {
113
+ OdinUtilities::ThrowNapiException(env, error, "Failed to configure APM settings");
114
+ }
115
+
116
+ /*
117
+ * Create the input audio stream with a samplerate of 48 kHz
118
+ */
119
+ OdinAudioStreamConfig audio_config;
120
+ audio_config.sample_rate = _sampleRate;
121
+ audio_config.channel_count = _numChannels;
122
+ _mediaStreamHandle = odin_audio_stream_create(audio_config);
123
+
124
+ error = odin_room_add_media(_room->GetRoomHandle(), _mediaStreamHandle);
125
+ if (odin_is_error(error)) {
126
+ OdinUtilities::ThrowNapiException(env, error, "Failed to add media to room");
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Destructor. Closes and destroys the OdinMedia and resets the event callback for this room handle.
132
+ */
133
+ void OdinMedia::Finalize(Napi::Env env) {
134
+ odin_media_stream_destroy(_mediaStreamHandle);
135
+ }
136
+
137
+ /**
138
+ * Exposes this class to JavaScript
139
+ * @param info Napi::CallbackInfo
140
+ */
141
+ Napi::Object OdinMedia::Init(Napi::Env env, Napi::Object exports) {
142
+ // This method is used to hook the accessor and method callbacks
143
+ Napi::Function func = DefineClass(env, "OdinMedia", {
144
+ InstanceMethod<&OdinMedia::Close>("close", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
145
+ InstanceMethod<&OdinMedia::SendData>("sendAudioData", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
146
+ InstanceAccessor("id", &OdinMedia::MediaId, nullptr, static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
147
+ StaticMethod<&OdinMedia::CreateNewItem>("CreateNewItem", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
148
+ });
149
+
150
+ // We use a static variable to store the constructor. This is because we need to create instances within C++ and
151
+ // expose to JavaScript. We can't use the constructor directly because it's not exposed to JavaScript.
152
+ constructor = new Napi::FunctionReference();
153
+
154
+ // Create a persistent reference to the class constructor. This will allow
155
+ // a function called on a class prototype and a function
156
+ // called on instance of a class to be distinguished from each other.
157
+ *constructor = Napi::Persistent(func);
158
+ exports.Set("OdinMedia", func);
159
+
160
+ // Store the constructor as the add-on instance data. This will allow this
161
+ // add-on to support multiple instances of itself running on multiple worker
162
+ // threads, as well as multiple instances of itself running in different
163
+ // contexts on the same thread.
164
+ //
165
+ // By default, the value set on the environment here will be destroyed when
166
+ // the add-on is unloaded using the `delete` operator, but it is also
167
+ // possible to supply a custom deleter.
168
+ env.SetInstanceData<Napi::FunctionReference>(constructor);
169
+
170
+ return exports;
171
+ }
172
+
173
+ /**
174
+ * Closes the room connection and destroys the room handle.
175
+ * @param info
176
+ */
177
+ void OdinMedia::Close(const Napi::CallbackInfo &info) {
178
+ //Napi::Env env = info.Env();
179
+
180
+ if (_mediaStreamHandle <= 0) return;
181
+
182
+ odin_media_stream_destroy(_mediaStreamHandle);
183
+ _mediaStreamHandle = 0;
184
+ }
185
+
186
+ /**
187
+ * Creates a new instance of the OdinMedia class. Requires a token as a parameter.
188
+ * @param info
189
+ * @return
190
+ */
191
+ Napi::Value OdinMedia::CreateNewItem(const Napi::CallbackInfo &info) {
192
+ Napi::Env env = info.Env();
193
+
194
+ if (info.Length() < 1 || !info[0].IsObject()) {
195
+ Napi::TypeError::New(env, "Token required as first parameter").ThrowAsJavaScriptException();
196
+ }
197
+
198
+ #ifdef DEBUG
199
+ printf("Odin NodeJS Addon: Creating OdinMedia Instance\n");
200
+ #endif
201
+
202
+ // Retrieve the instance data we stored during `Init()`. We only stored the
203
+ // constructor there, so we retrieve it here to create a new instance of the
204
+ // JS class the constructor represents.
205
+ Napi::FunctionReference *constructor =
206
+ info.Env().GetInstanceData<Napi::FunctionReference>();
207
+ return constructor->New({info[0]});
208
+ }
209
+
210
+ /**
211
+ * Creates a new instance of the OdinMedia class. Requires a token as a parameter.
212
+ * @param info
213
+ * @return
214
+ */
215
+ Napi::Object OdinMedia::NewInstance(const std::initializer_list<napi_value>& args) {
216
+ //printf("Creating OdinMedia Instance, sample rate %d, num channels %d\n", sampleRate.As<Napi::Number>().Uint32Value(), numChannels.As<Napi::Number>().Uint32Value());
217
+
218
+ #ifdef DEBUG
219
+ printf("Odin NodeJS Addon: Creating OdinMedia Instance with %d arguments\n", (int)args.size());
220
+ #endif
221
+
222
+ return constructor->New(args);
223
+ }
224
+
225
+ void OdinMedia::SendData(const Napi::CallbackInfo &info) {
226
+ Napi::Env env = info.Env();
227
+
228
+ if (info.Length() < 1 || !info[0].IsTypedArray()) {
229
+ Napi::TypeError::New(env, "TypedArray required as first parameter").ThrowAsJavaScriptException();
230
+ }
231
+
232
+ Napi::Float32Array array = info[0].As<Napi::Float32Array>();
233
+
234
+ #ifdef DEBUG
235
+ printf("Received %d bytes of audio data\n", (int)array.ElementLength());
236
+ #endif
237
+
238
+ OdinReturnCode result = odin_audio_push_data(_mediaStreamHandle, array.Data(), array.ElementLength());
239
+ if (odin_is_error(result)) {
240
+ OdinUtilities::ThrowNapiException(env, result, "Failed to push audio data");
241
+ }
242
+ }
@@ -0,0 +1,35 @@
1
+ //
2
+ // Created by Phillip Schuster on 11.02.23.
3
+ //
4
+
5
+ #ifndef ODIN_NODEJS_ODINMEDIA_H
6
+ #define ODIN_NODEJS_ODINMEDIA_H
7
+
8
+ #include <napi.h>
9
+ #include <odin.h>
10
+ #include "utilities.h"
11
+ #include <map>
12
+ #include <thread>
13
+ #include "odinroom.h"
14
+
15
+ class OdinMedia : public Napi::ObjectWrap<OdinMedia> {
16
+ public:
17
+ OdinMedia(const Napi::CallbackInfo& info); //Constructor to initialise
18
+ static Napi::FunctionReference *New;
19
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
20
+ static Napi::Value CreateNewItem(const Napi::CallbackInfo& info);
21
+ void Finalize(Napi::Env env) override;
22
+ static Napi::FunctionReference *constructor;
23
+ static Napi::Object NewInstance(const std::initializer_list<napi_value>& args);
24
+ private:
25
+ OdinMediaStreamHandle _mediaStreamHandle;
26
+ OdinRoom* _room;
27
+ uint32_t _sampleRate;
28
+ uint8_t _numChannels;
29
+ void Close(const Napi::CallbackInfo& info);
30
+ void SendData(const Napi::CallbackInfo& info);
31
+ Napi::Value MediaId(const Napi::CallbackInfo &info);
32
+ };
33
+
34
+
35
+ #endif //ODIN_NODEJS_ODINMEDIA_H