react-native-audio-api 0.4.10 → 0.4.11
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/build.gradle +2 -0
- package/android/src/main/cpp/{core/AudioAPIInstaller.cpp → AudioAPIModule.cpp} +12 -11
- package/android/src/main/cpp/{core/AudioAPIInstaller.h → AudioAPIModule.h} +9 -11
- package/android/src/main/cpp/OnLoad.cpp +2 -2
- package/android/src/main/cpp/core/AudioDecoder.cpp +5 -5
- package/android/src/main/cpp/core/AudioPlayer.cpp +12 -0
- package/android/src/main/cpp/core/AudioPlayer.h +2 -0
- package/android/src/main/java/com/swmansion/audioapi/{module/AudioAPIInstaller.kt → AudioAPIModule.kt} +22 -10
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +31 -6
- package/android/src/oldarch/NativeAudioAPIModuleSpec.java +37 -0
- package/common/cpp/HostObjects/AudioContextHostObject.h +34 -1
- package/common/cpp/core/AnalyserNode.cpp +2 -2
- package/common/cpp/core/AnalyserNode.h +1 -1
- package/common/cpp/core/AudioBuffer.cpp +4 -2
- package/common/cpp/core/AudioBuffer.h +1 -1
- package/common/cpp/core/AudioBufferSourceNode.cpp +3 -3
- package/common/cpp/core/AudioBufferSourceNode.h +3 -3
- package/common/cpp/core/AudioContext.cpp +10 -0
- package/common/cpp/core/AudioContext.h +2 -0
- package/common/cpp/core/AudioDecoder.h +2 -1
- package/common/cpp/core/AudioDestinationNode.h +1 -1
- package/common/cpp/core/AudioNode.cpp +1 -1
- package/common/cpp/core/AudioNode.h +1 -1
- package/common/cpp/core/AudioScheduledSourceNode.cpp +1 -1
- package/common/cpp/core/AudioScheduledSourceNode.h +1 -1
- package/common/cpp/core/BiquadFilterNode.cpp +1 -1
- package/common/cpp/core/BiquadFilterNode.h +1 -1
- package/common/cpp/core/GainNode.cpp +3 -1
- package/common/cpp/core/GainNode.h +1 -1
- package/common/cpp/core/OscillatorNode.cpp +3 -1
- package/common/cpp/core/OscillatorNode.h +1 -1
- package/common/cpp/core/StereoPannerNode.cpp +1 -1
- package/common/cpp/core/StereoPannerNode.h +1 -1
- package/common/cpp/installer/AudioAPIModuleInstaller.cpp +49 -0
- package/common/cpp/installer/AudioAPIModuleInstaller.h +49 -0
- package/ios/AudioAPIModule.h +1 -1
- package/ios/AudioAPIModule.mm +10 -3
- package/ios/core/AudioDecoder.mm +2 -3
- package/ios/core/AudioPlayer.h +14 -0
- package/ios/core/AudioPlayer.m +85 -24
- package/ios/core/IOSAudioPlayer.h +2 -0
- package/ios/core/IOSAudioPlayer.mm +10 -0
- package/lib/module/core/AudioContext.js +7 -1
- package/lib/module/core/AudioContext.js.map +1 -1
- package/lib/module/index.js +11 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/NativeAudioAPIModule.js +5 -0
- package/lib/module/specs/NativeAudioAPIModule.js.map +1 -0
- package/lib/module/web-core/AudioContext.js +6 -0
- package/lib/module/web-core/AudioContext.js.map +1 -1
- package/lib/typescript/core/AudioContext.d.ts +2 -0
- package/lib/typescript/core/AudioContext.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +4 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +6 -1
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts +7 -0
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -0
- package/lib/typescript/web-core/AudioContext.d.ts +3 -1
- package/lib/typescript/web-core/AudioContext.d.ts.map +1 -1
- package/package.json +9 -7
- package/src/core/AudioContext.ts +9 -1
- package/src/index.ts +16 -3
- package/src/interfaces.ts +7 -1
- package/src/specs/NativeAudioAPIModule.ts +7 -0
- package/src/web-core/AudioContext.tsx +9 -1
- package/android/src/main/java/com/swmansion/audioapi/nativemodules/AudioAPIModule.kt +0 -26
- package/common/cpp/HostObjects/AudioAPIInstallerHostObject.h +0 -56
- package/lib/module/specs/global.d.js +0 -4
- package/lib/module/specs/global.d.js.map +0 -1
- package/lib/module/specs/install.js +0 -18
- package/lib/module/specs/install.js.map +0 -1
- package/lib/typescript/specs/install.d.ts +0 -7
- package/lib/typescript/specs/install.d.ts.map +0 -1
- package/src/specs/global.d.ts +0 -12
- package/src/specs/install.ts +0 -32
package/android/build.gradle
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
#include "
|
|
1
|
+
#include "AudioAPIModule.h"
|
|
2
|
+
|
|
3
|
+
#include "AudioContext.h"
|
|
4
|
+
#include "AudioContextHostObject.h"
|
|
2
5
|
|
|
3
6
|
namespace audioapi {
|
|
4
7
|
|
|
5
8
|
using namespace facebook::jni;
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
jni::alias_ref<
|
|
10
|
+
AudioAPIModule::AudioAPIModule(
|
|
11
|
+
jni::alias_ref<AudioAPIModule::jhybridobject> &jThis,
|
|
9
12
|
jsi::Runtime *jsiRuntime,
|
|
10
13
|
const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker)
|
|
11
14
|
: javaPart_(make_global(jThis)),
|
|
12
15
|
jsiRuntime_(jsiRuntime),
|
|
13
16
|
jsCallInvoker_(jsCallInvoker) {}
|
|
14
17
|
|
|
15
|
-
jni::local_ref<
|
|
18
|
+
jni::local_ref<AudioAPIModule::jhybriddata> AudioAPIModule::initHybrid(
|
|
16
19
|
jni::alias_ref<jhybridobject> jThis,
|
|
17
20
|
jlong jsContext,
|
|
18
21
|
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
|
|
@@ -22,16 +25,14 @@ jni::local_ref<AudioAPIInstaller::jhybriddata> AudioAPIInstaller::initHybrid(
|
|
|
22
25
|
return makeCxxInstance(jThis, rnRuntime, jsCallInvoker);
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
void
|
|
28
|
+
void AudioAPIModule::registerNatives() {
|
|
26
29
|
registerHybrid({
|
|
27
|
-
makeNativeMethod("initHybrid",
|
|
28
|
-
makeNativeMethod("
|
|
30
|
+
makeNativeMethod("initHybrid", AudioAPIModule::initHybrid),
|
|
31
|
+
makeNativeMethod("injectJSIBindings", AudioAPIModule::injectJSIBindings),
|
|
29
32
|
});
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
void
|
|
33
|
-
|
|
34
|
-
jsiRuntime_, jsCallInvoker_);
|
|
35
|
-
hostObject->install();
|
|
35
|
+
void AudioAPIModule::injectJSIBindings() {
|
|
36
|
+
AudioAPIModuleInstaller::injectJSIBindings(jsiRuntime_, jsCallInvoker_);
|
|
36
37
|
}
|
|
37
38
|
} // namespace audioapi
|
|
@@ -6,21 +6,19 @@
|
|
|
6
6
|
#include <react/jni/JMessageQueueThread.h>
|
|
7
7
|
#include <memory>
|
|
8
8
|
#include <utility>
|
|
9
|
-
|
|
10
|
-
#include "AudioAPIInstallerHostObject.h"
|
|
11
|
-
#include "AudioContext.h"
|
|
9
|
+
#include "AudioAPIModuleInstaller.h"
|
|
12
10
|
|
|
13
11
|
namespace audioapi {
|
|
14
12
|
|
|
15
13
|
using namespace facebook;
|
|
16
14
|
using namespace react;
|
|
17
15
|
|
|
18
|
-
class
|
|
16
|
+
class AudioAPIModule : public jni::HybridClass<AudioAPIModule> {
|
|
19
17
|
public:
|
|
20
18
|
static auto constexpr kJavaDescriptor =
|
|
21
|
-
"Lcom/swmansion/audioapi/
|
|
19
|
+
"Lcom/swmansion/audioapi/AudioAPIModule;";
|
|
22
20
|
|
|
23
|
-
static jni::local_ref<
|
|
21
|
+
static jni::local_ref<AudioAPIModule::jhybriddata> initHybrid(
|
|
24
22
|
jni::alias_ref<jhybridobject> jThis,
|
|
25
23
|
jlong jsContext,
|
|
26
24
|
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
|
|
@@ -28,18 +26,18 @@ class AudioAPIInstaller : public jni::HybridClass<AudioAPIInstaller> {
|
|
|
28
26
|
|
|
29
27
|
static void registerNatives();
|
|
30
28
|
|
|
31
|
-
void
|
|
29
|
+
void injectJSIBindings();
|
|
32
30
|
|
|
33
31
|
private:
|
|
34
32
|
friend HybridBase;
|
|
35
33
|
|
|
36
|
-
jni::global_ref<
|
|
34
|
+
jni::global_ref<AudioAPIModule::javaobject> javaPart_;
|
|
37
35
|
jsi::Runtime *jsiRuntime_;
|
|
38
36
|
std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker_;
|
|
39
37
|
|
|
40
|
-
explicit
|
|
41
|
-
jni::alias_ref<
|
|
42
|
-
jsi::Runtime *
|
|
38
|
+
explicit AudioAPIModule(
|
|
39
|
+
jni::alias_ref<AudioAPIModule::jhybridobject> &jThis,
|
|
40
|
+
jsi::Runtime *jsiRuntime,
|
|
43
41
|
const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker);
|
|
44
42
|
};
|
|
45
43
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#include <fbjni/fbjni.h>
|
|
2
|
-
#include "
|
|
2
|
+
#include "AudioAPIModule.h"
|
|
3
3
|
|
|
4
4
|
using namespace audioapi;
|
|
5
5
|
|
|
6
6
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
|
7
7
|
return facebook::jni::initialize(
|
|
8
|
-
vm, [] {
|
|
8
|
+
vm, [] { AudioAPIModule::registerNatives(); });
|
|
9
9
|
}
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
namespace audioapi {
|
|
11
11
|
|
|
12
|
-
AudioBus
|
|
12
|
+
std::shared_ptr<AudioBus> AudioDecoder::decodeWithFilePath(
|
|
13
|
+
const std::string &path) const {
|
|
13
14
|
ma_decoder decoder;
|
|
14
15
|
ma_decoder_config config =
|
|
15
16
|
ma_decoder_config_init(ma_format_f32, 2, sampleRate_);
|
|
@@ -29,8 +30,8 @@ AudioBus *AudioDecoder::decodeWithFilePath(const std::string &path) const {
|
|
|
29
30
|
ma_uint64 totalFrameCount;
|
|
30
31
|
ma_decoder_get_length_in_pcm_frames(&decoder, &totalFrameCount);
|
|
31
32
|
|
|
32
|
-
auto
|
|
33
|
-
|
|
33
|
+
auto audioBus = std::make_shared<AudioBus>(
|
|
34
|
+
static_cast<int>(totalFrameCount), 2, sampleRate_);
|
|
34
35
|
auto *buffer = new float[totalFrameCount * 2];
|
|
35
36
|
|
|
36
37
|
ma_uint64 framesDecoded;
|
|
@@ -43,14 +44,13 @@ AudioBus *AudioDecoder::decodeWithFilePath(const std::string &path) const {
|
|
|
43
44
|
path.c_str());
|
|
44
45
|
|
|
45
46
|
delete[] buffer;
|
|
46
|
-
delete audioBus;
|
|
47
47
|
ma_decoder_uninit(&decoder);
|
|
48
48
|
|
|
49
49
|
return nullptr;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
for (int i = 0; i < decoder.outputChannels; ++i) {
|
|
53
|
-
|
|
53
|
+
auto channelData = audioBus->getChannel(i)->getData();
|
|
54
54
|
|
|
55
55
|
for (ma_uint64 j = 0; j < framesDecoded; ++j) {
|
|
56
56
|
channelData[j] = buffer[j * decoder.outputChannels + i];
|
|
@@ -70,6 +70,18 @@ void AudioPlayer::stop() {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
void AudioPlayer::resume() {
|
|
74
|
+
if (mStream_) {
|
|
75
|
+
mStream_->requestStart();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
void AudioPlayer::suspend() {
|
|
80
|
+
if (mStream_) {
|
|
81
|
+
mStream_->requestPause();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
73
85
|
DataCallbackResult AudioPlayer::onAudioReady(
|
|
74
86
|
AudioStream *oboeStream,
|
|
75
87
|
void *audioData,
|
|
@@ -1,31 +1,43 @@
|
|
|
1
|
-
package com.swmansion.audioapi
|
|
1
|
+
package com.swmansion.audioapi
|
|
2
2
|
|
|
3
3
|
import com.facebook.jni.HybridData
|
|
4
4
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.bridge.ReactMethod
|
|
5
6
|
import com.facebook.react.common.annotations.FrameworkAPI
|
|
7
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
6
8
|
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
|
|
7
9
|
|
|
8
10
|
@OptIn(FrameworkAPI::class)
|
|
9
|
-
|
|
11
|
+
@ReactModule(name = AudioAPIModule.NAME)
|
|
12
|
+
class AudioAPIModule(
|
|
10
13
|
reactContext: ReactApplicationContext,
|
|
11
|
-
) {
|
|
12
|
-
private val mHybridData: HybridData?
|
|
13
|
-
|
|
14
|
+
) : NativeAudioAPIModuleSpec(reactContext) {
|
|
14
15
|
companion object {
|
|
15
16
|
init {
|
|
16
17
|
System.loadLibrary("react-native-audio-api")
|
|
17
18
|
}
|
|
19
|
+
|
|
20
|
+
const val NAME = NativeAudioAPIModuleSpec.NAME
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
private val mHybridData: HybridData
|
|
24
|
+
|
|
25
|
+
external fun initHybrid(
|
|
26
|
+
jsContext: Long,
|
|
27
|
+
callInvoker: CallInvokerHolderImpl,
|
|
28
|
+
): HybridData
|
|
29
|
+
|
|
30
|
+
private external fun injectJSIBindings()
|
|
31
|
+
|
|
20
32
|
init {
|
|
21
33
|
val jsCallInvokerHolder = reactContext.jsCallInvokerHolder as CallInvokerHolderImpl
|
|
22
34
|
mHybridData = initHybrid(reactContext.javaScriptContextHolder!!.get(), jsCallInvokerHolder)
|
|
23
35
|
}
|
|
24
36
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
): HybridData?
|
|
37
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
38
|
+
override fun install(): Boolean {
|
|
39
|
+
injectJSIBindings()
|
|
29
40
|
|
|
30
|
-
|
|
41
|
+
return true
|
|
42
|
+
}
|
|
31
43
|
}
|
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
package com.swmansion.audioapi
|
|
2
2
|
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
3
4
|
import com.facebook.react.ReactPackage
|
|
4
5
|
import com.facebook.react.bridge.NativeModule
|
|
5
6
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
|
6
8
|
import com.facebook.react.module.annotations.ReactModuleList
|
|
7
|
-
import com.facebook.react.
|
|
8
|
-
import com.
|
|
9
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
10
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
9
11
|
|
|
10
12
|
@ReactModuleList(nativeModules = [AudioAPIModule::class])
|
|
11
|
-
class AudioAPIPackage :
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
class AudioAPIPackage :
|
|
14
|
+
BaseReactPackage(),
|
|
15
|
+
ReactPackage {
|
|
16
|
+
@UnstableReactNativeAPI
|
|
17
|
+
override fun getModule(
|
|
18
|
+
name: String,
|
|
19
|
+
reactContext: ReactApplicationContext,
|
|
20
|
+
): NativeModule? =
|
|
21
|
+
when (name) {
|
|
22
|
+
AudioAPIModule.NAME -> AudioAPIModule(reactContext)
|
|
23
|
+
else -> null
|
|
24
|
+
}
|
|
14
25
|
|
|
15
|
-
override fun
|
|
26
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider =
|
|
27
|
+
ReactModuleInfoProvider(
|
|
28
|
+
fun (): Map<String, ReactModuleInfo> =
|
|
29
|
+
mapOf(
|
|
30
|
+
AudioAPIModule.NAME to
|
|
31
|
+
ReactModuleInfo(
|
|
32
|
+
AudioAPIModule.NAME,
|
|
33
|
+
AudioAPIModule::class.java.simpleName,
|
|
34
|
+
_canOverrideExistingModule = true,
|
|
35
|
+
_needsEagerInit = false,
|
|
36
|
+
isCxxModule = false,
|
|
37
|
+
isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
)
|
|
16
41
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
4
|
+
*
|
|
5
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
6
|
+
* once the code is regenerated.
|
|
7
|
+
*
|
|
8
|
+
* @generated by codegen project: GenerateModuleJavaSpec.js
|
|
9
|
+
*
|
|
10
|
+
* @nolint
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
package com.swmansion.audioapi;
|
|
14
|
+
|
|
15
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
16
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
17
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
18
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
19
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
|
20
|
+
import javax.annotation.Nonnull;
|
|
21
|
+
|
|
22
|
+
public abstract class NativeAudioAPIModuleSpec extends ReactContextBaseJavaModule implements TurboModule {
|
|
23
|
+
public static final String NAME = "AudioAPIModule";
|
|
24
|
+
|
|
25
|
+
public NativeAudioAPIModuleSpec(ReactApplicationContext reactContext) {
|
|
26
|
+
super(reactContext);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Override
|
|
30
|
+
public @Nonnull String getName() {
|
|
31
|
+
return NAME;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
35
|
+
@DoNotStrip
|
|
36
|
+
public abstract boolean install();
|
|
37
|
+
}
|
|
@@ -17,7 +17,10 @@ class AudioContextHostObject : public BaseAudioContextHostObject {
|
|
|
17
17
|
const std::shared_ptr<AudioContext> &audioContext,
|
|
18
18
|
const std::shared_ptr<PromiseVendor> &promiseVendor)
|
|
19
19
|
: BaseAudioContextHostObject(audioContext, promiseVendor) {
|
|
20
|
-
addFunctions(
|
|
20
|
+
addFunctions(
|
|
21
|
+
JSI_EXPORT_FUNCTION(AudioContextHostObject, close),
|
|
22
|
+
JSI_EXPORT_FUNCTION(AudioContextHostObject, resume),
|
|
23
|
+
JSI_EXPORT_FUNCTION(AudioContextHostObject, suspend));
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
JSI_HOST_FUNCTION(close) {
|
|
@@ -34,5 +37,35 @@ class AudioContextHostObject : public BaseAudioContextHostObject {
|
|
|
34
37
|
|
|
35
38
|
return promise;
|
|
36
39
|
}
|
|
40
|
+
|
|
41
|
+
JSI_HOST_FUNCTION(resume) {
|
|
42
|
+
auto promise = promiseVendor_->createPromise([this](std::shared_ptr<Promise> promise) {
|
|
43
|
+
std::thread([this, promise = std::move(promise)]() {
|
|
44
|
+
auto audioContext = std::static_pointer_cast<AudioContext>(context_);
|
|
45
|
+
audioContext->resume();
|
|
46
|
+
|
|
47
|
+
promise->resolve([](jsi::Runtime &runtime) {
|
|
48
|
+
return jsi::Value::undefined();
|
|
49
|
+
});
|
|
50
|
+
}).detach();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return promise;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
JSI_HOST_FUNCTION(suspend) {
|
|
57
|
+
auto promise = promiseVendor_->createPromise([this](std::shared_ptr<Promise> promise) {
|
|
58
|
+
std::thread([this, promise = std::move(promise)]() {
|
|
59
|
+
auto audioContext = std::static_pointer_cast<AudioContext>(context_);
|
|
60
|
+
audioContext->suspend();
|
|
61
|
+
|
|
62
|
+
promise->resolve([](jsi::Runtime &runtime) {
|
|
63
|
+
return jsi::Value::undefined();
|
|
64
|
+
});
|
|
65
|
+
}).detach();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return promise;
|
|
69
|
+
}
|
|
37
70
|
};
|
|
38
71
|
} // namespace audioapi
|
|
@@ -147,13 +147,13 @@ void AnalyserNode::getByteTimeDomainData(uint8_t *data, int length) {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
void AnalyserNode::processNode(
|
|
150
|
-
|
|
150
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
151
151
|
int framesToProcess) {
|
|
152
152
|
// Analyser should behave like a sniffer node, it should not modify the
|
|
153
153
|
// processingBus but instead copy the data to its own input buffer.
|
|
154
154
|
|
|
155
155
|
// Down mix the input bus to mono
|
|
156
|
-
downMixBus_->copy(processingBus);
|
|
156
|
+
downMixBus_->copy(processingBus.get());
|
|
157
157
|
|
|
158
158
|
if (vWriteIndex_ + framesToProcess > inputBuffer_->getSize()) {
|
|
159
159
|
auto framesToCopy =
|
|
@@ -36,7 +36,7 @@ class AnalyserNode : public AudioNode {
|
|
|
36
36
|
void getByteTimeDomainData(uint8_t *data, int length);
|
|
37
37
|
|
|
38
38
|
protected:
|
|
39
|
-
void processNode(AudioBus
|
|
39
|
+
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
40
40
|
|
|
41
41
|
private:
|
|
42
42
|
int fftSize_;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#include "AudioBuffer.h"
|
|
2
|
+
|
|
3
|
+
#include <utility>
|
|
2
4
|
#include "AudioArray.h"
|
|
3
5
|
#include "AudioBus.h"
|
|
4
6
|
|
|
@@ -11,8 +13,8 @@ AudioBuffer::AudioBuffer(
|
|
|
11
13
|
bus_ = std::make_shared<AudioBus>(length, numberOfChannels, sampleRate);
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
AudioBuffer::AudioBuffer(AudioBus
|
|
15
|
-
bus_ = std::
|
|
16
|
+
AudioBuffer::AudioBuffer(std::shared_ptr<AudioBus> bus) {
|
|
17
|
+
bus_ = std::move(bus);
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
size_t AudioBuffer::getLength() const {
|
|
@@ -13,7 +13,7 @@ class AudioBus;
|
|
|
13
13
|
class AudioBuffer : public std::enable_shared_from_this<AudioBuffer> {
|
|
14
14
|
public:
|
|
15
15
|
explicit AudioBuffer(int numberOfChannels, size_t length, float sampleRate);
|
|
16
|
-
explicit AudioBuffer(AudioBus
|
|
16
|
+
explicit AudioBuffer(std::shared_ptr<AudioBus> bus);
|
|
17
17
|
|
|
18
18
|
[[nodiscard]] size_t getLength() const;
|
|
19
19
|
[[nodiscard]] float getSampleRate() const;
|
|
@@ -117,7 +117,7 @@ std::mutex &AudioBufferSourceNode::getBufferLock() {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
void AudioBufferSourceNode::processNode(
|
|
120
|
-
AudioBus
|
|
120
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
121
121
|
int framesToProcess) {
|
|
122
122
|
// No audio data to fill, zero the output and return.
|
|
123
123
|
if (!buffer_) {
|
|
@@ -158,7 +158,7 @@ void AudioBufferSourceNode::processNode(
|
|
|
158
158
|
*/
|
|
159
159
|
|
|
160
160
|
void AudioBufferSourceNode::processWithoutInterpolation(
|
|
161
|
-
AudioBus
|
|
161
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
162
162
|
size_t startOffset,
|
|
163
163
|
size_t offsetLength,
|
|
164
164
|
float playbackRate) {
|
|
@@ -216,7 +216,7 @@ void AudioBufferSourceNode::processWithoutInterpolation(
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
void AudioBufferSourceNode::processWithInterpolation(
|
|
219
|
-
AudioBus
|
|
219
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
220
220
|
size_t startOffset,
|
|
221
221
|
size_t offsetLength,
|
|
222
222
|
float playbackRate) {
|
|
@@ -31,7 +31,7 @@ class AudioBufferSourceNode : public AudioScheduledSourceNode {
|
|
|
31
31
|
|
|
32
32
|
protected:
|
|
33
33
|
std::mutex &getBufferLock();
|
|
34
|
-
void processNode(AudioBus
|
|
34
|
+
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
35
35
|
|
|
36
36
|
private:
|
|
37
37
|
// Looping related properties
|
|
@@ -57,13 +57,13 @@ class AudioBufferSourceNode : public AudioScheduledSourceNode {
|
|
|
57
57
|
double getVirtualEndFrame();
|
|
58
58
|
|
|
59
59
|
void processWithoutInterpolation(
|
|
60
|
-
AudioBus
|
|
60
|
+
const std::shared_ptr<AudioBus>& processingBus,
|
|
61
61
|
size_t startOffset,
|
|
62
62
|
size_t offsetLength,
|
|
63
63
|
float playbackRate);
|
|
64
64
|
|
|
65
65
|
void processWithInterpolation(
|
|
66
|
-
AudioBus
|
|
66
|
+
const std::shared_ptr<AudioBus>& processingBus,
|
|
67
67
|
size_t startOffset,
|
|
68
68
|
size_t offsetLength,
|
|
69
69
|
float playbackRate);
|
|
@@ -48,6 +48,16 @@ void AudioContext::close() {
|
|
|
48
48
|
audioPlayer_->stop();
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
void AudioContext::resume() {
|
|
52
|
+
state_ = ContextState::RUNNING;
|
|
53
|
+
audioPlayer_->resume();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void AudioContext::suspend() {
|
|
57
|
+
state_ = ContextState::SUSPENDED;
|
|
58
|
+
audioPlayer_->suspend();
|
|
59
|
+
}
|
|
60
|
+
|
|
51
61
|
std::function<void(std::shared_ptr<AudioBus>, int)>
|
|
52
62
|
AudioContext::renderAudio() {
|
|
53
63
|
if (!isRunning() || !destination_) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include <memory>
|
|
3
4
|
#include <string>
|
|
4
5
|
|
|
5
6
|
namespace audioapi {
|
|
@@ -10,7 +11,7 @@ class AudioDecoder {
|
|
|
10
11
|
public:
|
|
11
12
|
explicit AudioDecoder(float sampleRate) : sampleRate_(sampleRate) {}
|
|
12
13
|
|
|
13
|
-
[[nodiscard]] AudioBus
|
|
14
|
+
[[nodiscard]] std::shared_ptr<AudioBus> decodeWithFilePath(const std::string &path) const;
|
|
14
15
|
|
|
15
16
|
private:
|
|
16
17
|
float sampleRate_;
|
|
@@ -24,7 +24,7 @@ class AudioDestinationNode : public AudioNode {
|
|
|
24
24
|
protected:
|
|
25
25
|
// DestinationNode is triggered by AudioContext using renderAudio
|
|
26
26
|
// processNode function is not necessary and is never called.
|
|
27
|
-
void processNode(AudioBus
|
|
27
|
+
void processNode(const std::shared_ptr<AudioBus>& processingBus, int) final {};
|
|
28
28
|
|
|
29
29
|
private:
|
|
30
30
|
std::size_t currentSampleFrame_;
|
|
@@ -119,7 +119,7 @@ std::shared_ptr<AudioBus> AudioNode::processAudio(
|
|
|
119
119
|
|
|
120
120
|
assert(processingBus != nullptr);
|
|
121
121
|
// Finally, process the node itself.
|
|
122
|
-
processNode(processingBus
|
|
122
|
+
processNode(processingBus, framesToProcess);
|
|
123
123
|
|
|
124
124
|
return processingBus;
|
|
125
125
|
}
|
|
@@ -63,7 +63,7 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {
|
|
|
63
63
|
static std::string toString(ChannelInterpretation interpretation);
|
|
64
64
|
|
|
65
65
|
std::shared_ptr<AudioBus> processAudio(std::shared_ptr<AudioBus> outputBus, int framesToProcess);
|
|
66
|
-
virtual void processNode(AudioBus
|
|
66
|
+
virtual void processNode(const std::shared_ptr<AudioBus>&, int) = 0;
|
|
67
67
|
|
|
68
68
|
bool isAlreadyProcessed();
|
|
69
69
|
std::shared_ptr<AudioBus> processInputs(const std::shared_ptr<AudioBus>& outputBus, int framesToProcess);
|
|
@@ -43,7 +43,7 @@ bool AudioScheduledSourceNode::isFinished() {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
void AudioScheduledSourceNode::updatePlaybackInfo(
|
|
46
|
-
AudioBus
|
|
46
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
47
47
|
int framesToProcess,
|
|
48
48
|
size_t &startOffset,
|
|
49
49
|
size_t &nonSilentFramesToProcess) {
|
|
@@ -31,7 +31,7 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
31
31
|
PlaybackState playbackState_;
|
|
32
32
|
|
|
33
33
|
void updatePlaybackInfo(
|
|
34
|
-
AudioBus
|
|
34
|
+
const std::shared_ptr<AudioBus>& processingBus,
|
|
35
35
|
int framesToProcess,
|
|
36
36
|
size_t &startOffset,
|
|
37
37
|
size_t &nonSilentFramesToProcess);
|
|
@@ -32,7 +32,7 @@ class BiquadFilterNode : public AudioNode {
|
|
|
32
32
|
std::vector<float> &phaseResponseOutput);
|
|
33
33
|
|
|
34
34
|
protected:
|
|
35
|
-
void processNode(AudioBus
|
|
35
|
+
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
36
36
|
|
|
37
37
|
private:
|
|
38
38
|
std::shared_ptr<AudioParam> frequencyParam_;
|
|
@@ -14,7 +14,9 @@ std::shared_ptr<AudioParam> GainNode::getGainParam() const {
|
|
|
14
14
|
return gainParam_;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
void GainNode::processNode(
|
|
17
|
+
void GainNode::processNode(
|
|
18
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
19
|
+
int framesToProcess) {
|
|
18
20
|
double time = context_->getCurrentTime();
|
|
19
21
|
double deltaTime = 1.0 / context_->getSampleRate();
|
|
20
22
|
|
|
@@ -16,7 +16,7 @@ class GainNode : public AudioNode {
|
|
|
16
16
|
[[nodiscard]] std::shared_ptr<AudioParam> getGainParam() const;
|
|
17
17
|
|
|
18
18
|
protected:
|
|
19
|
-
void processNode(AudioBus
|
|
19
|
+
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
20
20
|
|
|
21
21
|
private:
|
|
22
22
|
std::shared_ptr<AudioParam> gainParam_;
|
|
@@ -38,7 +38,9 @@ void OscillatorNode::setPeriodicWave(
|
|
|
38
38
|
type_ = OscillatorType::CUSTOM;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
void OscillatorNode::processNode(
|
|
41
|
+
void OscillatorNode::processNode(
|
|
42
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
43
|
+
int framesToProcess) {
|
|
42
44
|
size_t startOffset = 0;
|
|
43
45
|
size_t offsetLength = 0;
|
|
44
46
|
|
|
@@ -24,7 +24,7 @@ class OscillatorNode : public AudioScheduledSourceNode {
|
|
|
24
24
|
void setPeriodicWave(const std::shared_ptr<PeriodicWave> &periodicWave);
|
|
25
25
|
|
|
26
26
|
protected:
|
|
27
|
-
void processNode(AudioBus
|
|
27
|
+
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
28
28
|
|
|
29
29
|
private:
|
|
30
30
|
std::shared_ptr<AudioParam> frequencyParam_;
|
|
@@ -22,7 +22,7 @@ std::shared_ptr<AudioParam> StereoPannerNode::getPanParam() const {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
void StereoPannerNode::processNode(
|
|
25
|
-
AudioBus
|
|
25
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
26
26
|
int framesToProcess) {
|
|
27
27
|
double time = context_->getCurrentTime();
|
|
28
28
|
double deltaTime = 1.0 / context_->getSampleRate();
|