react-native-audio-api 0.9.0-nightly-7ecb495-20251008 → 0.9.1
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/{utils/AudioDecoder.cpp → AudioDecoder.cpp} +75 -79
- package/android/src/main/jniLibs/arm64-v8a/libavcodec.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libavformat.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libavutil.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libswresample.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavcodec.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavformat.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavutil.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libswresample.so +0 -0
- package/android/src/main/jniLibs/x86/libavcodec.so +0 -0
- package/android/src/main/jniLibs/x86/libavformat.so +0 -0
- package/android/src/main/jniLibs/x86/libavutil.so +0 -0
- package/android/src/main/jniLibs/x86/libswresample.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavcodec.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavformat.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavutil.so +0 -0
- package/android/src/main/jniLibs/x86_64/libswresample.so +0 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +43 -124
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +101 -1
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +3 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.cpp +3 -8
- package/common/cpp/audioapi/core/AudioContext.cpp +2 -0
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +35 -0
- package/common/cpp/audioapi/core/BaseAudioContext.h +12 -4
- package/common/cpp/audioapi/core/OfflineAudioContext.cpp +2 -0
- package/common/cpp/audioapi/core/effects/WorkletNode.cpp +16 -28
- package/common/cpp/audioapi/core/effects/WorkletNode.h +2 -3
- package/common/cpp/audioapi/core/effects/WorkletProcessingNode.cpp +5 -6
- package/common/cpp/audioapi/core/sources/AudioBuffer.h +1 -0
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +0 -4
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +0 -1
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +0 -2
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +0 -4
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +0 -1
- package/common/cpp/audioapi/core/sources/StreamerNode.cpp +16 -6
- package/common/cpp/audioapi/core/sources/StreamerNode.h +3 -1
- package/common/cpp/audioapi/core/sources/WorkletSourceNode.cpp +2 -3
- package/common/cpp/audioapi/core/utils/AudioDecoder.h +91 -36
- package/common/cpp/audioapi/core/utils/Constants.h +0 -4
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +5 -1
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64/libavcodec.framework/libavcodec +0 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64_x86_64-simulator/libavcodec.framework/libavcodec +0 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/Info.plist +5 -5
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64/libavformat.framework/libavformat +0 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64_x86_64-simulator/libavformat.framework/libavformat +0 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64/libavutil.framework/libavutil +0 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64_x86_64-simulator/libavutil.framework/libavutil +0 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/Info.plist +5 -5
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64/libswresample.framework/libswresample +0 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64_x86_64-simulator/libswresample.framework/libswresample +0 -0
- package/common/cpp/audioapi/jsi/AudioArrayBuffer.cpp +2 -2
- package/common/cpp/audioapi/jsi/AudioArrayBuffer.h +10 -11
- package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.cpp +282 -241
- package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.h +19 -57
- package/common/cpp/audioapi/libs/ffmpeg/ffmpeg_setup.sh +1 -1
- package/common/cpp/audioapi/utils/AudioBus.cpp +4 -0
- package/common/cpp/audioapi/utils/AudioBus.h +1 -0
- package/common/cpp/test/CMakeLists.txt +8 -5
- package/common/cpp/test/RunTests.sh +2 -2
- package/common/cpp/test/{AudioParamTest.cpp → src/AudioParamTest.cpp} +1 -1
- package/common/cpp/test/src/ConstantSourceTest.cpp +64 -0
- package/common/cpp/test/{GainTest.cpp → src/GainTest.cpp} +11 -10
- package/common/cpp/test/{MockAudioEventHandlerRegistry.h → src/MockAudioEventHandlerRegistry.h} +4 -2
- package/common/cpp/test/{OscillatorTest.cpp → src/OscillatorTest.cpp} +6 -4
- package/common/cpp/test/{StereoPannerTest.cpp → src/StereoPannerTest.cpp} +1 -1
- package/ios/audioapi/ios/core/AudioDecoder.mm +156 -0
- package/lib/commonjs/api.js +1 -21
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/BaseAudioContext.js +18 -11
- package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
- package/lib/module/api.js +1 -3
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +18 -11
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/typescript/api.d.ts +1 -5
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts +6 -3
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +3 -10
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api.ts +0 -10
- package/src/core/BaseAudioContext.ts +29 -26
- package/src/interfaces.ts +6 -26
- package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.cpp +0 -133
- package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.h +0 -28
- package/common/cpp/audioapi/HostObjects/utils/AudioStretcherHostObject.cpp +0 -58
- package/common/cpp/audioapi/HostObjects/utils/AudioStretcherHostObject.h +0 -26
- package/common/cpp/audioapi/core/types/AudioFormat.h +0 -16
- package/common/cpp/audioapi/core/utils/AudioStretcher.cpp +0 -75
- package/common/cpp/audioapi/core/utils/AudioStretcher.h +0 -30
- package/ios/audioapi/ios/core/utils/AudioDecoder.mm +0 -160
- package/lib/commonjs/core/AudioDecoder.js +0 -48
- package/lib/commonjs/core/AudioDecoder.js.map +0 -1
- package/lib/commonjs/core/AudioStretcher.js +0 -31
- package/lib/commonjs/core/AudioStretcher.js.map +0 -1
- package/lib/module/core/AudioDecoder.js +0 -42
- package/lib/module/core/AudioDecoder.js.map +0 -1
- package/lib/module/core/AudioStretcher.js +0 -26
- package/lib/module/core/AudioStretcher.js.map +0 -1
- package/lib/typescript/core/AudioDecoder.d.ts +0 -4
- package/lib/typescript/core/AudioDecoder.d.ts.map +0 -1
- package/lib/typescript/core/AudioStretcher.d.ts +0 -3
- package/lib/typescript/core/AudioStretcher.d.ts.map +0 -1
- package/src/core/AudioDecoder.ts +0 -78
- package/src/core/AudioStretcher.ts +0 -43
package/android/src/main/cpp/audioapi/android/core/{utils/AudioDecoder.cpp → AudioDecoder.cpp}
RENAMED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#include <audioapi/core/sources/AudioBuffer.h>
|
|
2
1
|
#include <audioapi/core/utils/AudioDecoder.h>
|
|
3
2
|
#include <audioapi/dsp/VectorMath.h>
|
|
4
3
|
#include <audioapi/libs/base64/base64.h>
|
|
@@ -6,28 +5,28 @@
|
|
|
6
5
|
#include <audioapi/utils/AudioBus.h>
|
|
7
6
|
|
|
8
7
|
#define MINIAUDIO_IMPLEMENTATION
|
|
9
|
-
#include <audioapi/libs/miniaudio/decoders/libopus/miniaudio_libopus.h>
|
|
10
|
-
#include <audioapi/libs/miniaudio/decoders/libvorbis/miniaudio_libvorbis.h>
|
|
11
8
|
#include <audioapi/libs/miniaudio/miniaudio.h>
|
|
12
9
|
|
|
13
10
|
#ifndef AUDIO_API_TEST_SUITE
|
|
14
11
|
#include <android/log.h>
|
|
15
12
|
#include <audioapi/libs/ffmpeg/FFmpegDecoding.h>
|
|
16
13
|
#endif
|
|
14
|
+
#include <audioapi/libs/miniaudio/decoders/libopus/miniaudio_libopus.h>
|
|
15
|
+
#include <audioapi/libs/miniaudio/decoders/libvorbis/miniaudio_libvorbis.h>
|
|
17
16
|
|
|
18
17
|
namespace audioapi {
|
|
19
18
|
|
|
20
19
|
// Decoding audio in fixed-size chunks because total frame count can't be
|
|
21
20
|
// determined in advance. Note: ma_decoder_get_length_in_pcm_frames() always
|
|
22
21
|
// returns 0 for Vorbis decoders.
|
|
23
|
-
std::vector<
|
|
22
|
+
std::vector<int16_t> AudioDecoder::readAllPcmFrames(
|
|
24
23
|
ma_decoder &decoder,
|
|
25
|
-
int
|
|
26
|
-
|
|
27
|
-
std::vector<
|
|
28
|
-
|
|
24
|
+
int numChannels,
|
|
25
|
+
ma_uint64 &outFramesRead) {
|
|
26
|
+
std::vector<int16_t> buffer;
|
|
27
|
+
std::vector<int16_t> temp(CHUNK_SIZE * numChannels);
|
|
28
|
+
outFramesRead = 0;
|
|
29
29
|
|
|
30
|
-
#ifndef AUDIO_API_TEST_SUITE
|
|
31
30
|
while (true) {
|
|
32
31
|
ma_uint64 tempFramesDecoded = 0;
|
|
33
32
|
ma_decoder_read_pcm_frames(
|
|
@@ -39,46 +38,38 @@ std::vector<float> AudioDecoder::readAllPcmFrames(
|
|
|
39
38
|
buffer.insert(
|
|
40
39
|
buffer.end(),
|
|
41
40
|
temp.data(),
|
|
42
|
-
temp.data() + tempFramesDecoded *
|
|
41
|
+
temp.data() + tempFramesDecoded * numChannels);
|
|
43
42
|
outFramesRead += tempFramesDecoded;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
if (outFramesRead == 0) {
|
|
47
|
-
__android_log_print(ANDROID_LOG_ERROR, "AudioDecoder", "Failed to decode");
|
|
48
|
-
}
|
|
49
|
-
#endif
|
|
50
45
|
return buffer;
|
|
51
46
|
}
|
|
52
47
|
|
|
53
|
-
std::shared_ptr<
|
|
54
|
-
const std::vector<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
auto outputFrames = buffer.size() / outputChannels;
|
|
62
|
-
auto audioBus = std::make_shared<AudioBus>(
|
|
63
|
-
outputFrames, outputChannels, outputSampleRate);
|
|
48
|
+
std::shared_ptr<AudioBus> AudioDecoder::makeAudioBusFromInt16Buffer(
|
|
49
|
+
const std::vector<int16_t> &buffer,
|
|
50
|
+
int numChannels,
|
|
51
|
+
float sampleRate) {
|
|
52
|
+
auto outputFrames = buffer.size() / numChannels;
|
|
53
|
+
auto audioBus =
|
|
54
|
+
std::make_shared<AudioBus>(outputFrames, numChannels, sampleRate);
|
|
64
55
|
|
|
65
|
-
for (int ch = 0; ch <
|
|
56
|
+
for (int ch = 0; ch < numChannels; ++ch) {
|
|
66
57
|
auto channelData = audioBus->getChannel(ch)->getData();
|
|
67
58
|
for (int i = 0; i < outputFrames; ++i) {
|
|
68
|
-
channelData[i] = buffer[i *
|
|
59
|
+
channelData[i] = int16ToFloat(buffer[i * numChannels + ch]);
|
|
69
60
|
}
|
|
70
61
|
}
|
|
71
|
-
return
|
|
62
|
+
return audioBus;
|
|
72
63
|
}
|
|
73
64
|
|
|
74
|
-
std::shared_ptr<
|
|
75
|
-
const std::string &path
|
|
76
|
-
float sampleRate) {
|
|
65
|
+
std::shared_ptr<AudioBus> AudioDecoder::decodeWithFilePath(
|
|
66
|
+
const std::string &path) const {
|
|
77
67
|
#ifndef AUDIO_API_TEST_SUITE
|
|
68
|
+
std::vector<int16_t> buffer;
|
|
78
69
|
if (AudioDecoder::pathHasExtension(path, {".mp4", ".m4a", ".aac"})) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (buffer
|
|
70
|
+
buffer = ffmpegdecoding::decodeWithFilePath(
|
|
71
|
+
path, numChannels_, static_cast<int>(sampleRate_));
|
|
72
|
+
if (buffer.empty()) {
|
|
82
73
|
__android_log_print(
|
|
83
74
|
ANDROID_LOG_ERROR,
|
|
84
75
|
"AudioDecoder",
|
|
@@ -86,11 +77,11 @@ std::shared_ptr<AudioBuffer> AudioDecoder::decodeWithFilePath(
|
|
|
86
77
|
path.c_str());
|
|
87
78
|
return nullptr;
|
|
88
79
|
}
|
|
89
|
-
return buffer;
|
|
80
|
+
return makeAudioBusFromInt16Buffer(buffer, numChannels_, sampleRate_);
|
|
90
81
|
}
|
|
91
82
|
ma_decoder decoder;
|
|
92
|
-
ma_decoder_config config =
|
|
93
|
-
|
|
83
|
+
ma_decoder_config config = ma_decoder_config_init(
|
|
84
|
+
ma_format_s16, numChannels_, static_cast<int>(sampleRate_));
|
|
94
85
|
ma_decoding_backend_vtable *customBackends[] = {
|
|
95
86
|
ma_decoding_backend_libvorbis, ma_decoding_backend_libopus};
|
|
96
87
|
|
|
@@ -108,38 +99,41 @@ std::shared_ptr<AudioBuffer> AudioDecoder::decodeWithFilePath(
|
|
|
108
99
|
return nullptr;
|
|
109
100
|
}
|
|
110
101
|
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
ma_uint64 framesRead = 0;
|
|
103
|
+
buffer = readAllPcmFrames(decoder, numChannels_, framesRead);
|
|
104
|
+
if (framesRead == 0) {
|
|
105
|
+
__android_log_print(ANDROID_LOG_ERROR, "AudioDecoder", "Failed to decode");
|
|
106
|
+
ma_decoder_uninit(&decoder);
|
|
107
|
+
return nullptr;
|
|
108
|
+
}
|
|
113
109
|
|
|
114
|
-
std::vector<float> buffer = readAllPcmFrames(decoder, outputChannels);
|
|
115
110
|
ma_decoder_uninit(&decoder);
|
|
116
|
-
return
|
|
117
|
-
buffer, outputSampleRate, outputChannels);
|
|
111
|
+
return makeAudioBusFromInt16Buffer(buffer, numChannels_, sampleRate_);
|
|
118
112
|
#else
|
|
119
113
|
return nullptr;
|
|
120
114
|
#endif
|
|
121
115
|
}
|
|
122
116
|
|
|
123
|
-
std::shared_ptr<
|
|
117
|
+
std::shared_ptr<AudioBus> AudioDecoder::decodeWithMemoryBlock(
|
|
124
118
|
const void *data,
|
|
125
|
-
size_t size
|
|
126
|
-
float sampleRate) {
|
|
119
|
+
size_t size) const {
|
|
127
120
|
#ifndef AUDIO_API_TEST_SUITE
|
|
121
|
+
std::vector<int16_t> buffer;
|
|
128
122
|
const AudioFormat format = AudioDecoder::detectAudioFormat(data, size);
|
|
129
123
|
if (format == AudioFormat::MP4 || format == AudioFormat::M4A ||
|
|
130
124
|
format == AudioFormat::AAC) {
|
|
131
|
-
|
|
132
|
-
data, size,
|
|
133
|
-
if (buffer
|
|
125
|
+
buffer = ffmpegdecoding::decodeWithMemoryBlock(
|
|
126
|
+
data, size, numChannels_, sampleRate_);
|
|
127
|
+
if (buffer.empty()) {
|
|
134
128
|
__android_log_print(
|
|
135
129
|
ANDROID_LOG_ERROR, "AudioDecoder", "Failed to decode with FFmpeg");
|
|
136
130
|
return nullptr;
|
|
137
131
|
}
|
|
138
|
-
return buffer;
|
|
132
|
+
return makeAudioBusFromInt16Buffer(buffer, numChannels_, sampleRate_);
|
|
139
133
|
}
|
|
140
134
|
ma_decoder decoder;
|
|
141
|
-
ma_decoder_config config =
|
|
142
|
-
|
|
135
|
+
ma_decoder_config config = ma_decoder_config_init(
|
|
136
|
+
ma_format_s16, numChannels_, static_cast<int>(sampleRate_));
|
|
143
137
|
|
|
144
138
|
ma_decoding_backend_vtable *customBackends[] = {
|
|
145
139
|
ma_decoding_backend_libvorbis, ma_decoding_backend_libopus};
|
|
@@ -157,48 +151,50 @@ std::shared_ptr<AudioBuffer> AudioDecoder::decodeWithMemoryBlock(
|
|
|
157
151
|
return nullptr;
|
|
158
152
|
}
|
|
159
153
|
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
ma_uint64 framesRead = 0;
|
|
155
|
+
buffer = readAllPcmFrames(decoder, numChannels_, framesRead);
|
|
156
|
+
if (framesRead == 0) {
|
|
157
|
+
__android_log_print(ANDROID_LOG_ERROR, "AudioDecoder", "Failed to decode");
|
|
158
|
+
ma_decoder_uninit(&decoder);
|
|
159
|
+
return nullptr;
|
|
160
|
+
}
|
|
162
161
|
|
|
163
|
-
std::vector<float> buffer = readAllPcmFrames(decoder, outputChannels);
|
|
164
162
|
ma_decoder_uninit(&decoder);
|
|
165
|
-
return
|
|
166
|
-
buffer, outputSampleRate, outputChannels);
|
|
163
|
+
return makeAudioBusFromInt16Buffer(buffer, numChannels_, sampleRate_);
|
|
167
164
|
#else
|
|
168
165
|
return nullptr;
|
|
169
166
|
#endif
|
|
170
167
|
}
|
|
171
168
|
|
|
172
|
-
std::shared_ptr<
|
|
169
|
+
std::shared_ptr<AudioBus> AudioDecoder::decodeWithPCMInBase64(
|
|
173
170
|
const std::string &data,
|
|
174
|
-
float
|
|
175
|
-
int inputChannelCount,
|
|
176
|
-
bool interleaved) {
|
|
171
|
+
float playbackSpeed) const {
|
|
177
172
|
auto decodedData = base64_decode(data, false);
|
|
173
|
+
|
|
178
174
|
const auto uint8Data = reinterpret_cast<uint8_t *>(decodedData.data());
|
|
179
|
-
size_t
|
|
180
|
-
decodedData.size() / (inputChannelCount * sizeof(int16_t));
|
|
175
|
+
size_t framesDecoded = decodedData.size() / 2;
|
|
181
176
|
|
|
182
|
-
|
|
183
|
-
|
|
177
|
+
std::vector<int16_t> buffer(framesDecoded);
|
|
178
|
+
for (size_t i = 0; i < framesDecoded; ++i) {
|
|
179
|
+
buffer[i] =
|
|
180
|
+
static_cast<int16_t>((uint8Data[i * 2 + 1] << 8) | uint8Data[i * 2]);
|
|
181
|
+
}
|
|
184
182
|
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
changePlaybackSpeedIfNeeded(buffer, framesDecoded, 1, playbackSpeed);
|
|
184
|
+
auto outputFrames = buffer.size();
|
|
187
185
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
channelData[i] = uint8ToFloat(uint8Data[offset], uint8Data[offset + 1]);
|
|
199
|
-
}
|
|
186
|
+
auto audioBus =
|
|
187
|
+
std::make_shared<AudioBus>(outputFrames, numChannels_, sampleRate_);
|
|
188
|
+
auto leftChannelData = audioBus->getChannel(0)->getData();
|
|
189
|
+
auto rightChannelData = audioBus->getChannel(1)->getData();
|
|
190
|
+
|
|
191
|
+
for (size_t i = 0; i < outputFrames; ++i) {
|
|
192
|
+
auto sample = int16ToFloat(buffer[i]);
|
|
193
|
+
leftChannelData[i] = sample;
|
|
194
|
+
rightChannelData[i] = sample;
|
|
200
195
|
}
|
|
201
|
-
|
|
196
|
+
|
|
197
|
+
return audioBus;
|
|
202
198
|
}
|
|
203
199
|
|
|
204
200
|
} // namespace audioapi
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <audioapi/
|
|
4
|
-
#include <audioapi/HostObjects/OfflineAudioContextHostObject.h>
|
|
5
|
-
#include <audioapi/HostObjects/inputs/AudioRecorderHostObject.h>
|
|
6
|
-
#include <audioapi/HostObjects/utils/AudioDecoderHostObject.h>
|
|
7
|
-
#include <audioapi/HostObjects/utils/AudioStretcherHostObject.h>
|
|
3
|
+
#include <audioapi/jsi/JsiPromise.h>
|
|
8
4
|
#include <audioapi/core/AudioContext.h>
|
|
9
5
|
#include <audioapi/core/OfflineAudioContext.h>
|
|
10
6
|
#include <audioapi/core/inputs/AudioRecorder.h>
|
|
11
|
-
#include <audioapi/
|
|
7
|
+
#include <audioapi/HostObjects/AudioContextHostObject.h>
|
|
8
|
+
#include <audioapi/HostObjects/OfflineAudioContextHostObject.h>
|
|
9
|
+
#include <audioapi/HostObjects/inputs/AudioRecorderHostObject.h>
|
|
12
10
|
|
|
13
|
-
#include <audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.h>
|
|
14
11
|
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
12
|
+
#include <audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.h>
|
|
15
13
|
|
|
16
14
|
#include <audioapi/core/utils/worklets/SafeIncludes.h>
|
|
17
15
|
|
|
@@ -24,50 +22,29 @@ using namespace facebook;
|
|
|
24
22
|
class AudioAPIModuleInstaller {
|
|
25
23
|
public:
|
|
26
24
|
static void injectJSIBindings(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
auto createAudioContext = getCreateAudioContextFunction(
|
|
33
|
-
|
|
34
|
-
auto
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
auto
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
jsiRuntime->global().setProperty(
|
|
44
|
-
*jsiRuntime, "createAudioContext", createAudioContext);
|
|
45
|
-
jsiRuntime->global().setProperty(
|
|
46
|
-
*jsiRuntime, "createAudioRecorder", createAudioRecorder);
|
|
47
|
-
jsiRuntime->global().setProperty(
|
|
48
|
-
*jsiRuntime, "createOfflineAudioContext", createOfflineAudioContext);
|
|
49
|
-
jsiRuntime->global().setProperty(
|
|
50
|
-
*jsiRuntime, "createAudioDecoder", createAudioDecoder);
|
|
51
|
-
jsiRuntime->global().setProperty(
|
|
52
|
-
*jsiRuntime, "createAudioStretcher", createAudioStretcher);
|
|
53
|
-
|
|
54
|
-
auto audioEventHandlerRegistryHostObject =
|
|
55
|
-
std::make_shared<AudioEventHandlerRegistryHostObject>(
|
|
56
|
-
audioEventHandlerRegistry);
|
|
57
|
-
jsiRuntime->global().setProperty(
|
|
58
|
-
*jsiRuntime,
|
|
59
|
-
"AudioEventEmitter",
|
|
60
|
-
jsi::Object::createFromHostObject(
|
|
61
|
-
*jsiRuntime, audioEventHandlerRegistryHostObject));
|
|
25
|
+
jsi::Runtime *jsiRuntime,
|
|
26
|
+
const std::shared_ptr<react::CallInvoker> &jsCallInvoker,
|
|
27
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry,
|
|
28
|
+
std::shared_ptr<worklets::WorkletRuntime> uiRuntime = nullptr) {
|
|
29
|
+
|
|
30
|
+
auto createAudioContext = getCreateAudioContextFunction(jsiRuntime, jsCallInvoker, audioEventHandlerRegistry, uiRuntime);
|
|
31
|
+
auto createAudioRecorder = getCreateAudioRecorderFunction(jsiRuntime, audioEventHandlerRegistry);
|
|
32
|
+
auto createOfflineAudioContext = getCreateOfflineAudioContextFunction(jsiRuntime, jsCallInvoker, audioEventHandlerRegistry, uiRuntime);
|
|
33
|
+
|
|
34
|
+
jsiRuntime->global().setProperty(*jsiRuntime, "createAudioContext", createAudioContext);
|
|
35
|
+
jsiRuntime->global().setProperty(*jsiRuntime, "createAudioRecorder", createAudioRecorder);
|
|
36
|
+
jsiRuntime->global().setProperty(*jsiRuntime, "createOfflineAudioContext", createOfflineAudioContext);
|
|
37
|
+
|
|
38
|
+
auto audioEventHandlerRegistryHostObject = std::make_shared<AudioEventHandlerRegistryHostObject>(audioEventHandlerRegistry);
|
|
39
|
+
jsiRuntime->global().setProperty(*jsiRuntime, "AudioEventEmitter", jsi::Object::createFromHostObject(*jsiRuntime, audioEventHandlerRegistryHostObject));
|
|
62
40
|
}
|
|
63
41
|
|
|
64
42
|
private:
|
|
65
43
|
static jsi::Function getCreateAudioContextFunction(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const std::weak_ptr<worklets::WorkletRuntime> &uiRuntime) {
|
|
44
|
+
jsi::Runtime *jsiRuntime,
|
|
45
|
+
const std::shared_ptr<react::CallInvoker> &jsCallInvoker,
|
|
46
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry,
|
|
47
|
+
const std::weak_ptr<worklets::WorkletRuntime> &uiRuntime) {
|
|
71
48
|
return jsi::Function::createFromHostFunction(
|
|
72
49
|
*jsiRuntime,
|
|
73
50
|
jsi::PropNameID::forAscii(*jsiRuntime, "createAudioContext"),
|
|
@@ -90,14 +67,9 @@ class AudioAPIModuleInstaller {
|
|
|
90
67
|
auto runtimeRegistry = RuntimeRegistry{};
|
|
91
68
|
#endif
|
|
92
69
|
|
|
93
|
-
audioContext = std::make_shared<AudioContext>(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
audioEventHandlerRegistry,
|
|
97
|
-
runtimeRegistry);
|
|
98
|
-
auto audioContextHostObject =
|
|
99
|
-
std::make_shared<AudioContextHostObject>(
|
|
100
|
-
audioContext, &runtime, jsCallInvoker);
|
|
70
|
+
audioContext = std::make_shared<AudioContext>(sampleRate, initSuspended, audioEventHandlerRegistry, runtimeRegistry);
|
|
71
|
+
auto audioContextHostObject = std::make_shared<AudioContextHostObject>(
|
|
72
|
+
audioContext, &runtime, jsCallInvoker);
|
|
101
73
|
|
|
102
74
|
return jsi::Object::createFromHostObject(
|
|
103
75
|
runtime, audioContextHostObject);
|
|
@@ -105,11 +77,10 @@ class AudioAPIModuleInstaller {
|
|
|
105
77
|
}
|
|
106
78
|
|
|
107
79
|
static jsi::Function getCreateOfflineAudioContextFunction(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const std::weak_ptr<worklets::WorkletRuntime> &uiRuntime) {
|
|
80
|
+
jsi::Runtime *jsiRuntime,
|
|
81
|
+
const std::shared_ptr<react::CallInvoker> &jsCallInvoker,
|
|
82
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry,
|
|
83
|
+
const std::weak_ptr<worklets::WorkletRuntime> &uiRuntime) {
|
|
113
84
|
return jsi::Function::createFromHostFunction(
|
|
114
85
|
*jsiRuntime,
|
|
115
86
|
jsi::PropNameID::forAscii(*jsiRuntime, "createOfflineAudioContext"),
|
|
@@ -119,9 +90,9 @@ class AudioAPIModuleInstaller {
|
|
|
119
90
|
const jsi::Value &thisValue,
|
|
120
91
|
const jsi::Value *args,
|
|
121
92
|
size_t count) -> jsi::Value {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
93
|
+
auto numberOfChannels = static_cast<int>(args[0].getNumber());
|
|
94
|
+
auto length = static_cast<size_t>(args[1].getNumber());
|
|
95
|
+
auto sampleRate = static_cast<float>(args[2].getNumber());
|
|
125
96
|
|
|
126
97
|
#if RN_AUDIO_API_ENABLE_WORKLETS
|
|
127
98
|
auto runtimeRegistry = RuntimeRegistry{
|
|
@@ -132,15 +103,9 @@ class AudioAPIModuleInstaller {
|
|
|
132
103
|
auto runtimeRegistry = RuntimeRegistry{};
|
|
133
104
|
#endif
|
|
134
105
|
|
|
135
|
-
auto offlineAudioContext = std::make_shared<OfflineAudioContext>(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
sampleRate,
|
|
139
|
-
audioEventHandlerRegistry,
|
|
140
|
-
runtimeRegistry);
|
|
141
|
-
auto audioContextHostObject =
|
|
142
|
-
std::make_shared<OfflineAudioContextHostObject>(
|
|
143
|
-
offlineAudioContext, &runtime, jsCallInvoker);
|
|
106
|
+
auto offlineAudioContext = std::make_shared<OfflineAudioContext>(numberOfChannels, length, sampleRate, audioEventHandlerRegistry, runtimeRegistry);
|
|
107
|
+
auto audioContextHostObject = std::make_shared<OfflineAudioContextHostObject>(
|
|
108
|
+
offlineAudioContext, &runtime, jsCallInvoker);
|
|
144
109
|
|
|
145
110
|
return jsi::Object::createFromHostObject(
|
|
146
111
|
runtime, audioContextHostObject);
|
|
@@ -148,9 +113,8 @@ class AudioAPIModuleInstaller {
|
|
|
148
113
|
}
|
|
149
114
|
|
|
150
115
|
static jsi::Function getCreateAudioRecorderFunction(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
&audioEventHandlerRegistry) {
|
|
116
|
+
jsi::Runtime *jsiRuntime,
|
|
117
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry) {
|
|
154
118
|
return jsi::Function::createFromHostFunction(
|
|
155
119
|
*jsiRuntime,
|
|
156
120
|
jsi::PropNameID::forAscii(*jsiRuntime, "createAudioRecorder"),
|
|
@@ -162,57 +126,12 @@ class AudioAPIModuleInstaller {
|
|
|
162
126
|
size_t count) -> jsi::Value {
|
|
163
127
|
auto options = args[0].getObject(runtime);
|
|
164
128
|
|
|
165
|
-
auto sampleRate = static_cast<float>(
|
|
166
|
-
|
|
167
|
-
auto bufferLength = static_cast<int>(
|
|
168
|
-
options.getProperty(runtime, "bufferLengthInSamples")
|
|
169
|
-
.getNumber());
|
|
129
|
+
auto sampleRate = static_cast<float>(options.getProperty(runtime, "sampleRate").getNumber());
|
|
130
|
+
auto bufferLength = static_cast<int>(options.getProperty(runtime, "bufferLengthInSamples").getNumber());
|
|
170
131
|
|
|
171
|
-
auto audioRecorderHostObject =
|
|
172
|
-
std::make_shared<AudioRecorderHostObject>(
|
|
173
|
-
audioEventHandlerRegistry, sampleRate, bufferLength);
|
|
132
|
+
auto audioRecorderHostObject = std::make_shared<AudioRecorderHostObject>(audioEventHandlerRegistry, sampleRate, bufferLength);
|
|
174
133
|
|
|
175
|
-
return jsi::Object::createFromHostObject(
|
|
176
|
-
runtime, audioRecorderHostObject);
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
static jsi::Function getCreateAudioDecoderFunction(
|
|
181
|
-
jsi::Runtime *jsiRuntime,
|
|
182
|
-
const std::shared_ptr<react::CallInvoker> &jsCallInvoker) {
|
|
183
|
-
return jsi::Function::createFromHostFunction(
|
|
184
|
-
*jsiRuntime,
|
|
185
|
-
jsi::PropNameID::forAscii(*jsiRuntime, "createAudioDecoder"),
|
|
186
|
-
0,
|
|
187
|
-
[jsCallInvoker](
|
|
188
|
-
jsi::Runtime &runtime,
|
|
189
|
-
const jsi::Value &thisValue,
|
|
190
|
-
const jsi::Value *args,
|
|
191
|
-
size_t count) -> jsi::Value {
|
|
192
|
-
auto audioDecoderHostObject =
|
|
193
|
-
std::make_shared<AudioDecoderHostObject>(&runtime, jsCallInvoker);
|
|
194
|
-
return jsi::Object::createFromHostObject(
|
|
195
|
-
runtime, audioDecoderHostObject);
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
static jsi::Function getCreateAudioStretcherFunction(
|
|
200
|
-
jsi::Runtime *jsiRuntime,
|
|
201
|
-
const std::shared_ptr<react::CallInvoker> &jsCallInvoker) {
|
|
202
|
-
return jsi::Function::createFromHostFunction(
|
|
203
|
-
*jsiRuntime,
|
|
204
|
-
jsi::PropNameID::forAscii(*jsiRuntime, "createAudioStretcher"),
|
|
205
|
-
0,
|
|
206
|
-
[jsCallInvoker](
|
|
207
|
-
jsi::Runtime &runtime,
|
|
208
|
-
const jsi::Value &thisValue,
|
|
209
|
-
const jsi::Value *args,
|
|
210
|
-
size_t count) -> jsi::Value {
|
|
211
|
-
auto audioStretcherHostObject =
|
|
212
|
-
std::make_shared<AudioStretcherHostObject>(
|
|
213
|
-
&runtime, jsCallInvoker);
|
|
214
|
-
return jsi::Object::createFromHostObject(
|
|
215
|
-
runtime, audioStretcherHostObject);
|
|
134
|
+
return jsi::Object::createFromHostObject(runtime, audioRecorderHostObject);
|
|
216
135
|
});
|
|
217
136
|
}
|
|
218
137
|
};
|
|
@@ -49,7 +49,11 @@ BaseAudioContextHostObject::BaseAudioContextHostObject(
|
|
|
49
49
|
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createBufferQueueSource),
|
|
50
50
|
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createBuffer),
|
|
51
51
|
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createPeriodicWave),
|
|
52
|
-
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createAnalyser)
|
|
52
|
+
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createAnalyser),
|
|
53
|
+
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, decodeAudioData),
|
|
54
|
+
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, decodeAudioDataSource),
|
|
55
|
+
JSI_EXPORT_FUNCTION(
|
|
56
|
+
BaseAudioContextHostObject, decodePCMAudioDataInBase64));
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
JSI_PROPERTY_GETTER_IMPL(BaseAudioContextHostObject, destination) {
|
|
@@ -262,4 +266,100 @@ JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createAnalyser) {
|
|
|
262
266
|
auto analyserHostObject = std::make_shared<AnalyserNodeHostObject>(analyser);
|
|
263
267
|
return jsi::Object::createFromHostObject(runtime, analyserHostObject);
|
|
264
268
|
}
|
|
269
|
+
|
|
270
|
+
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, decodeAudioDataSource) {
|
|
271
|
+
auto sourcePath = args[0].getString(runtime).utf8(runtime);
|
|
272
|
+
|
|
273
|
+
auto promise = promiseVendor_->createPromise(
|
|
274
|
+
[this, sourcePath](std::shared_ptr<Promise> promise) {
|
|
275
|
+
std::thread([this, sourcePath, promise = std::move(promise)]() {
|
|
276
|
+
auto results = context_->decodeAudioDataSource(sourcePath);
|
|
277
|
+
|
|
278
|
+
if (!results) {
|
|
279
|
+
promise->reject("Failed to decode audio data source.");
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
auto audioBufferHostObject =
|
|
284
|
+
std::make_shared<AudioBufferHostObject>(results);
|
|
285
|
+
|
|
286
|
+
promise->resolve([audioBufferHostObject = std::move(
|
|
287
|
+
audioBufferHostObject)](jsi::Runtime &runtime) {
|
|
288
|
+
auto jsiObject = jsi::Object::createFromHostObject(
|
|
289
|
+
runtime, audioBufferHostObject);
|
|
290
|
+
jsiObject.setExternalMemoryPressure(
|
|
291
|
+
runtime, audioBufferHostObject->getSizeInBytes());
|
|
292
|
+
return jsiObject;
|
|
293
|
+
});
|
|
294
|
+
}).detach();
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
return promise;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, decodeAudioData) {
|
|
301
|
+
auto arrayBuffer = args[0]
|
|
302
|
+
.getObject(runtime)
|
|
303
|
+
.getPropertyAsObject(runtime, "buffer")
|
|
304
|
+
.getArrayBuffer(runtime);
|
|
305
|
+
auto data = arrayBuffer.data(runtime);
|
|
306
|
+
auto size = static_cast<int>(arrayBuffer.size(runtime));
|
|
307
|
+
|
|
308
|
+
auto promise = promiseVendor_->createPromise(
|
|
309
|
+
[this, data, size](std::shared_ptr<Promise> promise) {
|
|
310
|
+
std::thread([this, data, size, promise = std::move(promise)]() {
|
|
311
|
+
auto results = context_->decodeAudioData(data, size);
|
|
312
|
+
|
|
313
|
+
if (!results) {
|
|
314
|
+
promise->reject("Failed to decode audio data source.");
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
auto audioBufferHostObject =
|
|
319
|
+
std::make_shared<AudioBufferHostObject>(results);
|
|
320
|
+
|
|
321
|
+
promise->resolve([audioBufferHostObject = std::move(
|
|
322
|
+
audioBufferHostObject)](jsi::Runtime &runtime) {
|
|
323
|
+
auto jsiObject = jsi::Object::createFromHostObject(
|
|
324
|
+
runtime, audioBufferHostObject);
|
|
325
|
+
jsiObject.setExternalMemoryPressure(
|
|
326
|
+
runtime, audioBufferHostObject->getSizeInBytes());
|
|
327
|
+
return jsiObject;
|
|
328
|
+
});
|
|
329
|
+
}).detach();
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
return promise;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, decodePCMAudioDataInBase64) {
|
|
336
|
+
auto b64 = args[0].getString(runtime).utf8(runtime);
|
|
337
|
+
auto playbackSpeed = static_cast<float>(args[1].getNumber());
|
|
338
|
+
|
|
339
|
+
auto promise = promiseVendor_->createPromise(
|
|
340
|
+
[this, b64, playbackSpeed](std::shared_ptr<Promise> promise) {
|
|
341
|
+
std::thread([this, b64, playbackSpeed, promise = std::move(promise)]() {
|
|
342
|
+
auto results = context_->decodeWithPCMInBase64(b64, playbackSpeed);
|
|
343
|
+
|
|
344
|
+
if (!results) {
|
|
345
|
+
promise->reject("Failed to decode audio data source.");
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
auto audioBufferHostObject =
|
|
350
|
+
std::make_shared<AudioBufferHostObject>(results);
|
|
351
|
+
|
|
352
|
+
promise->resolve([audioBufferHostObject = std::move(
|
|
353
|
+
audioBufferHostObject)](jsi::Runtime &runtime) {
|
|
354
|
+
auto jsiObject = jsi::Object::createFromHostObject(
|
|
355
|
+
runtime, audioBufferHostObject);
|
|
356
|
+
jsiObject.setExternalMemoryPressure(
|
|
357
|
+
runtime, audioBufferHostObject->getSizeInBytes());
|
|
358
|
+
return jsiObject;
|
|
359
|
+
});
|
|
360
|
+
}).detach();
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
return promise;
|
|
364
|
+
}
|
|
265
365
|
} // namespace audioapi
|
|
@@ -41,6 +41,9 @@ class BaseAudioContextHostObject : public JsiHostObject {
|
|
|
41
41
|
JSI_HOST_FUNCTION_DECL(createBuffer);
|
|
42
42
|
JSI_HOST_FUNCTION_DECL(createPeriodicWave);
|
|
43
43
|
JSI_HOST_FUNCTION_DECL(createAnalyser);
|
|
44
|
+
JSI_HOST_FUNCTION_DECL(decodeAudioDataSource);
|
|
45
|
+
JSI_HOST_FUNCTION_DECL(decodeAudioData);
|
|
46
|
+
JSI_HOST_FUNCTION_DECL(decodePCMAudioDataInBase64);
|
|
44
47
|
|
|
45
48
|
std::shared_ptr<BaseAudioContext> context_;
|
|
46
49
|
|