react-native-audio-api 0.3.2 → 0.4.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 (41) hide show
  1. package/README.md +17 -11
  2. package/common/cpp/HostObjects/AnalyserNodeHostObject.h +151 -0
  3. package/common/cpp/HostObjects/BaseAudioContextHostObject.h +8 -0
  4. package/common/cpp/core/AnalyserNode.cpp +237 -0
  5. package/common/cpp/core/AnalyserNode.h +54 -0
  6. package/common/cpp/core/AudioNode.cpp +6 -5
  7. package/common/cpp/core/AudioScheduledSourceNode.cpp +1 -2
  8. package/common/cpp/core/BaseAudioContext.cpp +5 -0
  9. package/common/cpp/core/BaseAudioContext.h +2 -0
  10. package/common/cpp/core/Constants.h +9 -1
  11. package/common/cpp/core/PeriodicWave.cpp +2 -2
  12. package/common/cpp/utils/AudioUtils.cpp +7 -0
  13. package/common/cpp/utils/AudioUtils.h +5 -1
  14. package/common/cpp/utils/FFTFrame.cpp +69 -23
  15. package/common/cpp/utils/FFTFrame.h +25 -10
  16. package/common/cpp/utils/VectorMath.cpp +10 -0
  17. package/common/cpp/utils/VectorMath.h +2 -0
  18. package/lib/module/core/AnalyserNode.js +59 -0
  19. package/lib/module/core/AnalyserNode.js.map +1 -0
  20. package/lib/module/core/BaseAudioContext.js +8 -0
  21. package/lib/module/core/BaseAudioContext.js.map +1 -1
  22. package/lib/module/index.js +25 -0
  23. package/lib/module/index.js.map +1 -1
  24. package/lib/module/index.native.js +1 -0
  25. package/lib/module/index.native.js.map +1 -1
  26. package/lib/typescript/core/AnalyserNode.d.ts +18 -0
  27. package/lib/typescript/core/AnalyserNode.d.ts.map +1 -0
  28. package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
  29. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  30. package/lib/typescript/index.d.ts +13 -0
  31. package/lib/typescript/index.d.ts.map +1 -1
  32. package/lib/typescript/index.native.d.ts +1 -0
  33. package/lib/typescript/index.native.d.ts.map +1 -1
  34. package/lib/typescript/interfaces.d.ts +12 -0
  35. package/lib/typescript/interfaces.d.ts.map +1 -1
  36. package/package.json +4 -2
  37. package/src/core/AnalyserNode.ts +85 -0
  38. package/src/core/BaseAudioContext.ts +10 -0
  39. package/src/index.native.ts +1 -0
  40. package/src/index.ts +46 -0
  41. package/src/interfaces.ts +14 -0
@@ -0,0 +1,85 @@
1
+ import { IndexSizeError } from '../errors';
2
+ import { IAnalyserNode } from '../interfaces';
3
+ import AudioNode from './AudioNode';
4
+
5
+ export default class AnalyserNode extends AudioNode {
6
+ private static allowedFFTSize: number[] = [
7
+ 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
8
+ ];
9
+
10
+ public get fftSize(): number {
11
+ return (this.node as IAnalyserNode).fftSize;
12
+ }
13
+
14
+ public set fftSize(value: number) {
15
+ if (!AnalyserNode.allowedFFTSize.includes(value)) {
16
+ throw new IndexSizeError(
17
+ `Provided value (${value}) must be a power of 2 between 32 and 32768`
18
+ );
19
+ }
20
+
21
+ (this.node as IAnalyserNode).fftSize = value;
22
+ }
23
+
24
+ public get minDecibels(): number {
25
+ return (this.node as IAnalyserNode).minDecibels;
26
+ }
27
+
28
+ public set minDecibels(value: number) {
29
+ if (value >= this.maxDecibels) {
30
+ throw new IndexSizeError(
31
+ `The minDecibels value (${value}) must be less than maxDecibels`
32
+ );
33
+ }
34
+
35
+ (this.node as IAnalyserNode).minDecibels = value;
36
+ }
37
+
38
+ public get maxDecibels(): number {
39
+ return (this.node as IAnalyserNode).maxDecibels;
40
+ }
41
+
42
+ public set maxDecibels(value: number) {
43
+ if (value <= this.minDecibels) {
44
+ throw new IndexSizeError(
45
+ `The maxDecibels value (${value}) must be greater than minDecibels`
46
+ );
47
+ }
48
+
49
+ (this.node as IAnalyserNode).maxDecibels = value;
50
+ }
51
+
52
+ public get smoothingTimeConstant(): number {
53
+ return (this.node as IAnalyserNode).smoothingTimeConstant;
54
+ }
55
+
56
+ public set smoothingTimeConstant(value: number) {
57
+ if (value < 0 || value > 1) {
58
+ throw new IndexSizeError(
59
+ `The smoothingTimeConstant value (${value}) must be between 0 and 1`
60
+ );
61
+ }
62
+
63
+ (this.node as IAnalyserNode).smoothingTimeConstant = value;
64
+ }
65
+
66
+ public get frequencyBinCount(): number {
67
+ return (this.node as IAnalyserNode).frequencyBinCount;
68
+ }
69
+
70
+ public getFloatFrequencyData(array: number[]): void {
71
+ (this.node as IAnalyserNode).getFloatFrequencyData(array);
72
+ }
73
+
74
+ public getByteFrequencyData(array: number[]): void {
75
+ (this.node as IAnalyserNode).getByteFrequencyData(array);
76
+ }
77
+
78
+ public getFloatTimeDomainData(array: number[]): void {
79
+ (this.node as IAnalyserNode).getFloatTimeDomainData(array);
80
+ }
81
+
82
+ public getByteTimeDomainData(array: number[]): void {
83
+ (this.node as IAnalyserNode).getByteTimeDomainData(array);
84
+ }
85
+ }
@@ -8,6 +8,7 @@ import BiquadFilterNode from './BiquadFilterNode';
8
8
  import AudioBufferSourceNode from './AudioBufferSourceNode';
9
9
  import AudioBuffer from './AudioBuffer';
10
10
  import PeriodicWave from './PeriodicWave';
11
+ import AnalyserNode from './AnalyserNode';
11
12
  import { InvalidAccessError } from '../errors';
12
13
 
13
14
  export default class BaseAudioContext {
@@ -95,7 +96,16 @@ export default class BaseAudioContext {
95
96
  );
96
97
  }
97
98
 
99
+ createAnalyser(): AnalyserNode {
100
+ return new AnalyserNode(this, this.context.createAnalyser());
101
+ }
102
+
98
103
  async decodeAudioDataSource(sourcePath: string): Promise<AudioBuffer> {
104
+ // Remove the file:// prefix if it exists
105
+ if (sourcePath.startsWith('file://')) {
106
+ sourcePath = sourcePath.replace('file://', '');
107
+ }
108
+
99
109
  const buffer = await this.context.decodeAudioDataSource(sourcePath);
100
110
 
101
111
  return new AudioBuffer(buffer);
@@ -9,6 +9,7 @@ export { default as AudioBufferSourceNode } from './core/AudioBufferSourceNode';
9
9
  export { default as AudioContext } from './core/AudioContext';
10
10
  export { default as AudioDestinationNode } from './core/AudioDestinationNode';
11
11
  export { default as AudioNode } from './core/AudioNode';
12
+ export { default as AnalyserNode } from './core/AnalyserNode';
12
13
  export { default as AudioParam } from './core/AudioParam';
13
14
  export { default as AudioScheduledSourceNode } from './core/AudioScheduledSourceNode';
14
15
  export { default as BaseAudioContext } from './core/BaseAudioContext';
package/src/index.ts CHANGED
@@ -110,6 +110,48 @@ export class AudioNode {
110
110
  }
111
111
  }
112
112
 
113
+ export class AnalyserNode extends AudioNode {
114
+ fftSize: number;
115
+ readonly frequencyBinCount: number;
116
+ minDecibels: number;
117
+ maxDecibels: number;
118
+ smoothingTimeConstant: number;
119
+
120
+ constructor(context: AudioContext, node: globalThis.AnalyserNode) {
121
+ super(context, node);
122
+
123
+ this.fftSize = node.fftSize;
124
+ this.frequencyBinCount = node.frequencyBinCount;
125
+ this.minDecibels = node.minDecibels;
126
+ this.maxDecibels = node.maxDecibels;
127
+ this.smoothingTimeConstant = node.smoothingTimeConstant;
128
+ }
129
+
130
+ public getByteFrequencyData(array: number[]): void {
131
+ (this.node as globalThis.AnalyserNode).getByteFrequencyData(
132
+ new Uint8Array(array)
133
+ );
134
+ }
135
+
136
+ public getByteTimeDomainData(array: number[]): void {
137
+ (this.node as globalThis.AnalyserNode).getByteTimeDomainData(
138
+ new Uint8Array(array)
139
+ );
140
+ }
141
+
142
+ public getFloatFrequencyData(array: number[]): void {
143
+ (this.node as globalThis.AnalyserNode).getFloatFrequencyData(
144
+ new Float32Array(array)
145
+ );
146
+ }
147
+
148
+ public getFloatTimeDomainData(array: number[]): void {
149
+ (this.node as globalThis.AnalyserNode).getFloatTimeDomainData(
150
+ new Float32Array(array)
151
+ );
152
+ }
153
+ }
154
+
113
155
  export class AudioScheduledSourceNode extends AudioNode {
114
156
  private hasBeenStarted: boolean = false;
115
157
 
@@ -428,6 +470,10 @@ export class AudioContext {
428
470
  );
429
471
  }
430
472
 
473
+ createAnalyser(): AnalyserNode {
474
+ return new AnalyserNode(this, this.context.createAnalyser());
475
+ }
476
+
431
477
  async decodeAudioDataSource(source: string): Promise<AudioBuffer> {
432
478
  const arrayBuffer = await fetch(source).then((response) =>
433
479
  response.arrayBuffer()
package/src/interfaces.ts CHANGED
@@ -27,6 +27,7 @@ export interface IBaseAudioContext {
27
27
  imag: number[],
28
28
  disableNormalization: boolean
29
29
  ) => IPeriodicWave;
30
+ createAnalyser: () => IAnalyserNode;
30
31
  decodeAudioDataSource: (sourcePath: string) => Promise<IAudioBuffer>;
31
32
  }
32
33
 
@@ -136,3 +137,16 @@ export interface IAudioParam {
136
137
  }
137
138
 
138
139
  export interface IPeriodicWave {}
140
+
141
+ export interface IAnalyserNode extends IAudioNode {
142
+ fftSize: number;
143
+ readonly frequencyBinCount: number;
144
+ minDecibels: number;
145
+ maxDecibels: number;
146
+ smoothingTimeConstant: number;
147
+
148
+ getFloatFrequencyData: (array: number[]) => void;
149
+ getByteFrequencyData: (array: number[]) => void;
150
+ getFloatTimeDomainData: (array: number[]) => void;
151
+ getByteTimeDomainData: (array: number[]) => void;
152
+ }