nodejs-audio-visualizer 2.1.4 → 3.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.
@@ -8,7 +8,6 @@ import {
8
8
  skipEvery,
9
9
  getPeaks,
10
10
  correctPeaks,
11
- smoothValues,
12
11
  createSpectrumsProcessor,
13
12
  } from '../audio';
14
13
  import { createSandbox } from 'sinon';
@@ -85,21 +84,13 @@ describe('audio', function () {
85
84
  expect(result).deep.equal(expected);
86
85
  });
87
86
 
88
- it('smoothValues', () => {
89
- const spectrums = [1, 2, 3, 4];
90
- const prevSpectrums = [2, 4, 6, 3];
91
- const result = smoothValues(spectrums, prevSpectrums);
92
- const expected = [1.5, 3, 4.5, 3.5];
93
- expect(result).deep.equal(expected);
94
- });
95
87
 
96
88
  it('createSpectrumsProcessor', () => {
97
- const busesCount = 2;
98
- const spectrumsProcessor = createSpectrumsProcessor(busesCount);
89
+ const spectrumsProcessor = createSpectrumsProcessor(44100);
99
90
 
100
- const frame0 = spectrumsProcessor(0, () => ([1, 2, 3, 4]));
101
- expect(frame0).to.have.length(2);
102
- const frame1 = spectrumsProcessor(1, () => ([2, 2, 6, 2]));
103
- expect(frame1).to.have.length(2);
91
+ const frame0 = spectrumsProcessor(() => ([1, 2, 3, 4]));
92
+ expect(frame0).to.have.length(24);
93
+ const frame1 = spectrumsProcessor(() => ([2, 2, 6, 2]));
94
+ expect(frame1).to.have.length(24);
104
95
  });
105
96
  });
@@ -79,9 +79,9 @@ describe('config', function() {
79
79
  );
80
80
 
81
81
  const result2 = getSpectrumWidthAbsolute({
82
- outVideo: { spectrum: { width: 420 }}
82
+ outVideo: { spectrum: { width: 600 }}
83
83
  } as Config, backgroundImageWidth);
84
- expect(result2).equal(420);
84
+ expect(result2).equal(600);
85
85
 
86
86
  const result3 = getSpectrumWidthAbsolute({
87
87
  outVideo: { spectrum: { width: '69%' }}
@@ -117,13 +117,11 @@ describe('config', function() {
117
117
  });
118
118
 
119
119
  it('getSpectrumHeightAbsolute', function() {
120
- const backgroundImageHeight = 768;
120
+ const backgroundImageHeight = 720;
121
121
  const result1 = getSpectrumHeightAbsolute({
122
122
  outVideo: {}
123
123
  } as Config, backgroundImageHeight);
124
- expect(result1).equal(
125
- backgroundImageHeight * (parseInt(defaults.spectrumHeight) / 100)
126
- );
124
+ expect(result1).equal(160);
127
125
 
128
126
  const result2 = getSpectrumHeightAbsolute({
129
127
  outVideo: { spectrum: { height: 420 }}
@@ -212,7 +210,7 @@ describe('config', function() {
212
210
 
213
211
  it('getSpectrumYAbsolute', function() {
214
212
  const spectrumHeight = 125;
215
- const backgroundImageHeight = 768;
213
+ const backgroundImageHeight = 721;
216
214
  const result1 = getSpectrumYAbsolute(
217
215
  {
218
216
  outVideo: {},
@@ -221,7 +219,7 @@ describe('config', function() {
221
219
  backgroundImageHeight
222
220
  );
223
221
  expect(result1).equal(
224
- 0
222
+ 298
225
223
  );
226
224
 
227
225
  const result2 = getSpectrumYAbsolute(
@@ -16,10 +16,9 @@ describe('fft', function () {
16
16
  });
17
17
 
18
18
  it('getSpectrum', function () {
19
- var signal = [1, 0, 0, 0, 1, 0, 0, 0];
20
- const fft = [8.317766166719343, 0, 11.090354888959125, 0];
19
+ const signal = Array(Math.pow(2, 12)).fill(1);
21
20
 
22
- const result = getSpectrum(signal);
23
- expect(result).deep.equal(fft);
21
+ const result = getSpectrum(signal, 44100);
22
+ expect(result).to.have.length(24);
24
23
  });
25
24
  });
@@ -1,10 +1,9 @@
1
1
  import { expect } from 'chai';
2
2
  import path from 'path';
3
- import fs from 'fs';
4
3
  import {
5
4
  drawRect,
6
5
  Color,
7
- createVisualizerFrame,
6
+ createVisualizerFrameGenerator,
8
7
  parseImage,
9
8
  convertToBmp,
10
9
  mixValues,
@@ -12,10 +11,6 @@ import {
12
11
  } from '../image';
13
12
  import { createBpmEncoder } from '../bpmEncoder';
14
13
 
15
- import frameSnapshotSpectrumDown from './snapshots/frameSnapshotSpectrumDown.json';
16
- import frameSnapshotSpectrumUp from './snapshots/frameSnapshotSpectrumUp.json';
17
- import frameSnapshotSpectrumUpOpacity50 from './snapshots/frameSnapshotSpectrumUpOpacity50.json';
18
-
19
14
  describe('image', function () {
20
15
  it('mixValues', function () {
21
16
  expect(mixValues(420, 0.69, 96)).equal(320);
@@ -82,11 +77,13 @@ describe('image', function () {
82
77
  });
83
78
 
84
79
  it('createVisualizerFrame', async function () {
85
- const backgroundImagePath = path.resolve('example/media/background.png');
80
+ const expectedImageLength = 6220854;
81
+ const backgroundImagePath = path.resolve('example/media/horses.png');
86
82
  const backgroundImageBmpBuffer = await convertToBmp(backgroundImagePath);
87
83
  const backgroundImage = parseImage(backgroundImageBmpBuffer);
88
84
  const bpmEncoder = createBpmEncoder({ width: backgroundImage.width, height: backgroundImage.height });
89
85
  const backgroundImageBuffer = bpmEncoder(backgroundImage.data);
86
+ const createVisualizerFrame = createVisualizerFrameGenerator();
90
87
  const frameSpectrumDown = createVisualizerFrame({
91
88
  backgroundImageBuffer,
92
89
  spectrum: [0.5, 0, 1],
@@ -98,7 +95,7 @@ describe('image', function () {
98
95
  opacity: 1,
99
96
  });
100
97
  const resultSpectrumDown = frameSpectrumDown.data.toJSON().data;
101
- expect(resultSpectrumDown).deep.equal(frameSnapshotSpectrumDown);
98
+ expect(resultSpectrumDown).to.have.length(expectedImageLength);
102
99
 
103
100
  const frameSpectrumUp = createVisualizerFrame({
104
101
  backgroundImageBuffer,
@@ -111,7 +108,20 @@ describe('image', function () {
111
108
  opacity: 1,
112
109
  });
113
110
  const resultSpectrumUp = frameSpectrumUp.data.toJSON().data;
114
- expect(resultSpectrumUp).deep.equal(frameSnapshotSpectrumUp);
111
+ expect(resultSpectrumUp).to.have.length(expectedImageLength);
112
+
113
+ const frameSpectrumMirror = createVisualizerFrame({
114
+ backgroundImageBuffer,
115
+ spectrum: [0.1, 1, 0],
116
+ size: { width: 25, height: 23 },
117
+ position: { x: 10, y: 5 },
118
+ rotation: 'mirror',
119
+ margin: 4,
120
+ color: { red: 0, green: 123, blue: 69 },
121
+ opacity: 1,
122
+ });
123
+ const resultSpectrumMirror = frameSpectrumMirror.data.toJSON().data;
124
+ expect(resultSpectrumMirror).to.have.length(expectedImageLength);
115
125
 
116
126
  const frameSpectrumUpOpacity50 = createVisualizerFrame({
117
127
  backgroundImageBuffer,
@@ -124,6 +134,6 @@ describe('image', function () {
124
134
  opacity: 0.5,
125
135
  });
126
136
  const resultSpectrumUpOpacity50 = frameSpectrumUpOpacity50.data.toJSON().data;
127
- expect(resultSpectrumUpOpacity50).deep.equal(frameSnapshotSpectrumUpOpacity50);
137
+ expect(resultSpectrumUpOpacity50).to.have.length(expectedImageLength);
128
138
  });
129
139
  });
@@ -42,7 +42,7 @@ describe('index', function () {
42
42
  path: 'audioPath'
43
43
  },
44
44
  image: {
45
- path: 'example/media/background.png'
45
+ path: 'example/media/horses.png'
46
46
  },
47
47
  outVideo: {
48
48
  path: 'outVideoPath',
@@ -0,0 +1,7 @@
1
+ declare module 'fft-js' {
2
+ export function fft(signal: number[]): [number, number][];
3
+ export const util: {
4
+ fftFreq(phasors: [number, number][], sampleRate: number): number[];
5
+ fftMag(phasors: [number, number][]): number[];
6
+ };
7
+ }
@@ -1 +0,0 @@
1
- export declare const createSpectrumAnalyzer: (bufferSize: number) => (buffer: number[]) => number[];
package/dist/spectrum.js DELETED
@@ -1,72 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createSpectrumAnalyzer = function (bufferSize) {
4
- var real = new Float64Array(bufferSize);
5
- var imag = new Float64Array(bufferSize);
6
- var reverseTable = new Uint32Array(bufferSize);
7
- var limit = 1;
8
- var bit = bufferSize >> 1;
9
- while (limit < bufferSize) {
10
- for (var i = 0; i < limit; i++) {
11
- reverseTable[i + limit] = reverseTable[i] + bit;
12
- }
13
- limit = limit << 1;
14
- bit = bit >> 1;
15
- }
16
- var sinTable = new Float64Array(bufferSize);
17
- var cosTable = new Float64Array(bufferSize);
18
- for (var i = 0; i < bufferSize; i++) {
19
- sinTable[i] = Math.sin(-Math.PI / i);
20
- cosTable[i] = Math.cos(-Math.PI / i);
21
- }
22
- var calculateSpectrum = function () {
23
- var spectrum = new Array(bufferSize / 2);
24
- var bSi = 2 / bufferSize;
25
- for (var i = 0, N = bufferSize / 2; i < N; i++) {
26
- var rval = real[i];
27
- var ival = imag[i];
28
- var mag = bSi * Math.sqrt(rval * rval + ival * ival);
29
- spectrum[i] = mag;
30
- }
31
- return spectrum;
32
- };
33
- return function (buffer) {
34
- var k = Math.floor(Math.log(bufferSize) / Math.LN2);
35
- if (Math.pow(2, k) !== bufferSize) {
36
- throw new Error('Invalid buffer size, must be a power of 2');
37
- }
38
- if (bufferSize !== buffer.length) {
39
- throw new Error("Supplied buffer is not the same size as defined FFT. FFT Size: " + bufferSize + " Buffer Size: " + buffer.length);
40
- }
41
- var halfSize = 1;
42
- for (var i = 0; i < bufferSize; i++) {
43
- real[i] = buffer[reverseTable[i]];
44
- imag[i] = 0;
45
- }
46
- while (halfSize < bufferSize) {
47
- var phaseShiftStepReal = cosTable[halfSize];
48
- var phaseShiftStepImag = sinTable[halfSize];
49
- var currentPhaseShiftReal = 1;
50
- var currentPhaseShiftImag = 0;
51
- for (var fftStep = 0; fftStep < halfSize; fftStep++) {
52
- var i = fftStep;
53
- while (i < bufferSize) {
54
- var off = i + halfSize;
55
- var tr = (currentPhaseShiftReal * real[off]) - (currentPhaseShiftImag * imag[off]);
56
- var ti = (currentPhaseShiftReal * imag[off]) + (currentPhaseShiftImag * real[off]);
57
- real[off] = real[i] - tr;
58
- imag[off] = imag[i] - ti;
59
- real[i] += tr;
60
- imag[i] += ti;
61
- i += halfSize << 1;
62
- }
63
- var tmpReal = currentPhaseShiftReal;
64
- currentPhaseShiftReal = (tmpReal * phaseShiftStepReal) - (currentPhaseShiftImag * phaseShiftStepImag);
65
- currentPhaseShiftImag = (tmpReal * phaseShiftStepImag) + (currentPhaseShiftImag * phaseShiftStepReal);
66
- }
67
- halfSize = halfSize << 1;
68
- }
69
- return calculateSpectrum();
70
- };
71
- };
72
- //# sourceMappingURL=spectrum.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spectrum.js","sourceRoot":"","sources":["../src/spectrum.ts"],"names":[],"mappings":"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"}
package/src/spectrum.ts DELETED
@@ -1,91 +0,0 @@
1
- export const createSpectrumAnalyzer = (bufferSize: number) => {
2
- const real = new Float64Array(bufferSize);
3
- const imag = new Float64Array(bufferSize);
4
- const reverseTable = new Uint32Array(bufferSize);
5
-
6
- let limit = 1;
7
- let bit = bufferSize >> 1;
8
-
9
- while (limit < bufferSize) {
10
- for (let i = 0; i < limit; i++) {
11
- reverseTable[i + limit] = reverseTable[i] + bit;
12
- }
13
-
14
- limit = limit << 1;
15
- bit = bit >> 1;
16
- }
17
-
18
- const sinTable = new Float64Array(bufferSize);
19
- const cosTable = new Float64Array(bufferSize);
20
-
21
- for (let i = 0; i < bufferSize; i++) {
22
- sinTable[i] = Math.sin(-Math.PI / i);
23
- cosTable[i] = Math.cos(-Math.PI / i);
24
- }
25
-
26
- const calculateSpectrum = () => {
27
- const spectrum: number[] = new Array(bufferSize / 2);
28
- const bSi = 2 / bufferSize;
29
-
30
- for (var i = 0, N = bufferSize / 2; i < N; i++) {
31
- const rval = real[i];
32
- const ival = imag[i];
33
- const mag = bSi * Math.sqrt(rval * rval + ival * ival);
34
-
35
- spectrum[i] = mag;
36
- }
37
-
38
- return spectrum;
39
- }
40
-
41
- return (buffer: number[]) => {
42
- const k = Math.floor(Math.log(bufferSize) / Math.LN2);
43
-
44
- if (Math.pow(2, k) !== bufferSize) {
45
- throw new Error('Invalid buffer size, must be a power of 2');
46
- }
47
- if (bufferSize !== buffer.length) {
48
- throw new Error(`Supplied buffer is not the same size as defined FFT. FFT Size: ${bufferSize} Buffer Size: ${buffer.length}`);
49
- }
50
-
51
- let halfSize = 1;
52
-
53
- for (let i = 0; i < bufferSize; i++) {
54
- real[i] = buffer[reverseTable[i]];
55
- imag[i] = 0;
56
- }
57
-
58
- while (halfSize < bufferSize) {
59
- const phaseShiftStepReal = cosTable[halfSize];
60
- const phaseShiftStepImag = sinTable[halfSize];
61
-
62
- let currentPhaseShiftReal = 1;
63
- let currentPhaseShiftImag = 0;
64
-
65
- for (var fftStep = 0; fftStep < halfSize; fftStep++) {
66
- let i = fftStep;
67
-
68
- while (i < bufferSize) {
69
- const off = i + halfSize;
70
- const tr = (currentPhaseShiftReal * real[off]) - (currentPhaseShiftImag * imag[off]);
71
- const ti = (currentPhaseShiftReal * imag[off]) + (currentPhaseShiftImag * real[off]);
72
-
73
- real[off] = real[i] - tr;
74
- imag[off] = imag[i] - ti;
75
- real[i] += tr;
76
- imag[i] += ti;
77
-
78
- i += halfSize << 1;
79
- }
80
-
81
- const tmpReal = currentPhaseShiftReal;
82
- currentPhaseShiftReal = (tmpReal * phaseShiftStepReal) - (currentPhaseShiftImag * phaseShiftStepImag);
83
- currentPhaseShiftImag = (tmpReal * phaseShiftStepImag) + (currentPhaseShiftImag * phaseShiftStepReal);
84
- }
85
-
86
- halfSize = halfSize << 1;
87
- }
88
-
89
- return calculateSpectrum();
90
- };
91
- };