react-native-audio-api 0.4.8-rc2 → 0.4.9

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 (147) hide show
  1. package/android/CMakeLists.txt +2 -5
  2. package/android/build.gradle +25 -2
  3. package/android/src/main/cpp/core/AudioDecoder.cpp +10 -1
  4. package/android/src/main/cpp/core/AudioPlayer.cpp +6 -3
  5. package/android/src/main/cpp/libs/pffft.c +1906 -0
  6. package/android/src/main/cpp/libs/pffft.h +198 -0
  7. package/common/cpp/core/AnalyserNode.cpp +11 -10
  8. package/common/cpp/core/AnalyserNode.h +2 -0
  9. package/common/cpp/core/AudioBuffer.cpp +1 -1
  10. package/common/cpp/core/AudioBufferSourceNode.cpp +26 -16
  11. package/common/cpp/core/AudioBus.cpp +105 -13
  12. package/common/cpp/core/AudioBus.h +6 -4
  13. package/common/cpp/core/AudioContext.cpp +4 -3
  14. package/common/cpp/core/AudioContext.h +4 -4
  15. package/common/cpp/core/AudioDestinationNode.cpp +2 -3
  16. package/common/cpp/core/AudioNode.cpp +78 -58
  17. package/common/cpp/core/AudioNode.h +10 -1
  18. package/common/cpp/core/AudioNodeManager.cpp +13 -1
  19. package/common/cpp/core/AudioNodeManager.h +2 -0
  20. package/common/cpp/core/AudioScheduledSourceNode.cpp +5 -1
  21. package/common/cpp/core/BaseAudioContext.cpp +4 -1
  22. package/common/cpp/core/BaseAudioContext.h +4 -2
  23. package/common/cpp/core/PeriodicWave.cpp +9 -3
  24. package/common/cpp/core/StereoPannerNode.cpp +9 -12
  25. package/common/cpp/utils/FFTFrame.cpp +44 -37
  26. package/common/cpp/utils/FFTFrame.h +5 -14
  27. package/ios/core/AudioDecoder.mm +10 -1
  28. package/ios/core/AudioPlayer.m +23 -23
  29. package/ios/core/IOSAudioPlayer.mm +3 -3
  30. package/lib/module/core/AudioBufferSourceNode.js +2 -2
  31. package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
  32. package/lib/module/index.js +19 -335
  33. package/lib/module/index.js.map +1 -1
  34. package/lib/module/index.web.js +18 -0
  35. package/lib/module/index.web.js.map +1 -0
  36. package/lib/module/types.js.map +1 -0
  37. package/lib/module/web-core/AnalyserNode.js +48 -0
  38. package/lib/module/web-core/AnalyserNode.js.map +1 -0
  39. package/lib/module/web-core/AudioBuffer.js +43 -0
  40. package/lib/module/web-core/AudioBuffer.js.map +1 -0
  41. package/lib/module/web-core/AudioBufferSourceNode.js +62 -0
  42. package/lib/module/web-core/AudioBufferSourceNode.js.map +1 -0
  43. package/lib/module/web-core/AudioContext.js +69 -0
  44. package/lib/module/web-core/AudioContext.js.map +1 -0
  45. package/lib/module/web-core/AudioDestinationNode.js +5 -0
  46. package/lib/module/web-core/AudioDestinationNode.js.map +1 -0
  47. package/lib/module/web-core/AudioNode.js +27 -0
  48. package/lib/module/web-core/AudioNode.js.map +1 -0
  49. package/lib/module/web-core/AudioParam.js +60 -0
  50. package/lib/module/web-core/AudioParam.js.map +1 -0
  51. package/lib/module/web-core/AudioScheduledSourceNode.js +27 -0
  52. package/lib/module/web-core/AudioScheduledSourceNode.js.map +1 -0
  53. package/lib/module/web-core/BaseAudioContext.js +2 -0
  54. package/lib/module/{core/types.js.map → web-core/BaseAudioContext.js.map} +1 -1
  55. package/lib/module/web-core/BiquadFilterNode.js +35 -0
  56. package/lib/module/web-core/BiquadFilterNode.js.map +1 -0
  57. package/lib/module/web-core/GainNode.js +11 -0
  58. package/lib/module/web-core/GainNode.js.map +1 -0
  59. package/lib/module/web-core/OscillatorNode.js +25 -0
  60. package/lib/module/web-core/OscillatorNode.js.map +1 -0
  61. package/lib/module/web-core/PeriodicWave.js +10 -0
  62. package/lib/module/web-core/PeriodicWave.js.map +1 -0
  63. package/lib/module/web-core/StereoPannerNode.js +11 -0
  64. package/lib/module/web-core/StereoPannerNode.js.map +1 -0
  65. package/lib/typescript/core/AnalyserNode.d.ts +1 -1
  66. package/lib/typescript/core/AnalyserNode.d.ts.map +1 -1
  67. package/lib/typescript/core/AudioNode.d.ts +1 -1
  68. package/lib/typescript/core/AudioNode.d.ts.map +1 -1
  69. package/lib/typescript/core/BaseAudioContext.d.ts +1 -1
  70. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  71. package/lib/typescript/core/BiquadFilterNode.d.ts +1 -1
  72. package/lib/typescript/core/BiquadFilterNode.d.ts.map +1 -1
  73. package/lib/typescript/core/OscillatorNode.d.ts +1 -1
  74. package/lib/typescript/core/OscillatorNode.d.ts.map +1 -1
  75. package/lib/typescript/index.d.ts +15 -126
  76. package/lib/typescript/index.d.ts.map +1 -1
  77. package/lib/typescript/index.web.d.ts +16 -0
  78. package/lib/typescript/index.web.d.ts.map +1 -0
  79. package/lib/typescript/interfaces.d.ts +1 -1
  80. package/lib/typescript/interfaces.d.ts.map +1 -1
  81. package/lib/typescript/types.d.ts.map +1 -0
  82. package/lib/typescript/web-core/AnalyserNode.d.ts +18 -0
  83. package/lib/typescript/web-core/AnalyserNode.d.ts.map +1 -0
  84. package/lib/typescript/web-core/AudioBuffer.d.ts +13 -0
  85. package/lib/typescript/web-core/AudioBuffer.d.ts.map +1 -0
  86. package/lib/typescript/web-core/AudioBufferSourceNode.d.ts +19 -0
  87. package/lib/typescript/web-core/AudioBufferSourceNode.d.ts.map +1 -0
  88. package/lib/typescript/web-core/AudioContext.d.ts +30 -0
  89. package/lib/typescript/web-core/AudioContext.d.ts.map +1 -0
  90. package/lib/typescript/web-core/AudioDestinationNode.d.ts +4 -0
  91. package/lib/typescript/web-core/AudioDestinationNode.d.ts.map +1 -0
  92. package/lib/typescript/web-core/AudioNode.d.ts +15 -0
  93. package/lib/typescript/web-core/AudioNode.d.ts.map +1 -0
  94. package/lib/typescript/web-core/AudioParam.d.ts +17 -0
  95. package/lib/typescript/web-core/AudioParam.d.ts.map +1 -0
  96. package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts +7 -0
  97. package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts.map +1 -0
  98. package/lib/typescript/web-core/BaseAudioContext.d.ts +27 -0
  99. package/lib/typescript/web-core/BaseAudioContext.d.ts.map +1 -0
  100. package/lib/typescript/web-core/BiquadFilterNode.d.ts +15 -0
  101. package/lib/typescript/web-core/BiquadFilterNode.d.ts.map +1 -0
  102. package/lib/typescript/web-core/GainNode.d.ts +8 -0
  103. package/lib/typescript/web-core/GainNode.d.ts.map +1 -0
  104. package/lib/typescript/web-core/OscillatorNode.d.ts +14 -0
  105. package/lib/typescript/web-core/OscillatorNode.d.ts.map +1 -0
  106. package/lib/typescript/web-core/PeriodicWave.d.ts +6 -0
  107. package/lib/typescript/web-core/PeriodicWave.d.ts.map +1 -0
  108. package/lib/typescript/web-core/StereoPannerNode.d.ts +8 -0
  109. package/lib/typescript/web-core/StereoPannerNode.d.ts.map +1 -0
  110. package/package.json +1 -1
  111. package/src/core/AnalyserNode.ts +1 -1
  112. package/src/core/AudioBufferSourceNode.ts +2 -2
  113. package/src/core/AudioNode.ts +1 -1
  114. package/src/core/BaseAudioContext.ts +1 -1
  115. package/src/core/BiquadFilterNode.ts +1 -1
  116. package/src/core/OscillatorNode.ts +1 -1
  117. package/src/index.ts +30 -568
  118. package/src/index.web.ts +30 -0
  119. package/src/interfaces.ts +1 -1
  120. package/src/web-core/AnalyserNode.tsx +69 -0
  121. package/src/web-core/AudioBuffer.tsx +79 -0
  122. package/src/web-core/AudioBufferSourceNode.tsx +94 -0
  123. package/src/web-core/AudioContext.tsx +114 -0
  124. package/src/web-core/AudioDestinationNode.tsx +3 -0
  125. package/src/web-core/AudioNode.tsx +40 -0
  126. package/src/web-core/AudioParam.tsx +106 -0
  127. package/src/web-core/AudioScheduledSourceNode.tsx +37 -0
  128. package/src/web-core/BaseAudioContext.tsx +37 -0
  129. package/src/web-core/BiquadFilterNode.tsx +62 -0
  130. package/src/web-core/GainNode.tsx +12 -0
  131. package/src/web-core/OscillatorNode.tsx +36 -0
  132. package/src/web-core/PeriodicWave.tsx +8 -0
  133. package/src/web-core/StereoPannerNode.tsx +12 -0
  134. package/android/libs/arm64-v8a/libfftw3.a +0 -0
  135. package/android/libs/armeabi-v7a/libfftw3.a +0 -0
  136. package/android/libs/include/fftw3.h +0 -413
  137. package/android/libs/x86/libfftw3.a +0 -0
  138. package/android/libs/x86_64/libfftw3.a +0 -0
  139. package/lib/module/index.native.js +0 -21
  140. package/lib/module/index.native.js.map +0 -1
  141. package/lib/typescript/core/types.d.ts.map +0 -1
  142. package/lib/typescript/index.native.d.ts +0 -15
  143. package/lib/typescript/index.native.d.ts.map +0 -1
  144. package/src/index.native.ts +0 -27
  145. /package/lib/module/{core/types.js → types.js} +0 -0
  146. /package/lib/typescript/{core/types.d.ts → types.d.ts} +0 -0
  147. /package/src/{core/types.ts → types.ts} +0 -0
package/src/index.ts CHANGED
@@ -1,574 +1,36 @@
1
- import {
2
- ContextState,
3
- PeriodicWaveConstraints,
4
- WindowType,
5
- } from './core/types';
6
-
7
- import { InvalidStateError } from './errors';
8
-
9
- export class AudioBuffer {
10
- readonly length: number;
11
- readonly duration: number;
12
- readonly sampleRate: number;
13
- readonly numberOfChannels: number;
14
-
15
- /** @internal */
16
- public readonly buffer: globalThis.AudioBuffer;
17
-
18
- constructor(buffer: globalThis.AudioBuffer) {
19
- this.buffer = buffer;
20
- this.length = buffer.length;
21
- this.duration = buffer.duration;
22
- this.sampleRate = buffer.sampleRate;
23
- this.numberOfChannels = buffer.numberOfChannels;
24
- }
25
-
26
- public getChannelData(channel: number): number[] {
27
- if (channel < 0 || channel >= this.numberOfChannels) {
28
- throw new Error(
29
- `The channel number provided (${channel}) is outside the range [0, ${this.numberOfChannels - 1}]`
30
- );
31
- }
32
-
33
- // TODO: we probably will want to move to Float32Array on native side too
34
- return Array.from(this.buffer.getChannelData(channel));
35
- }
36
-
37
- public copyFromChannel(
38
- destination: number[],
39
- channelNumber: number,
40
- startInChannel: number = 0
41
- ): void {
42
- if (channelNumber < 0 || channelNumber >= this.numberOfChannels) {
43
- throw new Error(
44
- `The channel number provided (${channelNumber}) is outside the range [0, ${this.numberOfChannels - 1}]`
45
- );
46
- }
47
-
48
- if (startInChannel < 0 || startInChannel >= this.length) {
49
- throw new Error(
50
- `The startInChannel number provided (${startInChannel}) is outside the range [0, ${this.length - 1}]`
51
- );
52
- }
53
-
54
- const array = new Float32Array(destination);
55
-
56
- this.buffer.copyFromChannel(array, channelNumber, startInChannel);
57
-
58
- for (let i = 0; i < destination.length; i++) {
59
- destination[i] = array[i];
60
- }
61
- }
62
-
63
- public copyToChannel(
64
- source: number[],
65
- channelNumber: number,
66
- startInChannel: number = 0
67
- ): void {
68
- if (channelNumber < 0 || channelNumber >= this.numberOfChannels) {
69
- throw new Error(
70
- `The channel number provided (${channelNumber}) is outside the range [0, ${this.numberOfChannels - 1}]`
71
- );
72
- }
73
-
74
- if (startInChannel < 0 || startInChannel >= this.length) {
75
- throw new Error(
76
- `The startInChannel number provided (${startInChannel}) is outside the range [0, ${this.length - 1}]`
77
- );
78
- }
79
-
80
- this.buffer.copyToChannel(
81
- new Float32Array(source),
82
- channelNumber,
83
- startInChannel
84
- );
85
- }
86
- }
87
-
88
- export class AudioNode {
89
- readonly context: AudioContext;
90
- readonly numberOfInputs: number;
91
- readonly numberOfOutputs: number;
92
- readonly channelCount: number;
93
- readonly channelCountMode: ChannelCountMode;
94
- readonly channelInterpretation: ChannelInterpretation;
95
-
96
- protected readonly node: globalThis.AudioNode;
97
-
98
- constructor(context: AudioContext, node: globalThis.AudioNode) {
99
- this.context = context;
100
- this.node = node;
101
- this.numberOfInputs = this.node.numberOfInputs;
102
- this.numberOfOutputs = this.node.numberOfOutputs;
103
- this.channelCount = this.node.channelCount;
104
- this.channelCountMode = this.node.channelCountMode;
105
- this.channelInterpretation = this.node.channelInterpretation;
106
- }
107
-
108
- public connect(destination: AudioNode): void {
109
- if (this.context !== destination.context) {
110
- throw new Error('The AudioNodes are from different BaseAudioContexts');
111
- }
112
-
113
- this.node.connect(destination.node);
114
- }
115
-
116
- public disconnect(destination?: AudioNode): void {
117
- if (destination === undefined) {
118
- this.node.disconnect();
119
- return;
120
- }
121
-
122
- this.node.disconnect(destination.node);
123
- }
124
- }
125
-
126
- export class AnalyserNode extends AudioNode {
127
- fftSize: number;
128
- readonly frequencyBinCount: number;
129
- minDecibels: number;
130
- maxDecibels: number;
131
- smoothingTimeConstant: number;
132
-
133
- constructor(context: AudioContext, node: globalThis.AnalyserNode) {
134
- super(context, node);
135
-
136
- this.fftSize = node.fftSize;
137
- this.frequencyBinCount = node.frequencyBinCount;
138
- this.minDecibels = node.minDecibels;
139
- this.maxDecibels = node.maxDecibels;
140
- this.smoothingTimeConstant = node.smoothingTimeConstant;
141
- }
142
-
143
- public get window(): WindowType {
144
- return 'blackman';
145
- }
146
-
147
- public set window(value: WindowType) {
148
- console.log(
149
- 'React Native Audio API: setting window is not supported on web'
150
- );
151
- }
152
-
153
- public getByteFrequencyData(array: number[]): void {
154
- const data = new Uint8Array(array);
155
-
156
- (this.node as globalThis.AnalyserNode).getByteFrequencyData(data);
157
-
158
- for (let i = 0; i < array.length; i++) {
159
- array[i] = data[i];
160
- }
161
- }
162
-
163
- public getByteTimeDomainData(array: number[]): void {
164
- const data = new Uint8Array(array);
165
-
166
- (this.node as globalThis.AnalyserNode).getByteTimeDomainData(data);
167
-
168
- for (let i = 0; i < array.length; i++) {
169
- array[i] = data[i];
170
- }
171
- }
172
-
173
- public getFloatFrequencyData(array: number[]): void {
174
- const data = new Float32Array(array);
175
- (this.node as globalThis.AnalyserNode).getFloatFrequencyData(data);
176
-
177
- for (let i = 0; i < array.length; i++) {
178
- array[i] = data[i];
179
- }
180
- }
181
-
182
- public getFloatTimeDomainData(array: number[]): void {
183
- const data = new Float32Array(array);
184
- (this.node as globalThis.AnalyserNode).getFloatTimeDomainData(data);
185
-
186
- for (let i = 0; i < array.length; i++) {
187
- array[i] = data[i];
188
- }
189
- }
190
- }
191
-
192
- export class AudioScheduledSourceNode extends AudioNode {
193
- protected hasBeenStarted: boolean = false;
194
-
195
- public start(when: number = 0): void {
196
- if (when < 0) {
197
- throw new RangeError(
198
- `Time must be a finite non-negative number: ${when}`
199
- );
200
- }
201
-
202
- if (this.hasBeenStarted) {
203
- throw new Error('Cannot call start more than once');
204
- }
205
-
206
- this.hasBeenStarted = true;
207
- (this.node as globalThis.AudioScheduledSourceNode).start(when);
208
- }
209
-
210
- public stop(when: number = 0): void {
211
- if (when < 0) {
212
- throw new RangeError(
213
- `Time must be a finite non-negative number: ${when}`
214
- );
215
- }
216
-
217
- if (!this.hasBeenStarted) {
218
- throw new Error('Cannot call stop without calling start first');
219
- }
220
-
221
- (this.node as globalThis.AudioScheduledSourceNode).stop(when);
222
- }
223
- }
224
-
225
- export class AudioBufferSourceNode extends AudioScheduledSourceNode {
226
- readonly playbackRate: AudioParam;
227
- readonly detune: AudioParam;
228
-
229
- constructor(context: AudioContext, node: globalThis.AudioBufferSourceNode) {
230
- super(context, node);
231
-
232
- this.detune = new AudioParam(node.detune);
233
- this.playbackRate = new AudioParam(node.playbackRate);
234
- }
235
-
236
- public get buffer(): AudioBuffer | null {
237
- const buffer = (this.node as globalThis.AudioBufferSourceNode).buffer;
238
-
239
- if (!buffer) {
240
- return null;
241
- }
242
-
243
- return new AudioBuffer(buffer);
244
- }
245
-
246
- public set buffer(buffer: AudioBuffer | null) {
247
- if (!buffer) {
248
- (this.node as globalThis.AudioBufferSourceNode | null) = null;
249
- return;
250
- }
251
-
252
- (this.node as globalThis.AudioBufferSourceNode).buffer = buffer.buffer;
253
- }
254
-
255
- public get loop(): boolean {
256
- return (this.node as globalThis.AudioBufferSourceNode).loop;
257
- }
258
-
259
- public set loop(value: boolean) {
260
- (this.node as globalThis.AudioBufferSourceNode).loop = value;
261
- }
262
-
263
- public get loopStart(): number {
264
- return (this.node as globalThis.AudioBufferSourceNode).loopStart;
265
- }
266
-
267
- public set loopStart(value: number) {
268
- (this.node as globalThis.AudioBufferSourceNode).loopStart = value;
269
- }
270
-
271
- public get loopEnd(): number {
272
- return (this.node as globalThis.AudioBufferSourceNode).loopEnd;
273
- }
274
-
275
- public set loopEnd(value: number) {
276
- (this.node as globalThis.AudioBufferSourceNode).loopEnd = value;
277
- }
278
-
279
- public start(when?: number, offset?: number, duration?: number): void {
280
- if (when && when < 0) {
281
- throw new RangeError(
282
- `when must be a finite non-negative number: ${when}`
283
- );
284
- }
285
-
286
- if (offset && offset < 0) {
287
- throw new RangeError(
288
- `offset must be a finite non-negative number: ${when}`
289
- );
290
- }
291
-
292
- if (duration && duration < 0) {
293
- throw new RangeError(
294
- `duration must be a finite non-negative number: ${when}`
295
- );
296
- }
297
-
298
- if (this.hasBeenStarted) {
299
- throw new InvalidStateError('Cannot call start more than once');
300
- }
301
-
302
- this.hasBeenStarted = true;
303
- (this.node as globalThis.AudioBufferSourceNode).start(
304
- when,
305
- offset,
306
- duration
307
- );
308
- }
309
- }
310
-
311
- export class AudioDestinationNode extends AudioNode {}
312
-
313
- export class AudioParam {
314
- readonly defaultValue: number;
315
- readonly minValue: number;
316
- readonly maxValue: number;
317
-
318
- private readonly param: globalThis.AudioParam;
319
-
320
- constructor(param: globalThis.AudioParam) {
321
- this.param = param;
322
- this.defaultValue = param.defaultValue;
323
- this.minValue = param.minValue;
324
- this.maxValue = param.maxValue;
325
- }
326
-
327
- public get value(): number {
328
- return this.param.value;
329
- }
330
-
331
- public set value(value: number) {
332
- this.param.value = value;
333
- }
334
-
335
- public setValueAtTime(value: number, startTime: number): void {
336
- this.param.setValueAtTime(value, startTime);
337
- }
338
-
339
- public linearRampToValueAtTime(value: number, endTime: number): void {
340
- this.param.linearRampToValueAtTime(value, endTime);
341
- }
342
-
343
- public exponentialRampToValueAtTime(value: number, endTime: number): void {
344
- this.param.exponentialRampToValueAtTime(value, endTime);
345
- }
346
-
347
- public setTargetAtTime(
348
- target: number,
349
- startTime: number,
350
- timeConstant: number
351
- ): void {
352
- this.param.setTargetAtTime(target, startTime, timeConstant);
353
- }
354
-
355
- public setValueCurveAtTime(
356
- values: number[],
357
- startTime: number,
358
- duration: number
359
- ): void {
360
- this.param.setValueCurveAtTime(
361
- new Float32Array(values),
362
- startTime,
363
- duration
364
- );
365
- }
366
-
367
- public cancelScheduledValues(startTime: number): void {
368
- this.param.cancelScheduledValues(startTime);
369
- }
370
-
371
- public cancelAndHoldAtTime(cancelTime: number): void {
372
- this.param.cancelAndHoldAtTime(cancelTime);
373
- }
374
- }
375
-
376
- export class BiquadFilterNode extends AudioNode {
377
- readonly frequency: AudioParam;
378
- readonly detune: AudioParam;
379
- readonly Q: AudioParam;
380
- readonly gain: AudioParam;
381
-
382
- constructor(
383
- context: AudioContext,
384
- biquadFilter: globalThis.BiquadFilterNode
385
- ) {
386
- super(context, biquadFilter);
387
- this.frequency = new AudioParam(biquadFilter.frequency);
388
- this.detune = new AudioParam(biquadFilter.detune);
389
- this.Q = new AudioParam(biquadFilter.Q);
390
- this.gain = new AudioParam(biquadFilter.gain);
391
- }
392
-
393
- public get type(): BiquadFilterType {
394
- return (this.node as globalThis.BiquadFilterNode).type;
395
- }
396
-
397
- public set type(value: BiquadFilterType) {
398
- (this.node as globalThis.BiquadFilterNode).type = value;
399
- }
400
-
401
- public getFrequencyResponse(
402
- frequencyArray: number[],
403
- magResponseOutput: number[],
404
- phaseResponseOutput: number[]
405
- ) {
406
- if (
407
- frequencyArray.length !== magResponseOutput.length ||
408
- frequencyArray.length !== phaseResponseOutput.length
409
- ) {
410
- throw new Error(
411
- `The lengths of the arrays are not the same frequencyArray: ${frequencyArray.length}, magResponseOutput: ${magResponseOutput.length}, phaseResponseOutput: ${phaseResponseOutput.length}`
412
- );
413
- }
414
- const magData = new Float32Array(magResponseOutput);
415
- const phaseData = new Float32Array(phaseResponseOutput);
416
-
417
- (this.node as globalThis.BiquadFilterNode).getFrequencyResponse(
418
- new Float32Array(frequencyArray),
419
- magData,
420
- phaseData
421
- );
422
-
423
- for (let i = 0; i < magData.length; i++) {
424
- magResponseOutput[i] = magData[i];
425
- }
426
-
427
- for (let i = 0; i < phaseData.length; i++) {
428
- phaseResponseOutput[i] = phaseData[i];
429
- }
430
- }
431
- }
432
-
433
- export class PeriodicWave {
434
- /** @internal */
435
- readonly periodicWave: globalThis.PeriodicWave;
436
-
437
- constructor(periodicWave: globalThis.PeriodicWave) {
438
- this.periodicWave = periodicWave;
439
- }
440
- }
441
-
442
- export class OscillatorNode extends AudioScheduledSourceNode {
443
- readonly frequency: AudioParam;
444
- readonly detune: AudioParam;
445
-
446
- constructor(context: AudioContext, node: globalThis.OscillatorNode) {
447
- super(context, node);
448
-
449
- this.detune = new AudioParam(node.detune);
450
- this.frequency = new AudioParam(node.frequency);
451
- }
452
-
453
- public get type(): OscillatorType {
454
- return (this.node as globalThis.OscillatorNode).type;
455
- }
456
-
457
- public set type(value: OscillatorType) {
458
- if (value === 'custom') {
459
- throw new Error(
460
- "'type' cannot be set directly to 'custom'. Use setPeriodicWave() to create a custom Oscillator type."
461
- );
462
- }
463
-
464
- (this.node as globalThis.OscillatorNode).type = value;
465
- }
466
-
467
- public setPeriodicWave(wave: PeriodicWave): void {
468
- (this.node as globalThis.OscillatorNode).setPeriodicWave(wave.periodicWave);
469
- }
470
- }
471
-
472
- export class GainNode extends AudioNode {
473
- readonly gain: AudioParam;
474
-
475
- constructor(context: AudioContext, gain: globalThis.GainNode) {
476
- super(context, gain);
477
- this.gain = new AudioParam(gain.gain);
478
- }
479
- }
480
-
481
- export class StereoPannerNode extends AudioNode {
482
- readonly pan: AudioParam;
483
-
484
- constructor(context: AudioContext, pan: globalThis.StereoPannerNode) {
485
- super(context, pan);
486
- this.pan = new AudioParam(pan.pan);
487
- }
488
- }
489
-
490
- export class AudioContext {
491
- protected readonly context: globalThis.AudioContext;
492
-
493
- readonly destination: AudioDestinationNode;
494
- readonly sampleRate: number;
495
-
496
- constructor(_sampleRate?: number) {
497
- this.context = new window.AudioContext();
498
-
499
- this.sampleRate = this.context.sampleRate;
500
- this.destination = new AudioDestinationNode(this, this.context.destination);
501
- }
502
-
503
- public get currentTime(): number {
504
- return this.context.currentTime;
505
- }
506
-
507
- public get state(): ContextState {
508
- return this.context.state as ContextState;
509
- }
510
-
511
- createOscillator(): OscillatorNode {
512
- return new OscillatorNode(this, this.context.createOscillator());
513
- }
514
-
515
- createGain(): GainNode {
516
- return new GainNode(this, this.context.createGain());
517
- }
518
-
519
- createStereoPanner(): StereoPannerNode {
520
- return new StereoPannerNode(this, this.context.createStereoPanner());
521
- }
522
-
523
- createBiquadFilter(): BiquadFilterNode {
524
- return new BiquadFilterNode(this, this.context.createBiquadFilter());
525
- }
526
-
527
- createBufferSource(): AudioBufferSourceNode {
528
- return new AudioBufferSourceNode(this, this.context.createBufferSource());
529
- }
530
-
531
- createBuffer(
532
- numOfChannels: number,
533
- length: number,
534
- sampleRate: number
535
- ): AudioBuffer {
536
- return new AudioBuffer(
537
- this.context.createBuffer(numOfChannels, length, sampleRate)
538
- );
539
- }
540
-
541
- createPeriodicWave(
542
- real: number[],
543
- imag: number[],
544
- constraints?: PeriodicWaveConstraints
545
- ): PeriodicWave {
546
- return new PeriodicWave(
547
- this.context.createPeriodicWave(real, imag, constraints)
548
- );
549
- }
550
-
551
- createAnalyser(): AnalyserNode {
552
- return new AnalyserNode(this, this.context.createAnalyser());
553
- }
554
-
555
- async decodeAudioDataSource(source: string): Promise<AudioBuffer> {
556
- const arrayBuffer = await fetch(source).then((response) =>
557
- response.arrayBuffer()
558
- );
559
-
560
- return new AudioBuffer(await this.context.decodeAudioData(arrayBuffer));
561
- }
562
-
563
- async close(): Promise<void> {
564
- await this.context.close();
565
- }
566
- }
1
+ import { installModule } from './specs/install';
2
+
3
+ if (global.__AudioAPIInstaller == null) {
4
+ installModule();
5
+ }
6
+
7
+ export { default as AudioBuffer } from './core/AudioBuffer';
8
+ export { default as AudioBufferSourceNode } from './core/AudioBufferSourceNode';
9
+ export { default as AudioContext } from './core/AudioContext';
10
+ export { default as AudioDestinationNode } from './core/AudioDestinationNode';
11
+ export { default as AudioNode } from './core/AudioNode';
12
+ export { default as AnalyserNode } from './core/AnalyserNode';
13
+ export { default as AudioParam } from './core/AudioParam';
14
+ export { default as AudioScheduledSourceNode } from './core/AudioScheduledSourceNode';
15
+ export { default as BaseAudioContext } from './core/BaseAudioContext';
16
+ export { default as BiquadFilterNode } from './core/BiquadFilterNode';
17
+ export { default as GainNode } from './core/GainNode';
18
+ export { default as OscillatorNode } from './core/OscillatorNode';
19
+ export { default as StereoPannerNode } from './core/StereoPannerNode';
567
20
 
568
21
  export {
569
- ContextState,
570
22
  OscillatorType,
571
23
  BiquadFilterType,
572
24
  ChannelCountMode,
573
25
  ChannelInterpretation,
574
- } from './core/types';
26
+ ContextState,
27
+ WindowType,
28
+ PeriodicWaveConstraints,
29
+ } from './types';
30
+
31
+ export {
32
+ IndexSizeError,
33
+ InvalidAccessError,
34
+ InvalidStateError,
35
+ RangeError,
36
+ } from './errors';
@@ -0,0 +1,30 @@
1
+ export { default as AudioBuffer } from './web-core/AudioBuffer';
2
+ export { default as AudioBufferSourceNode } from './web-core/AudioBufferSourceNode';
3
+ export { default as AudioContext } from './web-core/AudioContext';
4
+ export { default as AudioDestinationNode } from './web-core/AudioDestinationNode';
5
+ export { default as AudioNode } from './web-core/AudioNode';
6
+ export { default as AnalyserNode } from './web-core/AnalyserNode';
7
+ export { default as AudioParam } from './web-core/AudioParam';
8
+ export { default as AudioScheduledSourceNode } from './web-core/AudioScheduledSourceNode';
9
+ export { default as BaseAudioContext } from './web-core/BaseAudioContext';
10
+ export { default as BiquadFilterNode } from './web-core/BiquadFilterNode';
11
+ export { default as GainNode } from './web-core/GainNode';
12
+ export { default as OscillatorNode } from './web-core/OscillatorNode';
13
+ export { default as StereoPannerNode } from './web-core/StereoPannerNode';
14
+
15
+ export {
16
+ OscillatorType,
17
+ BiquadFilterType,
18
+ ChannelCountMode,
19
+ ChannelInterpretation,
20
+ ContextState,
21
+ WindowType,
22
+ PeriodicWaveConstraints,
23
+ } from './types';
24
+
25
+ export {
26
+ IndexSizeError,
27
+ InvalidAccessError,
28
+ InvalidStateError,
29
+ RangeError,
30
+ } from './errors';
package/src/interfaces.ts CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  ChannelCountMode,
6
6
  ChannelInterpretation,
7
7
  WindowType,
8
- } from './core/types';
8
+ } from './types';
9
9
 
10
10
  export interface IBaseAudioContext {
11
11
  readonly destination: IAudioDestinationNode;
@@ -0,0 +1,69 @@
1
+ import AudioNode from './AudioNode';
2
+ import { WindowType } from '../types';
3
+ import BaseAudioContext from './BaseAudioContext';
4
+
5
+ export default class AnalyserNode extends AudioNode {
6
+ fftSize: number;
7
+ readonly frequencyBinCount: number;
8
+ minDecibels: number;
9
+ maxDecibels: number;
10
+ smoothingTimeConstant: number;
11
+
12
+ constructor(context: BaseAudioContext, node: globalThis.AnalyserNode) {
13
+ super(context, node);
14
+
15
+ this.fftSize = node.fftSize;
16
+ this.frequencyBinCount = node.frequencyBinCount;
17
+ this.minDecibels = node.minDecibels;
18
+ this.maxDecibels = node.maxDecibels;
19
+ this.smoothingTimeConstant = node.smoothingTimeConstant;
20
+ }
21
+
22
+ public get window(): WindowType {
23
+ return 'blackman';
24
+ }
25
+
26
+ public set window(value: WindowType) {
27
+ console.log(
28
+ 'React Native Audio API: setting window is not supported on web'
29
+ );
30
+ }
31
+
32
+ public getByteFrequencyData(array: number[]): void {
33
+ const data = new Uint8Array(array);
34
+
35
+ (this.node as globalThis.AnalyserNode).getByteFrequencyData(data);
36
+
37
+ for (let i = 0; i < array.length; i++) {
38
+ array[i] = data[i];
39
+ }
40
+ }
41
+
42
+ public getByteTimeDomainData(array: number[]): void {
43
+ const data = new Uint8Array(array);
44
+
45
+ (this.node as globalThis.AnalyserNode).getByteTimeDomainData(data);
46
+
47
+ for (let i = 0; i < array.length; i++) {
48
+ array[i] = data[i];
49
+ }
50
+ }
51
+
52
+ public getFloatFrequencyData(array: number[]): void {
53
+ const data = new Float32Array(array);
54
+ (this.node as globalThis.AnalyserNode).getFloatFrequencyData(data);
55
+
56
+ for (let i = 0; i < array.length; i++) {
57
+ array[i] = data[i];
58
+ }
59
+ }
60
+
61
+ public getFloatTimeDomainData(array: number[]): void {
62
+ const data = new Float32Array(array);
63
+ (this.node as globalThis.AnalyserNode).getFloatTimeDomainData(data);
64
+
65
+ for (let i = 0; i < array.length; i++) {
66
+ array[i] = data[i];
67
+ }
68
+ }
69
+ }