react-native-audio-api 0.4.12 → 0.4.14
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/android/src/main/cpp/audioapi/CMakeLists.txt +3 -2
- package/android/src/main/cpp/audioapi/android/core/AudioDecoder.cpp +3 -3
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +13 -12
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.h +0 -1
- package/{common/cpp/audioapi/libs/pffft → android/src/main/cpp/audioapi/android/libs}/pffft.c +1 -1
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +1 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +3 -1
- package/common/cpp/audioapi/HostObjects/AnalyserNodeHostObject.h +16 -24
- package/common/cpp/audioapi/HostObjects/AudioBufferHostObject.h +0 -4
- package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +4 -20
- package/common/cpp/audioapi/HostObjects/AudioContextHostObject.h +2 -3
- package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +2 -32
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +21 -14
- package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +2 -4
- package/common/cpp/audioapi/HostObjects/StretcherNodeHostObject.h +35 -0
- package/common/cpp/audioapi/core/AudioNode.cpp +2 -2
- package/common/cpp/audioapi/core/AudioParam.cpp +1 -1
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +12 -4
- package/common/cpp/audioapi/core/BaseAudioContext.h +4 -2
- package/common/cpp/audioapi/core/Constants.h +33 -8
- package/common/cpp/audioapi/core/analysis/AnalyserNode.cpp +45 -42
- package/common/cpp/audioapi/core/analysis/AnalyserNode.h +6 -8
- package/common/cpp/audioapi/core/destinations/AudioDestinationNode.cpp +1 -1
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +8 -12
- package/common/cpp/audioapi/core/effects/GainNode.cpp +3 -4
- package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +49 -32
- package/common/cpp/audioapi/core/effects/PeriodicWave.h +3 -8
- package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +3 -3
- package/common/cpp/audioapi/core/effects/StretcherNode.cpp +94 -0
- package/common/cpp/audioapi/core/effects/StretcherNode.h +35 -0
- package/common/cpp/audioapi/core/sources/AudioBuffer.cpp +2 -9
- package/common/cpp/audioapi/core/sources/AudioBuffer.h +2 -5
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +35 -72
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +8 -41
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +6 -18
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +0 -7
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +3 -12
- package/common/cpp/audioapi/core/sources/OscillatorNode.h +0 -1
- package/common/cpp/audioapi/{utils → core/utils}/AudioArray.cpp +5 -5
- package/common/cpp/audioapi/{utils → core/utils}/AudioBus.cpp +29 -29
- package/common/cpp/audioapi/dsp/AudioUtils.cpp +2 -2
- package/common/cpp/audioapi/dsp/AudioUtils.h +2 -2
- package/common/cpp/audioapi/dsp/FFTFrame.cpp +100 -0
- package/common/cpp/audioapi/dsp/FFTFrame.h +74 -0
- package/common/cpp/audioapi/dsp/VectorMath.cpp +3 -3
- package/common/cpp/audioapi/dsp/VectorMath.h +2 -2
- package/common/cpp/audioapi/libs/dsp/common.h +47 -0
- package/common/cpp/audioapi/libs/{signalsmith-stretch → dsp}/delay.h +11 -9
- package/common/cpp/audioapi/libs/{signalsmith-stretch → dsp}/fft.h +7 -6
- package/common/cpp/audioapi/libs/{signalsmith-stretch → dsp}/perf.h +2 -0
- package/common/cpp/audioapi/libs/{signalsmith-stretch → dsp}/spectral.h +13 -10
- package/common/cpp/audioapi/libs/dsp/windows.h +219 -0
- package/common/cpp/audioapi/libs/{signalsmith-stretch/signalsmith-stretch.h → signalsmith-stretch.h} +4 -3
- package/ios/audioapi/ios/core/AudioDecoder.mm +3 -3
- package/ios/audioapi/ios/core/AudioPlayer.h +2 -5
- package/ios/audioapi/ios/core/AudioPlayer.m +5 -9
- package/ios/audioapi/ios/core/IOSAudioPlayer.h +0 -1
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +10 -12
- package/lib/module/api.js +2 -1
- package/lib/module/api.js.map +1 -1
- package/lib/module/api.web.js +1 -1
- package/lib/module/api.web.js.map +1 -1
- package/lib/module/core/AudioBufferSourceNode.js +0 -6
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/core/AudioScheduledSourceNode.js +0 -5
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +4 -0
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/core/StretcherNode.js +12 -0
- package/lib/module/core/StretcherNode.js.map +1 -0
- package/lib/module/web-core/AudioBufferSourceNode.js +0 -6
- package/lib/module/web-core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/web-core/AudioScheduledSourceNode.js +0 -8
- package/lib/module/web-core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/typescript/api.d.ts +2 -1
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/api.web.d.ts +1 -1
- package/lib/typescript/api.web.d.ts.map +1 -1
- package/lib/typescript/core/AudioBufferSourceNode.d.ts +0 -3
- package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +0 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/core/StretcherNode.d.ts +10 -0
- package/lib/typescript/core/StretcherNode.d.ts.map +1 -0
- package/lib/typescript/interfaces.d.ts +6 -3
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +0 -1
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioBufferSourceNode.d.ts +0 -3
- package/lib/typescript/web-core/AudioBufferSourceNode.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts +0 -1
- package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/api.ts +1 -1
- package/src/api.web.ts +0 -1
- package/src/core/AudioBufferSourceNode.ts +0 -9
- package/src/core/AudioScheduledSourceNode.ts +0 -5
- package/src/core/BaseAudioContext.ts +5 -0
- package/src/core/StretcherNode.ts +15 -0
- package/src/interfaces.ts +6 -3
- package/src/types.ts +0 -2
- package/src/web-core/AudioBufferSourceNode.tsx +0 -11
- package/src/web-core/AudioScheduledSourceNode.tsx +0 -9
- package/common/cpp/audioapi/core/types/TimeStretchType.h +0 -7
- package/common/cpp/audioapi/dsp/FFT.cpp +0 -41
- package/common/cpp/audioapi/dsp/FFT.h +0 -29
- package/common/cpp/audioapi/dsp/Windows.cpp +0 -80
- package/common/cpp/audioapi/dsp/Windows.h +0 -95
- /package/{common/cpp/audioapi/libs/pffft → android/src/main/cpp/audioapi/android/libs}/pffft.h +0 -0
- /package/common/cpp/audioapi/{utils → core/utils}/AudioArray.h +0 -0
- /package/common/cpp/audioapi/{utils → core/utils}/AudioBus.h +0 -0
- /package/common/cpp/audioapi/libs/{miniaudio/miniaudio.h → miniaudio.h} +0 -0
package/src/api.ts
CHANGED
|
@@ -30,6 +30,7 @@ export { default as BiquadFilterNode } from './core/BiquadFilterNode';
|
|
|
30
30
|
export { default as GainNode } from './core/GainNode';
|
|
31
31
|
export { default as OscillatorNode } from './core/OscillatorNode';
|
|
32
32
|
export { default as StereoPannerNode } from './core/StereoPannerNode';
|
|
33
|
+
export { default as StretcherNode } from './core/StretcherNode';
|
|
33
34
|
|
|
34
35
|
export {
|
|
35
36
|
OscillatorType,
|
|
@@ -39,7 +40,6 @@ export {
|
|
|
39
40
|
ContextState,
|
|
40
41
|
WindowType,
|
|
41
42
|
PeriodicWaveConstraints,
|
|
42
|
-
TimeStretchType,
|
|
43
43
|
} from './types';
|
|
44
44
|
|
|
45
45
|
export {
|
package/src/api.web.ts
CHANGED
|
@@ -4,7 +4,6 @@ import BaseAudioContext from './BaseAudioContext';
|
|
|
4
4
|
import AudioBuffer from './AudioBuffer';
|
|
5
5
|
import AudioParam from './AudioParam';
|
|
6
6
|
import { InvalidStateError, RangeError } from '../errors';
|
|
7
|
-
import { TimeStretchType } from '../types';
|
|
8
7
|
|
|
9
8
|
export default class AudioBufferSourceNode extends AudioScheduledSourceNode {
|
|
10
9
|
readonly playbackRate: AudioParam;
|
|
@@ -58,14 +57,6 @@ export default class AudioBufferSourceNode extends AudioScheduledSourceNode {
|
|
|
58
57
|
(this.node as IAudioBufferSourceNode).loopEnd = value;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
public get timeStretch(): TimeStretchType {
|
|
62
|
-
return (this.node as IAudioBufferSourceNode).timeStretch;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
public set timeStretch(value: TimeStretchType) {
|
|
66
|
-
(this.node as IAudioBufferSourceNode).timeStretch = value;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
60
|
public start(when: number = 0, offset: number = 0, duration?: number): void {
|
|
70
61
|
if (when < 0) {
|
|
71
62
|
throw new RangeError(
|
|
@@ -35,9 +35,4 @@ export default class AudioScheduledSourceNode extends AudioNode {
|
|
|
35
35
|
|
|
36
36
|
(this.node as IAudioScheduledSourceNode).stop(when);
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
// eslint-disable-next-line accessor-pairs
|
|
40
|
-
public set onended(callback: (arg?: number) => void) {
|
|
41
|
-
(this.node as IAudioScheduledSourceNode).onended = callback;
|
|
42
|
-
}
|
|
43
38
|
}
|
|
@@ -9,6 +9,7 @@ import AudioBufferSourceNode from './AudioBufferSourceNode';
|
|
|
9
9
|
import AudioBuffer from './AudioBuffer';
|
|
10
10
|
import PeriodicWave from './PeriodicWave';
|
|
11
11
|
import AnalyserNode from './AnalyserNode';
|
|
12
|
+
import StretcherNode from './StretcherNode';
|
|
12
13
|
import { InvalidAccessError, NotSupportedError } from '../errors';
|
|
13
14
|
|
|
14
15
|
export default class BaseAudioContext {
|
|
@@ -100,6 +101,10 @@ export default class BaseAudioContext {
|
|
|
100
101
|
return new AnalyserNode(this, this.context.createAnalyser());
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
createStretcher(): StretcherNode {
|
|
105
|
+
return new StretcherNode(this, this.context.createStretcher());
|
|
106
|
+
}
|
|
107
|
+
|
|
103
108
|
async decodeAudioDataSource(sourcePath: string): Promise<AudioBuffer> {
|
|
104
109
|
// Remove the file:// prefix if it exists
|
|
105
110
|
if (sourcePath.startsWith('file://')) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IStretcherNode } from '../interfaces';
|
|
2
|
+
import AudioNode from './AudioNode';
|
|
3
|
+
import AudioParam from './AudioParam';
|
|
4
|
+
import BaseAudioContext from './BaseAudioContext';
|
|
5
|
+
|
|
6
|
+
export default class StretcherNode extends AudioNode {
|
|
7
|
+
readonly rate: AudioParam;
|
|
8
|
+
readonly semitones: AudioParam;
|
|
9
|
+
|
|
10
|
+
constructor(context: BaseAudioContext, stretcher: IStretcherNode) {
|
|
11
|
+
super(context, stretcher);
|
|
12
|
+
this.rate = new AudioParam(stretcher.rate);
|
|
13
|
+
this.semitones = new AudioParam(stretcher.semitones);
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/interfaces.ts
CHANGED
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
ChannelCountMode,
|
|
6
6
|
ChannelInterpretation,
|
|
7
7
|
WindowType,
|
|
8
|
-
TimeStretchType,
|
|
9
8
|
} from './types';
|
|
10
9
|
|
|
11
10
|
export interface AudioAPIInstaller {
|
|
@@ -34,6 +33,7 @@ export interface IBaseAudioContext {
|
|
|
34
33
|
disableNormalization: boolean
|
|
35
34
|
) => IPeriodicWave;
|
|
36
35
|
createAnalyser: () => IAnalyserNode;
|
|
36
|
+
createStretcher: () => IStretcherNode;
|
|
37
37
|
decodeAudioDataSource: (sourcePath: string) => Promise<IAudioBuffer>;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -82,7 +82,6 @@ export interface IAudioDestinationNode extends IAudioNode {}
|
|
|
82
82
|
export interface IAudioScheduledSourceNode extends IAudioNode {
|
|
83
83
|
start(when?: number): void;
|
|
84
84
|
stop: (when: number) => void;
|
|
85
|
-
onended: (arg?: number) => void | null;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
export interface IOscillatorNode extends IAudioScheduledSourceNode {
|
|
@@ -100,7 +99,6 @@ export interface IAudioBufferSourceNode extends IAudioScheduledSourceNode {
|
|
|
100
99
|
loopEnd: number;
|
|
101
100
|
detune: IAudioParam;
|
|
102
101
|
playbackRate: IAudioParam;
|
|
103
|
-
timeStretch: TimeStretchType;
|
|
104
102
|
|
|
105
103
|
start: (when?: number, offset?: number, duration?: number) => void;
|
|
106
104
|
}
|
|
@@ -162,3 +160,8 @@ export interface IAnalyserNode extends IAudioNode {
|
|
|
162
160
|
getFloatTimeDomainData: (array: number[]) => void;
|
|
163
161
|
getByteTimeDomainData: (array: number[]) => void;
|
|
164
162
|
}
|
|
163
|
+
|
|
164
|
+
export interface IStretcherNode extends IAudioNode {
|
|
165
|
+
readonly rate: IAudioParam;
|
|
166
|
+
readonly semitones: IAudioParam;
|
|
167
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -3,7 +3,6 @@ import AudioParam from './AudioParam';
|
|
|
3
3
|
import AudioBuffer from './AudioBuffer';
|
|
4
4
|
import { InvalidStateError, RangeError } from '../errors';
|
|
5
5
|
import BaseAudioContext from './BaseAudioContext';
|
|
6
|
-
import { TimeStretchType } from '../types';
|
|
7
6
|
|
|
8
7
|
export default class AudioBufferSourceNode extends AudioScheduledSourceNode {
|
|
9
8
|
readonly playbackRate: AudioParam;
|
|
@@ -62,16 +61,6 @@ export default class AudioBufferSourceNode extends AudioScheduledSourceNode {
|
|
|
62
61
|
(this.node as globalThis.AudioBufferSourceNode).loopEnd = value;
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
public get timeStretch(): TimeStretchType {
|
|
66
|
-
return 'linear';
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
public set timeStretch(value: TimeStretchType) {
|
|
70
|
-
console.log(
|
|
71
|
-
'React Native Audio API: setting timeStretch is not supported on web'
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
64
|
public start(when?: number, offset?: number, duration?: number): void {
|
|
76
65
|
if (when && when < 0) {
|
|
77
66
|
throw new RangeError(
|
|
@@ -34,13 +34,4 @@ export default class AudioScheduledSourceNode extends AudioNode {
|
|
|
34
34
|
|
|
35
35
|
(this.node as globalThis.AudioScheduledSourceNode).stop(when);
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
// eslint-disable-next-line accessor-pairs
|
|
39
|
-
public set onended(callback: (arg?: number) => void) {
|
|
40
|
-
const eventCallback = (_event: Event) => {
|
|
41
|
-
callback();
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
(this.node as globalThis.AudioScheduledSourceNode).onended = eventCallback;
|
|
45
|
-
}
|
|
46
37
|
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
#include <audioapi/dsp/FFT.h>
|
|
2
|
-
|
|
3
|
-
namespace audioapi::dsp {
|
|
4
|
-
|
|
5
|
-
FFT::FFT(int size) : size_(size) {
|
|
6
|
-
pffftSetup_ = pffft_new_setup(size_, PFFFT_REAL);
|
|
7
|
-
work_ = (float *)pffft_aligned_malloc(size_ * sizeof(float));
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
FFT::~FFT() {
|
|
11
|
-
pffft_destroy_setup(pffftSetup_);
|
|
12
|
-
pffft_aligned_free(work_);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
void FFT::doFFT(float *in, std::vector<std::complex<float>> &out) {
|
|
16
|
-
pffft_transform_ordered(
|
|
17
|
-
pffftSetup_,
|
|
18
|
-
in,
|
|
19
|
-
reinterpret_cast<float *>(&out[0]),
|
|
20
|
-
work_,
|
|
21
|
-
PFFFT_FORWARD);
|
|
22
|
-
|
|
23
|
-
dsp::multiplyByScalar(
|
|
24
|
-
reinterpret_cast<float *>(&out[0]),
|
|
25
|
-
0.5f,
|
|
26
|
-
reinterpret_cast<float *>(&out[0]),
|
|
27
|
-
size_ * 2);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
void FFT::doInverseFFT(std::vector<std::complex<float>> &in, float *out) {
|
|
31
|
-
pffft_transform_ordered(
|
|
32
|
-
pffftSetup_,
|
|
33
|
-
reinterpret_cast<float *>(&in[0]),
|
|
34
|
-
out,
|
|
35
|
-
work_,
|
|
36
|
-
PFFFT_BACKWARD);
|
|
37
|
-
|
|
38
|
-
dsp::multiplyByScalar(out, 1.0f / static_cast<float>(size_), out, size_);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
} // namespace audioapi::dsp
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <audioapi/dsp/VectorMath.h>
|
|
4
|
-
#include <audioapi/libs/pffft/pffft.h>
|
|
5
|
-
|
|
6
|
-
#include <algorithm>
|
|
7
|
-
#include <cmath>
|
|
8
|
-
#include <utility>
|
|
9
|
-
#include <complex>
|
|
10
|
-
#include <vector>
|
|
11
|
-
|
|
12
|
-
namespace audioapi::dsp {
|
|
13
|
-
|
|
14
|
-
class FFT {
|
|
15
|
-
public:
|
|
16
|
-
explicit FFT(int size);
|
|
17
|
-
~FFT();
|
|
18
|
-
|
|
19
|
-
void doFFT(float *in, std::vector<std::complex<float>> &out);
|
|
20
|
-
void doInverseFFT(std::vector<std::complex<float>> &in, float *out);
|
|
21
|
-
|
|
22
|
-
private:
|
|
23
|
-
int size_;
|
|
24
|
-
|
|
25
|
-
PFFFT_Setup *pffftSetup_;
|
|
26
|
-
float *work_;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
} // namespace audioapi::dsp
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
#include <audioapi/core/Constants.h>
|
|
2
|
-
#include <audioapi/dsp/Windows.h>
|
|
3
|
-
|
|
4
|
-
namespace audioapi::dsp {
|
|
5
|
-
|
|
6
|
-
void WindowFunction::forcePerfectReconstruction(
|
|
7
|
-
float *data,
|
|
8
|
-
int windowLength,
|
|
9
|
-
int interval) {
|
|
10
|
-
for (int i = 0; i < interval; ++i) {
|
|
11
|
-
float sum2 = 0;
|
|
12
|
-
|
|
13
|
-
for (int index = i; index < windowLength; index += interval) {
|
|
14
|
-
sum2 += data[index] * data[index];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
float factor = 1 / std::sqrt(sum2);
|
|
18
|
-
|
|
19
|
-
for (int index = i; index < windowLength; index += interval) {
|
|
20
|
-
data[index] *= factor;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
void Hann::apply(float *data, int size) const {
|
|
26
|
-
for (int i = 0; i < size; ++i) {
|
|
27
|
-
auto x = static_cast<float>(i) / static_cast<float>(size - 1);
|
|
28
|
-
auto window = 0.5f - 0.5f * cos(2 * PI * x);
|
|
29
|
-
data[i] = window * amplitude_;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
void Blackman::apply(float *data, int size) const {
|
|
34
|
-
for (int i = 0; i < size; ++i) {
|
|
35
|
-
auto x = static_cast<float>(i) / static_cast<float>(size - 1);
|
|
36
|
-
auto window = 0.42f - 0.5f * cos(2 * PI * x) + 0.08f * cos(4 * PI * x);
|
|
37
|
-
data[i] = window * amplitude_;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
void Kaiser::apply(float *data, int size) const {
|
|
42
|
-
for (int i = 0; i < size; ++i) {
|
|
43
|
-
auto r = static_cast<float>(2 * i + 1) / static_cast<float>(size) - 1.0f;
|
|
44
|
-
auto arg = std::sqrt(1 - r * r);
|
|
45
|
-
data[i] = bessel0(beta_ * arg) * invB0_ * amplitude_;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
float Kaiser::bandwidthToBeta(float bandwidth, bool heuristicOptimal) {
|
|
50
|
-
if (heuristicOptimal) { // Heuristic based on numerical search
|
|
51
|
-
return bandwidth + 8.0f / (bandwidth + 3.0f) * (bandwidth + 3.0f) +
|
|
52
|
-
0.25f * std::max(3.0f - bandwidth, 0.0f);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
bandwidth = std::max(bandwidth, 2.0f);
|
|
56
|
-
auto alpha = std::sqrt(bandwidth * bandwidth * 0.25f - 1.0f);
|
|
57
|
-
return alpha * PI;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
void ApproximateConfinedGaussian::apply(float *data, int size) const {
|
|
61
|
-
auto offsetScale =
|
|
62
|
-
getGaussian(1.0f) / (getGaussian(3.0f) + getGaussian(-1.0f));
|
|
63
|
-
auto norm = 1 / (getGaussian(1.0f) - 2 * offsetScale * getGaussian(2.0f));
|
|
64
|
-
for (int i = 0; i < size; ++i) {
|
|
65
|
-
auto r = static_cast<float>(2 * i + 1) / static_cast<float>(size) - 1.0f;
|
|
66
|
-
data[i] = norm *
|
|
67
|
-
(getGaussian(r) -
|
|
68
|
-
offsetScale * (getGaussian(r - 2) + getGaussian(r + 2)));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
float ApproximateConfinedGaussian::bandwidthToSigma(float bandwidth) {
|
|
73
|
-
return 0.3f / std::sqrt(bandwidth);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
float ApproximateConfinedGaussian::getGaussian(float x) const {
|
|
77
|
-
return std::exp(-x * x * gaussianFactor_);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
} // namespace audioapi::dsp
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <cmath>
|
|
4
|
-
#include <algorithm>
|
|
5
|
-
|
|
6
|
-
namespace audioapi::dsp {
|
|
7
|
-
|
|
8
|
-
// https://en.wikipedia.org/wiki/Window_function
|
|
9
|
-
// https://personalpages.hs-kempten.de/~vollratj/InEl/pdf/Window%20function%20-%20Wikipedia.pdf
|
|
10
|
-
class WindowFunction {
|
|
11
|
-
public:
|
|
12
|
-
explicit WindowFunction(float amplitude = 1.0f): amplitude_(amplitude) {}
|
|
13
|
-
|
|
14
|
-
virtual void apply(float *data, int size) const = 0;
|
|
15
|
-
// forces STFT perfect-reconstruction (WOLA) on an existing window, for a given STFT interval.
|
|
16
|
-
static void forcePerfectReconstruction(float *data, int windowLength, int interval);
|
|
17
|
-
|
|
18
|
-
protected:
|
|
19
|
-
// 1/L = amplitude
|
|
20
|
-
float amplitude_;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
//https://en.wikipedia.org/wiki/Hann_function
|
|
24
|
-
// https://www.sciencedirect.com/topics/engineering/hanning-window
|
|
25
|
-
// https://docs.scipy.org/doc//scipy-1.2.3/reference/generated/scipy.signal.windows.hann.html#scipy.signal.windows.hann
|
|
26
|
-
class Hann: public WindowFunction {
|
|
27
|
-
public:
|
|
28
|
-
explicit Hann(float amplitude = 1.0f): WindowFunction(amplitude) {}
|
|
29
|
-
|
|
30
|
-
void apply(float *data, int size) const override;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
// https://www.sciencedirect.com/topics/engineering/blackman-window
|
|
34
|
-
// https://docs.scipy.org/doc//scipy-1.2.3/reference/generated/scipy.signal.windows.blackman.html#scipy.signal.windows.blackman
|
|
35
|
-
class Blackman: public WindowFunction {
|
|
36
|
-
public:
|
|
37
|
-
explicit Blackman(float amplitude = 1.0f): WindowFunction(amplitude) {}
|
|
38
|
-
|
|
39
|
-
void apply(float *data, int size) const override;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// https://en.wikipedia.org/wiki/Kaiser_window
|
|
44
|
-
class Kaiser: public WindowFunction {
|
|
45
|
-
public:
|
|
46
|
-
explicit Kaiser(float beta, float amplitude = 1.0f): WindowFunction(amplitude), beta_(beta), invB0_(1.0f / bessel0(beta)) {}
|
|
47
|
-
|
|
48
|
-
static Kaiser withBandwidth(float bandwidth, bool heuristicOptimal = false, float amplitude = 1.0f) {
|
|
49
|
-
return Kaiser(bandwidthToBeta(bandwidth, heuristicOptimal), amplitude);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
void apply(float *data, int size) const override;
|
|
53
|
-
|
|
54
|
-
private:
|
|
55
|
-
// beta = pi * alpha
|
|
56
|
-
// invB0 = 1 / I0(beta)
|
|
57
|
-
float beta_;
|
|
58
|
-
float invB0_;
|
|
59
|
-
|
|
60
|
-
// https://en.wikipedia.org/wiki/Bessel_function#Modified_Bessel_functions:_I%CE%B1,_K%CE%B1
|
|
61
|
-
static inline float bessel0(float x) {
|
|
62
|
-
const double significanceLimit = 1e-4;
|
|
63
|
-
auto result = 0.0f;
|
|
64
|
-
auto term = 1.0f;
|
|
65
|
-
auto m = 1.0f;
|
|
66
|
-
while (term > significanceLimit) {
|
|
67
|
-
result += term;
|
|
68
|
-
++m;
|
|
69
|
-
term *= (x * x) / (4 * m * m);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return result;
|
|
73
|
-
}
|
|
74
|
-
static float bandwidthToBeta(float bandwidth, bool heuristicOptimal = false);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// https://www.recordingblogs.com/wiki/gaussian-window
|
|
78
|
-
class ApproximateConfinedGaussian: public WindowFunction {
|
|
79
|
-
public:
|
|
80
|
-
explicit ApproximateConfinedGaussian(float sigma, float amplitude = 1.0f): WindowFunction(amplitude), gaussianFactor_(0.0625f/(sigma*sigma)) {}
|
|
81
|
-
|
|
82
|
-
static ApproximateConfinedGaussian withBandwidth(float bandwidth, float amplitude = 1.0f) {
|
|
83
|
-
return ApproximateConfinedGaussian(bandwidthToSigma(bandwidth), amplitude);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
void apply(float *data, int size) const override;
|
|
87
|
-
|
|
88
|
-
private:
|
|
89
|
-
float gaussianFactor_;
|
|
90
|
-
|
|
91
|
-
static float bandwidthToSigma(float bandwidth);
|
|
92
|
-
|
|
93
|
-
[[nodiscard]] float getGaussian(float x) const;
|
|
94
|
-
};
|
|
95
|
-
} // namespace audioapi::dsp
|
/package/{common/cpp/audioapi/libs/pffft → android/src/main/cpp/audioapi/android/libs}/pffft.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|