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.
- package/README.md +17 -11
- package/common/cpp/HostObjects/AnalyserNodeHostObject.h +151 -0
- package/common/cpp/HostObjects/BaseAudioContextHostObject.h +8 -0
- package/common/cpp/core/AnalyserNode.cpp +237 -0
- package/common/cpp/core/AnalyserNode.h +54 -0
- package/common/cpp/core/AudioNode.cpp +6 -5
- package/common/cpp/core/AudioScheduledSourceNode.cpp +1 -2
- package/common/cpp/core/BaseAudioContext.cpp +5 -0
- package/common/cpp/core/BaseAudioContext.h +2 -0
- package/common/cpp/core/Constants.h +9 -1
- package/common/cpp/core/PeriodicWave.cpp +2 -2
- package/common/cpp/utils/AudioUtils.cpp +7 -0
- package/common/cpp/utils/AudioUtils.h +5 -1
- package/common/cpp/utils/FFTFrame.cpp +69 -23
- package/common/cpp/utils/FFTFrame.h +25 -10
- package/common/cpp/utils/VectorMath.cpp +10 -0
- package/common/cpp/utils/VectorMath.h +2 -0
- package/lib/module/core/AnalyserNode.js +59 -0
- package/lib/module/core/AnalyserNode.js.map +1 -0
- package/lib/module/core/BaseAudioContext.js +8 -0
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/index.js +25 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.native.js +1 -0
- package/lib/module/index.native.js.map +1 -1
- package/lib/typescript/core/AnalyserNode.d.ts +18 -0
- package/lib/typescript/core/AnalyserNode.d.ts.map +1 -0
- package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +13 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/index.native.d.ts +1 -0
- package/lib/typescript/index.native.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +12 -0
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/core/AnalyserNode.ts +85 -0
- package/src/core/BaseAudioContext.ts +10 -0
- package/src/index.native.ts +1 -0
- package/src/index.ts +46 -0
- 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);
|
package/src/index.native.ts
CHANGED
|
@@ -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
|
+
}
|