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.
Files changed (106) hide show
  1. package/android/src/main/cpp/audioapi/android/core/{utils/AudioDecoder.cpp → AudioDecoder.cpp} +75 -79
  2. package/android/src/main/jniLibs/arm64-v8a/libavcodec.so +0 -0
  3. package/android/src/main/jniLibs/arm64-v8a/libavformat.so +0 -0
  4. package/android/src/main/jniLibs/arm64-v8a/libavutil.so +0 -0
  5. package/android/src/main/jniLibs/arm64-v8a/libswresample.so +0 -0
  6. package/android/src/main/jniLibs/armeabi-v7a/libavcodec.so +0 -0
  7. package/android/src/main/jniLibs/armeabi-v7a/libavformat.so +0 -0
  8. package/android/src/main/jniLibs/armeabi-v7a/libavutil.so +0 -0
  9. package/android/src/main/jniLibs/armeabi-v7a/libswresample.so +0 -0
  10. package/android/src/main/jniLibs/x86/libavcodec.so +0 -0
  11. package/android/src/main/jniLibs/x86/libavformat.so +0 -0
  12. package/android/src/main/jniLibs/x86/libavutil.so +0 -0
  13. package/android/src/main/jniLibs/x86/libswresample.so +0 -0
  14. package/android/src/main/jniLibs/x86_64/libavcodec.so +0 -0
  15. package/android/src/main/jniLibs/x86_64/libavformat.so +0 -0
  16. package/android/src/main/jniLibs/x86_64/libavutil.so +0 -0
  17. package/android/src/main/jniLibs/x86_64/libswresample.so +0 -0
  18. package/common/cpp/audioapi/AudioAPIModuleInstaller.h +43 -124
  19. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +101 -1
  20. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +3 -0
  21. package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.cpp +3 -8
  22. package/common/cpp/audioapi/core/AudioContext.cpp +2 -0
  23. package/common/cpp/audioapi/core/BaseAudioContext.cpp +35 -0
  24. package/common/cpp/audioapi/core/BaseAudioContext.h +12 -4
  25. package/common/cpp/audioapi/core/OfflineAudioContext.cpp +2 -0
  26. package/common/cpp/audioapi/core/effects/WorkletNode.cpp +16 -28
  27. package/common/cpp/audioapi/core/effects/WorkletNode.h +2 -3
  28. package/common/cpp/audioapi/core/effects/WorkletProcessingNode.cpp +5 -6
  29. package/common/cpp/audioapi/core/sources/AudioBuffer.h +1 -0
  30. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +0 -4
  31. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +0 -1
  32. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +0 -2
  33. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +0 -4
  34. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +0 -1
  35. package/common/cpp/audioapi/core/sources/StreamerNode.cpp +16 -6
  36. package/common/cpp/audioapi/core/sources/StreamerNode.h +3 -1
  37. package/common/cpp/audioapi/core/sources/WorkletSourceNode.cpp +2 -3
  38. package/common/cpp/audioapi/core/utils/AudioDecoder.h +91 -36
  39. package/common/cpp/audioapi/core/utils/Constants.h +0 -4
  40. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +5 -1
  41. package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64/libavcodec.framework/libavcodec +0 -0
  42. package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64_x86_64-simulator/libavcodec.framework/libavcodec +0 -0
  43. package/common/cpp/audioapi/external/libavformat.xcframework/Info.plist +5 -5
  44. package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64/libavformat.framework/libavformat +0 -0
  45. package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64_x86_64-simulator/libavformat.framework/libavformat +0 -0
  46. package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64/libavutil.framework/libavutil +0 -0
  47. package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64_x86_64-simulator/libavutil.framework/libavutil +0 -0
  48. package/common/cpp/audioapi/external/libswresample.xcframework/Info.plist +5 -5
  49. package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64/libswresample.framework/libswresample +0 -0
  50. package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64_x86_64-simulator/libswresample.framework/libswresample +0 -0
  51. package/common/cpp/audioapi/jsi/AudioArrayBuffer.cpp +2 -2
  52. package/common/cpp/audioapi/jsi/AudioArrayBuffer.h +10 -11
  53. package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.cpp +282 -241
  54. package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.h +19 -57
  55. package/common/cpp/audioapi/libs/ffmpeg/ffmpeg_setup.sh +1 -1
  56. package/common/cpp/audioapi/utils/AudioBus.cpp +4 -0
  57. package/common/cpp/audioapi/utils/AudioBus.h +1 -0
  58. package/common/cpp/test/CMakeLists.txt +8 -5
  59. package/common/cpp/test/RunTests.sh +2 -2
  60. package/common/cpp/test/{AudioParamTest.cpp → src/AudioParamTest.cpp} +1 -1
  61. package/common/cpp/test/src/ConstantSourceTest.cpp +64 -0
  62. package/common/cpp/test/{GainTest.cpp → src/GainTest.cpp} +11 -10
  63. package/common/cpp/test/{MockAudioEventHandlerRegistry.h → src/MockAudioEventHandlerRegistry.h} +4 -2
  64. package/common/cpp/test/{OscillatorTest.cpp → src/OscillatorTest.cpp} +6 -4
  65. package/common/cpp/test/{StereoPannerTest.cpp → src/StereoPannerTest.cpp} +1 -1
  66. package/ios/audioapi/ios/core/AudioDecoder.mm +156 -0
  67. package/lib/commonjs/api.js +1 -21
  68. package/lib/commonjs/api.js.map +1 -1
  69. package/lib/commonjs/core/BaseAudioContext.js +18 -11
  70. package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
  71. package/lib/module/api.js +1 -3
  72. package/lib/module/api.js.map +1 -1
  73. package/lib/module/core/BaseAudioContext.js +18 -11
  74. package/lib/module/core/BaseAudioContext.js.map +1 -1
  75. package/lib/typescript/api.d.ts +1 -5
  76. package/lib/typescript/api.d.ts.map +1 -1
  77. package/lib/typescript/core/BaseAudioContext.d.ts +6 -3
  78. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  79. package/lib/typescript/interfaces.d.ts +3 -10
  80. package/lib/typescript/interfaces.d.ts.map +1 -1
  81. package/package.json +1 -1
  82. package/src/api.ts +0 -10
  83. package/src/core/BaseAudioContext.ts +29 -26
  84. package/src/interfaces.ts +6 -26
  85. package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.cpp +0 -133
  86. package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.h +0 -28
  87. package/common/cpp/audioapi/HostObjects/utils/AudioStretcherHostObject.cpp +0 -58
  88. package/common/cpp/audioapi/HostObjects/utils/AudioStretcherHostObject.h +0 -26
  89. package/common/cpp/audioapi/core/types/AudioFormat.h +0 -16
  90. package/common/cpp/audioapi/core/utils/AudioStretcher.cpp +0 -75
  91. package/common/cpp/audioapi/core/utils/AudioStretcher.h +0 -30
  92. package/ios/audioapi/ios/core/utils/AudioDecoder.mm +0 -160
  93. package/lib/commonjs/core/AudioDecoder.js +0 -48
  94. package/lib/commonjs/core/AudioDecoder.js.map +0 -1
  95. package/lib/commonjs/core/AudioStretcher.js +0 -31
  96. package/lib/commonjs/core/AudioStretcher.js.map +0 -1
  97. package/lib/module/core/AudioDecoder.js +0 -42
  98. package/lib/module/core/AudioDecoder.js.map +0 -1
  99. package/lib/module/core/AudioStretcher.js +0 -26
  100. package/lib/module/core/AudioStretcher.js.map +0 -1
  101. package/lib/typescript/core/AudioDecoder.d.ts +0 -4
  102. package/lib/typescript/core/AudioDecoder.d.ts.map +0 -1
  103. package/lib/typescript/core/AudioStretcher.d.ts +0 -3
  104. package/lib/typescript/core/AudioStretcher.d.ts.map +0 -1
  105. package/src/core/AudioDecoder.ts +0 -78
  106. package/src/core/AudioStretcher.ts +0 -43
@@ -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<float> AudioDecoder::readAllPcmFrames(
22
+ std::vector<int16_t> AudioDecoder::readAllPcmFrames(
24
23
  ma_decoder &decoder,
25
- int outputChannels) {
26
- std::vector<float> buffer;
27
- std::vector<float> temp(CHUNK_SIZE * outputChannels);
28
- ma_uint64 outFramesRead = 0;
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 * outputChannels);
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<AudioBuffer> AudioDecoder::makeAudioBufferFromFloatBuffer(
54
- const std::vector<float> &buffer,
55
- float outputSampleRate,
56
- int outputChannels) {
57
- if (buffer.empty()) {
58
- return nullptr;
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 < outputChannels; ++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 * outputChannels + ch];
59
+ channelData[i] = int16ToFloat(buffer[i * numChannels + ch]);
69
60
  }
70
61
  }
71
- return std::make_shared<AudioBuffer>(audioBus);
62
+ return audioBus;
72
63
  }
73
64
 
74
- std::shared_ptr<AudioBuffer> AudioDecoder::decodeWithFilePath(
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
- auto buffer =
80
- ffmpegdecoder::decodeWithFilePath(path, static_cast<int>(sampleRate));
81
- if (buffer == nullptr) {
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
- ma_decoder_config_init(ma_format_f32, 0, static_cast<int>(sampleRate));
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
- auto outputSampleRate = static_cast<float>(decoder.outputSampleRate);
112
- auto outputChannels = static_cast<int>(decoder.outputChannels);
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 makeAudioBufferFromFloatBuffer(
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<AudioBuffer> AudioDecoder::decodeWithMemoryBlock(
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
- auto buffer = ffmpegdecoder::decodeWithMemoryBlock(
132
- data, size, static_cast<int>(sampleRate));
133
- if (buffer == nullptr) {
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
- ma_decoder_config_init(ma_format_f32, 0, static_cast<int>(sampleRate));
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
- auto outputSampleRate = static_cast<float>(decoder.outputSampleRate);
161
- auto outputChannels = static_cast<int>(decoder.outputChannels);
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 makeAudioBufferFromFloatBuffer(
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<AudioBuffer> AudioDecoder::decodeWithPCMInBase64(
169
+ std::shared_ptr<AudioBus> AudioDecoder::decodeWithPCMInBase64(
173
170
  const std::string &data,
174
- float inputSampleRate,
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 numFramesDecoded =
180
- decodedData.size() / (inputChannelCount * sizeof(int16_t));
175
+ size_t framesDecoded = decodedData.size() / 2;
181
176
 
182
- auto audioBus = std::make_shared<AudioBus>(
183
- numFramesDecoded, inputChannelCount, inputSampleRate);
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
- for (int ch = 0; ch < inputChannelCount; ++ch) {
186
- auto channelData = audioBus->getChannel(ch)->getData();
183
+ changePlaybackSpeedIfNeeded(buffer, framesDecoded, 1, playbackSpeed);
184
+ auto outputFrames = buffer.size();
187
185
 
188
- for (size_t i = 0; i < numFramesDecoded; ++i) {
189
- size_t offset;
190
- if (interleaved) {
191
- // Ch1, Ch2, Ch1, Ch2, ...
192
- offset = (i * inputChannelCount + ch) * sizeof(int16_t);
193
- } else {
194
- // Ch1, Ch1, Ch1, ..., Ch2, Ch2, Ch2, ...
195
- offset = (ch * numFramesDecoded + i) * sizeof(int16_t);
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
- return std::make_shared<AudioBuffer>(audioBus);
196
+
197
+ return audioBus;
202
198
  }
203
199
 
204
200
  } // namespace audioapi
@@ -1,17 +1,15 @@
1
1
  #pragma once
2
2
 
3
- #include <audioapi/HostObjects/AudioContextHostObject.h>
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/jsi/JsiPromise.h>
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
- jsi::Runtime *jsiRuntime,
28
- const std::shared_ptr<react::CallInvoker> &jsCallInvoker,
29
- const std::shared_ptr<AudioEventHandlerRegistry>
30
- &audioEventHandlerRegistry,
31
- std::shared_ptr<worklets::WorkletRuntime> uiRuntime = nullptr) {
32
- auto createAudioContext = getCreateAudioContextFunction(
33
- jsiRuntime, jsCallInvoker, audioEventHandlerRegistry, uiRuntime);
34
- auto createAudioRecorder =
35
- getCreateAudioRecorderFunction(jsiRuntime, audioEventHandlerRegistry);
36
- auto createOfflineAudioContext = getCreateOfflineAudioContextFunction(
37
- jsiRuntime, jsCallInvoker, audioEventHandlerRegistry, uiRuntime);
38
- auto createAudioDecoder =
39
- getCreateAudioDecoderFunction(jsiRuntime, jsCallInvoker);
40
- auto createAudioStretcher =
41
- getCreateAudioStretcherFunction(jsiRuntime, jsCallInvoker);
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
- jsi::Runtime *jsiRuntime,
67
- const std::shared_ptr<react::CallInvoker> &jsCallInvoker,
68
- const std::shared_ptr<AudioEventHandlerRegistry>
69
- &audioEventHandlerRegistry,
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
- sampleRate,
95
- initSuspended,
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
- jsi::Runtime *jsiRuntime,
109
- const std::shared_ptr<react::CallInvoker> &jsCallInvoker,
110
- const std::shared_ptr<AudioEventHandlerRegistry>
111
- &audioEventHandlerRegistry,
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
- auto numberOfChannels = static_cast<int>(args[0].getNumber());
123
- auto length = static_cast<size_t>(args[1].getNumber());
124
- auto sampleRate = static_cast<float>(args[2].getNumber());
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
- numberOfChannels,
137
- length,
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
- jsi::Runtime *jsiRuntime,
152
- const std::shared_ptr<AudioEventHandlerRegistry>
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
- options.getProperty(runtime, "sampleRate").getNumber());
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