react-native-audio-api 0.9.0 → 0.10.0-nightly-971a6b4-20251010

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 (60) hide show
  1. package/android/src/main/cpp/audioapi/android/core/{AudioDecoder.cpp → utils/AudioDecoder.cpp} +79 -75
  2. package/common/cpp/audioapi/AudioAPIModuleInstaller.h +124 -43
  3. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +1 -101
  4. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +0 -3
  5. package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.cpp +133 -0
  6. package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.h +28 -0
  7. package/common/cpp/audioapi/HostObjects/utils/AudioStretcherHostObject.cpp +58 -0
  8. package/common/cpp/audioapi/HostObjects/utils/AudioStretcherHostObject.h +26 -0
  9. package/common/cpp/audioapi/core/AudioContext.cpp +0 -2
  10. package/common/cpp/audioapi/core/BaseAudioContext.cpp +0 -35
  11. package/common/cpp/audioapi/core/BaseAudioContext.h +4 -12
  12. package/common/cpp/audioapi/core/OfflineAudioContext.cpp +0 -2
  13. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +0 -4
  14. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +0 -1
  15. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +0 -2
  16. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +0 -4
  17. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +0 -1
  18. package/common/cpp/audioapi/core/types/AudioFormat.h +16 -0
  19. package/common/cpp/audioapi/core/utils/AudioDecoder.h +36 -91
  20. package/common/cpp/audioapi/core/utils/AudioStretcher.cpp +75 -0
  21. package/common/cpp/audioapi/core/utils/AudioStretcher.h +30 -0
  22. package/common/cpp/audioapi/core/utils/Constants.h +4 -0
  23. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +5 -1
  24. package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.cpp +241 -282
  25. package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.h +57 -19
  26. package/common/cpp/test/CMakeLists.txt +1 -1
  27. package/ios/audioapi/ios/core/utils/AudioDecoder.mm +160 -0
  28. package/lib/commonjs/api.js +21 -1
  29. package/lib/commonjs/api.js.map +1 -1
  30. package/lib/commonjs/core/AudioDecoder.js +48 -0
  31. package/lib/commonjs/core/AudioDecoder.js.map +1 -0
  32. package/lib/commonjs/core/AudioStretcher.js +31 -0
  33. package/lib/commonjs/core/AudioStretcher.js.map +1 -0
  34. package/lib/commonjs/core/BaseAudioContext.js +11 -18
  35. package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
  36. package/lib/module/api.js +3 -1
  37. package/lib/module/api.js.map +1 -1
  38. package/lib/module/core/AudioDecoder.js +42 -0
  39. package/lib/module/core/AudioDecoder.js.map +1 -0
  40. package/lib/module/core/AudioStretcher.js +26 -0
  41. package/lib/module/core/AudioStretcher.js.map +1 -0
  42. package/lib/module/core/BaseAudioContext.js +11 -18
  43. package/lib/module/core/BaseAudioContext.js.map +1 -1
  44. package/lib/typescript/api.d.ts +5 -1
  45. package/lib/typescript/api.d.ts.map +1 -1
  46. package/lib/typescript/core/AudioDecoder.d.ts +4 -0
  47. package/lib/typescript/core/AudioDecoder.d.ts.map +1 -0
  48. package/lib/typescript/core/AudioStretcher.d.ts +3 -0
  49. package/lib/typescript/core/AudioStretcher.d.ts.map +1 -0
  50. package/lib/typescript/core/BaseAudioContext.d.ts +3 -6
  51. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  52. package/lib/typescript/interfaces.d.ts +10 -3
  53. package/lib/typescript/interfaces.d.ts.map +1 -1
  54. package/package.json +1 -1
  55. package/src/api.ts +10 -0
  56. package/src/core/AudioDecoder.ts +78 -0
  57. package/src/core/AudioStretcher.ts +43 -0
  58. package/src/core/BaseAudioContext.ts +26 -29
  59. package/src/interfaces.ts +26 -6
  60. package/ios/audioapi/ios/core/AudioDecoder.mm +0 -156
@@ -1,3 +1,4 @@
1
+ #include <audioapi/core/sources/AudioBuffer.h>
1
2
  #include <audioapi/core/utils/AudioDecoder.h>
2
3
  #include <audioapi/dsp/VectorMath.h>
3
4
  #include <audioapi/libs/base64/base64.h>
@@ -5,28 +6,28 @@
5
6
  #include <audioapi/utils/AudioBus.h>
6
7
 
7
8
  #define MINIAUDIO_IMPLEMENTATION
9
+ #include <audioapi/libs/miniaudio/decoders/libopus/miniaudio_libopus.h>
10
+ #include <audioapi/libs/miniaudio/decoders/libvorbis/miniaudio_libvorbis.h>
8
11
  #include <audioapi/libs/miniaudio/miniaudio.h>
9
12
 
10
13
  #ifndef AUDIO_API_TEST_SUITE
11
14
  #include <android/log.h>
12
15
  #include <audioapi/libs/ffmpeg/FFmpegDecoding.h>
13
16
  #endif
14
- #include <audioapi/libs/miniaudio/decoders/libopus/miniaudio_libopus.h>
15
- #include <audioapi/libs/miniaudio/decoders/libvorbis/miniaudio_libvorbis.h>
16
17
 
17
18
  namespace audioapi {
18
19
 
19
20
  // Decoding audio in fixed-size chunks because total frame count can't be
20
21
  // determined in advance. Note: ma_decoder_get_length_in_pcm_frames() always
21
22
  // returns 0 for Vorbis decoders.
22
- std::vector<int16_t> AudioDecoder::readAllPcmFrames(
23
+ std::vector<float> AudioDecoder::readAllPcmFrames(
23
24
  ma_decoder &decoder,
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;
25
+ int outputChannels) {
26
+ std::vector<float> buffer;
27
+ std::vector<float> temp(CHUNK_SIZE * outputChannels);
28
+ ma_uint64 outFramesRead = 0;
29
29
 
30
+ #ifndef AUDIO_API_TEST_SUITE
30
31
  while (true) {
31
32
  ma_uint64 tempFramesDecoded = 0;
32
33
  ma_decoder_read_pcm_frames(
@@ -38,38 +39,46 @@ std::vector<int16_t> AudioDecoder::readAllPcmFrames(
38
39
  buffer.insert(
39
40
  buffer.end(),
40
41
  temp.data(),
41
- temp.data() + tempFramesDecoded * numChannels);
42
+ temp.data() + tempFramesDecoded * outputChannels);
42
43
  outFramesRead += tempFramesDecoded;
43
44
  }
44
45
 
46
+ if (outFramesRead == 0) {
47
+ __android_log_print(ANDROID_LOG_ERROR, "AudioDecoder", "Failed to decode");
48
+ }
49
+ #endif
45
50
  return buffer;
46
51
  }
47
52
 
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);
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
+ }
55
60
 
56
- for (int ch = 0; ch < numChannels; ++ch) {
61
+ auto outputFrames = buffer.size() / outputChannels;
62
+ auto audioBus = std::make_shared<AudioBus>(
63
+ outputFrames, outputChannels, outputSampleRate);
64
+
65
+ for (int ch = 0; ch < outputChannels; ++ch) {
57
66
  auto channelData = audioBus->getChannel(ch)->getData();
58
67
  for (int i = 0; i < outputFrames; ++i) {
59
- channelData[i] = int16ToFloat(buffer[i * numChannels + ch]);
68
+ channelData[i] = buffer[i * outputChannels + ch];
60
69
  }
61
70
  }
62
- return audioBus;
71
+ return std::make_shared<AudioBuffer>(audioBus);
63
72
  }
64
73
 
65
- std::shared_ptr<AudioBus> AudioDecoder::decodeWithFilePath(
66
- const std::string &path) const {
74
+ std::shared_ptr<AudioBuffer> AudioDecoder::decodeWithFilePath(
75
+ const std::string &path,
76
+ float sampleRate) {
67
77
  #ifndef AUDIO_API_TEST_SUITE
68
- std::vector<int16_t> buffer;
69
78
  if (AudioDecoder::pathHasExtension(path, {".mp4", ".m4a", ".aac"})) {
70
- buffer = ffmpegdecoding::decodeWithFilePath(
71
- path, numChannels_, static_cast<int>(sampleRate_));
72
- if (buffer.empty()) {
79
+ auto buffer =
80
+ ffmpegdecoder::decodeWithFilePath(path, static_cast<int>(sampleRate));
81
+ if (buffer == nullptr) {
73
82
  __android_log_print(
74
83
  ANDROID_LOG_ERROR,
75
84
  "AudioDecoder",
@@ -77,11 +86,11 @@ std::shared_ptr<AudioBus> AudioDecoder::decodeWithFilePath(
77
86
  path.c_str());
78
87
  return nullptr;
79
88
  }
80
- return makeAudioBusFromInt16Buffer(buffer, numChannels_, sampleRate_);
89
+ return buffer;
81
90
  }
82
91
  ma_decoder decoder;
83
- ma_decoder_config config = ma_decoder_config_init(
84
- ma_format_s16, numChannels_, static_cast<int>(sampleRate_));
92
+ ma_decoder_config config =
93
+ ma_decoder_config_init(ma_format_f32, 0, static_cast<int>(sampleRate));
85
94
  ma_decoding_backend_vtable *customBackends[] = {
86
95
  ma_decoding_backend_libvorbis, ma_decoding_backend_libopus};
87
96
 
@@ -99,41 +108,38 @@ std::shared_ptr<AudioBus> AudioDecoder::decodeWithFilePath(
99
108
  return nullptr;
100
109
  }
101
110
 
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
- }
111
+ auto outputSampleRate = static_cast<float>(decoder.outputSampleRate);
112
+ auto outputChannels = static_cast<int>(decoder.outputChannels);
109
113
 
114
+ std::vector<float> buffer = readAllPcmFrames(decoder, outputChannels);
110
115
  ma_decoder_uninit(&decoder);
111
- return makeAudioBusFromInt16Buffer(buffer, numChannels_, sampleRate_);
116
+ return makeAudioBufferFromFloatBuffer(
117
+ buffer, outputSampleRate, outputChannels);
112
118
  #else
113
119
  return nullptr;
114
120
  #endif
115
121
  }
116
122
 
117
- std::shared_ptr<AudioBus> AudioDecoder::decodeWithMemoryBlock(
123
+ std::shared_ptr<AudioBuffer> AudioDecoder::decodeWithMemoryBlock(
118
124
  const void *data,
119
- size_t size) const {
125
+ size_t size,
126
+ float sampleRate) {
120
127
  #ifndef AUDIO_API_TEST_SUITE
121
- std::vector<int16_t> buffer;
122
128
  const AudioFormat format = AudioDecoder::detectAudioFormat(data, size);
123
129
  if (format == AudioFormat::MP4 || format == AudioFormat::M4A ||
124
130
  format == AudioFormat::AAC) {
125
- buffer = ffmpegdecoding::decodeWithMemoryBlock(
126
- data, size, numChannels_, sampleRate_);
127
- if (buffer.empty()) {
131
+ auto buffer = ffmpegdecoder::decodeWithMemoryBlock(
132
+ data, size, static_cast<int>(sampleRate));
133
+ if (buffer == nullptr) {
128
134
  __android_log_print(
129
135
  ANDROID_LOG_ERROR, "AudioDecoder", "Failed to decode with FFmpeg");
130
136
  return nullptr;
131
137
  }
132
- return makeAudioBusFromInt16Buffer(buffer, numChannels_, sampleRate_);
138
+ return buffer;
133
139
  }
134
140
  ma_decoder decoder;
135
- ma_decoder_config config = ma_decoder_config_init(
136
- ma_format_s16, numChannels_, static_cast<int>(sampleRate_));
141
+ ma_decoder_config config =
142
+ ma_decoder_config_init(ma_format_f32, 0, static_cast<int>(sampleRate));
137
143
 
138
144
  ma_decoding_backend_vtable *customBackends[] = {
139
145
  ma_decoding_backend_libvorbis, ma_decoding_backend_libopus};
@@ -151,50 +157,48 @@ std::shared_ptr<AudioBus> AudioDecoder::decodeWithMemoryBlock(
151
157
  return nullptr;
152
158
  }
153
159
 
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
- }
160
+ auto outputSampleRate = static_cast<float>(decoder.outputSampleRate);
161
+ auto outputChannels = static_cast<int>(decoder.outputChannels);
161
162
 
163
+ std::vector<float> buffer = readAllPcmFrames(decoder, outputChannels);
162
164
  ma_decoder_uninit(&decoder);
163
- return makeAudioBusFromInt16Buffer(buffer, numChannels_, sampleRate_);
165
+ return makeAudioBufferFromFloatBuffer(
166
+ buffer, outputSampleRate, outputChannels);
164
167
  #else
165
168
  return nullptr;
166
169
  #endif
167
170
  }
168
171
 
169
- std::shared_ptr<AudioBus> AudioDecoder::decodeWithPCMInBase64(
172
+ std::shared_ptr<AudioBuffer> AudioDecoder::decodeWithPCMInBase64(
170
173
  const std::string &data,
171
- float playbackSpeed) const {
174
+ float inputSampleRate,
175
+ int inputChannelCount,
176
+ bool interleaved) {
172
177
  auto decodedData = base64_decode(data, false);
173
-
174
178
  const auto uint8Data = reinterpret_cast<uint8_t *>(decodedData.data());
175
- size_t framesDecoded = decodedData.size() / 2;
176
-
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
- }
179
+ size_t numFramesDecoded =
180
+ decodedData.size() / (inputChannelCount * sizeof(int16_t));
182
181
 
183
- changePlaybackSpeedIfNeeded(buffer, framesDecoded, 1, playbackSpeed);
184
- auto outputFrames = buffer.size();
182
+ auto audioBus = std::make_shared<AudioBus>(
183
+ numFramesDecoded, inputChannelCount, inputSampleRate);
185
184
 
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();
185
+ for (int ch = 0; ch < inputChannelCount; ++ch) {
186
+ auto channelData = audioBus->getChannel(ch)->getData();
190
187
 
191
- for (size_t i = 0; i < outputFrames; ++i) {
192
- auto sample = int16ToFloat(buffer[i]);
193
- leftChannelData[i] = sample;
194
- rightChannelData[i] = sample;
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
+ }
195
200
  }
196
-
197
- return audioBus;
201
+ return std::make_shared<AudioBuffer>(audioBus);
198
202
  }
199
203
 
200
204
  } // namespace audioapi
@@ -1,15 +1,17 @@
1
1
  #pragma once
2
2
 
3
- #include <audioapi/jsi/JsiPromise.h>
4
- #include <audioapi/core/AudioContext.h>
5
- #include <audioapi/core/OfflineAudioContext.h>
6
- #include <audioapi/core/inputs/AudioRecorder.h>
7
3
  #include <audioapi/HostObjects/AudioContextHostObject.h>
8
4
  #include <audioapi/HostObjects/OfflineAudioContextHostObject.h>
9
5
  #include <audioapi/HostObjects/inputs/AudioRecorderHostObject.h>
6
+ #include <audioapi/HostObjects/utils/AudioDecoderHostObject.h>
7
+ #include <audioapi/HostObjects/utils/AudioStretcherHostObject.h>
8
+ #include <audioapi/core/AudioContext.h>
9
+ #include <audioapi/core/OfflineAudioContext.h>
10
+ #include <audioapi/core/inputs/AudioRecorder.h>
11
+ #include <audioapi/jsi/JsiPromise.h>
10
12
 
11
- #include <audioapi/events/AudioEventHandlerRegistry.h>
12
13
  #include <audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.h>
14
+ #include <audioapi/events/AudioEventHandlerRegistry.h>
13
15
 
14
16
  #include <audioapi/core/utils/worklets/SafeIncludes.h>
15
17
 
@@ -22,29 +24,50 @@ using namespace facebook;
22
24
  class AudioAPIModuleInstaller {
23
25
  public:
24
26
  static void injectJSIBindings(
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));
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));
40
62
  }
41
63
 
42
64
  private:
43
65
  static jsi::Function getCreateAudioContextFunction(
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) {
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) {
48
71
  return jsi::Function::createFromHostFunction(
49
72
  *jsiRuntime,
50
73
  jsi::PropNameID::forAscii(*jsiRuntime, "createAudioContext"),
@@ -67,9 +90,14 @@ class AudioAPIModuleInstaller {
67
90
  auto runtimeRegistry = RuntimeRegistry{};
68
91
  #endif
69
92
 
70
- audioContext = std::make_shared<AudioContext>(sampleRate, initSuspended, audioEventHandlerRegistry, runtimeRegistry);
71
- auto audioContextHostObject = std::make_shared<AudioContextHostObject>(
72
- audioContext, &runtime, jsCallInvoker);
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);
73
101
 
74
102
  return jsi::Object::createFromHostObject(
75
103
  runtime, audioContextHostObject);
@@ -77,10 +105,11 @@ class AudioAPIModuleInstaller {
77
105
  }
78
106
 
79
107
  static jsi::Function getCreateOfflineAudioContextFunction(
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) {
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) {
84
113
  return jsi::Function::createFromHostFunction(
85
114
  *jsiRuntime,
86
115
  jsi::PropNameID::forAscii(*jsiRuntime, "createOfflineAudioContext"),
@@ -90,9 +119,9 @@ class AudioAPIModuleInstaller {
90
119
  const jsi::Value &thisValue,
91
120
  const jsi::Value *args,
92
121
  size_t count) -> jsi::Value {
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());
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());
96
125
 
97
126
  #if RN_AUDIO_API_ENABLE_WORKLETS
98
127
  auto runtimeRegistry = RuntimeRegistry{
@@ -103,9 +132,15 @@ class AudioAPIModuleInstaller {
103
132
  auto runtimeRegistry = RuntimeRegistry{};
104
133
  #endif
105
134
 
106
- auto offlineAudioContext = std::make_shared<OfflineAudioContext>(numberOfChannels, length, sampleRate, audioEventHandlerRegistry, runtimeRegistry);
107
- auto audioContextHostObject = std::make_shared<OfflineAudioContextHostObject>(
108
- offlineAudioContext, &runtime, jsCallInvoker);
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);
109
144
 
110
145
  return jsi::Object::createFromHostObject(
111
146
  runtime, audioContextHostObject);
@@ -113,8 +148,9 @@ class AudioAPIModuleInstaller {
113
148
  }
114
149
 
115
150
  static jsi::Function getCreateAudioRecorderFunction(
116
- jsi::Runtime *jsiRuntime,
117
- const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry) {
151
+ jsi::Runtime *jsiRuntime,
152
+ const std::shared_ptr<AudioEventHandlerRegistry>
153
+ &audioEventHandlerRegistry) {
118
154
  return jsi::Function::createFromHostFunction(
119
155
  *jsiRuntime,
120
156
  jsi::PropNameID::forAscii(*jsiRuntime, "createAudioRecorder"),
@@ -126,12 +162,57 @@ class AudioAPIModuleInstaller {
126
162
  size_t count) -> jsi::Value {
127
163
  auto options = args[0].getObject(runtime);
128
164
 
129
- auto sampleRate = static_cast<float>(options.getProperty(runtime, "sampleRate").getNumber());
130
- auto bufferLength = static_cast<int>(options.getProperty(runtime, "bufferLengthInSamples").getNumber());
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());
131
170
 
132
- auto audioRecorderHostObject = std::make_shared<AudioRecorderHostObject>(audioEventHandlerRegistry, sampleRate, bufferLength);
171
+ auto audioRecorderHostObject =
172
+ std::make_shared<AudioRecorderHostObject>(
173
+ audioEventHandlerRegistry, sampleRate, bufferLength);
133
174
 
134
- return jsi::Object::createFromHostObject(runtime, audioRecorderHostObject);
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);
135
216
  });
136
217
  }
137
218
  };
@@ -49,11 +49,7 @@ 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),
53
- JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, decodeAudioData),
54
- JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, decodeAudioDataSource),
55
- JSI_EXPORT_FUNCTION(
56
- BaseAudioContextHostObject, decodePCMAudioDataInBase64));
52
+ JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createAnalyser));
57
53
  }
58
54
 
59
55
  JSI_PROPERTY_GETTER_IMPL(BaseAudioContextHostObject, destination) {
@@ -266,100 +262,4 @@ JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createAnalyser) {
266
262
  auto analyserHostObject = std::make_shared<AnalyserNodeHostObject>(analyser);
267
263
  return jsi::Object::createFromHostObject(runtime, analyserHostObject);
268
264
  }
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
- }
365
265
  } // namespace audioapi
@@ -41,9 +41,6 @@ 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);
47
44
 
48
45
  std::shared_ptr<BaseAudioContext> context_;
49
46