react-native-audio-api 0.5.1 → 0.5.3
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/AudioDecoder.cpp +0 -35
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +2 -2
- package/common/cpp/audioapi/HostObjects/AudioBufferHostObject.h +4 -2
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +11 -3
- package/common/cpp/audioapi/core/AudioNode.cpp +3 -1
- package/common/cpp/audioapi/core/AudioNode.h +1 -1
- package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +1 -1
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +22 -1
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +1 -0
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +2 -2
- package/common/cpp/audioapi/dsp/VectorMath.cpp +1 -0
- package/common/cpp/audioapi/dsp/VectorMath.h +1 -0
- package/common/cpp/audioapi/jsi/JsiHostObject.cpp +26 -0
- package/common/cpp/audioapi/jsi/JsiHostObject.h +1 -0
- package/ios/audioapi/ios/core/AudioPlayer.h +3 -0
- package/ios/audioapi/ios/core/AudioPlayer.m +55 -11
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +3 -8
- package/package.json +1 -1
|
@@ -109,39 +109,4 @@ std::shared_ptr<AudioBus> AudioDecoder::decodeWithMemoryBlock(
|
|
|
109
109
|
return audioBus;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
// std::shared_ptr<AudioBus> AudioDecoder::decode(ma_decoder &decoder) const {
|
|
113
|
-
// ma_uint64 totalFrameCount;
|
|
114
|
-
// ma_decoder_get_length_in_pcm_frames(&decoder, &totalFrameCount);
|
|
115
|
-
//
|
|
116
|
-
// auto audioBus = std::make_shared<AudioBus>(
|
|
117
|
-
// static_cast<int>(totalFrameCount), 2, sampleRate_);
|
|
118
|
-
// auto *buffer = new float[totalFrameCount * 2];
|
|
119
|
-
//
|
|
120
|
-
// ma_uint64 framesDecoded;
|
|
121
|
-
// ma_decoder_read_pcm_frames(&decoder, buffer, totalFrameCount,
|
|
122
|
-
// &framesDecoded); if (framesDecoded == 0) {
|
|
123
|
-
// __android_log_print(
|
|
124
|
-
// ANDROID_LOG_ERROR,
|
|
125
|
-
// "AudioDecoder",
|
|
126
|
-
// "Failed to decode");
|
|
127
|
-
//
|
|
128
|
-
// delete[] buffer;
|
|
129
|
-
// ma_decoder_uninit(&decoder);
|
|
130
|
-
//
|
|
131
|
-
// return nullptr;
|
|
132
|
-
// }
|
|
133
|
-
//
|
|
134
|
-
// for (int i = 0; i < decoder.outputChannels; ++i) {
|
|
135
|
-
// auto channelData = audioBus->getChannel(i)->getData();
|
|
136
|
-
//
|
|
137
|
-
// for (ma_uint64 j = 0; j < framesDecoded; ++j) {
|
|
138
|
-
// channelData[j] = buffer[j * decoder.outputChannels + i];
|
|
139
|
-
// }
|
|
140
|
-
// }
|
|
141
|
-
//
|
|
142
|
-
// delete[] buffer;
|
|
143
|
-
// ma_decoder_uninit(&decoder);
|
|
144
|
-
//
|
|
145
|
-
// return audioBus;
|
|
146
|
-
// }
|
|
147
112
|
} // namespace audioapi
|
|
@@ -14,7 +14,7 @@ AudioPlayer::AudioPlayer(
|
|
|
14
14
|
builder.setSharingMode(SharingMode::Exclusive)
|
|
15
15
|
->setFormat(AudioFormat::Float)
|
|
16
16
|
->setFormatConversionAllowed(true)
|
|
17
|
-
->setPerformanceMode(PerformanceMode::
|
|
17
|
+
->setPerformanceMode(PerformanceMode::None)
|
|
18
18
|
->setChannelCount(channelCount_)
|
|
19
19
|
->setSampleRateConversionQuality(SampleRateConversionQuality::Medium)
|
|
20
20
|
->setDataCallback(this)
|
|
@@ -35,7 +35,7 @@ AudioPlayer::AudioPlayer(
|
|
|
35
35
|
builder.setSharingMode(SharingMode::Exclusive)
|
|
36
36
|
->setFormat(AudioFormat::Float)
|
|
37
37
|
->setFormatConversionAllowed(true)
|
|
38
|
-
->setPerformanceMode(PerformanceMode::
|
|
38
|
+
->setPerformanceMode(PerformanceMode::None)
|
|
39
39
|
->setChannelCount(2)
|
|
40
40
|
->setSampleRateConversionQuality(SampleRateConversionQuality::Medium)
|
|
41
41
|
->setDataCallback(this)
|
|
@@ -31,6 +31,10 @@ class AudioBufferHostObject : public JsiHostObject {
|
|
|
31
31
|
JSI_EXPORT_FUNCTION(AudioBufferHostObject, copyToChannel));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
[[nodiscard]] size_t getSizeInBytes() const {
|
|
35
|
+
return audioBuffer_->getLength() * audioBuffer_->getNumberOfChannels() * sizeof(float);
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
JSI_PROPERTY_GETTER(sampleRate) {
|
|
35
39
|
return {audioBuffer_->getSampleRate()};
|
|
36
40
|
}
|
|
@@ -48,8 +52,6 @@ class AudioBufferHostObject : public JsiHostObject {
|
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
JSI_HOST_FUNCTION(getChannelData) {
|
|
51
|
-
// this method could cause a crash if channelData is already deallocated,
|
|
52
|
-
// but we handle deallocation internally so it should be safe
|
|
53
55
|
auto channel = static_cast<int>(args[0].getNumber());
|
|
54
56
|
auto channelData = reinterpret_cast<uint8_t *>(audioBuffer_->getChannelData(channel));
|
|
55
57
|
auto length = static_cast<int>(audioBuffer_->getLength());
|
|
@@ -109,7 +109,11 @@ class BaseAudioContextHostObject : public JsiHostObject {
|
|
|
109
109
|
auto sampleRate = static_cast<float>(args[2].getNumber());
|
|
110
110
|
auto buffer = BaseAudioContext::createBuffer(numberOfChannels, length, sampleRate);
|
|
111
111
|
auto bufferHostObject = std::make_shared<AudioBufferHostObject>(buffer);
|
|
112
|
-
|
|
112
|
+
|
|
113
|
+
auto jsiObject = jsi::Object::createFromHostObject(runtime, bufferHostObject);
|
|
114
|
+
jsiObject.setExternalMemoryPressure(runtime, bufferHostObject->getSizeInBytes());
|
|
115
|
+
|
|
116
|
+
return jsiObject;
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
JSI_HOST_FUNCTION(createPeriodicWave) {
|
|
@@ -158,7 +162,9 @@ class BaseAudioContextHostObject : public JsiHostObject {
|
|
|
158
162
|
}
|
|
159
163
|
|
|
160
164
|
promise->resolve([audioBufferHostObject = std::move(audioBufferHostObject)](jsi::Runtime &runtime) {
|
|
161
|
-
|
|
165
|
+
auto jsiObject = jsi::Object::createFromHostObject(runtime, audioBufferHostObject);
|
|
166
|
+
jsiObject.setExternalMemoryPressure(runtime, audioBufferHostObject->getSizeInBytes());
|
|
167
|
+
return jsiObject;
|
|
162
168
|
});
|
|
163
169
|
}).detach();
|
|
164
170
|
});
|
|
@@ -182,7 +188,9 @@ class BaseAudioContextHostObject : public JsiHostObject {
|
|
|
182
188
|
}
|
|
183
189
|
|
|
184
190
|
promise->resolve([audioBufferHostObject = std::move(audioBufferHostObject)](jsi::Runtime &runtime) {
|
|
185
|
-
|
|
191
|
+
auto jsiObject = jsi::Object::createFromHostObject(runtime, audioBufferHostObject);
|
|
192
|
+
jsiObject.setExternalMemoryPressure(runtime, audioBufferHostObject->getSizeInBytes());
|
|
193
|
+
return jsiObject;
|
|
186
194
|
});
|
|
187
195
|
}).detach();
|
|
188
196
|
});
|
|
@@ -254,7 +254,9 @@ void AudioNode::cleanup() {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
for (const auto &inputNode : inputNodes_) {
|
|
257
|
-
inputNode
|
|
257
|
+
if (inputNode) {
|
|
258
|
+
inputNode->disconnectNode(shared_from_this());
|
|
259
|
+
}
|
|
258
260
|
}
|
|
259
261
|
|
|
260
262
|
outputNodes_.clear();
|
|
@@ -121,7 +121,7 @@ int PeriodicWave::getNumberOfPartialsPerRange(int rangeIndex) const {
|
|
|
121
121
|
|
|
122
122
|
// The very top range will have all the partials culled.
|
|
123
123
|
int numberOfPartials =
|
|
124
|
-
|
|
124
|
+
int(static_cast<float>(getMaxNumberOfPartials()) * cullingScale);
|
|
125
125
|
|
|
126
126
|
return numberOfPartials;
|
|
127
127
|
}
|
|
@@ -109,6 +109,11 @@ void AudioBufferSourceNode::start(double when, double offset, double duration) {
|
|
|
109
109
|
vReadIndex_ = static_cast<double>(buffer_->getSampleRate() * offset);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
void AudioBufferSourceNode::disable() {
|
|
113
|
+
AudioNode::disable();
|
|
114
|
+
buffer_ = nullptr;
|
|
115
|
+
}
|
|
116
|
+
|
|
112
117
|
std::mutex &AudioBufferSourceNode::getBufferLock() {
|
|
113
118
|
return bufferLock_;
|
|
114
119
|
}
|
|
@@ -160,9 +165,19 @@ void AudioBufferSourceNode::processNode(
|
|
|
160
165
|
updatePlaybackInfo(
|
|
161
166
|
playbackRateBus_, framesNeededToStretch, startOffset, offsetLength);
|
|
162
167
|
|
|
168
|
+
if (playbackRate == 0.0f || !isPlaying() || !buffer_) {
|
|
169
|
+
processingBus->zero();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
163
173
|
processWithoutInterpolation(
|
|
164
174
|
playbackRateBus_, startOffset, offsetLength, playbackRate);
|
|
165
175
|
|
|
176
|
+
if (!buffer_) {
|
|
177
|
+
processingBus->zero();
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
166
181
|
auto stretch = buffer_->stretch_;
|
|
167
182
|
|
|
168
183
|
stretch->process(
|
|
@@ -171,7 +186,9 @@ void AudioBufferSourceNode::processNode(
|
|
|
171
186
|
processingBus.get()[0],
|
|
172
187
|
framesToProcess);
|
|
173
188
|
|
|
174
|
-
|
|
189
|
+
if (detune != 0.0f) {
|
|
190
|
+
stretch->setTransposeSemitones(detune);
|
|
191
|
+
}
|
|
175
192
|
}
|
|
176
193
|
|
|
177
194
|
handleStopScheduled();
|
|
@@ -233,6 +250,10 @@ void AudioBufferSourceNode::processWithoutInterpolation(
|
|
|
233
250
|
|
|
234
251
|
if (!loop_) {
|
|
235
252
|
processingBus->zero(writeIndex, framesLeft);
|
|
253
|
+
|
|
254
|
+
if (onendedCallback_) {
|
|
255
|
+
onendedCallback_(getStopTime());
|
|
256
|
+
}
|
|
236
257
|
playbackState_ = PlaybackState::FINISHED;
|
|
237
258
|
disable();
|
|
238
259
|
break;
|
|
@@ -30,6 +30,7 @@ class AudioBufferSourceNode : public AudioScheduledSourceNode {
|
|
|
30
30
|
void setBuffer(const std::shared_ptr<AudioBuffer> &buffer);
|
|
31
31
|
|
|
32
32
|
void start(double when, double offset, double duration = -1);
|
|
33
|
+
void disable() override;
|
|
33
34
|
|
|
34
35
|
protected:
|
|
35
36
|
std::mutex &getBufferLock();
|
|
@@ -36,6 +36,8 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
36
36
|
protected:
|
|
37
37
|
PlaybackState playbackState_;
|
|
38
38
|
|
|
39
|
+
std::function<void(double)> onendedCallback_;
|
|
40
|
+
|
|
39
41
|
void updatePlaybackInfo(
|
|
40
42
|
const std::shared_ptr<AudioBus>& processingBus,
|
|
41
43
|
int framesToProcess,
|
|
@@ -47,8 +49,6 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
47
49
|
private:
|
|
48
50
|
double startTime_;
|
|
49
51
|
double stopTime_;
|
|
50
|
-
|
|
51
|
-
std::function<void(double)> onendedCallback_;
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
} // namespace audioapi
|
|
@@ -46,4 +46,5 @@ void multiply(const float *inputVector1, const float *inputVector2, float *outpu
|
|
|
46
46
|
float maximumMagnitude(const float *inputVector, size_t numberOfElementsToProcess);
|
|
47
47
|
|
|
48
48
|
void linearToDecibels(const float *inputVector, float *outputVector, size_t numberOfElementsToProcess);
|
|
49
|
+
|
|
49
50
|
} // namespace audioapi::dsp
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
#include <audioapi/jsi/JsiHostObject.h>
|
|
2
2
|
|
|
3
|
+
// set this value to 1 in order to debug the construction/destruction
|
|
4
|
+
#define JSI_DEBUG_ALLOCATIONS 1
|
|
5
|
+
|
|
3
6
|
namespace audioapi {
|
|
7
|
+
|
|
8
|
+
#if JSI_DEBUG_ALLOCATIONS
|
|
9
|
+
int objCounter = 0;
|
|
10
|
+
std::vector<JsiHostObject *> objects;
|
|
11
|
+
#endif
|
|
12
|
+
|
|
4
13
|
JsiHostObject::JsiHostObject() {
|
|
5
14
|
getters_ = std::make_unique<std::unordered_map<
|
|
6
15
|
std::string,
|
|
@@ -12,6 +21,23 @@ JsiHostObject::JsiHostObject() {
|
|
|
12
21
|
setters_ = std::make_unique<std::unordered_map<
|
|
13
22
|
std::string,
|
|
14
23
|
void (JsiHostObject::*)(jsi::Runtime &, const jsi::Value &)>>();
|
|
24
|
+
|
|
25
|
+
#if JSI_DEBUG_ALLOCATIONS
|
|
26
|
+
objects.push_back(this);
|
|
27
|
+
objCounter++;
|
|
28
|
+
#endif
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
JsiHostObject::~JsiHostObject() {
|
|
32
|
+
#if JSI_DEBUG_ALLOCATIONS
|
|
33
|
+
for (size_t i = 0; i < objects.size(); ++i) {
|
|
34
|
+
if (objects.at(i) == this) {
|
|
35
|
+
objects.erase(objects.begin() + i);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
objCounter--;
|
|
40
|
+
#endif
|
|
15
41
|
}
|
|
16
42
|
|
|
17
43
|
std::vector<jsi::PropNameID> JsiHostObject::getPropertyNames(jsi::Runtime &rt) {
|
|
@@ -16,6 +16,8 @@ typedef void (^RenderAudioBlock)(AudioBufferList *outputBuffer, int numFrames);
|
|
|
16
16
|
@property (nonatomic, assign) float sampleRate;
|
|
17
17
|
@property (nonatomic, assign) int channelCount;
|
|
18
18
|
@property (nonatomic, assign) bool isRunning;
|
|
19
|
+
@property (nonatomic, assign) bool isInterrupted;
|
|
20
|
+
@property (nonatomic, assign) bool configurationChanged;
|
|
19
21
|
|
|
20
22
|
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio channelCount:(int)channelCount;
|
|
21
23
|
|
|
@@ -42,5 +44,6 @@ typedef void (^RenderAudioBlock)(AudioBufferList *outputBuffer, int numFrames);
|
|
|
42
44
|
- (void)connectAudioEngine;
|
|
43
45
|
|
|
44
46
|
- (void)handleEngineConfigurationChange:(NSNotification *)notification;
|
|
47
|
+
- (void)handleInterruption:(NSNotification *)notification;
|
|
45
48
|
|
|
46
49
|
@end
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
self.audioEngine = [[AVAudioEngine alloc] init];
|
|
10
10
|
self.audioEngine.mainMixerNode.outputVolume = 1;
|
|
11
11
|
self.isRunning = true;
|
|
12
|
+
self.isInterrupted = false;
|
|
13
|
+
self.configurationChanged = false;
|
|
12
14
|
|
|
13
15
|
[self setupAndInitAudioSession];
|
|
14
16
|
[self setupAndInitNotificationHandlers];
|
|
@@ -44,6 +46,8 @@
|
|
|
44
46
|
self.audioEngine = [[AVAudioEngine alloc] init];
|
|
45
47
|
self.audioEngine.mainMixerNode.outputVolume = 1;
|
|
46
48
|
self.isRunning = true;
|
|
49
|
+
self.isInterrupted = false;
|
|
50
|
+
self.configurationChanged = false;
|
|
47
51
|
|
|
48
52
|
[self setupAndInitAudioSession];
|
|
49
53
|
[self setupAndInitNotificationHandlers];
|
|
@@ -94,7 +98,7 @@
|
|
|
94
98
|
[self.audioSession setActive:false error:&error];
|
|
95
99
|
|
|
96
100
|
if (error != nil) {
|
|
97
|
-
@
|
|
101
|
+
NSLog(@"Error while deactivating audio session: %@", [error debugDescription]);
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
104
|
|
|
@@ -140,21 +144,28 @@
|
|
|
140
144
|
self.audioSession = [AVAudioSession sharedInstance];
|
|
141
145
|
}
|
|
142
146
|
|
|
143
|
-
[self.audioSession
|
|
144
|
-
mode:AVAudioSessionModeDefault
|
|
145
|
-
options:AVAudioSessionCategoryOptionDuckOthers | AVAudioSessionCategoryOptionAllowBluetooth |
|
|
146
|
-
AVAudioSessionCategoryOptionAllowAirPlay
|
|
147
|
-
error:&error];
|
|
147
|
+
[self.audioSession setPreferredIOBufferDuration:0.022 error:&error];
|
|
148
148
|
|
|
149
149
|
if (error != nil) {
|
|
150
|
-
NSLog(@"Error while
|
|
150
|
+
NSLog(@"Error while setting buffer size in audio session: %@", [error debugDescription]);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
[self.audioSession setCategory:AVAudioSessionCategoryPlayback error:&error];
|
|
155
|
+
|
|
156
|
+
if (error != nil) {
|
|
157
|
+
NSLog(@"Error while configuring audio session: %@", [error debugDescription]);
|
|
158
|
+
return;
|
|
151
159
|
}
|
|
152
160
|
|
|
153
161
|
[self.audioSession setActive:true error:&error];
|
|
154
162
|
|
|
155
163
|
if (error != nil) {
|
|
156
|
-
NSLog(@"Error while activating audio session: %@", [error
|
|
164
|
+
NSLog(@"Error while activating audio session: %@", [error debugDescription]);
|
|
165
|
+
return;
|
|
157
166
|
}
|
|
167
|
+
|
|
168
|
+
self.isInterrupted = false;
|
|
158
169
|
}
|
|
159
170
|
|
|
160
171
|
- (void)setupAndInitNotificationHandlers
|
|
@@ -167,6 +178,10 @@
|
|
|
167
178
|
selector:@selector(handleEngineConfigurationChange:)
|
|
168
179
|
name:AVAudioEngineConfigurationChangeNotification
|
|
169
180
|
object:nil];
|
|
181
|
+
[self.notificationCenter addObserver:self
|
|
182
|
+
selector:@selector(handleInterruption:)
|
|
183
|
+
name:AVAudioSessionInterruptionNotification
|
|
184
|
+
object:nil];
|
|
170
185
|
}
|
|
171
186
|
|
|
172
187
|
- (void)connectAudioEngine
|
|
@@ -182,18 +197,47 @@
|
|
|
182
197
|
NSError *error = nil;
|
|
183
198
|
|
|
184
199
|
if (![self.audioEngine startAndReturnError:&error]) {
|
|
185
|
-
NSLog(@"Error starting audio engine: %@", [error
|
|
200
|
+
NSLog(@"Error starting audio engine: %@", [error debugDescription]);
|
|
186
201
|
}
|
|
187
202
|
}
|
|
203
|
+
|
|
204
|
+
self.configurationChanged = false;
|
|
188
205
|
}
|
|
189
206
|
|
|
190
207
|
- (void)handleEngineConfigurationChange:(NSNotification *)notification
|
|
191
208
|
{
|
|
192
|
-
if (!self.isRunning) {
|
|
209
|
+
if (!self.isRunning || self.isInterrupted) {
|
|
210
|
+
self.configurationChanged = true;
|
|
193
211
|
return;
|
|
194
212
|
}
|
|
195
213
|
|
|
196
|
-
|
|
214
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
215
|
+
[self connectAudioEngine];
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
- (void)handleInterruption:(NSNotification *)notification
|
|
220
|
+
{
|
|
221
|
+
NSError *error;
|
|
222
|
+
UInt8 type = [[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] intValue];
|
|
223
|
+
UInt8 option = [[notification.userInfo valueForKey:AVAudioSessionInterruptionOptionKey] intValue];
|
|
224
|
+
|
|
225
|
+
if (type == AVAudioSessionInterruptionTypeBegan) {
|
|
226
|
+
self.isInterrupted = true;
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (type != AVAudioSessionInterruptionTypeEnded || option != AVAudioSessionInterruptionOptionShouldResume) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
[self setupAndInitAudioSession];
|
|
235
|
+
|
|
236
|
+
if (self.configurationChanged && self.isRunning) {
|
|
237
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
238
|
+
[self connectAudioEngine];
|
|
239
|
+
});
|
|
240
|
+
}
|
|
197
241
|
}
|
|
198
242
|
|
|
199
243
|
@end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#import <AVFoundation/AVFoundation.h>
|
|
2
2
|
|
|
3
3
|
#include <audioapi/core/Constants.h>
|
|
4
|
+
#include <audioapi/dsp/VectorMath.h>
|
|
4
5
|
#include <audioapi/ios/core/IOSAudioPlayer.h>
|
|
5
6
|
#include <audioapi/utils/AudioArray.h>
|
|
6
7
|
#include <audioapi/utils/AudioBus.h>
|
|
@@ -17,14 +18,11 @@ IOSAudioPlayer::IOSAudioPlayer(const std::function<void(std::shared_ptr<AudioBus
|
|
|
17
18
|
int framesToProcess = std::min(numFrames - processedFrames, RENDER_QUANTUM_SIZE);
|
|
18
19
|
renderAudio_(audioBus_, framesToProcess);
|
|
19
20
|
|
|
20
|
-
// TODO: optimize this with SIMD?
|
|
21
21
|
for (int channel = 0; channel < channelCount_; channel += 1) {
|
|
22
22
|
float *outputChannel = (float *)outputData->mBuffers[channel].mData;
|
|
23
23
|
auto *inputChannel = audioBus_->getChannel(channel)->getData();
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
outputChannel[processedFrames + i] = inputChannel[i];
|
|
27
|
-
}
|
|
25
|
+
memcpy(outputChannel + processedFrames, inputChannel, framesToProcess * sizeof(float));
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
processedFrames += framesToProcess;
|
|
@@ -45,14 +43,11 @@ IOSAudioPlayer::IOSAudioPlayer(const std::function<void(std::shared_ptr<AudioBus
|
|
|
45
43
|
int framesToProcess = std::min(numFrames - processedFrames, RENDER_QUANTUM_SIZE);
|
|
46
44
|
renderAudio_(audioBus_, framesToProcess);
|
|
47
45
|
|
|
48
|
-
// TODO: optimize this with SIMD?
|
|
49
46
|
for (int channel = 0; channel < channelCount_; channel += 1) {
|
|
50
47
|
float *outputChannel = (float *)outputData->mBuffers[channel].mData;
|
|
51
48
|
auto *inputChannel = audioBus_->getChannel(channel)->getData();
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
outputChannel[processedFrames + i] = inputChannel[i];
|
|
55
|
-
}
|
|
50
|
+
memcpy(outputChannel + processedFrames, inputChannel, framesToProcess * sizeof(float));
|
|
56
51
|
}
|
|
57
52
|
|
|
58
53
|
processedFrames += framesToProcess;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-audio-api",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification",
|
|
5
5
|
"bin": {
|
|
6
6
|
"setup-rn-audio-api-web": "./scripts/setup-rn-audio-api-web.js"
|