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.
Files changed (198) hide show
  1. package/README.md +10 -8
  2. package/RNAudioAPI.podspec +5 -0
  3. package/android/CMakeLists.txt +21 -10
  4. package/android/libs/fftw3/arm64-v8a/libfftw3.a +0 -0
  5. package/android/libs/fftw3/armeabi-v7a/libfftw3.a +0 -0
  6. package/android/libs/fftw3/x86/libfftw3.a +0 -0
  7. package/android/libs/fftw3/x86_64/libfftw3.a +0 -0
  8. package/android/libs/include/fftw3/fftw3.h +413 -0
  9. package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +23 -2
  10. package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +5 -2
  11. package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.cpp +13 -1
  12. package/common/cpp/HostObjects/AudioContextHostObject.cpp +11 -148
  13. package/common/cpp/HostObjects/AudioContextHostObject.h +4 -11
  14. package/common/cpp/HostObjects/AudioNodeHostObject.cpp +0 -6
  15. package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +214 -0
  16. package/common/cpp/HostObjects/BaseAudioContextHostObject.h +39 -0
  17. package/common/cpp/HostObjects/BiquadFilterNodeHostObject.cpp +44 -0
  18. package/common/cpp/HostObjects/OscillatorNodeHostObject.cpp +21 -0
  19. package/common/cpp/HostObjects/OscillatorNodeHostObject.h +1 -0
  20. package/common/cpp/HostObjects/PeriodicWaveHostObject.cpp +33 -0
  21. package/common/cpp/HostObjects/PeriodicWaveHostObject.h +33 -0
  22. package/common/cpp/core/AudioArray.cpp +103 -0
  23. package/common/cpp/core/AudioArray.h +42 -0
  24. package/common/cpp/core/AudioBuffer.cpp +23 -83
  25. package/common/cpp/core/AudioBuffer.h +11 -13
  26. package/common/cpp/core/AudioBufferSourceNode.cpp +102 -25
  27. package/common/cpp/core/AudioBufferSourceNode.h +10 -6
  28. package/common/cpp/core/AudioBus.cpp +357 -0
  29. package/common/cpp/core/AudioBus.h +63 -0
  30. package/common/cpp/core/AudioContext.cpp +6 -72
  31. package/common/cpp/core/AudioContext.h +3 -60
  32. package/common/cpp/core/AudioDestinationNode.cpp +25 -15
  33. package/common/cpp/core/AudioDestinationNode.h +15 -7
  34. package/common/cpp/core/AudioNode.cpp +176 -22
  35. package/common/cpp/core/AudioNode.h +37 -37
  36. package/common/cpp/core/AudioNodeManager.cpp +72 -0
  37. package/common/cpp/core/AudioNodeManager.h +35 -0
  38. package/common/cpp/core/AudioParam.cpp +8 -11
  39. package/common/cpp/core/AudioParam.h +8 -8
  40. package/common/cpp/core/AudioScheduledSourceNode.cpp +19 -5
  41. package/common/cpp/core/AudioScheduledSourceNode.h +6 -2
  42. package/common/cpp/core/BaseAudioContext.cpp +157 -0
  43. package/common/cpp/core/BaseAudioContext.h +80 -0
  44. package/common/cpp/core/BiquadFilterNode.cpp +90 -69
  45. package/common/cpp/core/BiquadFilterNode.h +53 -57
  46. package/common/cpp/core/GainNode.cpp +12 -12
  47. package/common/cpp/core/GainNode.h +5 -3
  48. package/common/cpp/core/OscillatorNode.cpp +38 -29
  49. package/common/cpp/core/OscillatorNode.h +29 -69
  50. package/common/cpp/core/ParamChange.h +6 -6
  51. package/common/cpp/core/PeriodicWave.cpp +362 -0
  52. package/common/cpp/core/PeriodicWave.h +119 -0
  53. package/common/cpp/core/StereoPannerNode.cpp +28 -30
  54. package/common/cpp/core/StereoPannerNode.h +6 -6
  55. package/common/cpp/types/BiquadFilterType.h +19 -0
  56. package/common/cpp/types/ChannelCountMode.h +10 -0
  57. package/common/cpp/types/ChannelInterpretation.h +10 -0
  58. package/common/cpp/types/ContextState.h +10 -0
  59. package/common/cpp/types/OscillatorType.h +11 -0
  60. package/common/cpp/utils/FFTFrame.h +63 -0
  61. package/common/cpp/utils/Locker.h +47 -0
  62. package/common/cpp/utils/VectorMath.cpp +72 -3
  63. package/common/cpp/utils/VectorMath.h +7 -1
  64. package/common/cpp/utils/android/FFTFrame.cpp +22 -0
  65. package/common/cpp/utils/ios/FFTFrame.cpp +24 -0
  66. package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.cpp +10 -0
  67. package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.h +3 -2
  68. package/common/cpp/wrappers/AudioBufferWrapper.h +5 -5
  69. package/common/cpp/wrappers/AudioContextWrapper.cpp +7 -60
  70. package/common/cpp/wrappers/AudioContextWrapper.h +5 -26
  71. package/common/cpp/wrappers/AudioNodeWrapper.h +5 -5
  72. package/common/cpp/wrappers/AudioParamWrapper.h +4 -4
  73. package/common/cpp/wrappers/BaseAudioContextWrapper.cpp +76 -0
  74. package/common/cpp/wrappers/BaseAudioContextWrapper.h +49 -0
  75. package/common/cpp/wrappers/BiquadFilterNodeWrapper.cpp +9 -0
  76. package/common/cpp/wrappers/BiquadFilterNodeWrapper.h +9 -4
  77. package/common/cpp/wrappers/GainNodeWrapper.h +1 -1
  78. package/common/cpp/wrappers/OscillatorNodeWrapper.cpp +6 -0
  79. package/common/cpp/wrappers/OscillatorNodeWrapper.h +5 -2
  80. package/common/cpp/wrappers/PeriodicWaveWrapper.h +17 -0
  81. package/common/cpp/wrappers/StereoPannerNodeWrapper.h +1 -1
  82. package/ios/AudioAPIModule.h +20 -1
  83. package/ios/AudioAPIModule.mm +3 -3
  84. package/ios/AudioPlayer/AudioPlayer.h +3 -2
  85. package/ios/AudioPlayer/AudioPlayer.m +15 -17
  86. package/ios/AudioPlayer/IOSAudioPlayer.h +8 -4
  87. package/ios/AudioPlayer/IOSAudioPlayer.mm +30 -7
  88. package/lib/module/core/AudioBuffer.js +37 -0
  89. package/lib/module/core/AudioBuffer.js.map +1 -0
  90. package/lib/module/core/AudioBufferSourceNode.js +28 -0
  91. package/lib/module/core/AudioBufferSourceNode.js.map +1 -0
  92. package/lib/module/core/AudioContext.js +10 -0
  93. package/lib/module/core/AudioContext.js.map +1 -0
  94. package/lib/module/core/AudioDestinationNode.js +7 -0
  95. package/lib/module/core/AudioDestinationNode.js.map +1 -0
  96. package/lib/module/core/AudioNode.js +22 -0
  97. package/lib/module/core/AudioNode.js.map +1 -0
  98. package/lib/module/core/AudioParam.js +35 -0
  99. package/lib/module/core/AudioParam.js.map +1 -0
  100. package/lib/module/core/AudioScheduledSourceNode.js +28 -0
  101. package/lib/module/core/AudioScheduledSourceNode.js.map +1 -0
  102. package/lib/module/core/BaseAudioContext.js +57 -0
  103. package/lib/module/core/BaseAudioContext.js.map +1 -0
  104. package/lib/module/core/BiquadFilterNode.js +25 -0
  105. package/lib/module/core/BiquadFilterNode.js.map +1 -0
  106. package/lib/module/core/GainNode.js +9 -0
  107. package/lib/module/core/GainNode.js.map +1 -0
  108. package/lib/module/core/OscillatorNode.js +24 -0
  109. package/lib/module/core/OscillatorNode.js.map +1 -0
  110. package/lib/module/core/PeriodicWave.js +8 -0
  111. package/lib/module/core/PeriodicWave.js.map +1 -0
  112. package/lib/module/core/StereoPannerNode.js +9 -0
  113. package/lib/module/core/StereoPannerNode.js.map +1 -0
  114. package/lib/module/core/types.js.map +1 -0
  115. package/lib/module/errors/IndexSizeError.js +8 -0
  116. package/lib/module/errors/IndexSizeError.js.map +1 -0
  117. package/lib/module/errors/InvalidAccessError.js +8 -0
  118. package/lib/module/errors/InvalidAccessError.js.map +1 -0
  119. package/lib/module/errors/InvalidStateError.js +8 -0
  120. package/lib/module/errors/InvalidStateError.js.map +1 -0
  121. package/lib/module/errors/RangeError.js +8 -0
  122. package/lib/module/errors/RangeError.js.map +1 -0
  123. package/lib/module/errors/index.js +5 -0
  124. package/lib/module/errors/index.js.map +1 -0
  125. package/lib/module/index.js +13 -34
  126. package/lib/module/index.js.map +1 -1
  127. package/lib/module/interfaces.js +2 -0
  128. package/lib/module/interfaces.js.map +1 -0
  129. package/lib/typescript/core/AudioBuffer.d.ts +12 -0
  130. package/lib/typescript/core/AudioBuffer.d.ts.map +1 -0
  131. package/lib/typescript/core/AudioBufferSourceNode.d.ts +12 -0
  132. package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -0
  133. package/lib/typescript/core/AudioContext.d.ts +6 -0
  134. package/lib/typescript/core/AudioContext.d.ts.map +1 -0
  135. package/lib/typescript/core/AudioDestinationNode.d.ts +7 -0
  136. package/lib/typescript/core/AudioDestinationNode.d.ts.map +1 -0
  137. package/lib/typescript/core/AudioNode.d.ts +16 -0
  138. package/lib/typescript/core/AudioNode.d.ts.map +1 -0
  139. package/lib/typescript/core/AudioParam.d.ts +14 -0
  140. package/lib/typescript/core/AudioParam.d.ts.map +1 -0
  141. package/lib/typescript/core/AudioScheduledSourceNode.d.ts +10 -0
  142. package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -0
  143. package/lib/typescript/core/BaseAudioContext.d.ts +26 -0
  144. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -0
  145. package/lib/typescript/core/BiquadFilterNode.d.ts +16 -0
  146. package/lib/typescript/core/BiquadFilterNode.d.ts.map +1 -0
  147. package/lib/typescript/core/GainNode.d.ts +9 -0
  148. package/lib/typescript/core/GainNode.d.ts.map +1 -0
  149. package/lib/typescript/core/OscillatorNode.d.ts +15 -0
  150. package/lib/typescript/core/OscillatorNode.d.ts.map +1 -0
  151. package/lib/typescript/core/PeriodicWave.d.ts +5 -0
  152. package/lib/typescript/core/PeriodicWave.d.ts.map +1 -0
  153. package/lib/typescript/core/StereoPannerNode.d.ts +9 -0
  154. package/lib/typescript/core/StereoPannerNode.d.ts.map +1 -0
  155. package/lib/typescript/core/types.d.ts +9 -0
  156. package/lib/typescript/core/types.d.ts.map +1 -0
  157. package/lib/typescript/errors/IndexSizeError.d.ts +5 -0
  158. package/lib/typescript/errors/IndexSizeError.d.ts.map +1 -0
  159. package/lib/typescript/errors/InvalidAccessError.d.ts +5 -0
  160. package/lib/typescript/errors/InvalidAccessError.d.ts.map +1 -0
  161. package/lib/typescript/errors/InvalidStateError.d.ts +5 -0
  162. package/lib/typescript/errors/InvalidStateError.d.ts.map +1 -0
  163. package/lib/typescript/errors/RangeError.d.ts +5 -0
  164. package/lib/typescript/errors/RangeError.d.ts.map +1 -0
  165. package/lib/typescript/errors/index.d.ts +5 -0
  166. package/lib/typescript/errors/index.d.ts.map +1 -0
  167. package/lib/typescript/index.d.ts +13 -17
  168. package/lib/typescript/index.d.ts.map +1 -1
  169. package/lib/typescript/interfaces.d.ts +78 -0
  170. package/lib/typescript/interfaces.d.ts.map +1 -0
  171. package/package.json +1 -1
  172. package/src/core/AudioBuffer.ts +68 -0
  173. package/src/core/AudioBufferSourceNode.ts +35 -0
  174. package/src/core/AudioContext.ts +12 -0
  175. package/src/core/AudioDestinationNode.ts +9 -0
  176. package/src/core/AudioNode.ts +38 -0
  177. package/src/core/AudioParam.ts +55 -0
  178. package/src/core/AudioScheduledSourceNode.ts +43 -0
  179. package/src/core/BaseAudioContext.ts +97 -0
  180. package/src/core/BiquadFilterNode.ts +49 -0
  181. package/src/core/GainNode.ts +13 -0
  182. package/src/core/OscillatorNode.ts +37 -0
  183. package/src/core/PeriodicWave.ts +10 -0
  184. package/src/core/StereoPannerNode.ts +13 -0
  185. package/src/core/types.ts +26 -0
  186. package/src/errors/IndexSizeError.ts +8 -0
  187. package/src/errors/InvalidAccessError.ts +8 -0
  188. package/src/errors/InvalidStateError.ts +8 -0
  189. package/src/errors/RangeError.ts +8 -0
  190. package/src/errors/index.ts +4 -0
  191. package/src/index.ts +19 -73
  192. package/src/interfaces.ts +120 -0
  193. package/src/modules/global.d.ts +3 -3
  194. package/lib/module/types.js.map +0 -1
  195. package/lib/typescript/types.d.ts +0 -76
  196. package/lib/typescript/types.d.ts.map +0 -1
  197. package/src/types.ts +0 -108
  198. /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_;
@@ -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
- @interface AudioAPIModule : NSObject <RCTBridgeModule>
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
@@ -4,8 +4,8 @@
4
4
  #import <React/RCTUtils.h>
5
5
  #import <jsi/jsi.h>
6
6
 
7
- #import "../common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h"
8
- #import "../common/cpp/AudioAPIInstaller/AudioAPIInstallerWrapper.h"
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 *)[RCTBridge currentBridge];
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)(float *audioData, int numFrames);
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
- if (!self.buffer) {
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
- AudioPlayer *audioPlayer_;
18
- std::function<void(float *, int)> renderAudio_;
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(float *, int)> &renderAudio);
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
- void renderAudio(float *audioData, int32_t numFrames);
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(float *, int)> &renderAudio) : renderAudio_(renderAudio)
10
+ IOSAudioPlayer::IOSAudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio) : renderAudio_(renderAudio), audioBus_(0)
6
11
  {
7
- RenderAudioBlock renderAudioBlock = ^(float *audioData, int numFrames) {
8
- renderAudio_(audioData, numFrames);
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
- int IOSAudioPlayer::getSampleRate() const
21
- {
22
- return [audioPlayer_ getSampleRate];
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,7 @@
1
+ import AudioNode from './AudioNode';
2
+ export default class AudioDestinationNode extends AudioNode {
3
+ constructor(context, destination) {
4
+ super(context, destination);
5
+ }
6
+ }
7
+ //# sourceMappingURL=AudioDestinationNode.js.map
@@ -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