nodejs-audio-visualizer 5.0.0 → 5.2.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 (53) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +3 -2
  3. package/dist/audio.d.ts +13 -12
  4. package/dist/audio.js +128 -120
  5. package/dist/audio.js.map +1 -1
  6. package/dist/beats.d.ts +39 -19
  7. package/dist/beats.js +220 -43
  8. package/dist/beats.js.map +1 -1
  9. package/dist/bpmEncoder.d.ts +14 -14
  10. package/dist/bpmEncoder.js +97 -97
  11. package/dist/config.d.ts +78 -77
  12. package/dist/config.js +377 -369
  13. package/dist/config.js.map +1 -1
  14. package/dist/dsp.d.ts +16 -16
  15. package/dist/dsp.js +76 -76
  16. package/dist/highlight.d.ts +34 -32
  17. package/dist/highlight.js +334 -325
  18. package/dist/highlight.js.map +1 -1
  19. package/dist/image.d.ts +97 -79
  20. package/dist/image.js +545 -458
  21. package/dist/image.js.map +1 -1
  22. package/dist/index.d.ts +87 -79
  23. package/dist/index.js +597 -534
  24. package/dist/index.js.map +1 -1
  25. package/dist/subtitleConvert.d.ts +3 -3
  26. package/dist/subtitleConvert.js +61 -61
  27. package/dist/video.d.ts +150 -80
  28. package/dist/video.js +677 -434
  29. package/dist/video.js.map +1 -1
  30. package/dist/waitForEventLoop.d.ts +1 -1
  31. package/dist/waitForEventLoop.js +5 -5
  32. package/package.json +62 -61
  33. package/src/audio.ts +129 -120
  34. package/src/beats.ts +279 -68
  35. package/src/bpmEncoder.ts +97 -97
  36. package/src/config.ts +487 -476
  37. package/src/dsp.ts +95 -95
  38. package/src/highlight.ts +291 -284
  39. package/src/image.ts +707 -602
  40. package/src/index.ts +124 -31
  41. package/src/subtitleConvert.ts +63 -63
  42. package/src/tests/audio.test.ts +102 -96
  43. package/src/tests/beats.test.ts +134 -0
  44. package/src/tests/config.test.ts +534 -496
  45. package/src/tests/dsp.test.ts +24 -24
  46. package/src/tests/highlight.test.ts +178 -178
  47. package/src/tests/image.test.ts +319 -222
  48. package/src/tests/index.test.ts +180 -180
  49. package/src/tests/subtitleConvert.test.ts +23 -23
  50. package/src/tests/video.test.ts +535 -285
  51. package/src/typings.d.ts +28 -6
  52. package/src/video.ts +856 -550
  53. package/src/waitForEventLoop.ts +2 -2
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2019 VladislavPetyukevich
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2019 VladislavPetyukevich
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -11,8 +11,9 @@ const config = {
11
11
  },
12
12
  // OR use a video as background (optional):
13
13
  // video: {
14
- // path: 'media/background.mp4', // Supports MP4, MOV, AVI, MKV. Loops automatically if shorter than audio.
15
- // autoEdit: true, // Optional. Detects scene cuts and advances between them on each beat so the background edits with the music; omit or false for one continuous play-through from the start.
14
+ // path: 'media/background.mp4', // Supports MP4, MOV, AVI, MKV. Loops automatically if shorter than audio. Can also be an array of paths, e.g. ['media/bg1.mp4', 'media/bg2.mp4']: with autoEdit false the videos play one after another (looping the sequence as needed), and with autoHighlight producing several videos each one starts with a different video from the array; with autoEdit true, cuts switch (shuffle) between the given videos instead of auto-detecting scene changes. Videos in an array should share the same resolution and frame rate for best results, especially when outVideo.resolution is not set.
15
+ // autoEdit: true, // Optional. Detects scene cuts and advances between them on the detected BPM beat grid about every 2–4 beats so the background edits with the music; omit or false for one continuous play-through from the start. When enabled, a brief camera shake starts 0.1s after each cut and decays over about one-third of a beat (if the video has no detected scene changes, and so no cuts, it shakes every 2 beats instead).
16
+ // cameraShake: false, // Optional. With autoEdit: set to false to disable the camera shake applied on cuts (default true).
16
17
  // },
17
18
  audio: {
18
19
  path: 'media/audio.wav', // Supports MP3 and WAV audio
package/dist/audio.d.ts CHANGED
@@ -1,12 +1,13 @@
1
- /// <reference types="node" />
2
- export declare const skipEvery: <T>(skipIndex: number) => (element: T, index: number) => boolean;
3
- export declare const getPeaks: (spectrums: number[], prevPeaks?: number[] | undefined) => number[];
4
- export declare const correctPeaks: (spectrums: number[], peaks: number[]) => number[];
5
- export declare const createSpectrumsProcessor: (sampleRate: number, skipFramesCount: number) => (parseAudioData: () => number[]) => number[];
6
- export declare const bufferToUInt8: (buffer: Buffer, start: number, end: number) => number[];
7
- export declare const normalizeAudioData: (PCMData: number[]) => number[];
8
- export declare const spawnFfmpegAudioReader: (filename: string, format: string) => import("child_process").ChildProcessWithoutNullStreams;
9
- export declare const createAudioBuffer: (filename: string, format: string) => Promise<{
10
- audioBuffer: Buffer;
11
- sampleRate: number;
12
- }>;
1
+ /// <reference types="node" />
2
+ export declare const skipEvery: <T>(skipIndex: number) => (element: T, index: number) => boolean;
3
+ export declare const getPeaks: (spectrums: number[], prevPeaks?: number[] | undefined) => number[];
4
+ export declare const correctPeaks: (spectrums: number[], peaks: number[]) => number[];
5
+ export declare const createSpectrumsProcessor: (sampleRate: number, skipFramesCount: number) => (parseAudioData: () => number[]) => number[];
6
+ export declare const bufferToUInt8: (buffer: Buffer, start: number, end: number) => number[];
7
+ export declare const normalizeAudioData: (PCMData: number[]) => number[];
8
+ export declare const pcmU8ToFloatSamples: (buffer: Buffer) => number[];
9
+ export declare const spawnFfmpegAudioReader: (filename: string, format: string) => import("child_process").ChildProcessWithoutNullStreams;
10
+ export declare const createAudioBuffer: (filename: string, format: string) => Promise<{
11
+ audioBuffer: Buffer;
12
+ sampleRate: number;
13
+ }>;
package/dist/audio.js CHANGED
@@ -1,121 +1,129 @@
1
- "use strict";
2
- var __spreadArrays = (this && this.__spreadArrays) || function () {
3
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
4
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
5
- for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
6
- r[k] = a[j];
7
- return r;
8
- };
9
- var __importDefault = (this && this.__importDefault) || function (mod) {
10
- return (mod && mod.__esModule) ? mod : { "default": mod };
11
- };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- var child_process_1 = require("child_process");
14
- var ffmpeg_static_1 = __importDefault(require("ffmpeg-static"));
15
- var dsp_1 = require("./dsp");
16
- exports.skipEvery = function (skipIndex) { return function (element, index) {
17
- return index % skipIndex === 0;
18
- }; };
19
- exports.getPeaks = function (spectrums, prevPeaks) {
20
- if (!prevPeaks) {
21
- return spectrums;
22
- }
23
- var resultPeaks = [];
24
- for (var i = 0; i < spectrums.length; i++) {
25
- var currValue = spectrums[i];
26
- var currPrevPeak = prevPeaks[i] || 0;
27
- resultPeaks.push((currValue > currPrevPeak) ? currValue : currPrevPeak);
28
- }
29
- return resultPeaks;
30
- };
31
- exports.correctPeaks = function (spectrums, peaks) {
32
- var resultSpectrum = [];
33
- for (var i = 0; i < spectrums.length; i++) {
34
- var value = spectrums[i];
35
- var peakValue = peaks[i] || 0;
36
- if (value < 3) {
37
- resultSpectrum.push(value / 3);
38
- }
39
- else {
40
- resultSpectrum.push(value / peakValue);
41
- }
42
- }
43
- return resultSpectrum;
44
- };
45
- var oldMax = 1;
46
- var newMin = 0.6;
47
- var getInterpolationFactor = function (skippedFramesCount, skipFramesCount) {
48
- var interpolationFactor = 1 - (skippedFramesCount / skipFramesCount);
49
- var interpolationFactorInRange = (interpolationFactor * (oldMax - newMin)) + newMin;
50
- return interpolationFactorInRange;
51
- };
52
- exports.createSpectrumsProcessor = function (sampleRate, skipFramesCount) {
53
- var prevAudioDataNormalized = [];
54
- var prevPeaks = [];
55
- var skippedFramesCount = 0;
56
- var targetSpectrum = [];
57
- var previousSpectrum = [];
58
- return function (parseAudioData) {
59
- if (skippedFramesCount === 0) {
60
- skippedFramesCount = skipFramesCount;
61
- var audioDataNomrmalized = exports.normalizeAudioData(parseAudioData());
62
- prevAudioDataNormalized = audioDataNomrmalized;
63
- var spectrum = dsp_1.getSpectrum(audioDataNomrmalized, sampleRate);
64
- var peaks = exports.getPeaks(spectrum, prevPeaks);
65
- var correctedSpectrum = prevPeaks.length === 0 ?
66
- Array(dsp_1.FREQUENCY_BANDS.length).fill(0) :
67
- exports.correctPeaks(spectrum, peaks);
68
- prevPeaks = peaks;
69
- previousSpectrum = __spreadArrays(targetSpectrum);
70
- targetSpectrum = correctedSpectrum;
71
- }
72
- else {
73
- skippedFramesCount--;
74
- }
75
- var interpolationFactor = getInterpolationFactor(skippedFramesCount, skipFramesCount);
76
- var interpolatedSpectrum = targetSpectrum.map(function (target, i) {
77
- var prev = previousSpectrum[i] || target;
78
- return prev + (target - prev) * interpolationFactor;
79
- });
80
- return interpolatedSpectrum;
81
- };
82
- };
83
- exports.bufferToUInt8 = function (buffer, start, end) {
84
- var numbers = [];
85
- for (var i = start; i < end; i += 1) {
86
- numbers.push(buffer.readUInt8(i));
87
- }
88
- return numbers;
89
- };
90
- exports.normalizeAudioData = function (PCMData) {
91
- return PCMData.map(function (num) { return (num - 128) / 128; });
92
- };
93
- exports.spawnFfmpegAudioReader = function (filename, format) {
94
- if (!ffmpeg_static_1.default) {
95
- throw new Error('ffmpeg path not found');
96
- }
97
- var ffmpegProcess = child_process_1.spawn(ffmpeg_static_1.default, ['-i', filename, '-f', format, '-ac', '1', '-']);
98
- return ffmpegProcess;
99
- };
100
- exports.createAudioBuffer = function (filename, format) {
101
- return new Promise(function (resolve, reject) {
102
- var sampleRate;
103
- var sampleRateRegExp = /(\d+) Hz/m;
104
- var audioBuffers = [];
105
- var ffmpegAudioReader = exports.spawnFfmpegAudioReader(filename, format);
106
- ffmpegAudioReader.stderr.on('data', function (data) {
107
- var match = data.toString().match(sampleRateRegExp);
108
- if (!sampleRate && match) {
109
- sampleRate = match[1];
110
- }
111
- });
112
- ffmpegAudioReader.stdout.on('data', function (chunkBuffer) {
113
- audioBuffers.push(chunkBuffer);
114
- });
115
- ffmpegAudioReader.stdout.on('end', function () {
116
- var audioBuffer = Buffer.concat(audioBuffers);
117
- resolve({ audioBuffer: audioBuffer, sampleRate: sampleRate });
118
- });
119
- });
120
- };
1
+ "use strict";
2
+ var __spreadArrays = (this && this.__spreadArrays) || function () {
3
+ for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
4
+ for (var r = Array(s), k = 0, i = 0; i < il; i++)
5
+ for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
6
+ r[k] = a[j];
7
+ return r;
8
+ };
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ var child_process_1 = require("child_process");
14
+ var ffmpeg_static_1 = __importDefault(require("ffmpeg-static"));
15
+ var dsp_1 = require("./dsp");
16
+ exports.skipEvery = function (skipIndex) { return function (element, index) {
17
+ return index % skipIndex === 0;
18
+ }; };
19
+ exports.getPeaks = function (spectrums, prevPeaks) {
20
+ if (!prevPeaks) {
21
+ return spectrums;
22
+ }
23
+ var resultPeaks = [];
24
+ for (var i = 0; i < spectrums.length; i++) {
25
+ var currValue = spectrums[i];
26
+ var currPrevPeak = prevPeaks[i] || 0;
27
+ resultPeaks.push((currValue > currPrevPeak) ? currValue : currPrevPeak);
28
+ }
29
+ return resultPeaks;
30
+ };
31
+ exports.correctPeaks = function (spectrums, peaks) {
32
+ var resultSpectrum = [];
33
+ for (var i = 0; i < spectrums.length; i++) {
34
+ var value = spectrums[i];
35
+ var peakValue = peaks[i] || 0;
36
+ if (value < 3) {
37
+ resultSpectrum.push(value / 3);
38
+ }
39
+ else {
40
+ resultSpectrum.push(value / peakValue);
41
+ }
42
+ }
43
+ return resultSpectrum;
44
+ };
45
+ var oldMax = 1;
46
+ var newMin = 0.6;
47
+ var getInterpolationFactor = function (skippedFramesCount, skipFramesCount) {
48
+ var interpolationFactor = 1 - (skippedFramesCount / skipFramesCount);
49
+ var interpolationFactorInRange = (interpolationFactor * (oldMax - newMin)) + newMin;
50
+ return interpolationFactorInRange;
51
+ };
52
+ exports.createSpectrumsProcessor = function (sampleRate, skipFramesCount) {
53
+ var prevAudioDataNormalized = [];
54
+ var prevPeaks = [];
55
+ var skippedFramesCount = 0;
56
+ var targetSpectrum = [];
57
+ var previousSpectrum = [];
58
+ return function (parseAudioData) {
59
+ if (skippedFramesCount === 0) {
60
+ skippedFramesCount = skipFramesCount;
61
+ var audioDataNomrmalized = exports.normalizeAudioData(parseAudioData());
62
+ prevAudioDataNormalized = audioDataNomrmalized;
63
+ var spectrum = dsp_1.getSpectrum(audioDataNomrmalized, sampleRate);
64
+ var peaks = exports.getPeaks(spectrum, prevPeaks);
65
+ var correctedSpectrum = prevPeaks.length === 0 ?
66
+ Array(dsp_1.FREQUENCY_BANDS.length).fill(0) :
67
+ exports.correctPeaks(spectrum, peaks);
68
+ prevPeaks = peaks;
69
+ previousSpectrum = __spreadArrays(targetSpectrum);
70
+ targetSpectrum = correctedSpectrum;
71
+ }
72
+ else {
73
+ skippedFramesCount--;
74
+ }
75
+ var interpolationFactor = getInterpolationFactor(skippedFramesCount, skipFramesCount);
76
+ var interpolatedSpectrum = targetSpectrum.map(function (target, i) {
77
+ var prev = previousSpectrum[i] || target;
78
+ return prev + (target - prev) * interpolationFactor;
79
+ });
80
+ return interpolatedSpectrum;
81
+ };
82
+ };
83
+ exports.bufferToUInt8 = function (buffer, start, end) {
84
+ var numbers = [];
85
+ for (var i = start; i < end; i += 1) {
86
+ numbers.push(buffer.readUInt8(i));
87
+ }
88
+ return numbers;
89
+ };
90
+ exports.normalizeAudioData = function (PCMData) {
91
+ return PCMData.map(function (num) { return (num - 128) / 128; });
92
+ };
93
+ exports.pcmU8ToFloatSamples = function (buffer) {
94
+ var n = buffer.length;
95
+ var samples = new Array(n);
96
+ for (var i = 0; i < n; i++) {
97
+ samples[i] = (buffer[i] - 128) / 128;
98
+ }
99
+ return samples;
100
+ };
101
+ exports.spawnFfmpegAudioReader = function (filename, format) {
102
+ if (!ffmpeg_static_1.default) {
103
+ throw new Error('ffmpeg path not found');
104
+ }
105
+ var ffmpegProcess = child_process_1.spawn(ffmpeg_static_1.default, ['-i', filename, '-f', format, '-ac', '1', '-']);
106
+ return ffmpegProcess;
107
+ };
108
+ exports.createAudioBuffer = function (filename, format) {
109
+ return new Promise(function (resolve, reject) {
110
+ var sampleRate;
111
+ var sampleRateRegExp = /(\d+) Hz/m;
112
+ var audioBuffers = [];
113
+ var ffmpegAudioReader = exports.spawnFfmpegAudioReader(filename, format);
114
+ ffmpegAudioReader.stderr.on('data', function (data) {
115
+ var match = data.toString().match(sampleRateRegExp);
116
+ if (!sampleRate && match) {
117
+ sampleRate = match[1];
118
+ }
119
+ });
120
+ ffmpegAudioReader.stdout.on('data', function (chunkBuffer) {
121
+ audioBuffers.push(chunkBuffer);
122
+ });
123
+ ffmpegAudioReader.stdout.on('end', function () {
124
+ var audioBuffer = Buffer.concat(audioBuffers);
125
+ resolve({ audioBuffer: audioBuffer, sampleRate: sampleRate });
126
+ });
127
+ });
128
+ };
121
129
  //# sourceMappingURL=audio.js.map
package/dist/audio.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"audio.js","sourceRoot":"","sources":["../src/audio.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audio.js","sourceRoot":"","sources":["../src/audio.ts"],"names":[],"mappings":"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"}
package/dist/beats.d.ts CHANGED
@@ -1,19 +1,39 @@
1
- export interface BeatInfo {
2
- isBeat: boolean;
3
- intensity: number;
4
- energy: number;
5
- threshold: number;
6
- }
7
- export interface BeatDetectorOptions {
8
- /** Number of past frames to average for adaptive threshold (~1.5s by default) */
9
- historySize?: number;
10
- /** Energy must exceed average * this multiplier to trigger a beat */
11
- thresholdMultiplier?: number;
12
- /** How fast the beat intensity fades between beats (0-1, lower = faster fade) */
13
- decayRate?: number;
14
- /** Minimum frames between consecutive beats (~150ms by default) */
15
- cooldownFrames?: number;
16
- /** How many low-frequency spectrum bands contribute to energy (sub-bass + bass) */
17
- bassEndIndex?: number;
18
- }
19
- export declare const createBeatDetector: (fps: number, options?: BeatDetectorOptions | undefined) => (spectrum: number[]) => BeatInfo;
1
+ export interface BeatInfo {
2
+ isBeat: boolean;
3
+ intensity: number;
4
+ energy: number;
5
+ threshold: number;
6
+ }
7
+ export interface BeatDetectorOptions {
8
+ /** Number of past frames to average for adaptive threshold (~1.5s by default) */
9
+ historySize?: number;
10
+ /** Energy must exceed average * this multiplier to trigger a beat */
11
+ thresholdMultiplier?: number;
12
+ /** How fast the beat intensity fades between beats (0-1, lower = faster fade) */
13
+ decayRate?: number;
14
+ /** Minimum frames between consecutive beats (~150ms by default) */
15
+ cooldownFrames?: number;
16
+ /** How many low-frequency spectrum bands contribute to energy (sub-bass + bass) */
17
+ bassEndIndex?: number;
18
+ }
19
+ export interface TempoEstimate {
20
+ bpm: number;
21
+ periodFrames: number;
22
+ phaseFrame: number;
23
+ /** Beat times in seconds from the start of the analyzed audio. */
24
+ beatsSec?: number[];
25
+ }
26
+ export declare const MIN_TEMPO_BPM = 70;
27
+ export declare const MAX_TEMPO_BPM = 180;
28
+ export declare const PREFERRED_TEMPO_BPM_MIN = 90;
29
+ export declare const PREFERRED_TEMPO_BPM_MAX = 160;
30
+ export declare const DEFAULT_BASS_END_INDEX = 8;
31
+ /** Longest PCM window passed to music-tempo (seconds), taken from the start of the audio. */
32
+ export declare const MAX_TEMPO_ANALYSIS_SECONDS = 90;
33
+ export declare const frameBassEnergy: (spectrum: number[], bassEndIndex?: number) => number;
34
+ export declare const createBeatDetector: (fps: number, options?: BeatDetectorOptions | undefined) => (spectrum: number[]) => BeatInfo;
35
+ export declare const estimateTempo: (samples: ArrayLike<number>, sampleRate: number, fps: number) => TempoEstimate | null;
36
+ export declare const shiftTempoPhase: (tempo: TempoEstimate, startFrame: number) => TempoEstimate;
37
+ /** Beat-grid phase for a later audio window, using in-window beat times when available. */
38
+ export declare const tempoForWindow: (tempo: TempoEstimate, startFrame: number, fps: number, windowFrames?: number | undefined, localOnsetFrames?: number[] | undefined) => TempoEstimate;
39
+ export declare const beatGridFrameIndices: (tempo: Pick<TempoEstimate, "periodFrames" | "phaseFrame">, totalFrames: number, stride?: number) => number[];