audio-ml 1.0.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 (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +213 -0
  3. package/dist/analysis/AutocorrelationAnalyzer.d.ts +23 -0
  4. package/dist/analysis/AutocorrelationAnalyzer.d.ts.map +1 -0
  5. package/dist/analysis/AutocorrelationAnalyzer.js +26 -0
  6. package/dist/analysis/AutocorrelationAnalyzer.js.map +1 -0
  7. package/dist/analysis/ChromaFeaturesAnalyzer.d.ts +12 -0
  8. package/dist/analysis/ChromaFeaturesAnalyzer.d.ts.map +1 -0
  9. package/dist/analysis/ChromaFeaturesAnalyzer.js +33 -0
  10. package/dist/analysis/ChromaFeaturesAnalyzer.js.map +1 -0
  11. package/dist/analysis/ConstantQTransformAnalyzer.d.ts +31 -0
  12. package/dist/analysis/ConstantQTransformAnalyzer.d.ts.map +1 -0
  13. package/dist/analysis/ConstantQTransformAnalyzer.js +101 -0
  14. package/dist/analysis/ConstantQTransformAnalyzer.js.map +1 -0
  15. package/dist/analysis/FFTAnalyzer.d.ts +16 -0
  16. package/dist/analysis/FFTAnalyzer.d.ts.map +1 -0
  17. package/dist/analysis/FFTAnalyzer.js +36 -0
  18. package/dist/analysis/FFTAnalyzer.js.map +1 -0
  19. package/dist/analysis/LPCAnalyzer.d.ts +10 -0
  20. package/dist/analysis/LPCAnalyzer.d.ts.map +1 -0
  21. package/dist/analysis/LPCAnalyzer.js +34 -0
  22. package/dist/analysis/LPCAnalyzer.js.map +1 -0
  23. package/dist/analysis/MFCCAnalyzer.d.ts +40 -0
  24. package/dist/analysis/MFCCAnalyzer.d.ts.map +1 -0
  25. package/dist/analysis/MFCCAnalyzer.js +101 -0
  26. package/dist/analysis/MFCCAnalyzer.js.map +1 -0
  27. package/dist/analysis/MelSpectrogramAnalyzer.d.ts +33 -0
  28. package/dist/analysis/MelSpectrogramAnalyzer.d.ts.map +1 -0
  29. package/dist/analysis/MelSpectrogramAnalyzer.js +86 -0
  30. package/dist/analysis/MelSpectrogramAnalyzer.js.map +1 -0
  31. package/dist/analysis/PLPAnalyzer.d.ts +47 -0
  32. package/dist/analysis/PLPAnalyzer.d.ts.map +1 -0
  33. package/dist/analysis/PLPAnalyzer.js +176 -0
  34. package/dist/analysis/PLPAnalyzer.js.map +1 -0
  35. package/dist/analysis/RMSEAnalyzer.d.ts +21 -0
  36. package/dist/analysis/RMSEAnalyzer.d.ts.map +1 -0
  37. package/dist/analysis/RMSEAnalyzer.js +20 -0
  38. package/dist/analysis/RMSEAnalyzer.js.map +1 -0
  39. package/dist/analysis/SpectralBandwidthAnalyzer.d.ts +22 -0
  40. package/dist/analysis/SpectralBandwidthAnalyzer.d.ts.map +1 -0
  41. package/dist/analysis/SpectralBandwidthAnalyzer.js +51 -0
  42. package/dist/analysis/SpectralBandwidthAnalyzer.js.map +1 -0
  43. package/dist/analysis/SpectralCentroidAnalyzer.d.ts +22 -0
  44. package/dist/analysis/SpectralCentroidAnalyzer.d.ts.map +1 -0
  45. package/dist/analysis/SpectralCentroidAnalyzer.js +44 -0
  46. package/dist/analysis/SpectralCentroidAnalyzer.js.map +1 -0
  47. package/dist/analysis/SpectralFlatnessAnalyzer.d.ts +21 -0
  48. package/dist/analysis/SpectralFlatnessAnalyzer.d.ts.map +1 -0
  49. package/dist/analysis/SpectralFlatnessAnalyzer.js +37 -0
  50. package/dist/analysis/SpectralFlatnessAnalyzer.js.map +1 -0
  51. package/dist/analysis/SpectralRolloffAnalyzer.d.ts +25 -0
  52. package/dist/analysis/SpectralRolloffAnalyzer.d.ts.map +1 -0
  53. package/dist/analysis/SpectralRolloffAnalyzer.js +48 -0
  54. package/dist/analysis/SpectralRolloffAnalyzer.js.map +1 -0
  55. package/dist/analysis/WaveformEnvelopeAnalyzer.d.ts +23 -0
  56. package/dist/analysis/WaveformEnvelopeAnalyzer.d.ts.map +1 -0
  57. package/dist/analysis/WaveformEnvelopeAnalyzer.js +28 -0
  58. package/dist/analysis/WaveformEnvelopeAnalyzer.js.map +1 -0
  59. package/dist/analysis/WaveletTransformAnalyzer.d.ts +10 -0
  60. package/dist/analysis/WaveletTransformAnalyzer.d.ts.map +1 -0
  61. package/dist/analysis/WaveletTransformAnalyzer.js +25 -0
  62. package/dist/analysis/WaveletTransformAnalyzer.js.map +1 -0
  63. package/dist/analysis/ZeroCrossingRateAnalyzer.d.ts +21 -0
  64. package/dist/analysis/ZeroCrossingRateAnalyzer.d.ts.map +1 -0
  65. package/dist/analysis/ZeroCrossingRateAnalyzer.js +22 -0
  66. package/dist/analysis/ZeroCrossingRateAnalyzer.js.map +1 -0
  67. package/dist/analysis/index.d.ts +31 -0
  68. package/dist/analysis/index.d.ts.map +1 -0
  69. package/dist/analysis/index.js +35 -0
  70. package/dist/analysis/index.js.map +1 -0
  71. package/package.json +57 -0
@@ -0,0 +1,101 @@
1
+ /**
2
+ * MFCCAnalyzer extracts Mel-Frequency Cepstral Coefficients (MFCCs) from PCM audio frames.
3
+ * MFCCs are widely used features in speech and audio processing, representing the short-term power spectrum of sound on a mel scale.
4
+ * This class uses FFT for spectral analysis, applies a mel filter bank, takes the log, and then applies a Discrete Cosine Transform (DCT).
5
+ * Usage: const mfcc = new MFCCAnalyzer({ sampleRate: 16000 }); mfcc.analyzeFrame(pcm)
6
+ */
7
+ import FFT from 'fft.js';
8
+ export class MFCCAnalyzer {
9
+ fft;
10
+ fftSize;
11
+ melBands;
12
+ numCoeffs;
13
+ sampleRate;
14
+ melFilters;
15
+ /**
16
+ * @param config - MFCC extraction configuration
17
+ */
18
+ constructor(config) {
19
+ this.fftSize = config.fftSize || 1024;
20
+ this.melBands = config.melBands || 26;
21
+ this.numCoeffs = config.numCoeffs || 13;
22
+ this.sampleRate = config.sampleRate;
23
+ this.fft = new FFT(this.fftSize);
24
+ this.melFilters = this.createMelFilterBank();
25
+ }
26
+ /**
27
+ * Extract MFCCs from a PCM frame.
28
+ * @param pcm - Input PCM audio frame (Float32Array, length = fftSize)
29
+ * @returns Array of MFCC coefficients (length = numCoeffs)
30
+ */
31
+ analyzeFrame(pcm) {
32
+ if (pcm.length !== this.fftSize)
33
+ throw new Error('PCM frame must be fftSize');
34
+ const spectrum = this.fft.createComplexArray();
35
+ this.fft.realTransform(spectrum, pcm);
36
+ this.fft.completeSpectrum(spectrum);
37
+ const mags = [];
38
+ for (let i = 0; i < this.fftSize / 2; i++) {
39
+ const re = spectrum[2 * i];
40
+ const im = spectrum[2 * i + 1];
41
+ mags.push(Math.sqrt(re * re + im * im));
42
+ }
43
+ const melEnergies = this.melFilters.map(filter => filter.reduce((sum, w, k) => sum + w * mags[k], 0));
44
+ const logMel = melEnergies.map(e => Math.log(e + 1e-6));
45
+ return this.dct(logMel).slice(0, this.numCoeffs);
46
+ }
47
+ /**
48
+ * Create a mel filter bank matrix.
49
+ * @returns Array of mel filters (each filter is an array of weights for FFT bins)
50
+ */
51
+ createMelFilterBank() {
52
+ const filters = [];
53
+ const lowFreq = 0;
54
+ const highFreq = this.sampleRate / 2;
55
+ const melLow = this.hzToMel(lowFreq);
56
+ const melHigh = this.hzToMel(highFreq);
57
+ const melPoints = [];
58
+ for (let i = 0; i <= this.melBands + 2; i++) {
59
+ melPoints.push(melLow + (melHigh - melLow) * i / (this.melBands + 2));
60
+ }
61
+ const hzPoints = melPoints.map(mel => this.melToHz(mel));
62
+ const binPoints = hzPoints.map(hz => Math.floor((this.fftSize + 1) * hz / this.sampleRate));
63
+ for (let i = 0; i < this.melBands; i++) {
64
+ const filter = new Array(this.fftSize / 2).fill(0);
65
+ for (let j = binPoints[i]; j < binPoints[i + 1]; j++) {
66
+ filter[j] = (j - binPoints[i]) / (binPoints[i + 1] - binPoints[i]);
67
+ }
68
+ for (let j = binPoints[i + 1]; j < binPoints[i + 2]; j++) {
69
+ filter[j] = (binPoints[i + 2] - j) / (binPoints[i + 2] - binPoints[i + 1]);
70
+ }
71
+ filters.push(filter);
72
+ }
73
+ return filters;
74
+ }
75
+ /** Convert Hz to mel scale */
76
+ hzToMel(hz) {
77
+ return 2595 * Math.log10(1 + hz / 700);
78
+ }
79
+ /** Convert mel scale to Hz */
80
+ melToHz(mel) {
81
+ return 700 * (Math.pow(10, mel / 2595) - 1);
82
+ }
83
+ /**
84
+ * Discrete Cosine Transform (DCT-II) for MFCCs.
85
+ * @param vector - Input array (log-mel energies)
86
+ * @returns DCT coefficients
87
+ */
88
+ dct(vector) {
89
+ const N = vector.length;
90
+ const result = new Array(N).fill(0);
91
+ for (let k = 0; k < N; k++) {
92
+ let sum = 0;
93
+ for (let n = 0; n < N; n++) {
94
+ sum += vector[n] * Math.cos(Math.PI * k * (2 * n + 1) / (2 * N));
95
+ }
96
+ result[k] = sum;
97
+ }
98
+ return result;
99
+ }
100
+ }
101
+ //# sourceMappingURL=MFCCAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MFCCAnalyzer.js","sourceRoot":"","sources":["../../src/analysis/MFCCAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export interface MelSpectrogramConfig {
2
+ sampleRate: number;
3
+ fftSize?: number;
4
+ melBands?: number;
5
+ }
6
+ export declare class MelSpectrogramAnalyzer {
7
+ private fft;
8
+ private fftSize;
9
+ private melBands;
10
+ private sampleRate;
11
+ private melFilters;
12
+ constructor(config: MelSpectrogramConfig);
13
+ /**
14
+ * Analyze a single frame of PCM samples and return mel spectrogram features.
15
+ * @param pcm - Input PCM audio frame (must be fftSize samples)
16
+ * @returns Array of log-mel energies
17
+ */
18
+ analyzeFrame(pcm: Float32Array): number[];
19
+ /**
20
+ * Create mel filter bank.
21
+ * @returns Array of mel filters (each filter is an array of weights for FFT bins)
22
+ */
23
+ private createMelFilterBank;
24
+ /**
25
+ * Convert Hz to mel scale.
26
+ */
27
+ private hzToMel;
28
+ /**
29
+ * Convert mel scale to Hz.
30
+ */
31
+ private melToHz;
32
+ }
33
+ //# sourceMappingURL=MelSpectrogramAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MelSpectrogramAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analysis/MelSpectrogramAnalyzer.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAa;gBAEnB,MAAM,EAAE,oBAAoB;IAQxC;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,EAAE;IAyBzC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA0B3B;;OAEG;IACH,OAAO,CAAC,OAAO;IAIf;;OAEG;IACH,OAAO,CAAC,OAAO;CAGhB"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * MelSpectrogramAnalyzer computes mel spectrogram features from PCM audio frames.
3
+ * Mel spectrogram applies a mel filter bank to the FFT spectrum and returns log-mel energies.
4
+ * This is similar to MFCC but without the DCT step.
5
+ * Usage: const mel = new MelSpectrogramAnalyzer({ sampleRate: 16000 }); mel.analyzeFrame(pcm)
6
+ */
7
+ import FFT from 'fft.js';
8
+ export class MelSpectrogramAnalyzer {
9
+ fft;
10
+ fftSize;
11
+ melBands;
12
+ sampleRate;
13
+ melFilters;
14
+ constructor(config) {
15
+ this.fftSize = config.fftSize || 1024;
16
+ this.melBands = config.melBands || 40;
17
+ this.sampleRate = config.sampleRate;
18
+ this.fft = new FFT(this.fftSize);
19
+ this.melFilters = this.createMelFilterBank();
20
+ }
21
+ /**
22
+ * Analyze a single frame of PCM samples and return mel spectrogram features.
23
+ * @param pcm - Input PCM audio frame (must be fftSize samples)
24
+ * @returns Array of log-mel energies
25
+ */
26
+ analyzeFrame(pcm) {
27
+ if (pcm.length !== this.fftSize) {
28
+ throw new Error(`PCM frame must be fftSize (${this.fftSize}) samples`);
29
+ }
30
+ const spectrum = this.fft.createComplexArray();
31
+ this.fft.realTransform(spectrum, pcm);
32
+ this.fft.completeSpectrum(spectrum);
33
+ // Get magnitude spectrum
34
+ const mags = [];
35
+ for (let i = 0; i < this.fftSize / 2; i++) {
36
+ const re = spectrum[2 * i];
37
+ const im = spectrum[2 * i + 1];
38
+ mags.push(Math.sqrt(re * re + im * im));
39
+ }
40
+ // Apply mel filter bank
41
+ const melEnergies = this.melFilters.map(filter => filter.reduce((sum, w, k) => sum + w * mags[k], 0));
42
+ // Log scaling
43
+ return melEnergies.map(e => Math.log(e + 1e-6));
44
+ }
45
+ /**
46
+ * Create mel filter bank.
47
+ * @returns Array of mel filters (each filter is an array of weights for FFT bins)
48
+ */
49
+ createMelFilterBank() {
50
+ const filters = [];
51
+ const lowFreq = 0;
52
+ const highFreq = this.sampleRate / 2;
53
+ const melLow = this.hzToMel(lowFreq);
54
+ const melHigh = this.hzToMel(highFreq);
55
+ const melPoints = [];
56
+ for (let i = 0; i <= this.melBands + 2; i++) {
57
+ melPoints.push(melLow + (melHigh - melLow) * i / (this.melBands + 2));
58
+ }
59
+ const hzPoints = melPoints.map(mel => this.melToHz(mel));
60
+ const binPoints = hzPoints.map(hz => Math.floor((this.fftSize + 1) * hz / this.sampleRate));
61
+ for (let i = 0; i < this.melBands; i++) {
62
+ const filter = new Array(this.fftSize / 2).fill(0);
63
+ for (let j = binPoints[i]; j < binPoints[i + 1]; j++) {
64
+ filter[j] = (j - binPoints[i]) / (binPoints[i + 1] - binPoints[i]);
65
+ }
66
+ for (let j = binPoints[i + 1]; j < binPoints[i + 2]; j++) {
67
+ filter[j] = (binPoints[i + 2] - j) / (binPoints[i + 2] - binPoints[i + 1]);
68
+ }
69
+ filters.push(filter);
70
+ }
71
+ return filters;
72
+ }
73
+ /**
74
+ * Convert Hz to mel scale.
75
+ */
76
+ hzToMel(hz) {
77
+ return 2595 * Math.log10(1 + hz / 700);
78
+ }
79
+ /**
80
+ * Convert mel scale to Hz.
81
+ */
82
+ melToHz(mel) {
83
+ return 700 * (Math.pow(10, mel / 2595) - 1);
84
+ }
85
+ }
86
+ //# sourceMappingURL=MelSpectrogramAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MelSpectrogramAnalyzer.js","sourceRoot":"","sources":["../../src/analysis/MelSpectrogramAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ export interface PLPConfig {
2
+ sampleRate: number;
3
+ fftSize?: number;
4
+ order?: number;
5
+ numBands?: number;
6
+ }
7
+ export declare class PLPAnalyzer {
8
+ private fft;
9
+ private fftSize;
10
+ private order;
11
+ private numBands;
12
+ private sampleRate;
13
+ private barkFilters;
14
+ /**
15
+ * @param config - Configuration with sample rate, optional FFT size, LPC order, and number of critical bands
16
+ */
17
+ constructor(config: PLPConfig);
18
+ /**
19
+ * Extract PLP coefficients from a PCM frame.
20
+ * @param pcm - Input PCM audio frame
21
+ * @returns Array of PLP coefficients
22
+ */
23
+ analyzeFrame(pcm: Float32Array): number[];
24
+ /**
25
+ * Create a Bark scale filter bank.
26
+ * @returns Array of Bark filters
27
+ */
28
+ private createBarkFilterBank;
29
+ /**
30
+ * Convert Hz to Bark scale.
31
+ */
32
+ private hzToBark;
33
+ /**
34
+ * Equal loudness pre-emphasis weight.
35
+ */
36
+ private equalLoudnessWeight;
37
+ /**
38
+ * Convert Bark domain loudness to autocorrelation via inverse FFT.
39
+ * Interpolates Bark domain loudness back to frequency domain, then computes autocorrelation.
40
+ */
41
+ private barkToAutocorr;
42
+ /**
43
+ * Levinson-Durbin recursion for LPC coefficients.
44
+ */
45
+ private levinsonDurbin;
46
+ }
47
+ //# sourceMappingURL=PLPAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PLPAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analysis/PLPAnalyzer.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAa;IAEhC;;OAEG;gBACS,MAAM,EAAE,SAAS;IAS7B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,EAAE;IAuCzC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAkC5B;;OAEG;IACH,OAAO,CAAC,QAAQ;IAIhB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;;OAGG;IACH,OAAO,CAAC,cAAc;IAkDtB;;OAEG;IACH,OAAO,CAAC,cAAc;CAqBvB"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * PLPAnalyzer extracts Perceptual Linear Prediction (PLP) coefficients from PCM audio frames.
3
+ * PLP is used in speech processing to model the auditory spectrum using perceptual principles.
4
+ * This implementation includes critical band analysis, equal loudness pre-emphasis, and LPC analysis.
5
+ * Usage: const plp = new PLPAnalyzer({ sampleRate: 16000 }); plp.analyzeFrame(pcm)
6
+ */
7
+ import FFT from 'fft.js';
8
+ export class PLPAnalyzer {
9
+ fft;
10
+ fftSize;
11
+ order;
12
+ numBands;
13
+ sampleRate;
14
+ barkFilters;
15
+ /**
16
+ * @param config - Configuration with sample rate, optional FFT size, LPC order, and number of critical bands
17
+ */
18
+ constructor(config) {
19
+ this.fftSize = config.fftSize || 512;
20
+ this.order = config.order || 12;
21
+ this.numBands = config.numBands || 18;
22
+ this.sampleRate = config.sampleRate;
23
+ this.fft = new FFT(this.fftSize);
24
+ this.barkFilters = this.createBarkFilterBank();
25
+ }
26
+ /**
27
+ * Extract PLP coefficients from a PCM frame.
28
+ * @param pcm - Input PCM audio frame
29
+ * @returns Array of PLP coefficients
30
+ */
31
+ analyzeFrame(pcm) {
32
+ // Ensure correct frame size
33
+ if (pcm.length !== this.fftSize) {
34
+ throw new Error(`PCM frame must be fftSize (${this.fftSize}) samples, got ${pcm.length}`);
35
+ }
36
+ // Step 1: Compute power spectrum
37
+ const spectrum = this.fft.createComplexArray();
38
+ this.fft.realTransform(spectrum, pcm);
39
+ this.fft.completeSpectrum(spectrum);
40
+ const powerSpectrum = [];
41
+ for (let i = 0; i < this.fftSize / 2; i++) {
42
+ const re = spectrum[2 * i];
43
+ const im = spectrum[2 * i + 1];
44
+ powerSpectrum.push(re * re + im * im);
45
+ }
46
+ // Step 2: Critical band analysis (Bark scale)
47
+ const barkEnergies = this.barkFilters.map(filter => filter.reduce((sum, w, k) => sum + w * powerSpectrum[k], 0));
48
+ // Step 3: Equal loudness pre-emphasis
49
+ const preemphasized = barkEnergies.map((energy, i) => {
50
+ const bark = i * 1.0; // Approximate bark value
51
+ const equalLoudness = this.equalLoudnessWeight(bark);
52
+ return energy * equalLoudness;
53
+ });
54
+ // Step 4: Intensity-loudness conversion (cube root)
55
+ const loudness = preemphasized.map(e => Math.pow(e + 1e-12, 1.0 / 3.0));
56
+ // Step 5: Inverse FFT to get autocorrelation
57
+ const autocorr = this.barkToAutocorr(loudness);
58
+ // Step 6: LPC analysis using Levinson-Durbin
59
+ return this.levinsonDurbin(autocorr, this.order);
60
+ }
61
+ /**
62
+ * Create a Bark scale filter bank.
63
+ * @returns Array of Bark filters
64
+ */
65
+ createBarkFilterBank() {
66
+ const filters = [];
67
+ const nyquist = this.sampleRate / 2;
68
+ const maxBark = this.hzToBark(nyquist);
69
+ for (let band = 0; band < this.numBands; band++) {
70
+ const filter = new Array(this.fftSize / 2).fill(0);
71
+ const centerBark = (band + 0.5) * maxBark / this.numBands;
72
+ for (let i = 0; i < this.fftSize / 2; i++) {
73
+ const freq = (i * this.sampleRate) / this.fftSize;
74
+ const bark = this.hzToBark(freq);
75
+ const distance = Math.abs(bark - centerBark);
76
+ // Triangular filter shape
77
+ if (distance < 1.0) {
78
+ filter[i] = 1.0 - distance;
79
+ }
80
+ }
81
+ // Normalize
82
+ const sum = filter.reduce((a, b) => a + b, 0);
83
+ if (sum > 0) {
84
+ for (let i = 0; i < filter.length; i++) {
85
+ filter[i] /= sum;
86
+ }
87
+ }
88
+ filters.push(filter);
89
+ }
90
+ return filters;
91
+ }
92
+ /**
93
+ * Convert Hz to Bark scale.
94
+ */
95
+ hzToBark(hz) {
96
+ return 13 * Math.atan(0.00076 * hz) + 3.5 * Math.atan(Math.pow(hz / 7500, 2));
97
+ }
98
+ /**
99
+ * Equal loudness pre-emphasis weight.
100
+ */
101
+ equalLoudnessWeight(bark) {
102
+ // Simplified equal loudness curve
103
+ const w = 1.0 / (1.0 + Math.pow(bark / 15.0, 2));
104
+ return w;
105
+ }
106
+ /**
107
+ * Convert Bark domain loudness to autocorrelation via inverse FFT.
108
+ * Interpolates Bark domain loudness back to frequency domain, then computes autocorrelation.
109
+ */
110
+ barkToAutocorr(loudness) {
111
+ // Interpolate Bark domain loudness back to frequency domain
112
+ const nyquist = this.sampleRate / 2;
113
+ const maxBark = this.hzToBark(nyquist);
114
+ const freqSpectrum = new Array(this.fftSize / 2).fill(0);
115
+ for (let i = 0; i < this.fftSize / 2; i++) {
116
+ const freq = (i * this.sampleRate) / this.fftSize;
117
+ const bark = this.hzToBark(freq);
118
+ const bandIndex = (bark / maxBark) * this.numBands;
119
+ // Linear interpolation
120
+ const lowerBand = Math.floor(bandIndex);
121
+ const upperBand = Math.min(Math.ceil(bandIndex), this.numBands - 1);
122
+ const t = bandIndex - lowerBand;
123
+ if (lowerBand >= 0 && lowerBand < loudness.length && upperBand >= 0 && upperBand < loudness.length) {
124
+ freqSpectrum[i] = loudness[lowerBand] * (1 - t) + loudness[upperBand] * t;
125
+ }
126
+ else if (lowerBand >= 0 && lowerBand < loudness.length) {
127
+ freqSpectrum[i] = loudness[lowerBand];
128
+ }
129
+ }
130
+ // Pad to fftSize for IFFT (mirror for real signal)
131
+ const padded = new Array(this.fftSize).fill(0);
132
+ for (let i = 0; i < this.fftSize / 2; i++) {
133
+ padded[i] = freqSpectrum[i];
134
+ if (i > 0) {
135
+ padded[this.fftSize - i] = freqSpectrum[i]; // Mirror for real IFFT
136
+ }
137
+ }
138
+ // Inverse FFT to get autocorrelation
139
+ const input = this.fft.createComplexArray();
140
+ const output = this.fft.createComplexArray();
141
+ for (let i = 0; i < padded.length; i++) {
142
+ input[2 * i] = padded[i];
143
+ input[2 * i + 1] = 0;
144
+ }
145
+ this.fft.inverseTransform(output, input);
146
+ // Extract autocorrelation (first order+1 values)
147
+ const autocorr = new Array(this.order + 1).fill(0);
148
+ for (let i = 0; i <= this.order; i++) {
149
+ autocorr[i] = output[2 * i] / this.fftSize;
150
+ }
151
+ return autocorr;
152
+ }
153
+ /**
154
+ * Levinson-Durbin recursion for LPC coefficients.
155
+ */
156
+ levinsonDurbin(R, order) {
157
+ const a = new Array(order + 1).fill(0);
158
+ const e = new Array(order + 1).fill(0);
159
+ a[0] = 1;
160
+ e[0] = R[0];
161
+ for (let i = 1; i <= order; i++) {
162
+ let acc = 0;
163
+ for (let j = 1; j < i; j++) {
164
+ acc += a[j] * R[i - j];
165
+ }
166
+ const k = (R[i] - acc) / (e[i - 1] + 1e-12);
167
+ a[i] = k;
168
+ for (let j = 1; j < i; j++) {
169
+ a[j] = a[j] - k * a[i - j];
170
+ }
171
+ e[i] = (1 - k * k) * e[i - 1];
172
+ }
173
+ return a.slice(1);
174
+ }
175
+ }
176
+ //# sourceMappingURL=PLPAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PLPAnalyzer.js","sourceRoot":"","sources":["../../src/analysis/PLPAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * RMSEAnalyzer computes the Root Mean Square Energy (RMSE) of a PCM audio frame.
3
+ * RMSE is a simple measure of signal energy, useful for detecting silence, loudness, or dynamic range.
4
+ * Usage: const rmse = new RMSEAnalyzer({ sampleRate: 16000 }); rmse.analyzeFrame(pcm)
5
+ */
6
+ export interface RMSEConfig {
7
+ sampleRate: number;
8
+ }
9
+ export declare class RMSEAnalyzer {
10
+ /**
11
+ * @param _config - Configuration with sample rate
12
+ */
13
+ constructor(_config: RMSEConfig);
14
+ /**
15
+ * Compute the root mean square energy for a PCM frame.
16
+ * @param pcm - Input PCM audio frame
17
+ * @returns RMSE value
18
+ */
19
+ analyzeFrame(pcm: Float32Array): number;
20
+ }
21
+ //# sourceMappingURL=RMSEAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RMSEAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analysis/RMSEAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,UAAU;IAAG,UAAU,EAAE,MAAM,CAAA;CAAE;AAElD,qBAAa,YAAY;IACvB;;OAEG;gBACS,OAAO,EAAE,UAAU;IAE/B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM;CAOxC"}
@@ -0,0 +1,20 @@
1
+ export class RMSEAnalyzer {
2
+ /**
3
+ * @param _config - Configuration with sample rate
4
+ */
5
+ constructor(_config) {
6
+ }
7
+ /**
8
+ * Compute the root mean square energy for a PCM frame.
9
+ * @param pcm - Input PCM audio frame
10
+ * @returns RMSE value
11
+ */
12
+ analyzeFrame(pcm) {
13
+ let sum = 0;
14
+ for (let i = 0; i < pcm.length; i++) {
15
+ sum += pcm[i] * pcm[i];
16
+ }
17
+ return Math.sqrt(sum / pcm.length);
18
+ }
19
+ }
20
+ //# sourceMappingURL=RMSEAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RMSEAnalyzer.js","sourceRoot":"","sources":["../../src/analysis/RMSEAnalyzer.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,YAAY;IACvB;;OAEG;IACH,YAAY,OAAmB;IAC/B,CAAC;IACD;;;;OAIG;IACH,YAAY,CAAC,GAAiB;QAC5B,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ export interface SpectralBandwidthConfig {
2
+ /** Sample rate of the audio (Hz) */
3
+ sampleRate: number;
4
+ /** FFT size (default: 1024) */
5
+ fftSize?: number;
6
+ }
7
+ export declare class SpectralBandwidthAnalyzer {
8
+ private fft;
9
+ private fftSize;
10
+ private sampleRate;
11
+ /**
12
+ * @param config - Configuration with sample rate and optional FFT size
13
+ */
14
+ constructor(config: SpectralBandwidthConfig);
15
+ /**
16
+ * Compute the spectral bandwidth for a PCM frame.
17
+ * @param pcm - Input PCM audio frame
18
+ * @returns Spectral bandwidth in Hz
19
+ */
20
+ analyzeFrame(pcm: Float32Array): number;
21
+ }
22
+ //# sourceMappingURL=SpectralBandwidthAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpectralBandwidthAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analysis/SpectralBandwidthAnalyzer.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,uBAAuB;IACtC,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,yBAAyB;IACpC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B;;OAEG;gBACS,MAAM,EAAE,uBAAuB;IAK3C;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM;CAyBxC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * SpectralBandwidthAnalyzer computes the spectral bandwidth of a PCM audio frame.
3
+ * The spectral bandwidth is the spread of the spectrum around the centroid, related to the perceived timbre of a sound.
4
+ * Usage: const sb = new SpectralBandwidthAnalyzer({ sampleRate: 16000 }); sb.analyzeFrame(pcm)
5
+ */
6
+ import FFT from 'fft.js';
7
+ export class SpectralBandwidthAnalyzer {
8
+ fft;
9
+ fftSize;
10
+ sampleRate;
11
+ /**
12
+ * @param config - Configuration with sample rate and optional FFT size
13
+ */
14
+ constructor(config) {
15
+ this.fftSize = config.fftSize || 1024;
16
+ this.fft = new FFT(this.fftSize);
17
+ this.sampleRate = config.sampleRate;
18
+ }
19
+ /**
20
+ * Compute the spectral bandwidth for a PCM frame.
21
+ * @param pcm - Input PCM audio frame
22
+ * @returns Spectral bandwidth in Hz
23
+ */
24
+ analyzeFrame(pcm) {
25
+ const spectrum = this.fft.createComplexArray();
26
+ this.fft.realTransform(spectrum, pcm);
27
+ this.fft.completeSpectrum(spectrum);
28
+ let mags = [];
29
+ for (let i = 0; i < this.fftSize / 2; i++) {
30
+ const re = spectrum[2 * i];
31
+ const im = spectrum[2 * i + 1];
32
+ mags.push(Math.sqrt(re * re + im * im));
33
+ }
34
+ // Spectral centroid
35
+ let num = 0, denom = 0;
36
+ for (let i = 0; i < mags.length; i++) {
37
+ num += i * mags[i];
38
+ denom += mags[i];
39
+ }
40
+ if (denom === 0)
41
+ return 0;
42
+ const centroid = (num / denom);
43
+ // Bandwidth
44
+ let spread = 0;
45
+ for (let i = 0; i < mags.length; i++) {
46
+ spread += mags[i] * Math.pow(i - centroid, 2);
47
+ }
48
+ return Math.sqrt(spread / denom) * (this.sampleRate / 2) / mags.length;
49
+ }
50
+ }
51
+ //# sourceMappingURL=SpectralBandwidthAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpectralBandwidthAnalyzer.js","sourceRoot":"","sources":["../../src/analysis/SpectralBandwidthAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,GAAG,MAAM,QAAQ,CAAC;AASzB,MAAM,OAAO,yBAAyB;IAC5B,GAAG,CAAM;IACT,OAAO,CAAS;IAChB,UAAU,CAAS;IAC3B;;OAEG;IACH,YAAY,MAA+B;QACzC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC;QACtC,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACtC,CAAC;IACD;;;;OAIG;IACH,YAAY,CAAC,GAAiB;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,IAAI,GAAa,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,oBAAoB;QACpB,IAAI,GAAG,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;QACD,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAC1B,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;QAC/B,YAAY;QACZ,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACzE,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ export interface SpectralCentroidConfig {
2
+ /** Sample rate of the audio (Hz) */
3
+ sampleRate: number;
4
+ /** FFT size (default: 1024) */
5
+ fftSize?: number;
6
+ }
7
+ export declare class SpectralCentroidAnalyzer {
8
+ private fft;
9
+ private fftSize;
10
+ private sampleRate;
11
+ /**
12
+ * @param config - Configuration with sample rate and optional FFT size
13
+ */
14
+ constructor(config: SpectralCentroidConfig);
15
+ /**
16
+ * Compute the spectral centroid for a PCM frame.
17
+ * @param pcm - Input PCM audio frame
18
+ * @returns Spectral centroid in Hz
19
+ */
20
+ analyzeFrame(pcm: Float32Array): number;
21
+ }
22
+ //# sourceMappingURL=SpectralCentroidAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpectralCentroidAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analysis/SpectralCentroidAnalyzer.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,sBAAsB;IACrC,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,wBAAwB;IACnC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B;;OAEG;gBACS,MAAM,EAAE,sBAAsB;IAK1C;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM;CAkBxC"}