dsp-collection 0.2.4 → 0.2.6
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 +23 -1
- package/filter/SpecFilt.d.ts +10 -0
- package/filter/SpecFilt.js +98 -0
- package/math/Complex.d.ts +42 -42
- package/math/Complex.js +130 -130
- package/math/ComplexArray.d.ts +36 -32
- package/math/ComplexArray.js +170 -143
- package/math/MathUtils.d.ts +9 -7
- package/math/MathUtils.js +116 -82
- package/math/MutableComplex.d.ts +22 -22
- package/math/MutableComplex.js +64 -65
- package/math/NumApprox.d.ts +3 -3
- package/math/NumApprox.js +67 -68
- package/math/PolyReal.d.ts +13 -13
- package/math/PolyReal.js +226 -227
- package/package.json +13 -7
- package/signal/AdaptiveStft.d.ts +12 -12
- package/signal/AdaptiveStft.js +57 -58
- package/signal/Autocorrelation.d.ts +5 -5
- package/signal/Autocorrelation.js +53 -54
- package/signal/Dft.d.ts +9 -9
- package/signal/Dft.js +87 -88
- package/signal/EnvelopeDetection.d.ts +1 -1
- package/signal/EnvelopeDetection.js +9 -10
- package/signal/Fft.d.ts +9 -6
- package/signal/Fft.js +275 -201
- package/signal/Goertzel.d.ts +5 -5
- package/signal/Goertzel.js +48 -49
- package/signal/InstFreq.d.ts +8 -8
- package/signal/InstFreq.js +26 -27
- package/signal/PitchDetectionHarm.d.ts +26 -26
- package/signal/PitchDetectionHarm.js +68 -69
- package/signal/Resampling.d.ts +7 -0
- package/signal/Resampling.js +218 -0
- package/signal/WindowFunctions.d.ts +40 -40
- package/signal/WindowFunctions.js +194 -195
- package/utils/ArrayUtils.d.ts +9 -5
- package/utils/ArrayUtils.js +68 -51
- package/utils/DspUtils.d.ts +4 -2
- package/utils/DspUtils.js +12 -7
- package/utils/MiscUtils.d.ts +6 -1
- package/utils/MiscUtils.js +20 -16
- package/math/Complex.js.map +0 -1
- package/math/ComplexArray.js.map +0 -1
- package/math/MathUtils.js.map +0 -1
- package/math/MutableComplex.js.map +0 -1
- package/math/NumApprox.js.map +0 -1
- package/math/PolyReal.js.map +0 -1
- package/signal/AdaptiveStft.js.map +0 -1
- package/signal/Autocorrelation.js.map +0 -1
- package/signal/Dft.js.map +0 -1
- package/signal/EnvelopeDetection.js.map +0 -1
- package/signal/Fft.js.map +0 -1
- package/signal/Goertzel.js.map +0 -1
- package/signal/InstFreq.js.map +0 -1
- package/signal/PitchDetectionHarm.js.map +0 -1
- package/signal/WindowFunctions.js.map +0 -1
- package/utils/ArrayUtils.js.map +0 -1
- package/utils/DspUtils.js.map +0 -1
- package/utils/MiscUtils.js.map +0 -1
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import * as WindowFunctions from "./WindowFunctions";
|
|
2
|
-
export interface HarmonicAmplitudeEvaluationParms {
|
|
3
|
-
amplitudeCompressionExponent: number;
|
|
4
|
-
harmonicsDeclineRate: number;
|
|
5
|
-
harmonicsDeclineExponent: number;
|
|
6
|
-
}
|
|
7
|
-
export interface HarmonicSumParms extends HarmonicAmplitudeEvaluationParms {
|
|
8
|
-
fCutoff: number;
|
|
9
|
-
relWindowWidth: number;
|
|
10
|
-
windowFunction: WindowFunctions.WindowFunction | undefined;
|
|
11
|
-
}
|
|
12
|
-
export interface HarmonicInstSumParms extends HarmonicSumParms {
|
|
13
|
-
shiftFactor: number;
|
|
14
|
-
peakWidthFactor: number;
|
|
15
|
-
}
|
|
16
|
-
export declare function getDefaultHarmonicSumParms(): HarmonicSumParms;
|
|
17
|
-
export declare function getDefaultHarmonicInstSumParms(): HarmonicInstSumParms;
|
|
18
|
-
export declare function harmonicSum(samples: Float64Array, sampleRate: number, position: number, f0: number, parms?: HarmonicSumParms): number;
|
|
19
|
-
export declare function harmonicInstSum(samples: Float64Array, sampleRate: number, position: number, f0: number, parms?: HarmonicInstSumParms): number;
|
|
20
|
-
export declare function evaluateHarmonicAmplitude(amplitude: number, harmonic: number, parms: HarmonicAmplitudeEvaluationParms): number;
|
|
21
|
-
export declare function findPitchSalienceFunctionArgMax(salienceFunction: (f0: number) => number, f0Min: number, f0Max: number, { scanFactor, relTolerance, absTolerance }?: {
|
|
22
|
-
scanFactor?: number | undefined;
|
|
23
|
-
relTolerance?: number | undefined;
|
|
24
|
-
absTolerance?: number | undefined;
|
|
25
|
-
}): number;
|
|
26
|
-
export declare function estimatePitch_harmonicSum(samples: Float64Array, sampleRate: number, position: number, f0Min?: number, f0Max?: number, parms?: HarmonicSumParms): number;
|
|
1
|
+
import * as WindowFunctions from "./WindowFunctions.ts";
|
|
2
|
+
export interface HarmonicAmplitudeEvaluationParms {
|
|
3
|
+
amplitudeCompressionExponent: number;
|
|
4
|
+
harmonicsDeclineRate: number;
|
|
5
|
+
harmonicsDeclineExponent: number;
|
|
6
|
+
}
|
|
7
|
+
export interface HarmonicSumParms extends HarmonicAmplitudeEvaluationParms {
|
|
8
|
+
fCutoff: number;
|
|
9
|
+
relWindowWidth: number;
|
|
10
|
+
windowFunction: WindowFunctions.WindowFunction | undefined;
|
|
11
|
+
}
|
|
12
|
+
export interface HarmonicInstSumParms extends HarmonicSumParms {
|
|
13
|
+
shiftFactor: number;
|
|
14
|
+
peakWidthFactor: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function getDefaultHarmonicSumParms(): HarmonicSumParms;
|
|
17
|
+
export declare function getDefaultHarmonicInstSumParms(): HarmonicInstSumParms;
|
|
18
|
+
export declare function harmonicSum(samples: Float64Array | Float32Array, sampleRate: number, position: number, f0: number, parms?: HarmonicSumParms): number;
|
|
19
|
+
export declare function harmonicInstSum(samples: Float64Array | Float32Array, sampleRate: number, position: number, f0: number, parms?: HarmonicInstSumParms): number;
|
|
20
|
+
export declare function evaluateHarmonicAmplitude(amplitude: number, harmonic: number, parms: HarmonicAmplitudeEvaluationParms): number;
|
|
21
|
+
export declare function findPitchSalienceFunctionArgMax(salienceFunction: (f0: number) => number, f0Min: number, f0Max: number, { scanFactor, relTolerance, absTolerance }?: {
|
|
22
|
+
scanFactor?: number | undefined;
|
|
23
|
+
relTolerance?: number | undefined;
|
|
24
|
+
absTolerance?: number | undefined;
|
|
25
|
+
}): number;
|
|
26
|
+
export declare function estimatePitch_harmonicSum(samples: Float64Array | Float32Array, sampleRate: number, position: number, f0Min?: number, f0Max?: number, parms?: HarmonicSumParms): number;
|
|
@@ -1,69 +1,68 @@
|
|
|
1
|
-
import * as MathUtils from "../math/MathUtils";
|
|
2
|
-
import * as NumApprox from "../math/NumApprox";
|
|
3
|
-
import * as WindowFunctions from "./WindowFunctions";
|
|
4
|
-
import * as AdaptiveStft from "./AdaptiveStft";
|
|
5
|
-
import * as InstFreq from "./InstFreq";
|
|
6
|
-
export function getDefaultHarmonicSumParms() {
|
|
7
|
-
return {
|
|
8
|
-
amplitudeCompressionExponent: 0.5,
|
|
9
|
-
harmonicsDeclineRate: 0.2,
|
|
10
|
-
harmonicsDeclineExponent: 0,
|
|
11
|
-
fCutoff: 5000,
|
|
12
|
-
relWindowWidth: 16,
|
|
13
|
-
windowFunction: WindowFunctions.getFunctionbyId("hann", { tableCacheCostLimit: 1 })
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
export function getDefaultHarmonicInstSumParms() {
|
|
17
|
-
return Object.assign({}, getDefaultHarmonicSumParms(), { shiftFactor: 0.25, peakWidthFactor: 0.2 });
|
|
18
|
-
}
|
|
19
|
-
export function harmonicSum(samples, sampleRate, position, f0, parms = getDefaultHarmonicSumParms()) {
|
|
20
|
-
const n = Math.floor(parms.fCutoff / f0);
|
|
21
|
-
const a = AdaptiveStft.getHarmonicAmplitudes(samples, position * sampleRate, f0 / sampleRate, n, parms.relWindowWidth, parms.windowFunction);
|
|
22
|
-
if (!a) {
|
|
23
|
-
return NaN;
|
|
24
|
-
}
|
|
25
|
-
return evaluateHarmonicAmplitudes(a, parms);
|
|
26
|
-
}
|
|
27
|
-
export function harmonicInstSum(samples, sampleRate, position, f0, parms = getDefaultHarmonicInstSumParms()) {
|
|
28
|
-
const peakWidth = f0 * parms.peakWidthFactor / sampleRate;
|
|
29
|
-
const n = Math.floor(parms.fCutoff / f0);
|
|
30
|
-
let sum = 0;
|
|
31
|
-
let count = 0;
|
|
32
|
-
for (let harmonic = 1; harmonic <= n; harmonic++) {
|
|
33
|
-
const f = harmonic * f0 / sampleRate;
|
|
34
|
-
const r = InstFreq.instFreqSingle_relWindow(samples, position * sampleRate, f, parms.shiftFactor, parms.relWindowWidth * harmonic, parms.windowFunction);
|
|
35
|
-
if (r) {
|
|
36
|
-
const absDelta = Math.abs(r.measuringFrequency - r.instFrequency);
|
|
37
|
-
const a = r.amplitude * Math.max(0, 1 - (2 * absDelta) / peakWidth);
|
|
38
|
-
sum += evaluateHarmonicAmplitude(a, harmonic, parms);
|
|
39
|
-
count++;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return (count > 0) ? sum : NaN;
|
|
43
|
-
}
|
|
44
|
-
export function evaluateHarmonicAmplitude(amplitude, harmonic, parms) {
|
|
45
|
-
const attenuation = MathUtils.hyperbolicDecline(harmonic - 1, parms.harmonicsDeclineRate, parms.harmonicsDeclineExponent);
|
|
46
|
-
return amplitude ** parms.amplitudeCompressionExponent * attenuation;
|
|
47
|
-
}
|
|
48
|
-
function evaluateHarmonicAmplitudes(amplitudes, parms) {
|
|
49
|
-
let sum = 0;
|
|
50
|
-
for (let harmonic = 1; harmonic <= amplitudes.length; harmonic++) {
|
|
51
|
-
sum += evaluateHarmonicAmplitude(amplitudes[harmonic - 1], harmonic, parms);
|
|
52
|
-
}
|
|
53
|
-
return sum;
|
|
54
|
-
}
|
|
55
|
-
export function findPitchSalienceFunctionArgMax(salienceFunction, f0Min, f0Max, { scanFactor = 1.005, relTolerance = 1E-3, absTolerance = 0.05 } = {}) {
|
|
56
|
-
const f1 = NumApprox.argMax_scanGeom(salienceFunction, f0Min, f0Max, scanFactor);
|
|
57
|
-
if (!isFinite(f1)) {
|
|
58
|
-
return NaN;
|
|
59
|
-
}
|
|
60
|
-
const f1Lo = Math.max(f1 / scanFactor, f0Min);
|
|
61
|
-
const f1Hi = Math.min(f1 * scanFactor, f0Max);
|
|
62
|
-
const tolerance = Math.min(f1 * relTolerance, absTolerance);
|
|
63
|
-
return NumApprox.argMax_goldenSectionSearch(salienceFunction, f1Lo, f1Hi, tolerance);
|
|
64
|
-
}
|
|
65
|
-
export function estimatePitch_harmonicSum(samples, sampleRate, position, f0Min = 75, f0Max = 900, parms = getDefaultHarmonicSumParms()) {
|
|
66
|
-
const salienceFunction = (f0) => harmonicSum(samples, sampleRate, position, f0, parms);
|
|
67
|
-
return findPitchSalienceFunctionArgMax(salienceFunction, f0Min, f0Max);
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=PitchDetectionHarm.js.map
|
|
1
|
+
import * as MathUtils from "../math/MathUtils.js";
|
|
2
|
+
import * as NumApprox from "../math/NumApprox.js";
|
|
3
|
+
import * as WindowFunctions from "./WindowFunctions.js";
|
|
4
|
+
import * as AdaptiveStft from "./AdaptiveStft.js";
|
|
5
|
+
import * as InstFreq from "./InstFreq.js";
|
|
6
|
+
export function getDefaultHarmonicSumParms() {
|
|
7
|
+
return {
|
|
8
|
+
amplitudeCompressionExponent: 0.5,
|
|
9
|
+
harmonicsDeclineRate: 0.2,
|
|
10
|
+
harmonicsDeclineExponent: 0,
|
|
11
|
+
fCutoff: 5000,
|
|
12
|
+
relWindowWidth: 16,
|
|
13
|
+
windowFunction: WindowFunctions.getFunctionbyId("hann", { tableCacheCostLimit: 1 })
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function getDefaultHarmonicInstSumParms() {
|
|
17
|
+
return Object.assign(Object.assign({}, getDefaultHarmonicSumParms()), { shiftFactor: 0.25, peakWidthFactor: 0.2 });
|
|
18
|
+
}
|
|
19
|
+
export function harmonicSum(samples, sampleRate, position, f0, parms = getDefaultHarmonicSumParms()) {
|
|
20
|
+
const n = Math.floor(parms.fCutoff / f0);
|
|
21
|
+
const a = AdaptiveStft.getHarmonicAmplitudes(samples, position * sampleRate, f0 / sampleRate, n, parms.relWindowWidth, parms.windowFunction);
|
|
22
|
+
if (!a) {
|
|
23
|
+
return NaN;
|
|
24
|
+
}
|
|
25
|
+
return evaluateHarmonicAmplitudes(a, parms);
|
|
26
|
+
}
|
|
27
|
+
export function harmonicInstSum(samples, sampleRate, position, f0, parms = getDefaultHarmonicInstSumParms()) {
|
|
28
|
+
const peakWidth = f0 * parms.peakWidthFactor / sampleRate;
|
|
29
|
+
const n = Math.floor(parms.fCutoff / f0);
|
|
30
|
+
let sum = 0;
|
|
31
|
+
let count = 0;
|
|
32
|
+
for (let harmonic = 1; harmonic <= n; harmonic++) {
|
|
33
|
+
const f = harmonic * f0 / sampleRate;
|
|
34
|
+
const r = InstFreq.instFreqSingle_relWindow(samples, position * sampleRate, f, parms.shiftFactor, parms.relWindowWidth * harmonic, parms.windowFunction);
|
|
35
|
+
if (r) {
|
|
36
|
+
const absDelta = Math.abs(r.measuringFrequency - r.instFrequency);
|
|
37
|
+
const a = r.amplitude * Math.max(0, 1 - (2 * absDelta) / peakWidth);
|
|
38
|
+
sum += evaluateHarmonicAmplitude(a, harmonic, parms);
|
|
39
|
+
count++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return (count > 0) ? sum : NaN;
|
|
43
|
+
}
|
|
44
|
+
export function evaluateHarmonicAmplitude(amplitude, harmonic, parms) {
|
|
45
|
+
const attenuation = MathUtils.hyperbolicDecline(harmonic - 1, parms.harmonicsDeclineRate, parms.harmonicsDeclineExponent);
|
|
46
|
+
return amplitude ** parms.amplitudeCompressionExponent * attenuation;
|
|
47
|
+
}
|
|
48
|
+
function evaluateHarmonicAmplitudes(amplitudes, parms) {
|
|
49
|
+
let sum = 0;
|
|
50
|
+
for (let harmonic = 1; harmonic <= amplitudes.length; harmonic++) {
|
|
51
|
+
sum += evaluateHarmonicAmplitude(amplitudes[harmonic - 1], harmonic, parms);
|
|
52
|
+
}
|
|
53
|
+
return sum;
|
|
54
|
+
}
|
|
55
|
+
export function findPitchSalienceFunctionArgMax(salienceFunction, f0Min, f0Max, { scanFactor = 1.005, relTolerance = 1E-3, absTolerance = 0.05 } = {}) {
|
|
56
|
+
const f1 = NumApprox.argMax_scanGeom(salienceFunction, f0Min, f0Max, scanFactor);
|
|
57
|
+
if (!isFinite(f1)) {
|
|
58
|
+
return NaN;
|
|
59
|
+
}
|
|
60
|
+
const f1Lo = Math.max(f1 / scanFactor, f0Min);
|
|
61
|
+
const f1Hi = Math.min(f1 * scanFactor, f0Max);
|
|
62
|
+
const tolerance = Math.min(f1 * relTolerance, absTolerance);
|
|
63
|
+
return NumApprox.argMax_goldenSectionSearch(salienceFunction, f1Lo, f1Hi, tolerance);
|
|
64
|
+
}
|
|
65
|
+
export function estimatePitch_harmonicSum(samples, sampleRate, position, f0Min = 75, f0Max = 900, parms = getDefaultHarmonicSumParms()) {
|
|
66
|
+
const salienceFunction = (f0) => harmonicSum(samples, sampleRate, position, f0, parms);
|
|
67
|
+
return findPitchSalienceFunctionArgMax(salienceFunction, f0Min, f0Max);
|
|
68
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MutableArrayLike } from "../utils/MiscUtils.ts";
|
|
2
|
+
export declare function resampleNearestNeighbor(ia: ArrayLike<number>, oa: MutableArrayLike<number>, preserveScale?: boolean, extraValues?: number): void;
|
|
3
|
+
export declare function resampleNearestNeighborRef(ia: ArrayLike<number>, oa: MutableArrayLike<number>, preserveScale?: boolean, extraValues?: number): void;
|
|
4
|
+
export declare function resampleLinear(ia: ArrayLike<number>, oa: MutableArrayLike<number>, preserveScale?: boolean, extraValues?: number): void;
|
|
5
|
+
export declare function resampleLinearRef(ia: ArrayLike<number>, oa: MutableArrayLike<number>, preserveScale?: boolean, extraValues?: number): void;
|
|
6
|
+
export declare function resampleAverage(ia: ArrayLike<number>, oa: MutableArrayLike<number>): void;
|
|
7
|
+
export declare function resampleAverageRef(ia: ArrayLike<number>, oa: MutableArrayLike<number>): void;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as ArrayUtils from "../utils/ArrayUtils.js";
|
|
2
|
+
function handleTrivialCases(ia, oa, preserveScale = false, neNe = false) {
|
|
3
|
+
const iLen = ia.length;
|
|
4
|
+
const oLen = oa.length;
|
|
5
|
+
if (iLen == oLen) {
|
|
6
|
+
ArrayUtils.copy(ia, oa);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (oLen == 0) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if (iLen == 0) {
|
|
13
|
+
ArrayUtils.fill(oa, NaN);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
if (iLen == 1) {
|
|
17
|
+
ArrayUtils.fill(oa, ia[0]);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
if (oLen == 1) {
|
|
21
|
+
if (preserveScale) {
|
|
22
|
+
oa[0] = ia[0];
|
|
23
|
+
}
|
|
24
|
+
else if (neNe) {
|
|
25
|
+
oa[0] = ia[Math.trunc(iLen / 2)];
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
oa[0] = ArrayUtils.sum(ia) / iLen;
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
export function resampleNearestNeighbor(ia, oa, preserveScale = false, extraValues = 0) {
|
|
35
|
+
if (handleTrivialCases(ia, oa, preserveScale, true)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const iLen = ia.length;
|
|
39
|
+
const oLen = oa.length;
|
|
40
|
+
const id = iLen * 2;
|
|
41
|
+
const od = oLen * 2;
|
|
42
|
+
const oLen1 = preserveScale ? Math.trunc((iLen - 0.5) / iLen * oLen + 1 - 1E-9) : oLen;
|
|
43
|
+
let ip = 0;
|
|
44
|
+
let op = 0;
|
|
45
|
+
let d = preserveScale ? od / 2 : id / 2;
|
|
46
|
+
while (op < oLen1) {
|
|
47
|
+
if (d >= od) {
|
|
48
|
+
if (od >= id) {
|
|
49
|
+
ip++;
|
|
50
|
+
d -= od;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const i = Math.trunc(d / od);
|
|
54
|
+
ip += i;
|
|
55
|
+
d -= i * od;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
oa[op++] = ia[ip];
|
|
59
|
+
d += id;
|
|
60
|
+
}
|
|
61
|
+
while (op < oLen) {
|
|
62
|
+
oa[op++] = extraValues;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function resampleNearestNeighborRef(ia, oa, preserveScale = false, extraValues = 0) {
|
|
66
|
+
if (handleTrivialCases(ia, oa, preserveScale, true)) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
for (let op = 0; op < oa.length; op++) {
|
|
70
|
+
let ip;
|
|
71
|
+
if (preserveScale) {
|
|
72
|
+
ip = op / oa.length * ia.length;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
ip = (op + 0.5) / oa.length * ia.length - 0.5;
|
|
76
|
+
}
|
|
77
|
+
if (ip <= ia.length - 0.5 - 1E-9) {
|
|
78
|
+
oa[op] = interpolateNearestNeighbor(ia, ip);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
oa[op] = extraValues;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function interpolateNearestNeighbor(a, pos) {
|
|
86
|
+
if (a.length == 0) {
|
|
87
|
+
return NaN;
|
|
88
|
+
}
|
|
89
|
+
const p0 = Math.round(pos + 1E-9);
|
|
90
|
+
const p = Math.max(0, Math.min(a.length - 1, p0));
|
|
91
|
+
return a[p];
|
|
92
|
+
}
|
|
93
|
+
export function resampleLinear(ia, oa, preserveScale = false, extraValues = 0) {
|
|
94
|
+
if (handleTrivialCases(ia, oa, preserveScale)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const iLen = ia.length;
|
|
98
|
+
const oLen = oa.length;
|
|
99
|
+
const id = preserveScale ? iLen : iLen - 1;
|
|
100
|
+
const od = preserveScale ? oLen : oLen - 1;
|
|
101
|
+
const oLen1 = preserveScale ? Math.trunc((iLen - 1) * oLen / iLen + 1 + 1E-9) : oLen;
|
|
102
|
+
let ip = 0;
|
|
103
|
+
let op = 0;
|
|
104
|
+
let d = 0;
|
|
105
|
+
while (op < oLen1) {
|
|
106
|
+
if (d >= od) {
|
|
107
|
+
if (od >= id) {
|
|
108
|
+
ip++;
|
|
109
|
+
d -= od;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const i = Math.trunc(d / od);
|
|
113
|
+
ip += i;
|
|
114
|
+
d -= i * od;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
let x;
|
|
118
|
+
if (d == 0) {
|
|
119
|
+
x = ia[ip];
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
x = ia[ip] * ((od - d) / od) + ia[ip + 1] * (d / od);
|
|
123
|
+
}
|
|
124
|
+
oa[op++] = x;
|
|
125
|
+
d += id;
|
|
126
|
+
}
|
|
127
|
+
while (op < oLen) {
|
|
128
|
+
oa[op++] = extraValues;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export function resampleLinearRef(ia, oa, preserveScale = false, extraValues = 0) {
|
|
132
|
+
if (handleTrivialCases(ia, oa, preserveScale)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
for (let op = 0; op < oa.length; op++) {
|
|
136
|
+
let ip;
|
|
137
|
+
if (preserveScale) {
|
|
138
|
+
ip = op / oa.length * ia.length;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
ip = op / (oa.length - 1) * (ia.length - 1);
|
|
142
|
+
}
|
|
143
|
+
if (Math.abs(ip - Math.round(ip)) < 1E-10) {
|
|
144
|
+
ip = Math.round(ip);
|
|
145
|
+
}
|
|
146
|
+
if (ip <= ia.length - 1) {
|
|
147
|
+
oa[op] = interpolateLinear(ia, ip);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
oa[op] = extraValues;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function interpolateLinear(a, pos) {
|
|
155
|
+
const p1 = Math.floor(pos);
|
|
156
|
+
const p2 = Math.ceil(pos);
|
|
157
|
+
if (p1 < 0 || p2 >= a.length) {
|
|
158
|
+
return NaN;
|
|
159
|
+
}
|
|
160
|
+
if (p1 == p2) {
|
|
161
|
+
return a[p1];
|
|
162
|
+
}
|
|
163
|
+
const v1 = a[p1];
|
|
164
|
+
const v2 = a[p2];
|
|
165
|
+
return v1 + (pos - p1) * (v2 - v1);
|
|
166
|
+
}
|
|
167
|
+
export function resampleAverage(ia, oa) {
|
|
168
|
+
if (handleTrivialCases(ia, oa)) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const iLen = ia.length;
|
|
172
|
+
const oLen = oa.length;
|
|
173
|
+
let ip = 0;
|
|
174
|
+
let op = 0;
|
|
175
|
+
let d = 0;
|
|
176
|
+
while (op < oLen) {
|
|
177
|
+
d += iLen;
|
|
178
|
+
let acc = 0;
|
|
179
|
+
while (d >= oLen) {
|
|
180
|
+
const w = Math.min(oLen, iLen + oLen - d);
|
|
181
|
+
acc += ia[ip++] * w;
|
|
182
|
+
d -= oLen;
|
|
183
|
+
}
|
|
184
|
+
if (d > 0) {
|
|
185
|
+
acc += ia[ip] * Math.min(d, iLen);
|
|
186
|
+
}
|
|
187
|
+
oa[op++] = acc / iLen;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
export function resampleAverageRef(ia, oa) {
|
|
191
|
+
if (handleTrivialCases(ia, oa)) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const w = 1 / oa.length * ia.length;
|
|
195
|
+
for (let i = 0; i < oa.length; i++) {
|
|
196
|
+
const p = i / oa.length * ia.length - 0.5;
|
|
197
|
+
oa[i] = computeAverageOfRange(ia, p, p + w);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function computeAverageOfRange(a, pos1, pos2) {
|
|
201
|
+
const p1 = Math.max(-0.5, pos1);
|
|
202
|
+
const p2 = Math.min(a.length - 0.5, pos2);
|
|
203
|
+
if (p1 >= p2) {
|
|
204
|
+
return NaN;
|
|
205
|
+
}
|
|
206
|
+
const p1i = Math.round(p1);
|
|
207
|
+
const p2i = Math.min(Math.round(p2), a.length - 1);
|
|
208
|
+
if (p1i >= p2i) {
|
|
209
|
+
return a[p1i];
|
|
210
|
+
}
|
|
211
|
+
let sum = 0;
|
|
212
|
+
sum += a[p1i] * (p1i + 0.5 - p1);
|
|
213
|
+
for (let i = p1i + 1; i < p2i; i++) {
|
|
214
|
+
sum += a[i];
|
|
215
|
+
}
|
|
216
|
+
sum += a[p2i] * (p2 - (p2i - 0.5));
|
|
217
|
+
return sum / (p2 - p1);
|
|
218
|
+
}
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
export
|
|
2
|
-
export interface WindowFunctionDescr {
|
|
3
|
-
name: string;
|
|
4
|
-
id: string;
|
|
5
|
-
f: WindowFunction;
|
|
6
|
-
fNorm: WindowFunction;
|
|
7
|
-
cpuCost: number;
|
|
8
|
-
}
|
|
9
|
-
export declare const windowFunctionIndex: WindowFunctionDescr[];
|
|
10
|
-
export declare function getFunctionDescrById(id: string): WindowFunctionDescr;
|
|
11
|
-
export declare function getFunctionbyId(id: string, { normalize, valueCacheCostLimit, tableCacheCostLimit }?: {
|
|
12
|
-
normalize?: boolean | undefined;
|
|
13
|
-
valueCacheCostLimit?: number | undefined;
|
|
14
|
-
tableCacheCostLimit?: number | undefined;
|
|
15
|
-
}): WindowFunction;
|
|
16
|
-
export declare function getWindowTable(windowFunction: WindowFunction, n: number): Float64Array;
|
|
17
|
-
export declare function applyWindow(a:
|
|
18
|
-
export declare function applyWindowById(a:
|
|
19
|
-
export declare function calculateCoherentGain(windowFunction: WindowFunction, n: number):
|
|
20
|
-
export declare function blackmanWindowNorm(x: number): number;
|
|
21
|
-
export declare function blackmanHarrisWindowNorm(x: number): number;
|
|
22
|
-
export declare function blackmanNuttallWindowNorm(x: number): number;
|
|
23
|
-
export declare function flatTopWindowNorm(x: number): number;
|
|
24
|
-
export declare function hammingWindowNorm(x: number): number;
|
|
25
|
-
export declare function hannWindowNorm(x: number): number;
|
|
26
|
-
export declare function nuttallWindowNorm(x: number): number;
|
|
27
|
-
export declare function parabolicWindowNorm(x: number): number;
|
|
28
|
-
export declare function triangularWindowNorm(x: number): number;
|
|
29
|
-
export declare function chdh1WindowNorm(x: number): number;
|
|
30
|
-
export declare function rectangularWindow(x: number): number;
|
|
31
|
-
export declare function triangularWindow(x: number): number;
|
|
32
|
-
export declare function parabolicWindow(x: number): number;
|
|
33
|
-
export declare function hammingWindow(x: number): number;
|
|
34
|
-
export declare function hannWindow(x: number): number;
|
|
35
|
-
export declare function blackmanWindow(x: number): number;
|
|
36
|
-
export declare function blackmanHarrisWindow(x: number): number;
|
|
37
|
-
export declare function blackmanNuttallWindow(x: number): number;
|
|
38
|
-
export declare function nuttallWindow(x: number): number;
|
|
39
|
-
export declare function flatTopWindow(x: number): number;
|
|
40
|
-
export declare function chdh1Window(x: number): number;
|
|
1
|
+
export type WindowFunction = (x: number) => number;
|
|
2
|
+
export interface WindowFunctionDescr {
|
|
3
|
+
name: string;
|
|
4
|
+
id: string;
|
|
5
|
+
f: WindowFunction;
|
|
6
|
+
fNorm: WindowFunction;
|
|
7
|
+
cpuCost: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const windowFunctionIndex: WindowFunctionDescr[];
|
|
10
|
+
export declare function getFunctionDescrById(id: string): WindowFunctionDescr;
|
|
11
|
+
export declare function getFunctionbyId(id: string, { normalize, valueCacheCostLimit, tableCacheCostLimit }?: {
|
|
12
|
+
normalize?: boolean | undefined;
|
|
13
|
+
valueCacheCostLimit?: number | undefined;
|
|
14
|
+
tableCacheCostLimit?: number | undefined;
|
|
15
|
+
}): WindowFunction;
|
|
16
|
+
export declare function getWindowTable(windowFunction: WindowFunction, n: number): Float64Array;
|
|
17
|
+
export declare function applyWindow(a: ArrayLike<number>, windowFunction: WindowFunction): Float64Array;
|
|
18
|
+
export declare function applyWindowById(a: ArrayLike<number>, windowFunctionId: string): Float64Array;
|
|
19
|
+
export declare function calculateCoherentGain(windowFunction: WindowFunction, n: number): number;
|
|
20
|
+
export declare function blackmanWindowNorm(x: number): number;
|
|
21
|
+
export declare function blackmanHarrisWindowNorm(x: number): number;
|
|
22
|
+
export declare function blackmanNuttallWindowNorm(x: number): number;
|
|
23
|
+
export declare function flatTopWindowNorm(x: number): number;
|
|
24
|
+
export declare function hammingWindowNorm(x: number): number;
|
|
25
|
+
export declare function hannWindowNorm(x: number): number;
|
|
26
|
+
export declare function nuttallWindowNorm(x: number): number;
|
|
27
|
+
export declare function parabolicWindowNorm(x: number): number;
|
|
28
|
+
export declare function triangularWindowNorm(x: number): number;
|
|
29
|
+
export declare function chdh1WindowNorm(x: number): number;
|
|
30
|
+
export declare function rectangularWindow(x: number): number;
|
|
31
|
+
export declare function triangularWindow(x: number): number;
|
|
32
|
+
export declare function parabolicWindow(x: number): number;
|
|
33
|
+
export declare function hammingWindow(x: number): number;
|
|
34
|
+
export declare function hannWindow(x: number): number;
|
|
35
|
+
export declare function blackmanWindow(x: number): number;
|
|
36
|
+
export declare function blackmanHarrisWindow(x: number): number;
|
|
37
|
+
export declare function blackmanNuttallWindow(x: number): number;
|
|
38
|
+
export declare function nuttallWindow(x: number): number;
|
|
39
|
+
export declare function flatTopWindow(x: number): number;
|
|
40
|
+
export declare function chdh1Window(x: number): number;
|