react-native-audio-api 0.1.0 → 0.2.0
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/README.md +10 -8
- package/RNAudioAPI.podspec +5 -0
- package/android/CMakeLists.txt +21 -10
- package/android/libs/fftw3/arm64-v8a/libfftw3.a +0 -0
- package/android/libs/fftw3/armeabi-v7a/libfftw3.a +0 -0
- package/android/libs/fftw3/x86/libfftw3.a +0 -0
- package/android/libs/fftw3/x86_64/libfftw3.a +0 -0
- package/android/libs/include/fftw3/fftw3.h +413 -0
- package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +23 -2
- package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +5 -2
- package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.cpp +13 -1
- package/common/cpp/HostObjects/AudioContextHostObject.cpp +11 -148
- package/common/cpp/HostObjects/AudioContextHostObject.h +4 -11
- package/common/cpp/HostObjects/AudioNodeHostObject.cpp +0 -6
- package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +214 -0
- package/common/cpp/HostObjects/BaseAudioContextHostObject.h +39 -0
- package/common/cpp/HostObjects/BiquadFilterNodeHostObject.cpp +44 -0
- package/common/cpp/HostObjects/OscillatorNodeHostObject.cpp +21 -0
- package/common/cpp/HostObjects/OscillatorNodeHostObject.h +1 -0
- package/common/cpp/HostObjects/PeriodicWaveHostObject.cpp +33 -0
- package/common/cpp/HostObjects/PeriodicWaveHostObject.h +33 -0
- package/common/cpp/core/AudioArray.cpp +103 -0
- package/common/cpp/core/AudioArray.h +42 -0
- package/common/cpp/core/AudioBuffer.cpp +23 -83
- package/common/cpp/core/AudioBuffer.h +11 -13
- package/common/cpp/core/AudioBufferSourceNode.cpp +102 -25
- package/common/cpp/core/AudioBufferSourceNode.h +10 -6
- package/common/cpp/core/AudioBus.cpp +357 -0
- package/common/cpp/core/AudioBus.h +63 -0
- package/common/cpp/core/AudioContext.cpp +6 -72
- package/common/cpp/core/AudioContext.h +3 -60
- package/common/cpp/core/AudioDestinationNode.cpp +25 -15
- package/common/cpp/core/AudioDestinationNode.h +15 -7
- package/common/cpp/core/AudioNode.cpp +176 -22
- package/common/cpp/core/AudioNode.h +37 -37
- package/common/cpp/core/AudioNodeManager.cpp +72 -0
- package/common/cpp/core/AudioNodeManager.h +35 -0
- package/common/cpp/core/AudioParam.cpp +8 -11
- package/common/cpp/core/AudioParam.h +8 -8
- package/common/cpp/core/AudioScheduledSourceNode.cpp +19 -5
- package/common/cpp/core/AudioScheduledSourceNode.h +6 -2
- package/common/cpp/core/BaseAudioContext.cpp +157 -0
- package/common/cpp/core/BaseAudioContext.h +80 -0
- package/common/cpp/core/BiquadFilterNode.cpp +90 -69
- package/common/cpp/core/BiquadFilterNode.h +53 -57
- package/common/cpp/core/GainNode.cpp +12 -12
- package/common/cpp/core/GainNode.h +5 -3
- package/common/cpp/core/OscillatorNode.cpp +38 -29
- package/common/cpp/core/OscillatorNode.h +29 -69
- package/common/cpp/core/ParamChange.h +6 -6
- package/common/cpp/core/PeriodicWave.cpp +362 -0
- package/common/cpp/core/PeriodicWave.h +119 -0
- package/common/cpp/core/StereoPannerNode.cpp +28 -30
- package/common/cpp/core/StereoPannerNode.h +6 -6
- package/common/cpp/types/BiquadFilterType.h +19 -0
- package/common/cpp/types/ChannelCountMode.h +10 -0
- package/common/cpp/types/ChannelInterpretation.h +10 -0
- package/common/cpp/types/ContextState.h +10 -0
- package/common/cpp/types/OscillatorType.h +11 -0
- package/common/cpp/utils/FFTFrame.h +63 -0
- package/common/cpp/utils/Locker.h +47 -0
- package/common/cpp/utils/VectorMath.cpp +72 -3
- package/common/cpp/utils/VectorMath.h +7 -1
- package/common/cpp/utils/android/FFTFrame.cpp +22 -0
- package/common/cpp/utils/ios/FFTFrame.cpp +24 -0
- package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.cpp +10 -0
- package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.h +3 -2
- package/common/cpp/wrappers/AudioBufferWrapper.h +5 -5
- package/common/cpp/wrappers/AudioContextWrapper.cpp +7 -60
- package/common/cpp/wrappers/AudioContextWrapper.h +5 -26
- package/common/cpp/wrappers/AudioNodeWrapper.h +5 -5
- package/common/cpp/wrappers/AudioParamWrapper.h +4 -4
- package/common/cpp/wrappers/BaseAudioContextWrapper.cpp +76 -0
- package/common/cpp/wrappers/BaseAudioContextWrapper.h +49 -0
- package/common/cpp/wrappers/BiquadFilterNodeWrapper.cpp +9 -0
- package/common/cpp/wrappers/BiquadFilterNodeWrapper.h +9 -4
- package/common/cpp/wrappers/GainNodeWrapper.h +1 -1
- package/common/cpp/wrappers/OscillatorNodeWrapper.cpp +6 -0
- package/common/cpp/wrappers/OscillatorNodeWrapper.h +5 -2
- package/common/cpp/wrappers/PeriodicWaveWrapper.h +17 -0
- package/common/cpp/wrappers/StereoPannerNodeWrapper.h +1 -1
- package/ios/AudioAPIModule.h +20 -1
- package/ios/AudioAPIModule.mm +3 -3
- package/ios/AudioPlayer/AudioPlayer.h +3 -2
- package/ios/AudioPlayer/AudioPlayer.m +15 -17
- package/ios/AudioPlayer/IOSAudioPlayer.h +8 -4
- package/ios/AudioPlayer/IOSAudioPlayer.mm +30 -7
- package/lib/module/core/AudioBuffer.js +37 -0
- package/lib/module/core/AudioBuffer.js.map +1 -0
- package/lib/module/core/AudioBufferSourceNode.js +28 -0
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -0
- package/lib/module/core/AudioContext.js +10 -0
- package/lib/module/core/AudioContext.js.map +1 -0
- package/lib/module/core/AudioDestinationNode.js +7 -0
- package/lib/module/core/AudioDestinationNode.js.map +1 -0
- package/lib/module/core/AudioNode.js +22 -0
- package/lib/module/core/AudioNode.js.map +1 -0
- package/lib/module/core/AudioParam.js +35 -0
- package/lib/module/core/AudioParam.js.map +1 -0
- package/lib/module/core/AudioScheduledSourceNode.js +28 -0
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -0
- package/lib/module/core/BaseAudioContext.js +57 -0
- package/lib/module/core/BaseAudioContext.js.map +1 -0
- package/lib/module/core/BiquadFilterNode.js +25 -0
- package/lib/module/core/BiquadFilterNode.js.map +1 -0
- package/lib/module/core/GainNode.js +9 -0
- package/lib/module/core/GainNode.js.map +1 -0
- package/lib/module/core/OscillatorNode.js +24 -0
- package/lib/module/core/OscillatorNode.js.map +1 -0
- package/lib/module/core/PeriodicWave.js +8 -0
- package/lib/module/core/PeriodicWave.js.map +1 -0
- package/lib/module/core/StereoPannerNode.js +9 -0
- package/lib/module/core/StereoPannerNode.js.map +1 -0
- package/lib/module/core/types.js.map +1 -0
- package/lib/module/errors/IndexSizeError.js +8 -0
- package/lib/module/errors/IndexSizeError.js.map +1 -0
- package/lib/module/errors/InvalidAccessError.js +8 -0
- package/lib/module/errors/InvalidAccessError.js.map +1 -0
- package/lib/module/errors/InvalidStateError.js +8 -0
- package/lib/module/errors/InvalidStateError.js.map +1 -0
- package/lib/module/errors/RangeError.js +8 -0
- package/lib/module/errors/RangeError.js.map +1 -0
- package/lib/module/errors/index.js +5 -0
- package/lib/module/errors/index.js.map +1 -0
- package/lib/module/index.js +13 -34
- package/lib/module/index.js.map +1 -1
- package/lib/module/interfaces.js +2 -0
- package/lib/module/interfaces.js.map +1 -0
- package/lib/typescript/core/AudioBuffer.d.ts +12 -0
- package/lib/typescript/core/AudioBuffer.d.ts.map +1 -0
- package/lib/typescript/core/AudioBufferSourceNode.d.ts +12 -0
- package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -0
- package/lib/typescript/core/AudioContext.d.ts +6 -0
- package/lib/typescript/core/AudioContext.d.ts.map +1 -0
- package/lib/typescript/core/AudioDestinationNode.d.ts +7 -0
- package/lib/typescript/core/AudioDestinationNode.d.ts.map +1 -0
- package/lib/typescript/core/AudioNode.d.ts +16 -0
- package/lib/typescript/core/AudioNode.d.ts.map +1 -0
- package/lib/typescript/core/AudioParam.d.ts +14 -0
- package/lib/typescript/core/AudioParam.d.ts.map +1 -0
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +10 -0
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -0
- package/lib/typescript/core/BaseAudioContext.d.ts +26 -0
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -0
- package/lib/typescript/core/BiquadFilterNode.d.ts +16 -0
- package/lib/typescript/core/BiquadFilterNode.d.ts.map +1 -0
- package/lib/typescript/core/GainNode.d.ts +9 -0
- package/lib/typescript/core/GainNode.d.ts.map +1 -0
- package/lib/typescript/core/OscillatorNode.d.ts +15 -0
- package/lib/typescript/core/OscillatorNode.d.ts.map +1 -0
- package/lib/typescript/core/PeriodicWave.d.ts +5 -0
- package/lib/typescript/core/PeriodicWave.d.ts.map +1 -0
- package/lib/typescript/core/StereoPannerNode.d.ts +9 -0
- package/lib/typescript/core/StereoPannerNode.d.ts.map +1 -0
- package/lib/typescript/core/types.d.ts +9 -0
- package/lib/typescript/core/types.d.ts.map +1 -0
- package/lib/typescript/errors/IndexSizeError.d.ts +5 -0
- package/lib/typescript/errors/IndexSizeError.d.ts.map +1 -0
- package/lib/typescript/errors/InvalidAccessError.d.ts +5 -0
- package/lib/typescript/errors/InvalidAccessError.d.ts.map +1 -0
- package/lib/typescript/errors/InvalidStateError.d.ts +5 -0
- package/lib/typescript/errors/InvalidStateError.d.ts.map +1 -0
- package/lib/typescript/errors/RangeError.d.ts +5 -0
- package/lib/typescript/errors/RangeError.d.ts.map +1 -0
- package/lib/typescript/errors/index.d.ts +5 -0
- package/lib/typescript/errors/index.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +13 -17
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +78 -0
- package/lib/typescript/interfaces.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/core/AudioBuffer.ts +68 -0
- package/src/core/AudioBufferSourceNode.ts +35 -0
- package/src/core/AudioContext.ts +12 -0
- package/src/core/AudioDestinationNode.ts +9 -0
- package/src/core/AudioNode.ts +38 -0
- package/src/core/AudioParam.ts +55 -0
- package/src/core/AudioScheduledSourceNode.ts +43 -0
- package/src/core/BaseAudioContext.ts +97 -0
- package/src/core/BiquadFilterNode.ts +49 -0
- package/src/core/GainNode.ts +13 -0
- package/src/core/OscillatorNode.ts +37 -0
- package/src/core/PeriodicWave.ts +10 -0
- package/src/core/StereoPannerNode.ts +13 -0
- package/src/core/types.ts +26 -0
- package/src/errors/IndexSizeError.ts +8 -0
- package/src/errors/InvalidAccessError.ts +8 -0
- package/src/errors/InvalidStateError.ts +8 -0
- package/src/errors/RangeError.ts +8 -0
- package/src/errors/index.ts +4 -0
- package/src/index.ts +19 -73
- package/src/interfaces.ts +120 -0
- package/src/modules/global.d.ts +3 -3
- package/lib/module/types.js.map +0 -1
- package/lib/typescript/types.d.ts +0 -76
- package/lib/typescript/types.d.ts.map +0 -1
- package/src/types.ts +0 -108
- /package/lib/module/{types.js → core/types.js} +0 -0
|
@@ -12,7 +12,7 @@ class GainNodeWrapper : public AudioNodeWrapper {
|
|
|
12
12
|
public:
|
|
13
13
|
explicit GainNodeWrapper(const std::shared_ptr<GainNode> &gainNode);
|
|
14
14
|
|
|
15
|
-
std::shared_ptr<AudioParamWrapper> getGainParam() const;
|
|
15
|
+
[[nodiscard]] std::shared_ptr<AudioParamWrapper> getGainParam() const;
|
|
16
16
|
|
|
17
17
|
private:
|
|
18
18
|
std::shared_ptr<AudioParamWrapper> gainParam_;
|
|
@@ -35,4 +35,10 @@ void OscillatorNodeWrapper::setType(const std::string &type) {
|
|
|
35
35
|
auto oscillatorNode_ = getOscillatorNodeFromAudioNode();
|
|
36
36
|
oscillatorNode_->setType(type);
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
void OscillatorNodeWrapper::setPeriodicWave(
|
|
40
|
+
const std::shared_ptr<PeriodicWaveWrapper> &periodicWave) {
|
|
41
|
+
auto oscillatorNode_ = getOscillatorNodeFromAudioNode();
|
|
42
|
+
oscillatorNode_->setPeriodicWave(periodicWave->periodicWave_);
|
|
43
|
+
}
|
|
38
44
|
} // namespace audioapi
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include "AudioParamWrapper.h"
|
|
7
7
|
#include "AudioScheduledSourceNodeWrapper.h"
|
|
8
8
|
#include "OscillatorNode.h"
|
|
9
|
+
#include "PeriodicWaveWrapper.h"
|
|
9
10
|
|
|
10
11
|
namespace audioapi {
|
|
11
12
|
|
|
@@ -14,10 +15,12 @@ class OscillatorNodeWrapper : public AudioScheduledSourceNodeWrapper {
|
|
|
14
15
|
explicit OscillatorNodeWrapper(
|
|
15
16
|
const std::shared_ptr<OscillatorNode> &oscillatorNode);
|
|
16
17
|
|
|
17
|
-
std::shared_ptr<AudioParamWrapper> getFrequencyParam() const;
|
|
18
|
-
std::shared_ptr<AudioParamWrapper> getDetuneParam() const;
|
|
18
|
+
[[nodiscard]] std::shared_ptr<AudioParamWrapper> getFrequencyParam() const;
|
|
19
|
+
[[nodiscard]] std::shared_ptr<AudioParamWrapper> getDetuneParam() const;
|
|
19
20
|
std::string getType();
|
|
20
21
|
void setType(const std::string &type);
|
|
22
|
+
void setPeriodicWave(
|
|
23
|
+
const std::shared_ptr<PeriodicWaveWrapper> &periodicWave);
|
|
21
24
|
|
|
22
25
|
private:
|
|
23
26
|
std::shared_ptr<AudioParamWrapper> frequencyParam_;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <memory>
|
|
4
|
+
|
|
5
|
+
#include "PeriodicWave.h"
|
|
6
|
+
|
|
7
|
+
namespace audioapi {
|
|
8
|
+
|
|
9
|
+
class PeriodicWaveWrapper {
|
|
10
|
+
public:
|
|
11
|
+
explicit PeriodicWaveWrapper(
|
|
12
|
+
const std::shared_ptr<PeriodicWave> &periodicWave)
|
|
13
|
+
: periodicWave_(periodicWave) {}
|
|
14
|
+
|
|
15
|
+
std::shared_ptr<PeriodicWave> periodicWave_;
|
|
16
|
+
};
|
|
17
|
+
} // namespace audioapi
|
|
@@ -13,7 +13,7 @@ class StereoPannerNodeWrapper : public AudioNodeWrapper {
|
|
|
13
13
|
explicit StereoPannerNodeWrapper(
|
|
14
14
|
const std::shared_ptr<StereoPannerNode> &stereoPannerNode);
|
|
15
15
|
|
|
16
|
-
std::shared_ptr<AudioParamWrapper> getPanParam() const;
|
|
16
|
+
[[nodiscard]] std::shared_ptr<AudioParamWrapper> getPanParam() const;
|
|
17
17
|
|
|
18
18
|
private:
|
|
19
19
|
std::shared_ptr<AudioParamWrapper> panParam_;
|
package/ios/AudioAPIModule.h
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
2
|
+
#import <React/RCTInitializing.h>
|
|
3
|
+
#if REACT_NATIVE_MINOR_VERSION >= 74
|
|
4
|
+
#import <React/RCTRuntimeExecutorModule.h>
|
|
5
|
+
#import <ReactCommon/RCTRuntimeExecutor.h>
|
|
6
|
+
#endif // REACT_NATIVE_MINOR_VERSION >= 74
|
|
7
|
+
#else // RCT_NEW_ARCH_ENABLED
|
|
1
8
|
#import <React/RCTBridgeModule.h>
|
|
9
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
2
10
|
|
|
3
|
-
|
|
11
|
+
#import <React/RCTEventEmitter.h>
|
|
4
12
|
|
|
13
|
+
@interface AudioAPIModule : RCTEventEmitter
|
|
14
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
15
|
+
<RCTInitializing
|
|
16
|
+
#if REACT_NATIVE_MINOR_VERSION >= 74
|
|
17
|
+
,
|
|
18
|
+
RCTRuntimeExecutorModule
|
|
19
|
+
#endif // REACT_NATIVE_MINOR_VERSION >= 74
|
|
20
|
+
#else
|
|
21
|
+
<RCTBridgeModule
|
|
22
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
23
|
+
>
|
|
5
24
|
@end
|
package/ios/AudioAPIModule.mm
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
#import <React/RCTUtils.h>
|
|
5
5
|
#import <jsi/jsi.h>
|
|
6
6
|
|
|
7
|
-
#import "
|
|
8
|
-
#import "
|
|
7
|
+
#import "AudioAPIInstallerHostObject.h"
|
|
8
|
+
#import "AudioAPIInstallerWrapper.h"
|
|
9
9
|
|
|
10
10
|
@implementation AudioAPIModule
|
|
11
11
|
|
|
@@ -14,7 +14,7 @@ RCT_EXPORT_MODULE(AudioAPIModule)
|
|
|
14
14
|
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
|
|
15
15
|
{
|
|
16
16
|
NSLog(@"Installing JSI bindings for react-native-audio-api...");
|
|
17
|
-
RCTCxxBridge *cxxBridge = (RCTCxxBridge *)
|
|
17
|
+
RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
|
|
18
18
|
|
|
19
19
|
if (cxxBridge == nil) {
|
|
20
20
|
NSLog(@"Error during getting bridge!");
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#import <AVFoundation/AVFoundation.h>
|
|
4
4
|
#import <Foundation/Foundation.h>
|
|
5
5
|
|
|
6
|
-
typedef void (^RenderAudioBlock)(
|
|
6
|
+
typedef void (^RenderAudioBlock)(AudioBufferList* outputBuffer, int numFrames);
|
|
7
7
|
|
|
8
8
|
@interface AudioPlayer : NSObject
|
|
9
9
|
|
|
@@ -12,12 +12,13 @@ typedef void (^RenderAudioBlock)(float *audioData, int numFrames);
|
|
|
12
12
|
@property (nonatomic, strong) AVAudioFormat *format;
|
|
13
13
|
@property (nonatomic, strong) AVAudioSourceNode *sourceNode;
|
|
14
14
|
@property (nonatomic, copy) RenderAudioBlock renderAudio;
|
|
15
|
-
@property (nonatomic, assign) float *buffer;
|
|
16
15
|
|
|
17
16
|
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio;
|
|
18
17
|
|
|
19
18
|
- (int)getSampleRate;
|
|
20
19
|
|
|
20
|
+
- (int)getBufferSizeInFrames;
|
|
21
|
+
|
|
21
22
|
- (void)start;
|
|
22
23
|
|
|
23
24
|
- (void)stop;
|
|
@@ -42,8 +42,6 @@
|
|
|
42
42
|
frameCount:frameCount
|
|
43
43
|
outputData:outputData];
|
|
44
44
|
}];
|
|
45
|
-
|
|
46
|
-
self.buffer = nil;
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
return self;
|
|
@@ -54,11 +52,25 @@
|
|
|
54
52
|
return [self.audioSession sampleRate];
|
|
55
53
|
}
|
|
56
54
|
|
|
55
|
+
- (int)getBufferSizeInFrames
|
|
56
|
+
{
|
|
57
|
+
// Note: might be important in the future.
|
|
58
|
+
// For some reason audioSession.IOBufferDuration is always 0.01, which for sample rate of 48k
|
|
59
|
+
// gives exactly 480 frames, while at the same time frameCount requested by AVAudioSourceEngine
|
|
60
|
+
// might vary f.e. between 555-560.
|
|
61
|
+
// preferredIOBufferDuration seems to be double the value (resulting in 960 frames),
|
|
62
|
+
// which is safer to base our internal AudioBus sizes.
|
|
63
|
+
// Buut no documentation => no guarantee :)
|
|
64
|
+
// If something is crackling when it should play silence, start here 📻
|
|
65
|
+
return (int)(self.audioSession.preferredIOBufferDuration * self.audioSession.sampleRate);
|
|
66
|
+
}
|
|
67
|
+
|
|
57
68
|
- (void)start
|
|
58
69
|
{
|
|
59
70
|
[self.audioEngine attachNode:self.sourceNode];
|
|
60
71
|
[self.audioEngine connect:self.sourceNode to:self.audioEngine.mainMixerNode format:self.format];
|
|
61
72
|
|
|
73
|
+
|
|
62
74
|
if (!self.audioEngine.isRunning) {
|
|
63
75
|
NSError *error = nil;
|
|
64
76
|
if (![self.audioEngine startAndReturnError:&error]) {
|
|
@@ -88,8 +100,6 @@
|
|
|
88
100
|
self.audioEngine = nil;
|
|
89
101
|
self.audioSession = nil;
|
|
90
102
|
self.renderAudio = nil;
|
|
91
|
-
|
|
92
|
-
free(_buffer);
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
- (OSStatus)renderCallbackWithIsSilence:(BOOL *)isSilence
|
|
@@ -101,19 +111,7 @@
|
|
|
101
111
|
return noErr; // Ensure we have stereo output
|
|
102
112
|
}
|
|
103
113
|
|
|
104
|
-
|
|
105
|
-
self.buffer = malloc(frameCount * 2 * sizeof(float));
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
float *leftBuffer = (float *)outputData->mBuffers[0].mData;
|
|
109
|
-
float *rightBuffer = (float *)outputData->mBuffers[1].mData;
|
|
110
|
-
|
|
111
|
-
self.renderAudio(self.buffer, frameCount);
|
|
112
|
-
|
|
113
|
-
for (int frame = 0; frame < frameCount; frame += 1) {
|
|
114
|
-
leftBuffer[frame] = self.buffer[frame * 2];
|
|
115
|
-
rightBuffer[frame] = self.buffer[frame * 2 + 1];
|
|
116
|
-
}
|
|
114
|
+
self.renderAudio(outputData, frameCount);
|
|
117
115
|
|
|
118
116
|
return noErr;
|
|
119
117
|
}
|
|
@@ -11,19 +11,23 @@ typedef struct objc_object AudioPlayer;
|
|
|
11
11
|
namespace audioapi {
|
|
12
12
|
|
|
13
13
|
class AudioContext;
|
|
14
|
+
class AudioBus;
|
|
14
15
|
|
|
15
16
|
class IOSAudioPlayer {
|
|
16
17
|
protected:
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
AudioBus* audioBus_;
|
|
19
|
+
AudioPlayer* audioPlayer_;
|
|
20
|
+
std::function<void(AudioBus*, int)> renderAudio_;
|
|
19
21
|
|
|
20
22
|
public:
|
|
21
|
-
explicit IOSAudioPlayer(const std::function<void(
|
|
23
|
+
explicit IOSAudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio);
|
|
22
24
|
~IOSAudioPlayer();
|
|
23
25
|
|
|
24
26
|
int getSampleRate() const;
|
|
27
|
+
int getBufferSizeInFrames() const;
|
|
28
|
+
|
|
25
29
|
void start();
|
|
26
30
|
void stop();
|
|
27
|
-
|
|
31
|
+
|
|
28
32
|
};
|
|
29
33
|
} // namespace audioapi
|
|
@@ -1,25 +1,37 @@
|
|
|
1
|
+
#import <AVFoundation/AVFoundation.h>
|
|
2
|
+
|
|
3
|
+
#include <AudioBus.h>
|
|
4
|
+
#include <Constants.h>
|
|
5
|
+
#include <AudioArray.h>
|
|
1
6
|
#include <IOSAudioPlayer.h>
|
|
2
7
|
|
|
3
8
|
namespace audioapi {
|
|
4
9
|
|
|
5
|
-
IOSAudioPlayer::IOSAudioPlayer(const std::function<void(
|
|
10
|
+
IOSAudioPlayer::IOSAudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio) : renderAudio_(renderAudio), audioBus_(0)
|
|
6
11
|
{
|
|
7
|
-
RenderAudioBlock renderAudioBlock = ^(
|
|
8
|
-
renderAudio_(
|
|
12
|
+
RenderAudioBlock renderAudioBlock = ^(AudioBufferList* outputData, int numFrames) {
|
|
13
|
+
renderAudio_(audioBus_, numFrames);
|
|
14
|
+
|
|
15
|
+
for (int i = 0; i < outputData->mNumberBuffers; i += 1) {
|
|
16
|
+
float *outputBuffer = (float *)outputData->mBuffers[i].mData;
|
|
17
|
+
|
|
18
|
+
memcpy(outputBuffer, audioBus_->getChannel(i)->getData(), sizeof(float) * numFrames);
|
|
19
|
+
}
|
|
9
20
|
};
|
|
10
21
|
|
|
11
22
|
audioPlayer_ = [[AudioPlayer alloc] initWithRenderAudioBlock:renderAudioBlock];
|
|
23
|
+
audioBus_ = new AudioBus(getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
|
|
12
24
|
}
|
|
13
25
|
|
|
14
26
|
IOSAudioPlayer::~IOSAudioPlayer()
|
|
15
27
|
{
|
|
16
28
|
stop();
|
|
17
29
|
[audioPlayer_ cleanup];
|
|
18
|
-
}
|
|
19
30
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
31
|
+
if (audioBus_) {
|
|
32
|
+
delete audioBus_;
|
|
33
|
+
audioBus_ = 0;
|
|
34
|
+
}
|
|
23
35
|
}
|
|
24
36
|
|
|
25
37
|
void IOSAudioPlayer::start()
|
|
@@ -31,4 +43,15 @@ void IOSAudioPlayer::stop()
|
|
|
31
43
|
{
|
|
32
44
|
return [audioPlayer_ stop];
|
|
33
45
|
}
|
|
46
|
+
|
|
47
|
+
int IOSAudioPlayer::getSampleRate() const
|
|
48
|
+
{
|
|
49
|
+
return [audioPlayer_ getSampleRate];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
int IOSAudioPlayer::getBufferSizeInFrames() const
|
|
53
|
+
{
|
|
54
|
+
return [audioPlayer_ getBufferSizeInFrames];
|
|
55
|
+
}
|
|
56
|
+
|
|
34
57
|
} // namespace audioapi
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { IndexSizeError } from '../errors';
|
|
2
|
+
export default class AudioBuffer {
|
|
3
|
+
/** @internal */
|
|
4
|
+
|
|
5
|
+
constructor(buffer) {
|
|
6
|
+
this.buffer = buffer;
|
|
7
|
+
this.length = buffer.length;
|
|
8
|
+
this.duration = buffer.duration;
|
|
9
|
+
this.sampleRate = buffer.sampleRate;
|
|
10
|
+
this.numberOfChannels = buffer.numberOfChannels;
|
|
11
|
+
}
|
|
12
|
+
getChannelData(channel) {
|
|
13
|
+
if (channel < 0 || channel >= this.numberOfChannels) {
|
|
14
|
+
throw new IndexSizeError(`The channel number provided (${channel}) is outside the range [0, ${this.numberOfChannels - 1}]`);
|
|
15
|
+
}
|
|
16
|
+
return this.buffer.getChannelData(channel);
|
|
17
|
+
}
|
|
18
|
+
copyFromChannel(destination, channelNumber, startInChannel = 0) {
|
|
19
|
+
if (channelNumber < 0 || channelNumber >= this.numberOfChannels) {
|
|
20
|
+
throw new IndexSizeError(`The channel number provided (${channelNumber}) is outside the range [0, ${this.numberOfChannels - 1}]`);
|
|
21
|
+
}
|
|
22
|
+
if (startInChannel < 0 || startInChannel >= this.length) {
|
|
23
|
+
throw new IndexSizeError(`The startInChannel number provided (${startInChannel}) is outside the range [0, ${this.length - 1}]`);
|
|
24
|
+
}
|
|
25
|
+
this.buffer.copyFromChannel(destination, channelNumber, startInChannel);
|
|
26
|
+
}
|
|
27
|
+
copyToChannel(source, channelNumber, startInChannel = 0) {
|
|
28
|
+
if (channelNumber < 0 || channelNumber >= this.numberOfChannels) {
|
|
29
|
+
throw new IndexSizeError(`The channel number provided (${channelNumber}) is outside the range [0, ${this.numberOfChannels - 1}]`);
|
|
30
|
+
}
|
|
31
|
+
if (startInChannel < 0 || startInChannel >= this.length) {
|
|
32
|
+
throw new IndexSizeError(`The startInChannel number provided (${startInChannel}) is outside the range [0, ${this.length - 1}]`);
|
|
33
|
+
}
|
|
34
|
+
this.buffer.copyToChannel(source, channelNumber, startInChannel);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=AudioBuffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["IndexSizeError","AudioBuffer","constructor","buffer","length","duration","sampleRate","numberOfChannels","getChannelData","channel","copyFromChannel","destination","channelNumber","startInChannel","copyToChannel","source"],"sourceRoot":"../../../src","sources":["core/AudioBuffer.ts"],"mappings":"AACA,SAASA,cAAc,QAAQ,WAAW;AAE1C,eAAe,MAAMC,WAAW,CAAC;EAK/B;;EAGAC,WAAWA,CAACC,MAAoB,EAAE;IAChC,IAAI,CAACA,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACC,MAAM,GAAGD,MAAM,CAACC,MAAM;IAC3B,IAAI,CAACC,QAAQ,GAAGF,MAAM,CAACE,QAAQ;IAC/B,IAAI,CAACC,UAAU,GAAGH,MAAM,CAACG,UAAU;IACnC,IAAI,CAACC,gBAAgB,GAAGJ,MAAM,CAACI,gBAAgB;EACjD;EAEOC,cAAcA,CAACC,OAAe,EAAY;IAC/C,IAAIA,OAAO,GAAG,CAAC,IAAIA,OAAO,IAAI,IAAI,CAACF,gBAAgB,EAAE;MACnD,MAAM,IAAIP,cAAc,CACtB,gCAAgCS,OAAO,8BAA8B,IAAI,CAACF,gBAAgB,GAAG,CAAC,GAChG,CAAC;IACH;IACA,OAAO,IAAI,CAACJ,MAAM,CAACK,cAAc,CAACC,OAAO,CAAC;EAC5C;EAEOC,eAAeA,CACpBC,WAAqB,EACrBC,aAAqB,EACrBC,cAAsB,GAAG,CAAC,EACpB;IACN,IAAID,aAAa,GAAG,CAAC,IAAIA,aAAa,IAAI,IAAI,CAACL,gBAAgB,EAAE;MAC/D,MAAM,IAAIP,cAAc,CACtB,gCAAgCY,aAAa,8BAA8B,IAAI,CAACL,gBAAgB,GAAG,CAAC,GACtG,CAAC;IACH;IAEA,IAAIM,cAAc,GAAG,CAAC,IAAIA,cAAc,IAAI,IAAI,CAACT,MAAM,EAAE;MACvD,MAAM,IAAIJ,cAAc,CACtB,uCAAuCa,cAAc,8BAA8B,IAAI,CAACT,MAAM,GAAG,CAAC,GACpG,CAAC;IACH;IAEA,IAAI,CAACD,MAAM,CAACO,eAAe,CAACC,WAAW,EAAEC,aAAa,EAAEC,cAAc,CAAC;EACzE;EAEOC,aAAaA,CAClBC,MAAgB,EAChBH,aAAqB,EACrBC,cAAsB,GAAG,CAAC,EACpB;IACN,IAAID,aAAa,GAAG,CAAC,IAAIA,aAAa,IAAI,IAAI,CAACL,gBAAgB,EAAE;MAC/D,MAAM,IAAIP,cAAc,CACtB,gCAAgCY,aAAa,8BAA8B,IAAI,CAACL,gBAAgB,GAAG,CAAC,GACtG,CAAC;IACH;IAEA,IAAIM,cAAc,GAAG,CAAC,IAAIA,cAAc,IAAI,IAAI,CAACT,MAAM,EAAE;MACvD,MAAM,IAAIJ,cAAc,CACtB,uCAAuCa,cAAc,8BAA8B,IAAI,CAACT,MAAM,GAAG,CAAC,GACpG,CAAC;IACH;IAEA,IAAI,CAACD,MAAM,CAACW,aAAa,CAACC,MAAM,EAAEH,aAAa,EAAEC,cAAc,CAAC;EAClE;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import AudioScheduledSourceNode from './AudioScheduledSourceNode';
|
|
2
|
+
import AudioBuffer from './AudioBuffer';
|
|
3
|
+
export default class AudioBufferSourceNode extends AudioScheduledSourceNode {
|
|
4
|
+
constructor(context, node) {
|
|
5
|
+
super(context, node);
|
|
6
|
+
}
|
|
7
|
+
get buffer() {
|
|
8
|
+
const buffer = this.node.buffer;
|
|
9
|
+
if (!buffer) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return new AudioBuffer(buffer);
|
|
13
|
+
}
|
|
14
|
+
set buffer(buffer) {
|
|
15
|
+
if (!buffer) {
|
|
16
|
+
this.node.buffer = null;
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
this.node.buffer = buffer.buffer;
|
|
20
|
+
}
|
|
21
|
+
get loop() {
|
|
22
|
+
return this.node.loop;
|
|
23
|
+
}
|
|
24
|
+
set loop(value) {
|
|
25
|
+
this.node.loop = value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=AudioBufferSourceNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["AudioScheduledSourceNode","AudioBuffer","AudioBufferSourceNode","constructor","context","node","buffer","loop","value"],"sourceRoot":"../../../src","sources":["core/AudioBufferSourceNode.ts"],"mappings":"AACA,OAAOA,wBAAwB,MAAM,4BAA4B;AAEjE,OAAOC,WAAW,MAAM,eAAe;AAEvC,eAAe,MAAMC,qBAAqB,SAASF,wBAAwB,CAAC;EAC1EG,WAAWA,CAACC,OAAyB,EAAEC,IAA4B,EAAE;IACnE,KAAK,CAACD,OAAO,EAAEC,IAAI,CAAC;EACtB;EAEA,IAAWC,MAAMA,CAAA,EAAuB;IACtC,MAAMA,MAAM,GAAI,IAAI,CAACD,IAAI,CAA4BC,MAAM;IAC3D,IAAI,CAACA,MAAM,EAAE;MACX,OAAO,IAAI;IACb;IACA,OAAO,IAAIL,WAAW,CAACK,MAAM,CAAC;EAChC;EAEA,IAAWA,MAAMA,CAACA,MAA0B,EAAE;IAC5C,IAAI,CAACA,MAAM,EAAE;MACV,IAAI,CAACD,IAAI,CAA4BC,MAAM,GAAG,IAAI;MACnD;IACF;IAEC,IAAI,CAACD,IAAI,CAA4BC,MAAM,GAAGA,MAAM,CAACA,MAAM;EAC9D;EAEA,IAAWC,IAAIA,CAAA,EAAY;IACzB,OAAQ,IAAI,CAACF,IAAI,CAA4BE,IAAI;EACnD;EAEA,IAAWA,IAAIA,CAACC,KAAc,EAAE;IAC7B,IAAI,CAACH,IAAI,CAA4BE,IAAI,GAAGC,KAAK;EACpD;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import BaseAudioContext from './BaseAudioContext';
|
|
2
|
+
export default class AudioContext extends BaseAudioContext {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(global.__AudioAPIInstaller.createAudioContext());
|
|
5
|
+
}
|
|
6
|
+
close() {
|
|
7
|
+
this.context.close();
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=AudioContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["BaseAudioContext","AudioContext","constructor","global","__AudioAPIInstaller","createAudioContext","close","context"],"sourceRoot":"../../../src","sources":["core/AudioContext.ts"],"mappings":"AACA,OAAOA,gBAAgB,MAAM,oBAAoB;AAEjD,eAAe,MAAMC,YAAY,SAASD,gBAAgB,CAAC;EACzDE,WAAWA,CAAA,EAAG;IACZ,KAAK,CAACC,MAAM,CAACC,mBAAmB,CAACC,kBAAkB,CAAC,CAAC,CAAC;EACxD;EAEAC,KAAKA,CAAA,EAAS;IACX,IAAI,CAACC,OAAO,CAAmBD,KAAK,CAAC,CAAC;EACzC;AACF","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["AudioNode","AudioDestinationNode","constructor","context","destination"],"sourceRoot":"../../../src","sources":["core/AudioDestinationNode.ts"],"mappings":"AACA,OAAOA,SAAS,MAAM,aAAa;AAGnC,eAAe,MAAMC,oBAAoB,SAASD,SAAS,CAAC;EAC1DE,WAAWA,CAACC,OAAyB,EAAEC,WAAkC,EAAE;IACzE,KAAK,CAACD,OAAO,EAAEC,WAAW,CAAC;EAC7B;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { InvalidAccessError } from '../errors';
|
|
2
|
+
export default class AudioNode {
|
|
3
|
+
constructor(context, node) {
|
|
4
|
+
this.context = context;
|
|
5
|
+
this.node = node;
|
|
6
|
+
this.numberOfInputs = this.node.numberOfInputs;
|
|
7
|
+
this.numberOfOutputs = this.node.numberOfOutputs;
|
|
8
|
+
this.channelCount = this.node.channelCount;
|
|
9
|
+
this.channelCountMode = this.node.channelCountMode;
|
|
10
|
+
this.channelInterpretation = this.node.channelInterpretation;
|
|
11
|
+
}
|
|
12
|
+
connect(node) {
|
|
13
|
+
if (this.context !== node.context) {
|
|
14
|
+
throw new InvalidAccessError('The AudioNodes are from different BaseAudioContexts');
|
|
15
|
+
}
|
|
16
|
+
this.node.connect(node.node);
|
|
17
|
+
}
|
|
18
|
+
disconnect(node) {
|
|
19
|
+
this.node.disconnect(node.node);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=AudioNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["InvalidAccessError","AudioNode","constructor","context","node","numberOfInputs","numberOfOutputs","channelCount","channelCountMode","channelInterpretation","connect","disconnect"],"sourceRoot":"../../../src","sources":["core/AudioNode.ts"],"mappings":"AAGA,SAASA,kBAAkB,QAAQ,WAAW;AAE9C,eAAe,MAAMC,SAAS,CAAC;EAS7BC,WAAWA,CAACC,OAAyB,EAAEC,IAAgB,EAAE;IACvD,IAAI,CAACD,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACC,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACC,cAAc,GAAG,IAAI,CAACD,IAAI,CAACC,cAAc;IAC9C,IAAI,CAACC,eAAe,GAAG,IAAI,CAACF,IAAI,CAACE,eAAe;IAChD,IAAI,CAACC,YAAY,GAAG,IAAI,CAACH,IAAI,CAACG,YAAY;IAC1C,IAAI,CAACC,gBAAgB,GAAG,IAAI,CAACJ,IAAI,CAACI,gBAAgB;IAClD,IAAI,CAACC,qBAAqB,GAAG,IAAI,CAACL,IAAI,CAACK,qBAAqB;EAC9D;EAEOC,OAAOA,CAACN,IAAe,EAAQ;IACpC,IAAI,IAAI,CAACD,OAAO,KAAKC,IAAI,CAACD,OAAO,EAAE;MACjC,MAAM,IAAIH,kBAAkB,CAC1B,qDACF,CAAC;IACH;IAEA,IAAI,CAACI,IAAI,CAACM,OAAO,CAACN,IAAI,CAACA,IAAI,CAAC;EAC9B;EAEOO,UAAUA,CAACP,IAAe,EAAQ;IACvC,IAAI,CAACA,IAAI,CAACO,UAAU,CAACP,IAAI,CAACA,IAAI,CAAC;EACjC;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { RangeError } from '../errors';
|
|
2
|
+
export default class AudioParam {
|
|
3
|
+
constructor(audioParam) {
|
|
4
|
+
this.audioParam = audioParam;
|
|
5
|
+
this.value = audioParam.value;
|
|
6
|
+
this.defaultValue = audioParam.defaultValue;
|
|
7
|
+
this.minValue = audioParam.minValue;
|
|
8
|
+
this.maxValue = audioParam.maxValue;
|
|
9
|
+
}
|
|
10
|
+
get value() {
|
|
11
|
+
return this.audioParam.value;
|
|
12
|
+
}
|
|
13
|
+
set value(value) {
|
|
14
|
+
this.audioParam.value = value;
|
|
15
|
+
}
|
|
16
|
+
setValueAtTime(value, startTime) {
|
|
17
|
+
if (startTime < 0) {
|
|
18
|
+
throw new RangeError(`Time must be a finite non-negative number: ${startTime}`);
|
|
19
|
+
}
|
|
20
|
+
this.audioParam.setValueAtTime(value, startTime);
|
|
21
|
+
}
|
|
22
|
+
linearRampToValueAtTime(value, endTime) {
|
|
23
|
+
if (endTime < 0) {
|
|
24
|
+
throw new RangeError(`Time must be a finite non-negative number: ${endTime}`);
|
|
25
|
+
}
|
|
26
|
+
this.audioParam.linearRampToValueAtTime(value, endTime);
|
|
27
|
+
}
|
|
28
|
+
exponentialRampToValueAtTime(value, endTime) {
|
|
29
|
+
if (endTime < 0) {
|
|
30
|
+
throw new RangeError(`Time must be a finite non-negative number: ${endTime}`);
|
|
31
|
+
}
|
|
32
|
+
this.audioParam.exponentialRampToValueAtTime(value, endTime);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=AudioParam.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["RangeError","AudioParam","constructor","audioParam","value","defaultValue","minValue","maxValue","setValueAtTime","startTime","linearRampToValueAtTime","endTime","exponentialRampToValueAtTime"],"sourceRoot":"../../../src","sources":["core/AudioParam.ts"],"mappings":"AACA,SAASA,UAAU,QAAQ,WAAW;AAEtC,eAAe,MAAMC,UAAU,CAAC;EAM9BC,WAAWA,CAACC,UAAuB,EAAE;IACnC,IAAI,CAACA,UAAU,GAAGA,UAAU;IAC5B,IAAI,CAACC,KAAK,GAAGD,UAAU,CAACC,KAAK;IAC7B,IAAI,CAACC,YAAY,GAAGF,UAAU,CAACE,YAAY;IAC3C,IAAI,CAACC,QAAQ,GAAGH,UAAU,CAACG,QAAQ;IACnC,IAAI,CAACC,QAAQ,GAAGJ,UAAU,CAACI,QAAQ;EACrC;EAEA,IAAWH,KAAKA,CAAA,EAAW;IACzB,OAAO,IAAI,CAACD,UAAU,CAACC,KAAK;EAC9B;EAEA,IAAWA,KAAKA,CAACA,KAAa,EAAE;IAC9B,IAAI,CAACD,UAAU,CAACC,KAAK,GAAGA,KAAK;EAC/B;EAEOI,cAAcA,CAACJ,KAAa,EAAEK,SAAiB,EAAQ;IAC5D,IAAIA,SAAS,GAAG,CAAC,EAAE;MACjB,MAAM,IAAIT,UAAU,CAClB,8CAA8CS,SAAS,EACzD,CAAC;IACH;IAEA,IAAI,CAACN,UAAU,CAACK,cAAc,CAACJ,KAAK,EAAEK,SAAS,CAAC;EAClD;EAEOC,uBAAuBA,CAACN,KAAa,EAAEO,OAAe,EAAQ;IACnE,IAAIA,OAAO,GAAG,CAAC,EAAE;MACf,MAAM,IAAIX,UAAU,CAClB,8CAA8CW,OAAO,EACvD,CAAC;IACH;IAEA,IAAI,CAACR,UAAU,CAACO,uBAAuB,CAACN,KAAK,EAAEO,OAAO,CAAC;EACzD;EAEOC,4BAA4BA,CAACR,KAAa,EAAEO,OAAe,EAAQ;IACxE,IAAIA,OAAO,GAAG,CAAC,EAAE;MACf,MAAM,IAAIX,UAAU,CAClB,8CAA8CW,OAAO,EACvD,CAAC;IACH;IAEA,IAAI,CAACR,UAAU,CAACS,4BAA4B,CAACR,KAAK,EAAEO,OAAO,CAAC;EAC9D;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import AudioNode from './AudioNode';
|
|
2
|
+
import { InvalidStateError, RangeError } from '../errors';
|
|
3
|
+
export default class AudioScheduledSourceNode extends AudioNode {
|
|
4
|
+
hasBeenStarted = false;
|
|
5
|
+
constructor(context, node) {
|
|
6
|
+
super(context, node);
|
|
7
|
+
}
|
|
8
|
+
start(when = 0) {
|
|
9
|
+
if (when < 0) {
|
|
10
|
+
throw new RangeError(`Time must be a finite non-negative number: ${when}`);
|
|
11
|
+
}
|
|
12
|
+
if (this.hasBeenStarted) {
|
|
13
|
+
throw new InvalidStateError('Cannot call start more than once');
|
|
14
|
+
}
|
|
15
|
+
this.hasBeenStarted = true;
|
|
16
|
+
this.node.start(when);
|
|
17
|
+
}
|
|
18
|
+
stop(when = 0) {
|
|
19
|
+
if (when < 0) {
|
|
20
|
+
throw new RangeError(`Time must be a finite non-negative number: ${when}`);
|
|
21
|
+
}
|
|
22
|
+
if (!this.hasBeenStarted) {
|
|
23
|
+
throw new InvalidStateError('Cannot call stop without calling start first');
|
|
24
|
+
}
|
|
25
|
+
this.node.stop(when);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=AudioScheduledSourceNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["AudioNode","InvalidStateError","RangeError","AudioScheduledSourceNode","hasBeenStarted","constructor","context","node","start","when","stop"],"sourceRoot":"../../../src","sources":["core/AudioScheduledSourceNode.ts"],"mappings":"AACA,OAAOA,SAAS,MAAM,aAAa;AAEnC,SAASC,iBAAiB,EAAEC,UAAU,QAAQ,WAAW;AAEzD,eAAe,MAAMC,wBAAwB,SAASH,SAAS,CAAC;EACtDI,cAAc,GAAY,KAAK;EAEvCC,WAAWA,CAACC,OAAyB,EAAEC,IAA+B,EAAE;IACtE,KAAK,CAACD,OAAO,EAAEC,IAAI,CAAC;EACtB;EAEOC,KAAKA,CAACC,IAAY,GAAG,CAAC,EAAQ;IACnC,IAAIA,IAAI,GAAG,CAAC,EAAE;MACZ,MAAM,IAAIP,UAAU,CAClB,8CAA8CO,IAAI,EACpD,CAAC;IACH;IAEA,IAAI,IAAI,CAACL,cAAc,EAAE;MACvB,MAAM,IAAIH,iBAAiB,CAAC,kCAAkC,CAAC;IACjE;IAEA,IAAI,CAACG,cAAc,GAAG,IAAI;IACzB,IAAI,CAACG,IAAI,CAA+BC,KAAK,CAACC,IAAI,CAAC;EACtD;EAEOC,IAAIA,CAACD,IAAY,GAAG,CAAC,EAAQ;IAClC,IAAIA,IAAI,GAAG,CAAC,EAAE;MACZ,MAAM,IAAIP,UAAU,CAClB,8CAA8CO,IAAI,EACpD,CAAC;IACH;IAEA,IAAI,CAAC,IAAI,CAACL,cAAc,EAAE;MACxB,MAAM,IAAIH,iBAAiB,CACzB,8CACF,CAAC;IACH;IAEC,IAAI,CAACM,IAAI,CAA+BG,IAAI,CAACD,IAAI,CAAC;EACrD;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import AudioDestinationNode from './AudioDestinationNode';
|
|
2
|
+
import OscillatorNode from './OscillatorNode';
|
|
3
|
+
import GainNode from './GainNode';
|
|
4
|
+
import StereoPannerNode from './StereoPannerNode';
|
|
5
|
+
import BiquadFilterNode from './BiquadFilterNode';
|
|
6
|
+
import AudioBufferSourceNode from './AudioBufferSourceNode';
|
|
7
|
+
import AudioBuffer from './AudioBuffer';
|
|
8
|
+
import PeriodicWave from './PeriodicWave';
|
|
9
|
+
import { InvalidAccessError } from '../errors';
|
|
10
|
+
export default class BaseAudioContext {
|
|
11
|
+
constructor(context) {
|
|
12
|
+
this.context = context;
|
|
13
|
+
this.destination = new AudioDestinationNode(this, context.destination);
|
|
14
|
+
this.sampleRate = context.sampleRate;
|
|
15
|
+
}
|
|
16
|
+
get currentTime() {
|
|
17
|
+
return this.context.currentTime;
|
|
18
|
+
}
|
|
19
|
+
get state() {
|
|
20
|
+
return this.context.state;
|
|
21
|
+
}
|
|
22
|
+
createOscillator() {
|
|
23
|
+
return new OscillatorNode(this, this.context.createOscillator());
|
|
24
|
+
}
|
|
25
|
+
createGain() {
|
|
26
|
+
return new GainNode(this, this.context.createGain());
|
|
27
|
+
}
|
|
28
|
+
createStereoPanner() {
|
|
29
|
+
return new StereoPannerNode(this, this.context.createStereoPanner());
|
|
30
|
+
}
|
|
31
|
+
createBiquadFilter() {
|
|
32
|
+
return new BiquadFilterNode(this, this.context.createBiquadFilter());
|
|
33
|
+
}
|
|
34
|
+
createBufferSource() {
|
|
35
|
+
return new AudioBufferSourceNode(this, this.context.createBufferSource());
|
|
36
|
+
}
|
|
37
|
+
createBuffer(numOfChannels, length, sampleRate) {
|
|
38
|
+
if (numOfChannels < 1 || numOfChannels > 3) {
|
|
39
|
+
throw new RangeError(`The number of channels provided (${numOfChannels}) is outside the range [1, 2]`);
|
|
40
|
+
}
|
|
41
|
+
if (length <= 0) {
|
|
42
|
+
throw new RangeError(`The number of frames provided (${length}) is less than or equal to the minimum bound (0)`);
|
|
43
|
+
}
|
|
44
|
+
if (sampleRate <= 0) {
|
|
45
|
+
throw new RangeError(`The sample rate provided (${sampleRate}) is outside the range [3000, 768000]`);
|
|
46
|
+
}
|
|
47
|
+
return new AudioBuffer(this.context.createBuffer(numOfChannels, length, sampleRate));
|
|
48
|
+
}
|
|
49
|
+
createPeriodicWave(real, imag, constraints) {
|
|
50
|
+
if (real.length !== imag.length) {
|
|
51
|
+
throw new InvalidAccessError(`The lengths of the real (${real.length}) and imaginary (${imag.length}) arrays must match.`);
|
|
52
|
+
}
|
|
53
|
+
const disableNormalization = constraints?.disableNormalization ?? false;
|
|
54
|
+
return new PeriodicWave(this.context.createPeriodicWave(real, imag, disableNormalization));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=BaseAudioContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["AudioDestinationNode","OscillatorNode","GainNode","StereoPannerNode","BiquadFilterNode","AudioBufferSourceNode","AudioBuffer","PeriodicWave","InvalidAccessError","BaseAudioContext","constructor","context","destination","sampleRate","currentTime","state","createOscillator","createGain","createStereoPanner","createBiquadFilter","createBufferSource","createBuffer","numOfChannels","length","RangeError","createPeriodicWave","real","imag","constraints","disableNormalization"],"sourceRoot":"../../../src","sources":["core/BaseAudioContext.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { InvalidAccessError } from '../errors';
|
|
2
|
+
import AudioNode from './AudioNode';
|
|
3
|
+
import AudioParam from './AudioParam';
|
|
4
|
+
export default class BiquadFilterNode extends AudioNode {
|
|
5
|
+
constructor(context, biquadFilter) {
|
|
6
|
+
super(context, biquadFilter);
|
|
7
|
+
this.frequency = new AudioParam(biquadFilter.frequency);
|
|
8
|
+
this.detune = new AudioParam(biquadFilter.detune);
|
|
9
|
+
this.Q = new AudioParam(biquadFilter.Q);
|
|
10
|
+
this.gain = new AudioParam(biquadFilter.gain);
|
|
11
|
+
}
|
|
12
|
+
get type() {
|
|
13
|
+
return this.node.type;
|
|
14
|
+
}
|
|
15
|
+
set type(value) {
|
|
16
|
+
this.node.type = value;
|
|
17
|
+
}
|
|
18
|
+
getFrequencyResponse(frequencyArray, magResponseOutput, phaseResponseOutput) {
|
|
19
|
+
if (frequencyArray.length !== magResponseOutput.length || frequencyArray.length !== phaseResponseOutput.length) {
|
|
20
|
+
throw new InvalidAccessError(`The lengths of the arrays are not the same frequencyArray: ${frequencyArray.length}, magResponseOutput: ${magResponseOutput.length}, phaseResponseOutput: ${phaseResponseOutput.length}`);
|
|
21
|
+
}
|
|
22
|
+
this.node.getFrequencyResponse(frequencyArray, magResponseOutput, phaseResponseOutput);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=BiquadFilterNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["InvalidAccessError","AudioNode","AudioParam","BiquadFilterNode","constructor","context","biquadFilter","frequency","detune","Q","gain","type","node","value","getFrequencyResponse","frequencyArray","magResponseOutput","phaseResponseOutput","length"],"sourceRoot":"../../../src","sources":["core/BiquadFilterNode.ts"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,WAAW;AAE9C,OAAOC,SAAS,MAAM,aAAa;AACnC,OAAOC,UAAU,MAAM,cAAc;AAIrC,eAAe,MAAMC,gBAAgB,SAASF,SAAS,CAAC;EAMtDG,WAAWA,CAACC,OAAyB,EAAEC,YAA+B,EAAE;IACtE,KAAK,CAACD,OAAO,EAAEC,YAAY,CAAC;IAC5B,IAAI,CAACC,SAAS,GAAG,IAAIL,UAAU,CAACI,YAAY,CAACC,SAAS,CAAC;IACvD,IAAI,CAACC,MAAM,GAAG,IAAIN,UAAU,CAACI,YAAY,CAACE,MAAM,CAAC;IACjD,IAAI,CAACC,CAAC,GAAG,IAAIP,UAAU,CAACI,YAAY,CAACG,CAAC,CAAC;IACvC,IAAI,CAACC,IAAI,GAAG,IAAIR,UAAU,CAACI,YAAY,CAACI,IAAI,CAAC;EAC/C;EAEA,IAAWC,IAAIA,CAAA,EAAqB;IAClC,OAAQ,IAAI,CAACC,IAAI,CAAuBD,IAAI;EAC9C;EAEA,IAAWA,IAAIA,CAACE,KAAuB,EAAE;IACtC,IAAI,CAACD,IAAI,CAAuBD,IAAI,GAAGE,KAAK;EAC/C;EAEOC,oBAAoBA,CACzBC,cAAwB,EACxBC,iBAA2B,EAC3BC,mBAA6B,EAC7B;IACA,IACEF,cAAc,CAACG,MAAM,KAAKF,iBAAiB,CAACE,MAAM,IAClDH,cAAc,CAACG,MAAM,KAAKD,mBAAmB,CAACC,MAAM,EACpD;MACA,MAAM,IAAIlB,kBAAkB,CAC1B,8DAA8De,cAAc,CAACG,MAAM,wBAAwBF,iBAAiB,CAACE,MAAM,0BAA0BD,mBAAmB,CAACC,MAAM,EACzL,CAAC;IACH;IACC,IAAI,CAACN,IAAI,CAAuBE,oBAAoB,CACnDC,cAAc,EACdC,iBAAiB,EACjBC,mBACF,CAAC;EACH;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import AudioNode from './AudioNode';
|
|
2
|
+
import AudioParam from './AudioParam';
|
|
3
|
+
export default class GainNode extends AudioNode {
|
|
4
|
+
constructor(context, gain) {
|
|
5
|
+
super(context, gain);
|
|
6
|
+
this.gain = new AudioParam(gain.gain);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=GainNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["AudioNode","AudioParam","GainNode","constructor","context","gain"],"sourceRoot":"../../../src","sources":["core/GainNode.ts"],"mappings":"AACA,OAAOA,SAAS,MAAM,aAAa;AACnC,OAAOC,UAAU,MAAM,cAAc;AAGrC,eAAe,MAAMC,QAAQ,SAASF,SAAS,CAAC;EAG9CG,WAAWA,CAACC,OAAyB,EAAEC,IAAe,EAAE;IACtD,KAAK,CAACD,OAAO,EAAEC,IAAI,CAAC;IACpB,IAAI,CAACA,IAAI,GAAG,IAAIJ,UAAU,CAACI,IAAI,CAACA,IAAI,CAAC;EACvC;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import AudioScheduledSourceNode from './AudioScheduledSourceNode';
|
|
2
|
+
import AudioParam from './AudioParam';
|
|
3
|
+
import { InvalidStateError } from '../errors';
|
|
4
|
+
export default class OscillatorNode extends AudioScheduledSourceNode {
|
|
5
|
+
constructor(context, node) {
|
|
6
|
+
super(context, node);
|
|
7
|
+
this.frequency = new AudioParam(node.frequency);
|
|
8
|
+
this.detune = new AudioParam(node.detune);
|
|
9
|
+
this.type = node.type;
|
|
10
|
+
}
|
|
11
|
+
get type() {
|
|
12
|
+
return this.node.type;
|
|
13
|
+
}
|
|
14
|
+
set type(value) {
|
|
15
|
+
if (value === 'custom') {
|
|
16
|
+
throw new InvalidStateError("'type' cannot be set directly to 'custom'. Use setPeriodicWave() to create a custom Oscillator type.");
|
|
17
|
+
}
|
|
18
|
+
this.node.type = value;
|
|
19
|
+
}
|
|
20
|
+
setPeriodicWave(wave) {
|
|
21
|
+
this.node.setPeriodicWave(wave.periodicWave);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=OscillatorNode.js.map
|