react-native-audio-api 0.11.0-nightly-95f9c99-20251215 → 0.11.0-nightly-dd83923-20251216
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/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +382 -39
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +45 -18
- package/android/src/main/cpp/audioapi/android/core/NativeAudioRecorder.hpp +9 -9
- package/android/src/main/cpp/audioapi/android/core/utils/AndroidFileWriterBackend.h +33 -0
- package/android/src/main/cpp/audioapi/android/core/utils/AndroidRecorderCallback.cpp +170 -0
- package/android/src/main/cpp/audioapi/android/core/utils/AndroidRecorderCallback.h +46 -0
- package/android/src/main/cpp/audioapi/android/core/utils/AudioDecoder.cpp +0 -1
- package/android/src/main/cpp/audioapi/android/core/utils/FileOptions.cpp +83 -0
- package/android/src/main/cpp/audioapi/android/core/utils/FileOptions.h +22 -0
- package/android/src/main/cpp/audioapi/android/core/utils/MiniaudioImplementation.cpp +8 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.cpp +493 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.h +70 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/ptrs.hpp +56 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/utils.cpp +114 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/utils.h +34 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.cpp +296 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.h +40 -0
- package/android/src/main/cpp/audioapi/android/system/NativeFileInfo.hpp +32 -0
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +2 -0
- package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +7 -3
- package/android/src/main/java/com/swmansion/audioapi/system/CentralizedForegroundService.kt +1 -0
- package/android/src/main/java/com/swmansion/audioapi/system/NativeFileInfo.kt +18 -0
- package/android/src/main/java/com/swmansion/audioapi/system/notification/PlaybackNotification.kt +1 -0
- package/android/src/main/java/com/swmansion/audioapi/system/notification/RecordingNotificationReceiver.kt +2 -0
- package/android/src/oldarch/NativeAudioAPIModuleSpec.java +100 -80
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +3 -11
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +145 -16
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.h +21 -6
- package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +43 -60
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +53 -33
- package/common/cpp/audioapi/core/sources/RecorderAdapterNode.cpp +42 -14
- package/common/cpp/audioapi/core/sources/RecorderAdapterNode.h +12 -9
- package/common/cpp/audioapi/core/utils/AudioFileWriter.cpp +41 -0
- package/common/cpp/audioapi/core/utils/AudioFileWriter.h +44 -0
- package/common/cpp/audioapi/core/utils/AudioRecorderCallback.cpp +101 -0
- package/common/cpp/audioapi/core/utils/AudioRecorderCallback.h +52 -0
- package/common/cpp/audioapi/utils/AudioFileProperties.cpp +92 -0
- package/common/cpp/audioapi/utils/AudioFileProperties.h +76 -0
- package/common/cpp/audioapi/utils/Result.hpp +323 -0
- package/common/cpp/audioapi/utils/UnitConversion.h +9 -0
- package/ios/audioapi/ios/AudioAPIModule.mm +9 -14
- package/ios/audioapi/ios/core/IOSAudioPlayer.h +1 -1
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +7 -6
- package/ios/audioapi/ios/core/IOSAudioRecorder.h +39 -13
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +302 -26
- package/ios/audioapi/ios/core/NativeAudioPlayer.m +7 -11
- package/ios/audioapi/ios/core/NativeAudioRecorder.h +8 -9
- package/ios/audioapi/ios/core/NativeAudioRecorder.m +70 -76
- package/ios/audioapi/ios/core/utils/AudioDecoder.mm +1 -0
- package/ios/audioapi/ios/core/utils/FileOptions.h +33 -0
- package/ios/audioapi/ios/core/utils/FileOptions.mm +195 -0
- package/ios/audioapi/ios/core/utils/IOSFileWriter.h +53 -0
- package/ios/audioapi/ios/core/utils/IOSFileWriter.mm +239 -0
- package/ios/audioapi/ios/core/utils/IOSRecorderCallback.h +47 -0
- package/ios/audioapi/ios/core/utils/IOSRecorderCallback.mm +185 -0
- package/ios/audioapi/ios/system/AudioEngine.h +21 -16
- package/ios/audioapi/ios/system/AudioEngine.mm +138 -130
- package/ios/audioapi/ios/system/AudioSessionManager.h +19 -9
- package/ios/audioapi/ios/system/AudioSessionManager.mm +250 -215
- package/ios/audioapi/ios/system/NotificationManager.mm +24 -42
- package/lib/commonjs/api.js +82 -109
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/AudioRecorder.js +159 -13
- package/lib/commonjs/core/AudioRecorder.js.map +1 -1
- package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/commonjs/system/notification/PlaybackNotificationManager.js +17 -14
- package/lib/commonjs/system/notification/PlaybackNotificationManager.js.map +1 -1
- package/lib/commonjs/system/notification/RecordingNotificationManager.js +22 -19
- package/lib/commonjs/system/notification/RecordingNotificationManager.js.map +1 -1
- package/lib/commonjs/system/notification/SimpleNotificationManager.js +16 -13
- package/lib/commonjs/system/notification/SimpleNotificationManager.js.map +1 -1
- package/lib/commonjs/types.js +39 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils/filePresets.js +43 -0
- package/lib/commonjs/utils/filePresets.js.map +1 -0
- package/lib/commonjs/web-system/notification/PlaybackNotificationManager.js +6 -3
- package/lib/commonjs/web-system/notification/PlaybackNotificationManager.js.map +1 -1
- package/lib/commonjs/web-system/notification/RecordingNotificationManager.js +6 -3
- package/lib/commonjs/web-system/notification/RecordingNotificationManager.js.map +1 -1
- package/lib/module/api.js +5 -4
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/AudioRecorder.js +159 -13
- package/lib/module/core/AudioRecorder.js.map +1 -1
- package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/module/system/notification/PlaybackNotificationManager.js +17 -14
- package/lib/module/system/notification/PlaybackNotificationManager.js.map +1 -1
- package/lib/module/system/notification/RecordingNotificationManager.js +22 -19
- package/lib/module/system/notification/RecordingNotificationManager.js.map +1 -1
- package/lib/module/system/notification/SimpleNotificationManager.js +16 -13
- package/lib/module/system/notification/SimpleNotificationManager.js.map +1 -1
- package/lib/module/types.js +38 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/filePresets.js +39 -0
- package/lib/module/utils/filePresets.js.map +1 -0
- package/lib/module/web-system/notification/PlaybackNotificationManager.js +6 -3
- package/lib/module/web-system/notification/PlaybackNotificationManager.js.map +1 -1
- package/lib/module/web-system/notification/RecordingNotificationManager.js +6 -3
- package/lib/module/web-system/notification/RecordingNotificationManager.js.map +1 -1
- package/lib/typescript/api.d.ts +5 -4
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/AudioRecorder.d.ts +69 -7
- package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
- package/lib/typescript/events/types.d.ts +36 -2
- package/lib/typescript/events/types.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +24 -4
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
- package/lib/typescript/system/notification/PlaybackNotificationManager.d.ts +4 -3
- package/lib/typescript/system/notification/PlaybackNotificationManager.d.ts.map +1 -1
- package/lib/typescript/system/notification/RecordingNotificationManager.d.ts +4 -3
- package/lib/typescript/system/notification/RecordingNotificationManager.d.ts.map +1 -1
- package/lib/typescript/system/notification/SimpleNotificationManager.d.ts +3 -2
- package/lib/typescript/system/notification/SimpleNotificationManager.d.ts.map +1 -1
- package/lib/typescript/system/notification/types.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +79 -3
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/utils/filePresets.d.ts +9 -0
- package/lib/typescript/utils/filePresets.d.ts.map +1 -0
- package/lib/typescript/web-system/notification/PlaybackNotificationManager.d.ts +4 -3
- package/lib/typescript/web-system/notification/PlaybackNotificationManager.d.ts.map +1 -1
- package/lib/typescript/web-system/notification/RecordingNotificationManager.d.ts +4 -3
- package/lib/typescript/web-system/notification/RecordingNotificationManager.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/AudioAPIModule/globals.d.ts +1 -2
- package/src/api.ts +8 -29
- package/src/core/AudioRecorder.ts +195 -23
- package/src/events/types.ts +40 -2
- package/src/interfaces.ts +34 -5
- package/src/specs/NativeAudioAPIModule.ts +2 -2
- package/src/system/notification/PlaybackNotificationManager.ts +20 -16
- package/src/system/notification/RecordingNotificationManager.ts +26 -21
- package/src/system/notification/SimpleNotificationManager.ts +18 -13
- package/src/system/notification/types.ts +1 -0
- package/src/types.ts +89 -3
- package/src/utils/filePresets.ts +47 -0
- package/src/web-system/notification/PlaybackNotificationManager.ts +9 -5
- package/src/web-system/notification/RecordingNotificationManager.ts +9 -5
|
@@ -10,83 +10,103 @@
|
|
|
10
10
|
* @nolint
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
13
|
+
package com.swmansion.audioapi;
|
|
14
|
+
|
|
15
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
16
|
+
import com.facebook.react.bridge.Promise;
|
|
17
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
18
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
19
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
20
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
21
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
22
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
|
23
|
+
import javax.annotation.Nonnull;
|
|
24
|
+
|
|
25
|
+
public abstract class NativeAudioAPIModuleSpec extends ReactContextBaseJavaModule implements TurboModule {
|
|
26
|
+
public static final String NAME = "AudioAPIModule";
|
|
27
|
+
|
|
28
|
+
public NativeAudioAPIModuleSpec(ReactApplicationContext reactContext) {
|
|
29
|
+
super(reactContext);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Override
|
|
33
|
+
public @Nonnull String getName() {
|
|
34
|
+
return NAME;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
38
|
+
@DoNotStrip
|
|
39
|
+
public abstract boolean install();
|
|
40
|
+
|
|
41
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
42
|
+
@DoNotStrip
|
|
43
|
+
public abstract double getDevicePreferredSampleRate();
|
|
44
|
+
|
|
45
|
+
@ReactMethod
|
|
46
|
+
@DoNotStrip
|
|
47
|
+
public abstract void setAudioSessionActivity(boolean enabled, Promise promise);
|
|
48
|
+
|
|
49
|
+
@ReactMethod
|
|
50
|
+
@DoNotStrip
|
|
51
|
+
public abstract void setAudioSessionOptions(String category, String mode, ReadableArray options, boolean allowHaptics);
|
|
52
|
+
|
|
53
|
+
@ReactMethod
|
|
54
|
+
@DoNotStrip
|
|
55
|
+
public abstract void disableSessionManagement();
|
|
56
|
+
|
|
57
|
+
@ReactMethod
|
|
58
|
+
@DoNotStrip
|
|
59
|
+
public abstract void observeAudioInterruptions(boolean enabled);
|
|
60
|
+
|
|
61
|
+
@ReactMethod
|
|
62
|
+
@DoNotStrip
|
|
63
|
+
public abstract void activelyReclaimSession(boolean enabled);
|
|
64
|
+
|
|
65
|
+
@ReactMethod
|
|
66
|
+
@DoNotStrip
|
|
67
|
+
public abstract void observeVolumeChanges(boolean enabled);
|
|
68
|
+
|
|
69
|
+
@ReactMethod
|
|
70
|
+
@DoNotStrip
|
|
71
|
+
public abstract void requestRecordingPermissions(Promise promise);
|
|
72
|
+
|
|
73
|
+
@ReactMethod
|
|
74
|
+
@DoNotStrip
|
|
75
|
+
public abstract void checkRecordingPermissions(Promise promise);
|
|
76
|
+
|
|
77
|
+
@ReactMethod
|
|
78
|
+
@DoNotStrip
|
|
79
|
+
public abstract void requestNotificationPermissions(Promise promise);
|
|
80
|
+
|
|
81
|
+
@ReactMethod
|
|
82
|
+
@DoNotStrip
|
|
83
|
+
public abstract void checkNotificationPermissions(Promise promise);
|
|
84
|
+
|
|
85
|
+
@ReactMethod
|
|
86
|
+
@DoNotStrip
|
|
87
|
+
public abstract void getDevicesInfo(Promise promise);
|
|
88
|
+
|
|
89
|
+
@ReactMethod
|
|
90
|
+
@DoNotStrip
|
|
91
|
+
public abstract void registerNotification(String type, String key, Promise promise);
|
|
92
|
+
|
|
93
|
+
@ReactMethod
|
|
94
|
+
@DoNotStrip
|
|
95
|
+
public abstract void showNotification(String key, ReadableMap options, Promise promise);
|
|
96
|
+
|
|
97
|
+
@ReactMethod
|
|
98
|
+
@DoNotStrip
|
|
99
|
+
public abstract void updateNotification(String key, ReadableMap options, Promise promise);
|
|
100
|
+
|
|
101
|
+
@ReactMethod
|
|
102
|
+
@DoNotStrip
|
|
103
|
+
public abstract void hideNotification(String key, Promise promise);
|
|
104
|
+
|
|
105
|
+
@ReactMethod
|
|
106
|
+
@DoNotStrip
|
|
107
|
+
public abstract void unregisterNotification(String key, Promise promise);
|
|
108
|
+
|
|
109
|
+
@ReactMethod
|
|
110
|
+
@DoNotStrip
|
|
111
|
+
public abstract void isNotificationActive(String key, Promise promise);
|
|
112
|
+
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
#include <audioapi/core/utils/worklets/SafeIncludes.h>
|
|
17
17
|
|
|
18
18
|
#include <memory>
|
|
19
|
+
#include <string>
|
|
19
20
|
#include <vector>
|
|
20
21
|
|
|
21
22
|
namespace audioapi {
|
|
@@ -137,19 +138,10 @@ class AudioAPIModuleInstaller {
|
|
|
137
138
|
const jsi::Value &thisValue,
|
|
138
139
|
const jsi::Value *args,
|
|
139
140
|
size_t count) -> jsi::Value {
|
|
140
|
-
auto
|
|
141
|
-
|
|
142
|
-
auto sampleRate =
|
|
143
|
-
static_cast<float>(options.getProperty(runtime, "sampleRate").getNumber());
|
|
144
|
-
auto bufferLength =
|
|
145
|
-
static_cast<int>(options.getProperty(runtime, "bufferLengthInSamples").getNumber());
|
|
146
|
-
|
|
147
|
-
auto audioRecorderHostObject = std::make_shared<AudioRecorderHostObject>(
|
|
148
|
-
audioEventHandlerRegistry, sampleRate, bufferLength);
|
|
141
|
+
auto audioRecorderHostObject =
|
|
142
|
+
std::make_shared<AudioRecorderHostObject>(audioEventHandlerRegistry);
|
|
149
143
|
|
|
150
144
|
auto jsiObject = jsi::Object::createFromHostObject(runtime, audioRecorderHostObject);
|
|
151
|
-
jsiObject.setExternalMemoryPressure(
|
|
152
|
-
runtime, sizeof(float) * bufferLength); // rough estimate of underlying buffer
|
|
153
145
|
|
|
154
146
|
return jsiObject;
|
|
155
147
|
});
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include <audioapi/core/inputs/AudioRecorder.h>
|
|
6
6
|
#include <audioapi/core/sources/AudioBuffer.h>
|
|
7
7
|
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
8
|
+
#include <audioapi/utils/AudioFileProperties.h>
|
|
8
9
|
#ifdef ANDROID
|
|
9
10
|
#include <audioapi/android/core/AndroidAudioRecorder.h>
|
|
10
11
|
#else
|
|
@@ -15,33 +16,121 @@
|
|
|
15
16
|
namespace audioapi {
|
|
16
17
|
|
|
17
18
|
AudioRecorderHostObject::AudioRecorderHostObject(
|
|
18
|
-
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry
|
|
19
|
-
float sampleRate,
|
|
20
|
-
int bufferLength) {
|
|
19
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry) {
|
|
21
20
|
#ifdef ANDROID
|
|
22
|
-
audioRecorder_ =
|
|
23
|
-
std::make_shared<AndroidAudioRecorder>(sampleRate, bufferLength, audioEventHandlerRegistry);
|
|
21
|
+
audioRecorder_ = std::make_shared<AndroidAudioRecorder>(audioEventHandlerRegistry);
|
|
24
22
|
#else
|
|
25
|
-
audioRecorder_ =
|
|
26
|
-
std::make_shared<IOSAudioRecorder>(sampleRate, bufferLength, audioEventHandlerRegistry);
|
|
23
|
+
audioRecorder_ = std::make_shared<IOSAudioRecorder>(audioEventHandlerRegistry);
|
|
27
24
|
#endif
|
|
28
25
|
|
|
29
|
-
addSetters(JSI_EXPORT_PROPERTY_SETTER(AudioRecorderHostObject, onAudioReady));
|
|
30
|
-
|
|
31
26
|
addFunctions(
|
|
32
27
|
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, start),
|
|
33
28
|
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, stop),
|
|
29
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, isRecording),
|
|
30
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, enableFileOutput),
|
|
31
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, disableFileOutput),
|
|
32
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, pause),
|
|
33
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, resume),
|
|
34
34
|
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, connect),
|
|
35
|
-
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, disconnect)
|
|
35
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, disconnect),
|
|
36
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, setOnAudioReady),
|
|
37
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, clearOnAudioReady),
|
|
38
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, setOnError),
|
|
39
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, clearOnError),
|
|
40
|
+
JSI_EXPORT_FUNCTION(AudioRecorderHostObject, getCurrentDuration));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, start) {
|
|
44
|
+
auto result = audioRecorder_->start();
|
|
45
|
+
auto jsResult = jsi::Object(runtime);
|
|
46
|
+
|
|
47
|
+
jsResult.setProperty(
|
|
48
|
+
runtime,
|
|
49
|
+
"status",
|
|
50
|
+
jsi::String::createFromUtf8(runtime, result.is_ok() ? "success" : "error"));
|
|
51
|
+
|
|
52
|
+
if (result.is_ok()) {
|
|
53
|
+
jsResult.setProperty(runtime, "path", jsi::String::createFromUtf8(runtime, result.unwrap()));
|
|
54
|
+
} else {
|
|
55
|
+
jsResult.setProperty(
|
|
56
|
+
runtime, "message", jsi::String::createFromUtf8(runtime, result.unwrap_err()));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return jsResult;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, stop) {
|
|
63
|
+
auto result = audioRecorder_->stop();
|
|
64
|
+
auto jsResult = jsi::Object(runtime);
|
|
65
|
+
|
|
66
|
+
jsResult.setProperty(
|
|
67
|
+
runtime,
|
|
68
|
+
"status",
|
|
69
|
+
jsi::String::createFromUtf8(runtime, result.is_ok() ? "success" : "error"));
|
|
70
|
+
|
|
71
|
+
if (result.is_ok()) {
|
|
72
|
+
auto info = result.unwrap();
|
|
73
|
+
|
|
74
|
+
jsResult.setProperty(runtime, "path", jsi::String::createFromUtf8(runtime, std::get<0>(info)));
|
|
75
|
+
jsResult.setProperty(runtime, "size", std::get<1>(info));
|
|
76
|
+
jsResult.setProperty(runtime, "duration", std::get<2>(info));
|
|
77
|
+
} else {
|
|
78
|
+
jsResult.setProperty(
|
|
79
|
+
runtime, "message", jsi::String::createFromUtf8(runtime, result.unwrap_err()));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return jsResult;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, isRecording) {
|
|
86
|
+
return jsi::Value(audioRecorder_->isRecording());
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, isPaused) {
|
|
90
|
+
return jsi::Value(audioRecorder_->isPaused());
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, enableFileOutput) {
|
|
94
|
+
auto fileProperties = AudioFileProperties::CreateFromJSIValue(runtime, args[0]);
|
|
95
|
+
|
|
96
|
+
auto result = audioRecorder_->enableFileOutput(fileProperties);
|
|
97
|
+
auto jsResult = jsi::Object(runtime);
|
|
98
|
+
|
|
99
|
+
jsResult.setProperty(
|
|
100
|
+
runtime,
|
|
101
|
+
"status",
|
|
102
|
+
jsi::String::createFromUtf8(runtime, result.is_ok() ? "success" : "error"));
|
|
103
|
+
|
|
104
|
+
if (result.is_ok()) {
|
|
105
|
+
jsResult.setProperty(runtime, "path", jsi::String::createFromUtf8(runtime, result.unwrap()));
|
|
106
|
+
} else {
|
|
107
|
+
jsResult.setProperty(
|
|
108
|
+
runtime, "message", jsi::String::createFromUtf8(runtime, result.unwrap_err()));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return jsResult;
|
|
36
112
|
}
|
|
37
113
|
|
|
38
|
-
|
|
39
|
-
audioRecorder_->
|
|
114
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, disableFileOutput) {
|
|
115
|
+
audioRecorder_->disableFileOutput();
|
|
116
|
+
return jsi::Value::undefined();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, pause) {
|
|
120
|
+
audioRecorder_->pause();
|
|
121
|
+
|
|
122
|
+
return jsi::Value::undefined();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, resume) {
|
|
126
|
+
audioRecorder_->resume();
|
|
127
|
+
return jsi::Value::undefined();
|
|
40
128
|
}
|
|
41
129
|
|
|
42
130
|
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, connect) {
|
|
43
131
|
auto adapterNodeHostObject =
|
|
44
132
|
args[0].getObject(runtime).getHostObject<RecorderAdapterNodeHostObject>(runtime);
|
|
133
|
+
|
|
45
134
|
audioRecorder_->connect(
|
|
46
135
|
std::static_pointer_cast<RecorderAdapterNode>(adapterNodeHostObject->node_));
|
|
47
136
|
return jsi::Value::undefined();
|
|
@@ -49,19 +138,59 @@ JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, connect) {
|
|
|
49
138
|
|
|
50
139
|
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, disconnect) {
|
|
51
140
|
audioRecorder_->disconnect();
|
|
141
|
+
|
|
52
142
|
return jsi::Value::undefined();
|
|
53
143
|
}
|
|
54
144
|
|
|
55
|
-
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject,
|
|
56
|
-
|
|
145
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, setOnAudioReady) {
|
|
146
|
+
auto options = args[0].getObject(runtime);
|
|
147
|
+
|
|
148
|
+
auto sampleRate = static_cast<float>(options.getProperty(runtime, "sampleRate").getNumber());
|
|
149
|
+
auto bufferLength = static_cast<size_t>(options.getProperty(runtime, "bufferLength").getNumber());
|
|
150
|
+
auto channelCount = static_cast<int>(options.getProperty(runtime, "channelCount").getNumber());
|
|
151
|
+
uint64_t callbackId =
|
|
152
|
+
std::stoull(options.getProperty(runtime, "callbackId").getString(runtime).utf8(runtime));
|
|
57
153
|
|
|
154
|
+
auto result =
|
|
155
|
+
audioRecorder_->setOnAudioReadyCallback(sampleRate, bufferLength, channelCount, callbackId);
|
|
156
|
+
auto jsResult = jsi::Object(runtime);
|
|
157
|
+
|
|
158
|
+
jsResult.setProperty(
|
|
159
|
+
runtime,
|
|
160
|
+
"status",
|
|
161
|
+
jsi::String::createFromUtf8(runtime, result.is_ok() ? "success" : "error"));
|
|
162
|
+
|
|
163
|
+
if (result.is_err()) {
|
|
164
|
+
jsResult.setProperty(
|
|
165
|
+
runtime, "message", jsi::String::createFromUtf8(runtime, result.unwrap_err()));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return jsResult;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, clearOnAudioReady) {
|
|
172
|
+
audioRecorder_->clearOnAudioReadyCallback();
|
|
58
173
|
return jsi::Value::undefined();
|
|
59
174
|
}
|
|
60
175
|
|
|
61
|
-
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject,
|
|
62
|
-
|
|
176
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, setOnError) {
|
|
177
|
+
auto options = args[0].getObject(runtime);
|
|
63
178
|
|
|
179
|
+
uint64_t callbackId =
|
|
180
|
+
std::stoull(options.getProperty(runtime, "callbackId").getString(runtime).utf8(runtime));
|
|
181
|
+
|
|
182
|
+
audioRecorder_->setOnErrorCallback(callbackId);
|
|
183
|
+
return jsi::Value::undefined();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, clearOnError) {
|
|
187
|
+
audioRecorder_->clearOnErrorCallback();
|
|
64
188
|
return jsi::Value::undefined();
|
|
65
189
|
}
|
|
66
190
|
|
|
191
|
+
JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, getCurrentDuration) {
|
|
192
|
+
double duration = audioRecorder_->getCurrentDuration();
|
|
193
|
+
return jsi::Value(duration);
|
|
194
|
+
}
|
|
195
|
+
|
|
67
196
|
} // namespace audioapi
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
#include <cstdio>
|
|
6
6
|
#include <memory>
|
|
7
|
+
#include <string>
|
|
7
8
|
#include <utility>
|
|
8
9
|
#include <vector>
|
|
9
10
|
|
|
@@ -16,18 +17,32 @@ class AudioEventHandlerRegistry;
|
|
|
16
17
|
class AudioRecorderHostObject : public JsiHostObject {
|
|
17
18
|
public:
|
|
18
19
|
explicit AudioRecorderHostObject(
|
|
19
|
-
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry
|
|
20
|
-
float sampleRate,
|
|
21
|
-
int bufferLength);
|
|
20
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry);
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
JSI_HOST_FUNCTION_DECL(start);
|
|
23
|
+
JSI_HOST_FUNCTION_DECL(stop);
|
|
24
|
+
JSI_HOST_FUNCTION_DECL(isRecording);
|
|
25
|
+
JSI_HOST_FUNCTION_DECL(isPaused);
|
|
26
|
+
|
|
27
|
+
JSI_HOST_FUNCTION_DECL(enableFileOutput);
|
|
28
|
+
JSI_HOST_FUNCTION_DECL(disableFileOutput);
|
|
29
|
+
|
|
30
|
+
JSI_HOST_FUNCTION_DECL(pause);
|
|
31
|
+
JSI_HOST_FUNCTION_DECL(resume);
|
|
24
32
|
|
|
25
33
|
JSI_HOST_FUNCTION_DECL(connect);
|
|
26
34
|
JSI_HOST_FUNCTION_DECL(disconnect);
|
|
27
|
-
|
|
28
|
-
JSI_HOST_FUNCTION_DECL(
|
|
35
|
+
|
|
36
|
+
JSI_HOST_FUNCTION_DECL(setOnAudioReady);
|
|
37
|
+
JSI_HOST_FUNCTION_DECL(clearOnAudioReady);
|
|
38
|
+
|
|
39
|
+
JSI_HOST_FUNCTION_DECL(setOnError);
|
|
40
|
+
JSI_HOST_FUNCTION_DECL(clearOnError);
|
|
41
|
+
|
|
42
|
+
JSI_HOST_FUNCTION_DECL(getCurrentDuration);
|
|
29
43
|
|
|
30
44
|
private:
|
|
31
45
|
std::shared_ptr<AudioRecorder> audioRecorder_;
|
|
32
46
|
};
|
|
47
|
+
|
|
33
48
|
} // namespace audioapi
|
|
@@ -1,83 +1,66 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
#include <audioapi/core/inputs/AudioRecorder.h>
|
|
3
|
-
#include <audioapi/core/
|
|
4
|
-
#include <audioapi/core/
|
|
5
|
-
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
6
|
-
#include <audioapi/utils/AudioBus.h>
|
|
7
|
-
#include <audioapi/utils/CircularAudioArray.h>
|
|
8
|
-
#include <audioapi/utils/CircularOverflowableAudioArray.h>
|
|
9
|
-
#include <algorithm>
|
|
10
|
-
#include <memory>
|
|
11
|
-
#include <string>
|
|
12
|
-
#include <unordered_map>
|
|
3
|
+
#include <audioapi/core/utils/AudioFileWriter.h>
|
|
4
|
+
#include <audioapi/core/utils/AudioRecorderCallback.h>
|
|
13
5
|
|
|
14
6
|
namespace audioapi {
|
|
15
7
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
/// @brief Sets the error callback to be invoked when an error occurs during recording.
|
|
9
|
+
/// This method should be called from the JS thread only.
|
|
10
|
+
/// @param callbackId Identifier for the JS callback to be invoked.
|
|
11
|
+
void AudioRecorder::setOnErrorCallback(uint64_t callbackId) {
|
|
12
|
+
std::scoped_lock lock(callbackMutex_, fileWriterMutex_, errorCallbackMutex_);
|
|
13
|
+
|
|
14
|
+
if (usesFileOutput()) {
|
|
15
|
+
fileWriter_->setOnErrorCallback(callbackId);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (usesCallback()) {
|
|
19
|
+
dataCallback_->setOnErrorCallback(callbackId);
|
|
20
|
+
}
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
onAudioReadyCallbackId_ = callbackId;
|
|
22
|
+
errorCallbackId_.store(callbackId, std::memory_order_release);
|
|
31
23
|
}
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
/// @brief Clears the error callback.
|
|
26
|
+
/// If the recorder is currently active, it will stop invoking the callback immediately.
|
|
27
|
+
/// This method should be called from the JS thread only.
|
|
28
|
+
void AudioRecorder::clearOnErrorCallback() {
|
|
29
|
+
std::scoped_lock lock(callbackMutex_, fileWriterMutex_, errorCallbackMutex_);
|
|
38
30
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
if (usesFileOutput()) {
|
|
32
|
+
fileWriter_->clearOnErrorCallback();
|
|
33
|
+
}
|
|
42
34
|
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
"audioReady", onAudioReadyCallbackId_, body);
|
|
35
|
+
if (usesCallback()) {
|
|
36
|
+
dataCallback_->clearOnErrorCallback();
|
|
46
37
|
}
|
|
38
|
+
|
|
39
|
+
errorCallbackId_.store(0, std::memory_order_release);
|
|
47
40
|
}
|
|
48
41
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
auto availableFrames = static_cast<int>(circularBuffer_->getNumberOfAvailableFrames());
|
|
42
|
+
/// @brief Gets the current duration of the recorded audio in seconds.
|
|
43
|
+
/// @returns Duration in seconds.
|
|
44
|
+
double AudioRecorder::getCurrentDuration() const {
|
|
45
|
+
double duration = 0.0;
|
|
54
46
|
|
|
55
|
-
|
|
47
|
+
if (usesFileOutput()) {
|
|
48
|
+
duration = fileWriter_->getCurrentDuration();
|
|
49
|
+
}
|
|
56
50
|
|
|
57
|
-
|
|
51
|
+
return duration;
|
|
58
52
|
}
|
|
59
53
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
adapterNodeLock_.lock();
|
|
63
|
-
adapterNode_ = node;
|
|
64
|
-
adapterNodeLock_.unlock();
|
|
54
|
+
bool AudioRecorder::usesCallback() const {
|
|
55
|
+
return callbackOutputEnabled_.load(std::memory_order_acquire);
|
|
65
56
|
}
|
|
66
57
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
adapterNode_ = nullptr;
|
|
70
|
-
adapterNodeLock_.unlock();
|
|
58
|
+
bool AudioRecorder::usesFileOutput() const {
|
|
59
|
+
return fileOutputEnabled_.load(std::memory_order_acquire);
|
|
71
60
|
}
|
|
72
61
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (adapterNode_ != nullptr) {
|
|
76
|
-
adapterNode_->buff_->write(data, numFrames);
|
|
77
|
-
}
|
|
78
|
-
adapterNodeLock_.unlock();
|
|
79
|
-
}
|
|
80
|
-
circularBuffer_->push_back(data, numFrames);
|
|
62
|
+
bool AudioRecorder::isConnected() const {
|
|
63
|
+
return isConnected_.load(std::memory_order_acquire);
|
|
81
64
|
}
|
|
82
65
|
|
|
83
66
|
} // namespace audioapi
|