react-native-audio-api 0.11.0-nightly-95f9c99-20251215 → 0.11.0-nightly-52d0b79-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/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 +31 -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
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <audioapi/utils/Result.hpp>
|
|
4
|
+
#include <atomic>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <tuple>
|
|
8
|
+
|
|
9
|
+
namespace audioapi {
|
|
10
|
+
|
|
11
|
+
class AudioFileProperties;
|
|
12
|
+
class AudioEventHandlerRegistry;
|
|
13
|
+
|
|
14
|
+
typedef Result<std::string, std::string> OpenFileResult;
|
|
15
|
+
typedef Result<std::tuple<double, double>, std::string> CloseFileResult;
|
|
16
|
+
|
|
17
|
+
class AudioFileWriter {
|
|
18
|
+
public:
|
|
19
|
+
AudioFileWriter(
|
|
20
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry,
|
|
21
|
+
const std::shared_ptr<AudioFileProperties> &fileProperties);
|
|
22
|
+
virtual ~AudioFileWriter() = default;
|
|
23
|
+
|
|
24
|
+
virtual CloseFileResult closeFile() = 0;
|
|
25
|
+
|
|
26
|
+
virtual std::string getFilePath() const = 0;
|
|
27
|
+
virtual double getCurrentDuration() const = 0;
|
|
28
|
+
|
|
29
|
+
void setOnErrorCallback(uint64_t callbackId);
|
|
30
|
+
void clearOnErrorCallback();
|
|
31
|
+
void invokeOnErrorCallback(const std::string &message);
|
|
32
|
+
|
|
33
|
+
protected:
|
|
34
|
+
bool isFileOpen();
|
|
35
|
+
|
|
36
|
+
std::atomic<bool> isFileOpen_{false};
|
|
37
|
+
std::atomic<size_t> framesWritten_{0};
|
|
38
|
+
std::atomic<uint64_t> errorCallbackId_{0};
|
|
39
|
+
|
|
40
|
+
std::shared_ptr<AudioFileProperties> fileProperties_;
|
|
41
|
+
std::shared_ptr<AudioEventHandlerRegistry> audioEventHandlerRegistry_;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
|
|
2
|
+
#include <audioapi/core/utils/AudioRecorderCallback.h>
|
|
3
|
+
|
|
4
|
+
#include <audioapi/HostObjects/sources/AudioBufferHostObject.h>
|
|
5
|
+
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
6
|
+
#include <audioapi/utils/AudioArray.h>
|
|
7
|
+
#include <audioapi/utils/AudioBus.h>
|
|
8
|
+
#include <audioapi/utils/CircularAudioArray.h>
|
|
9
|
+
|
|
10
|
+
#include <algorithm>
|
|
11
|
+
#include <memory>
|
|
12
|
+
#include <string>
|
|
13
|
+
#include <unordered_map>
|
|
14
|
+
|
|
15
|
+
namespace audioapi {
|
|
16
|
+
|
|
17
|
+
/// @brief Constructor
|
|
18
|
+
/// Allocates circular buffer (as every property to do so is already known at this point).
|
|
19
|
+
/// @param audioEventHandlerRegistry The audio event handler registry
|
|
20
|
+
/// @param sampleRate The user desired sample rate
|
|
21
|
+
/// @param bufferLength The user desired buffer length
|
|
22
|
+
/// @param channelCount The user desired channel count
|
|
23
|
+
/// @param callbackId The callback identifier
|
|
24
|
+
AudioRecorderCallback::AudioRecorderCallback(
|
|
25
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry,
|
|
26
|
+
float sampleRate,
|
|
27
|
+
size_t bufferLength,
|
|
28
|
+
int channelCount,
|
|
29
|
+
uint64_t callbackId)
|
|
30
|
+
: sampleRate_(sampleRate),
|
|
31
|
+
bufferLength_(bufferLength),
|
|
32
|
+
channelCount_(channelCount),
|
|
33
|
+
callbackId_(callbackId),
|
|
34
|
+
audioEventHandlerRegistry_(audioEventHandlerRegistry) {
|
|
35
|
+
ringBufferSize_ = std::max(bufferLength * 2, static_cast<size_t>(8192));
|
|
36
|
+
circularBus_.resize(channelCount_);
|
|
37
|
+
|
|
38
|
+
for (size_t i = 0; i < channelCount_; ++i) {
|
|
39
|
+
circularBus_[i] = std::make_shared<CircularAudioArray>(ringBufferSize_);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
isInitialized_.store(true, std::memory_order_release);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
AudioRecorderCallback::~AudioRecorderCallback() {
|
|
46
|
+
isInitialized_.store(false, std::memory_order_release);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// @brief Emits audio data from the circular buffer when enough frames are available.
|
|
50
|
+
/// @param flush If true, emits all available data regardless of buffer length.
|
|
51
|
+
void AudioRecorderCallback::emitAudioData(bool flush) {
|
|
52
|
+
size_t sizeLimit = flush ? circularBus_[0]->getNumberOfAvailableFrames() : bufferLength_;
|
|
53
|
+
|
|
54
|
+
while (circularBus_[0]->getNumberOfAvailableFrames() >= sizeLimit) {
|
|
55
|
+
auto bus = std::make_shared<AudioBus>(sizeLimit, channelCount_, sampleRate_);
|
|
56
|
+
|
|
57
|
+
for (int i = 0; i < channelCount_; ++i) {
|
|
58
|
+
auto *outputChannel = bus->getChannel(i)->getData();
|
|
59
|
+
circularBus_[i]->pop_front(outputChannel, sizeLimit);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
invokeCallback(bus, static_cast<int>(sizeLimit));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void AudioRecorderCallback::invokeCallback(const std::shared_ptr<AudioBus> &bus, int numFrames) {
|
|
67
|
+
auto audioBuffer = std::make_shared<AudioBuffer>(bus);
|
|
68
|
+
auto audioBufferHostObject = std::make_shared<AudioBufferHostObject>(audioBuffer);
|
|
69
|
+
|
|
70
|
+
std::unordered_map<std::string, EventValue> eventPayload = {};
|
|
71
|
+
eventPayload.insert({"buffer", audioBufferHostObject});
|
|
72
|
+
eventPayload.insert({"numFrames", numFrames});
|
|
73
|
+
|
|
74
|
+
if (audioEventHandlerRegistry_) {
|
|
75
|
+
audioEventHandlerRegistry_->invokeHandlerWithEventBody("audioReady", callbackId_, eventPayload);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
void AudioRecorderCallback::setOnErrorCallback(uint64_t callbackId) {
|
|
80
|
+
errorCallbackId_.store(callbackId, std::memory_order_release);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
void AudioRecorderCallback::clearOnErrorCallback() {
|
|
84
|
+
errorCallbackId_.store(0, std::memory_order_release);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// @brief Invokes the error callback with the provided message.
|
|
88
|
+
/// @param message The error message to be sent to the callback.
|
|
89
|
+
void AudioRecorderCallback::invokeOnErrorCallback(const std::string &message) {
|
|
90
|
+
uint64_t callbackId = errorCallbackId_.load(std::memory_order_acquire);
|
|
91
|
+
|
|
92
|
+
if (audioEventHandlerRegistry_ == nullptr || callbackId == 0) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
std::unordered_map<std::string, EventValue> eventPayload = {};
|
|
97
|
+
eventPayload.insert({"message", message});
|
|
98
|
+
audioEventHandlerRegistry_->invokeHandlerWithEventBody("error", callbackId, eventPayload);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <audioapi/utils/Result.hpp>
|
|
4
|
+
#include <atomic>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
namespace audioapi {
|
|
10
|
+
|
|
11
|
+
class AudioBus;
|
|
12
|
+
class AudioArray;
|
|
13
|
+
class CircularAudioArray;
|
|
14
|
+
class AudioEventHandlerRegistry;
|
|
15
|
+
|
|
16
|
+
class AudioRecorderCallback {
|
|
17
|
+
public:
|
|
18
|
+
AudioRecorderCallback(
|
|
19
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry,
|
|
20
|
+
float sampleRate,
|
|
21
|
+
size_t bufferLength,
|
|
22
|
+
int channelCount,
|
|
23
|
+
uint64_t callbackId);
|
|
24
|
+
virtual ~AudioRecorderCallback();
|
|
25
|
+
|
|
26
|
+
virtual void cleanup() = 0;
|
|
27
|
+
|
|
28
|
+
void emitAudioData(bool flush = false);
|
|
29
|
+
void invokeCallback(const std::shared_ptr<AudioBus> &bus, int numFrames);
|
|
30
|
+
|
|
31
|
+
void setOnErrorCallback(uint64_t callbackId);
|
|
32
|
+
void clearOnErrorCallback();
|
|
33
|
+
void invokeOnErrorCallback(const std::string &message);
|
|
34
|
+
|
|
35
|
+
protected:
|
|
36
|
+
std::atomic<bool> isInitialized_{false};
|
|
37
|
+
|
|
38
|
+
float sampleRate_;
|
|
39
|
+
size_t bufferLength_;
|
|
40
|
+
int channelCount_;
|
|
41
|
+
uint64_t callbackId_;
|
|
42
|
+
size_t ringBufferSize_;
|
|
43
|
+
|
|
44
|
+
std::atomic<uint64_t> errorCallbackId_{0};
|
|
45
|
+
|
|
46
|
+
std::shared_ptr<AudioEventHandlerRegistry> audioEventHandlerRegistry_;
|
|
47
|
+
|
|
48
|
+
// TODO: CircularAudioBus
|
|
49
|
+
std::vector<std::shared_ptr<CircularAudioArray>> circularBus_;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#include <audioapi/utils/AudioFileProperties.h>
|
|
2
|
+
|
|
3
|
+
#include <audioapi/jsi/JsiHostObject.h>
|
|
4
|
+
#include <jsi/jsi.h>
|
|
5
|
+
#include <algorithm>
|
|
6
|
+
#include <memory>
|
|
7
|
+
#include <string>
|
|
8
|
+
|
|
9
|
+
namespace audioapi {
|
|
10
|
+
|
|
11
|
+
AudioFileProperties::AudioFileProperties(
|
|
12
|
+
FileDirectory directory,
|
|
13
|
+
const std::string &subDirectory,
|
|
14
|
+
const std::string &fileNamePrefix,
|
|
15
|
+
int channelCount,
|
|
16
|
+
size_t batchDurationSeconds,
|
|
17
|
+
Format format,
|
|
18
|
+
float sampleRate,
|
|
19
|
+
size_t bitRate,
|
|
20
|
+
BitDepth bitDepth,
|
|
21
|
+
int flacCompressionLevel,
|
|
22
|
+
int androidFlushIntervalMs,
|
|
23
|
+
IOSAudioQuality iosAudioQuality)
|
|
24
|
+
: directory(directory),
|
|
25
|
+
subDirectory(subDirectory),
|
|
26
|
+
fileNamePrefix(fileNamePrefix),
|
|
27
|
+
channelCount(channelCount),
|
|
28
|
+
batchDurationSeconds(batchDurationSeconds),
|
|
29
|
+
format(format),
|
|
30
|
+
sampleRate(sampleRate),
|
|
31
|
+
bitRate(bitRate),
|
|
32
|
+
bitDepth(bitDepth),
|
|
33
|
+
flacCompressionLevel(flacCompressionLevel),
|
|
34
|
+
androidFlushIntervalMs(androidFlushIntervalMs),
|
|
35
|
+
iosAudioQuality(iosAudioQuality) {}
|
|
36
|
+
|
|
37
|
+
std::shared_ptr<AudioFileProperties> AudioFileProperties::CreateFromJSIValue(
|
|
38
|
+
facebook::jsi::Runtime &runtime,
|
|
39
|
+
const facebook::jsi::Value &value) {
|
|
40
|
+
auto options = value.getObject(runtime);
|
|
41
|
+
|
|
42
|
+
FileDirectory directory =
|
|
43
|
+
static_cast<FileDirectory>(options.getProperty(runtime, "directory").getNumber());
|
|
44
|
+
|
|
45
|
+
std::string subDirectory =
|
|
46
|
+
options.getProperty(runtime, "subDirectory").asString(runtime).utf8(runtime);
|
|
47
|
+
|
|
48
|
+
std::string fileNamePrefix =
|
|
49
|
+
options.getProperty(runtime, "fileNamePrefix").asString(runtime).utf8(runtime);
|
|
50
|
+
|
|
51
|
+
int channelCount = static_cast<int>(options.getProperty(runtime, "channelCount").getNumber());
|
|
52
|
+
|
|
53
|
+
size_t batchDurationSeconds =
|
|
54
|
+
static_cast<size_t>(options.getProperty(runtime, "batchDurationSeconds").getNumber());
|
|
55
|
+
|
|
56
|
+
Format format = static_cast<Format>(options.getProperty(runtime, "format").getNumber());
|
|
57
|
+
|
|
58
|
+
int androidFlushIntervalMs =
|
|
59
|
+
static_cast<int>(options.getProperty(runtime, "androidFlushIntervalMs").getNumber());
|
|
60
|
+
|
|
61
|
+
auto presetOptions = options.getProperty(runtime, "preset").getObject(runtime);
|
|
62
|
+
|
|
63
|
+
float sampleRate =
|
|
64
|
+
static_cast<float>(presetOptions.getProperty(runtime, "sampleRate").getNumber());
|
|
65
|
+
|
|
66
|
+
size_t bitRate = static_cast<size_t>(presetOptions.getProperty(runtime, "bitRate").getNumber());
|
|
67
|
+
|
|
68
|
+
BitDepth bitDepth =
|
|
69
|
+
static_cast<BitDepth>(presetOptions.getProperty(runtime, "bitDepth").getNumber());
|
|
70
|
+
|
|
71
|
+
int flacCompressionLevel =
|
|
72
|
+
static_cast<int>(presetOptions.getProperty(runtime, "flacCompressionLevel").getNumber());
|
|
73
|
+
|
|
74
|
+
IOSAudioQuality iosAudioQuality =
|
|
75
|
+
static_cast<IOSAudioQuality>(presetOptions.getProperty(runtime, "iosQuality").getNumber());
|
|
76
|
+
|
|
77
|
+
return std::make_shared<AudioFileProperties>(
|
|
78
|
+
directory,
|
|
79
|
+
subDirectory,
|
|
80
|
+
fileNamePrefix,
|
|
81
|
+
channelCount,
|
|
82
|
+
batchDurationSeconds,
|
|
83
|
+
format,
|
|
84
|
+
sampleRate,
|
|
85
|
+
bitRate,
|
|
86
|
+
bitDepth,
|
|
87
|
+
flacCompressionLevel,
|
|
88
|
+
androidFlushIntervalMs,
|
|
89
|
+
iosAudioQuality);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <cstddef>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <string>
|
|
6
|
+
|
|
7
|
+
namespace facebook {
|
|
8
|
+
namespace jsi {
|
|
9
|
+
class Runtime;
|
|
10
|
+
class Value;
|
|
11
|
+
} // namespace jsi
|
|
12
|
+
} // namespace facebook
|
|
13
|
+
|
|
14
|
+
namespace audioapi {
|
|
15
|
+
|
|
16
|
+
class AudioFileProperties {
|
|
17
|
+
public:
|
|
18
|
+
enum class FileDirectory {
|
|
19
|
+
Document = 0,
|
|
20
|
+
Cache = 1,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
enum class Format {
|
|
24
|
+
WAV = 0,
|
|
25
|
+
CAF = 1,
|
|
26
|
+
M4A = 2,
|
|
27
|
+
FLAC = 3,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
enum class IOSAudioQuality {
|
|
31
|
+
Min = 0,
|
|
32
|
+
Low = 1,
|
|
33
|
+
Medium = 2,
|
|
34
|
+
High = 3,
|
|
35
|
+
Max = 4,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
enum class BitDepth {
|
|
39
|
+
Bit16 = 0,
|
|
40
|
+
Bit24 = 1,
|
|
41
|
+
Bit32 = 2,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
AudioFileProperties(
|
|
45
|
+
FileDirectory directory,
|
|
46
|
+
const std::string &subDirectory,
|
|
47
|
+
const std::string &fileNamePrefix,
|
|
48
|
+
int channelCount,
|
|
49
|
+
size_t batchDurationSeconds,
|
|
50
|
+
Format format,
|
|
51
|
+
float sampleRate,
|
|
52
|
+
size_t bitRate,
|
|
53
|
+
BitDepth bitDepth,
|
|
54
|
+
int flacCompressionLevel,
|
|
55
|
+
int androidFlushIntervalMs,
|
|
56
|
+
IOSAudioQuality iosAudioQuality);
|
|
57
|
+
|
|
58
|
+
static std::shared_ptr<AudioFileProperties> CreateFromJSIValue(
|
|
59
|
+
facebook::jsi::Runtime &runtime,
|
|
60
|
+
const facebook::jsi::Value &value);
|
|
61
|
+
|
|
62
|
+
FileDirectory directory;
|
|
63
|
+
std::string subDirectory;
|
|
64
|
+
std::string fileNamePrefix;
|
|
65
|
+
int channelCount;
|
|
66
|
+
size_t batchDurationSeconds;
|
|
67
|
+
Format format;
|
|
68
|
+
float sampleRate;
|
|
69
|
+
size_t bitRate;
|
|
70
|
+
BitDepth bitDepth;
|
|
71
|
+
int flacCompressionLevel;
|
|
72
|
+
int androidFlushIntervalMs;
|
|
73
|
+
IOSAudioQuality iosAudioQuality;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <functional>
|
|
4
|
+
#include <new>
|
|
5
|
+
#include <stdexcept>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <type_traits>
|
|
8
|
+
#include <utility>
|
|
9
|
+
|
|
10
|
+
struct NoneType {};
|
|
11
|
+
inline constexpr NoneType None{};
|
|
12
|
+
|
|
13
|
+
/// @brief A Result type that can represent either a success (Ok) or an error (Err).
|
|
14
|
+
/// @tparam T value type for success
|
|
15
|
+
/// @tparam E error type for failure
|
|
16
|
+
/// @note Specializations for void T and/or void E are not provided. Use NoneType instead.
|
|
17
|
+
/// Design inspired by Rust's Result type.
|
|
18
|
+
/// https://doc.rust-lang.org/std/result/
|
|
19
|
+
///
|
|
20
|
+
/// @example
|
|
21
|
+
/// /// Creating an Ok Result and mapping its error:
|
|
22
|
+
/// Result<int, std::string> res = Result<int, int>::Err(404)
|
|
23
|
+
/// .map_err<std::string>([](auto code){
|
|
24
|
+
/// return "Error code: " + std::to_string(code);
|
|
25
|
+
/// });
|
|
26
|
+
///
|
|
27
|
+
template <typename T = NoneType, typename E = NoneType>
|
|
28
|
+
class Result {
|
|
29
|
+
struct OkTag {};
|
|
30
|
+
struct ErrTag {};
|
|
31
|
+
|
|
32
|
+
explicit Result(OkTag, const T &value) : ok_value(value), is_ok_(true) {}
|
|
33
|
+
explicit Result(OkTag, T &&value) : ok_value(std::move(value)), is_ok_(true) {}
|
|
34
|
+
explicit Result(ErrTag, const E &error) : err_value(error), is_ok_(false) {}
|
|
35
|
+
explicit Result(ErrTag, E &&error) : err_value(std::move(error)), is_ok_(false) {}
|
|
36
|
+
|
|
37
|
+
public:
|
|
38
|
+
Result(const Result<T, E> &other) {
|
|
39
|
+
is_ok_ = other.is_ok_;
|
|
40
|
+
if (is_ok_) {
|
|
41
|
+
new (&ok_value) T(other.ok_value);
|
|
42
|
+
} else {
|
|
43
|
+
new (&err_value) E(other.err_value);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Result(Result<T, E> &&other) noexcept(
|
|
48
|
+
std::is_nothrow_move_constructible_v<T> && std::is_nothrow_move_constructible_v<E>) {
|
|
49
|
+
is_ok_ = other.is_ok_;
|
|
50
|
+
if (is_ok_) {
|
|
51
|
+
new (&ok_value) T(std::move(other.ok_value));
|
|
52
|
+
} else {
|
|
53
|
+
new (&err_value) E(std::move(other.err_value));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
Result &operator=(const Result &other) {
|
|
58
|
+
if (this == &other)
|
|
59
|
+
return *this;
|
|
60
|
+
if (is_ok_ == other.is_ok_) {
|
|
61
|
+
if (is_ok_)
|
|
62
|
+
ok_value = other.ok_value;
|
|
63
|
+
else
|
|
64
|
+
err_value = other.err_value;
|
|
65
|
+
} else {
|
|
66
|
+
if (is_ok_) {
|
|
67
|
+
ok_value.~T();
|
|
68
|
+
new (&err_value) E(other.err_value);
|
|
69
|
+
is_ok_ = false;
|
|
70
|
+
} else {
|
|
71
|
+
err_value.~E();
|
|
72
|
+
new (&ok_value) T(other.ok_value);
|
|
73
|
+
is_ok_ = true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return *this;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Result &operator=(Result &&other) noexcept(
|
|
80
|
+
std::is_nothrow_move_assignable_v<T> && std::is_nothrow_move_assignable_v<E> &&
|
|
81
|
+
std::is_nothrow_move_constructible_v<T> && std::is_nothrow_move_constructible_v<E>) {
|
|
82
|
+
if (this == &other)
|
|
83
|
+
return *this;
|
|
84
|
+
if (is_ok_ == other.is_ok_) {
|
|
85
|
+
if (is_ok_)
|
|
86
|
+
ok_value = std::move(other.ok_value);
|
|
87
|
+
else
|
|
88
|
+
err_value = std::move(other.err_value);
|
|
89
|
+
} else {
|
|
90
|
+
if (is_ok_) {
|
|
91
|
+
ok_value.~T();
|
|
92
|
+
new (&err_value) E(std::move(other.err_value));
|
|
93
|
+
is_ok_ = false;
|
|
94
|
+
} else {
|
|
95
|
+
err_value.~E();
|
|
96
|
+
new (&ok_value) T(std::move(other.ok_value));
|
|
97
|
+
is_ok_ = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return *this;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
~Result() {
|
|
104
|
+
if (is_ok_) {
|
|
105
|
+
ok_value.~T();
|
|
106
|
+
} else {
|
|
107
|
+
err_value.~E();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/// @brief Creates a success Result.
|
|
112
|
+
static Result<T, E> Ok(const T &value) {
|
|
113
|
+
return Result<T, E>(OkTag{}, value);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/// @brief Creates a success Result from an rvalue.
|
|
117
|
+
static Result<T, E> Ok(T &&value) {
|
|
118
|
+
return Result<T, E>(OkTag{}, std::move(value));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// @brief Creates an error Result.
|
|
122
|
+
static Result<T, E> Err(const E &error) {
|
|
123
|
+
return Result<T, E>(ErrTag{}, error);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/// @brief Creates an error Result from an rvalue.
|
|
127
|
+
static Result<T, E> Err(E &&error) {
|
|
128
|
+
return Result<T, E>(ErrTag{}, std::move(error));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/// @brief Returns true if the result is Ok.
|
|
132
|
+
[[nodiscard]] bool is_ok() const {
|
|
133
|
+
return is_ok_;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/// @brief Returns true if the result is Err.
|
|
137
|
+
[[nodiscard]] bool is_err() const {
|
|
138
|
+
return !is_ok_;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/// @brief Returns the contained Ok value, consuming the Result.
|
|
142
|
+
/// @throws std::runtime_error if the value is an Err.
|
|
143
|
+
[[nodiscard]] T expect(const std::string &msg) && {
|
|
144
|
+
if (!is_ok_) {
|
|
145
|
+
throw std::runtime_error(msg);
|
|
146
|
+
}
|
|
147
|
+
return std::move(ok_value);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/// @brief Returns the contained Ok value.
|
|
151
|
+
/// @throws std::runtime_error if the value is an Err.
|
|
152
|
+
[[nodiscard]] const T &expect(const std::string &msg) const & {
|
|
153
|
+
if (!is_ok_) {
|
|
154
|
+
throw std::runtime_error(msg);
|
|
155
|
+
}
|
|
156
|
+
return ok_value;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/// @brief Returns the contained Ok value, consuming the Result.
|
|
160
|
+
/// @throws std::runtime_error if the value is an Err.
|
|
161
|
+
[[nodiscard]] T unwrap() && {
|
|
162
|
+
if (!is_ok_) {
|
|
163
|
+
throw std::runtime_error("Called unwrap on an Err value");
|
|
164
|
+
}
|
|
165
|
+
return std::move(ok_value);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/// @brief Returns the contained Ok value.
|
|
169
|
+
/// @throws std::runtime_error if the value is an Err.
|
|
170
|
+
[[nodiscard]] const T &unwrap() const & {
|
|
171
|
+
if (!is_ok_) {
|
|
172
|
+
throw std::runtime_error("Called unwrap on an Err value");
|
|
173
|
+
}
|
|
174
|
+
return ok_value;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/// @brief Returns the contained Ok value or a default. Consumes self.
|
|
178
|
+
[[nodiscard]] T unwrap_or(T &&default_value) && {
|
|
179
|
+
if (is_ok_) {
|
|
180
|
+
return std::move(ok_value);
|
|
181
|
+
}
|
|
182
|
+
return std::move(default_value);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/// @brief Returns the contained Ok value or computes it from a closure. Consumes self.
|
|
186
|
+
[[nodiscard]] T unwrap_or_else(const std::function<T(E &&)> &func) && {
|
|
187
|
+
if (is_ok_) {
|
|
188
|
+
return std::move(ok_value);
|
|
189
|
+
}
|
|
190
|
+
return func(std::move(err_value));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/// @brief Returns the contained Ok value without checking. UB if Err.
|
|
194
|
+
[[nodiscard]] T unwrap_unchecked() && noexcept {
|
|
195
|
+
return std::move(ok_value);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/// @brief Returns the contained Ok value without checking. UB if Err.
|
|
199
|
+
[[nodiscard]] const T &unwrap_unchecked() const & noexcept {
|
|
200
|
+
return ok_value;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/// @brief Returns the contained Err value, consuming the Result.
|
|
204
|
+
/// @throws std::runtime_error if the value is Ok.
|
|
205
|
+
[[nodiscard]] E unwrap_err() && {
|
|
206
|
+
if (is_ok_) {
|
|
207
|
+
throw std::runtime_error("Called unwrap_err on an Ok value");
|
|
208
|
+
}
|
|
209
|
+
return std::move(err_value);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/// @brief Returns the contained Err value.
|
|
213
|
+
/// @throws std::runtime_error if the value is Ok.
|
|
214
|
+
[[nodiscard]] const E &unwrap_err() const & {
|
|
215
|
+
if (is_ok_) {
|
|
216
|
+
throw std::runtime_error("Called unwrap_err on an Ok value");
|
|
217
|
+
}
|
|
218
|
+
return err_value;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/// @brief Returns the contained Err value, consuming the Result.
|
|
222
|
+
/// @throws std::runtime_error if the value is Ok.
|
|
223
|
+
[[nodiscard]] E expect_err(const std::string &msg) && {
|
|
224
|
+
if (is_ok_) {
|
|
225
|
+
throw std::runtime_error(msg);
|
|
226
|
+
}
|
|
227
|
+
return std::move(err_value);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/// @brief Returns the contained Err value.
|
|
231
|
+
/// @throws std::runtime_error if the value is Ok.
|
|
232
|
+
[[nodiscard]] const E &expect_err(const std::string &msg) const & {
|
|
233
|
+
if (is_ok_) {
|
|
234
|
+
throw std::runtime_error(msg);
|
|
235
|
+
}
|
|
236
|
+
return err_value;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/// @brief Returns the contained Err value without checking. UB if Ok.
|
|
240
|
+
[[nodiscard]] E unwrap_err_unchecked() && noexcept {
|
|
241
|
+
return std::move(err_value);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/// @brief Returns the contained Err value without checking. UB if Ok.
|
|
245
|
+
[[nodiscard]] const E &unwrap_err_unchecked() const & noexcept {
|
|
246
|
+
return err_value;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/// @brief Maps a Result<T, E> to Result<U, E> by applying a function to a contained Ok value.
|
|
250
|
+
template <typename F>
|
|
251
|
+
[[nodiscard]] auto map(F &&ok_func) && {
|
|
252
|
+
using U = std::invoke_result_t<F, T>;
|
|
253
|
+
using ResultType = Result<U, E>;
|
|
254
|
+
if (is_ok_) {
|
|
255
|
+
return ResultType::Ok(ok_func(std::move(ok_value)));
|
|
256
|
+
} else {
|
|
257
|
+
return ResultType::Err(std::move(err_value));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/// @brief Maps a Result<T, E> to Result<T, F> by applying a function to a contained Err value.
|
|
262
|
+
template <typename F>
|
|
263
|
+
[[nodiscard]] auto map_err(F &&err_func) && {
|
|
264
|
+
using U = std::invoke_result_t<F, E>;
|
|
265
|
+
using ResultType = Result<T, U>;
|
|
266
|
+
if (is_ok_) {
|
|
267
|
+
return ResultType::Ok(std::move(ok_value));
|
|
268
|
+
} else {
|
|
269
|
+
return ResultType::Err(err_func(std::move(err_value)));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/// @brief Returns the provided default (if Err), or applies a function to the contained value (if Ok).
|
|
274
|
+
template <typename F, typename U>
|
|
275
|
+
[[nodiscard]] auto map_or(F &&ok_func, U &&default_value) && {
|
|
276
|
+
if (is_ok_) {
|
|
277
|
+
return ok_func(std::move(ok_value));
|
|
278
|
+
} else {
|
|
279
|
+
return std::forward<U>(default_value);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/// @brief Maps a Result<T, E> to U by applying fallback function default to a contained Err value, or function f to a contained Ok value.
|
|
284
|
+
template <typename FT, typename FE>
|
|
285
|
+
[[nodiscard]] auto map_or_else(FT &&ok_func, FE &&err_func) && {
|
|
286
|
+
if (is_ok_) {
|
|
287
|
+
return ok_func(std::move(ok_value));
|
|
288
|
+
} else {
|
|
289
|
+
return err_func(std::move(err_value));
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/// @brief Calls the provided closure with the contained Ok value, if any, otherwise returns the Err value of self.
|
|
294
|
+
/// @tparam for Result<T,E> F is a closure that takes T and returns Result<TNew, E>
|
|
295
|
+
template <typename F>
|
|
296
|
+
[[nodiscard]] auto and_then(F &&ok_func) && {
|
|
297
|
+
using ResultType = std::invoke_result_t<F, T>;
|
|
298
|
+
if (is_ok_) {
|
|
299
|
+
return ok_func(std::move(ok_value));
|
|
300
|
+
} else {
|
|
301
|
+
return ResultType::Err(std::move(err_value));
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/// @brief Calls the provided closure with the contained Err value, if any, otherwise returns the Ok value of self.
|
|
306
|
+
/// @tparam for Result<T,E> F is a closure that takes E and returns Result<T, ENew>
|
|
307
|
+
template <typename F>
|
|
308
|
+
[[nodiscard]] auto or_else(F &&err_func) && {
|
|
309
|
+
using ResultType = std::invoke_result_t<F, E>;
|
|
310
|
+
if (is_ok_) {
|
|
311
|
+
return ResultType::Ok(std::move(ok_value));
|
|
312
|
+
} else {
|
|
313
|
+
return err_func(std::move(err_value));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
private:
|
|
318
|
+
union {
|
|
319
|
+
T ok_value;
|
|
320
|
+
E err_value;
|
|
321
|
+
};
|
|
322
|
+
bool is_ok_;
|
|
323
|
+
};
|