mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-10 02:54:15 +00:00
update assets
This commit is contained in:
parent
ca5e1be0f0
commit
d850b04f92
9
packages/app/public/assets/default_bg/dots.svg
Normal file
9
packages/app/public/assets/default_bg/dots.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="dots" fill="currentColor">
|
||||
<circle id="Oval-377-Copy-9" cx="3" cy="3" r="3"></circle>
|
||||
<circle id="Oval-377-Copy-14" cx="13" cy="13" r="3"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 498 B |
7
packages/app/public/assets/default_bg/hideout.svg
Normal file
7
packages/app/public/assets/default_bg/hideout.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
|
||||
<g id="Page-1" fill="none" fill-rule="evenodd">
|
||||
<g id="Artboard-5" fill="currentColor">
|
||||
<path id="Combined-Shape" d="M0 38.59l2.83-2.83 1.41 1.41L1.41 40H0v-1.41zM0 1.4l2.83 2.83 1.41-1.41L1.41 0H0v1.41zM38.59 40l-2.83-2.83 1.41-1.41L40 38.59V40h-1.41zM40 1.41l-2.83 2.83-1.41-1.41L38.59 0H40v1.41zM20 18.6l2.83-2.83 1.41 1.41L21.41 20l2.83 2.83-1.41 1.41L20 21.41l-2.83 2.83-1.41-1.41L18.59 20l-2.83-2.83 1.41-1.41L20 18.59z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 506 B |
139
packages/app/public/assets/default_bg/meteors.svg
Normal file
139
packages/app/public/assets/default_bg/meteors.svg
Normal file
@ -0,0 +1,139 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="1440" height="560" preserveAspectRatio="none" viewBox="0 0 1440 560">
|
||||
<g mask="url("#SvgjsMask1061")" fill="none">
|
||||
<use xlink:href="#SvgjsSymbol1068" x="0" y="0"></use>
|
||||
<use xlink:href="#SvgjsSymbol1068" x="720" y="0"></use>
|
||||
</g>
|
||||
<defs>
|
||||
<mask id="SvgjsMask1061">
|
||||
<rect width="1440" height="560" fill="#ffffff"></rect>
|
||||
</mask>
|
||||
<path d="M-1 0 a1 1 0 1 0 2 0 a1 1 0 1 0 -2 0z" id="SvgjsPath1064"></path>
|
||||
<path d="M-3 0 a3 3 0 1 0 6 0 a3 3 0 1 0 -6 0z" id="SvgjsPath1066"></path>
|
||||
<path d="M-5 0 a5 5 0 1 0 10 0 a5 5 0 1 0 -10 0z" id="SvgjsPath1062"></path>
|
||||
<path d="M2 -2 L-2 2z" id="SvgjsPath1063"></path>
|
||||
<path d="M6 -6 L-6 6z" id="SvgjsPath1065"></path>
|
||||
<path d="M30 -30 L-30 30z" id="SvgjsPath1067"></path>
|
||||
</defs>
|
||||
<symbol id="SvgjsSymbol1068">
|
||||
<use xlink:href="#SvgjsPath1062" x="30" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="30" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="30" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="30" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="30" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="30" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="30" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="30" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="30" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="30" y="570" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="90" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="90" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="90" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="90" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1066" x="90" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="90" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="90" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="90" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1067" x="90" y="510" stroke="currentColor" stroke-width="3"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="90" y="570" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="150" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="150" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1067" x="150" y="150" stroke="currentColor" stroke-width="3"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="150" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="150" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="150" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="150" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="150" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1067" x="150" y="510" stroke="currentColor" stroke-width="3"></use>
|
||||
<use xlink:href="#SvgjsPath1067" x="150" y="570" stroke="currentColor" stroke-width="3"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="210" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="210" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="210" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="210" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="210" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="210" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="210" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="210" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="210" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="210" y="570" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="270" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="270" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="270" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="270" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="270" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="270" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="270" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="270" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="270" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="270" y="570" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="330" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="330" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="330" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="330" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="330" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="330" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="330" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="330" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="330" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="330" y="570" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="390" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1066" x="390" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="390" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="390" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="390" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="390" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="390" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="390" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="390" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="390" y="570" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="450" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="450" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="450" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1066" x="450" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="450" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="450" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="450" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="450" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="450" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="450" y="570" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="510" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="510" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="510" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="510" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="510" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1066" x="510" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="510" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="510" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="510" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="510" y="570" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1067" x="570" y="30" stroke="currentColor" stroke-width="3"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="570" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="570" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="570" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="570" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="570" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="570" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="570" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="570" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1067" x="570" y="570" stroke="currentColor" stroke-width="3"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="630" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="630" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1066" x="630" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="630" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="630" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="630" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="630" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1067" x="630" y="450" stroke="currentColor" stroke-width="3"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="630" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="630" y="570" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1066" x="690" y="30" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1066" x="690" y="90" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="690" y="150" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="690" y="210" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1064" x="690" y="270" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="690" y="330" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1066" x="690" y="390" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1065" x="690" y="450" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1062" x="690" y="510" stroke="currentColor"></use>
|
||||
<use xlink:href="#SvgjsPath1063" x="690" y="570" stroke="currentColor"></use>
|
||||
</symbol>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
1
packages/app/public/assets/default_bg/topography.svg
Normal file
1
packages/app/public/assets/default_bg/topography.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 89 KiB |
324
packages/app/public/realtime-bpm-processor.js
Normal file
324
packages/app/public/realtime-bpm-processor.js
Normal file
@ -0,0 +1,324 @@
|
||||
"use strict";
|
||||
(() => {
|
||||
var __async = (__this, __arguments, generator) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
var fulfilled = (value) => {
|
||||
try {
|
||||
step(generator.next(value));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
};
|
||||
var rejected = (value) => {
|
||||
try {
|
||||
step(generator.throw(value));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
};
|
||||
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
||||
step((generator = generator.apply(__this, __arguments)).next());
|
||||
});
|
||||
};
|
||||
|
||||
// src/consts.ts
|
||||
var realtimeBpmProcessorName = "realtime-bpm-processor";
|
||||
var startThreshold = 0.95;
|
||||
var minValidThreshold = 0.3;
|
||||
var minPeaks = 15;
|
||||
var thresholdStep = 0.05;
|
||||
var skipForwardIndexes = 1e4;
|
||||
|
||||
// src/utils.ts
|
||||
function descendingOverThresholds(_0) {
|
||||
return __async(this, arguments, function* (onThreshold, minValidThreshold2 = minValidThreshold, startThreshold2 = startThreshold, thresholdStep2 = thresholdStep) {
|
||||
let threshold = startThreshold2;
|
||||
do {
|
||||
threshold -= thresholdStep2;
|
||||
const shouldExit = yield onThreshold(threshold);
|
||||
if (shouldExit) {
|
||||
break;
|
||||
}
|
||||
} while (threshold > minValidThreshold2);
|
||||
});
|
||||
}
|
||||
function generateValidPeaksModel(minValidThreshold2 = minValidThreshold, startThreshold2 = startThreshold, thresholdStep2 = thresholdStep) {
|
||||
const object = {};
|
||||
let threshold = startThreshold2;
|
||||
do {
|
||||
threshold -= thresholdStep2;
|
||||
object[threshold.toString()] = [];
|
||||
} while (threshold > minValidThreshold2);
|
||||
return object;
|
||||
}
|
||||
function generateNextIndexPeaksModel(minValidThreshold2 = minValidThreshold, startThreshold2 = startThreshold, thresholdStep2 = thresholdStep) {
|
||||
const object = {};
|
||||
let threshold = startThreshold2;
|
||||
do {
|
||||
threshold -= thresholdStep2;
|
||||
object[threshold.toString()] = 0;
|
||||
} while (threshold > minValidThreshold2);
|
||||
return object;
|
||||
}
|
||||
function chunckAggregator() {
|
||||
const bufferSize = 4096;
|
||||
let _bytesWritten = 0;
|
||||
let buffer = new Float32Array(0);
|
||||
function initBuffer() {
|
||||
_bytesWritten = 0;
|
||||
buffer = new Float32Array(0);
|
||||
}
|
||||
function isBufferFull() {
|
||||
return _bytesWritten === bufferSize;
|
||||
}
|
||||
function flush() {
|
||||
initBuffer();
|
||||
}
|
||||
return function (pcmData) {
|
||||
if (isBufferFull()) {
|
||||
flush();
|
||||
}
|
||||
const newBuffer = new Float32Array(buffer.length + pcmData.length);
|
||||
newBuffer.set(buffer, 0);
|
||||
newBuffer.set(pcmData, buffer.length);
|
||||
buffer = newBuffer;
|
||||
_bytesWritten += pcmData.length;
|
||||
return {
|
||||
isBufferFull: isBufferFull(),
|
||||
buffer,
|
||||
bufferSize
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// src/analyzer.ts
|
||||
function findPeaksAtThreshold(data, threshold, offset = 0, skipForwardIndexes2 = skipForwardIndexes) {
|
||||
const peaks = [];
|
||||
const { length } = data;
|
||||
for (let i = offset; i < length; i += 1) {
|
||||
if (data[i] > threshold) {
|
||||
peaks.push(i);
|
||||
i += skipForwardIndexes2;
|
||||
}
|
||||
}
|
||||
return {
|
||||
peaks,
|
||||
threshold
|
||||
};
|
||||
}
|
||||
function computeBpm(_0, _1) {
|
||||
return __async(this, arguments, function* (data, audioSampleRate, minPeaks2 = minPeaks) {
|
||||
let hasPeaks = false;
|
||||
let foundThreshold = minValidThreshold;
|
||||
yield descendingOverThresholds((threshold) => __async(this, null, function* () {
|
||||
if (hasPeaks) {
|
||||
return true;
|
||||
}
|
||||
if (data[threshold].length > minPeaks2) {
|
||||
hasPeaks = true;
|
||||
foundThreshold = threshold;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
if (hasPeaks && foundThreshold) {
|
||||
const intervals = identifyIntervals(data[foundThreshold]);
|
||||
const tempos = groupByTempo(audioSampleRate, intervals);
|
||||
const candidates = getTopCandidates(tempos);
|
||||
const bpmCandidates = {
|
||||
bpm: candidates,
|
||||
threshold: foundThreshold
|
||||
};
|
||||
return bpmCandidates;
|
||||
}
|
||||
return {
|
||||
bpm: [],
|
||||
threshold: foundThreshold
|
||||
};
|
||||
});
|
||||
}
|
||||
function getTopCandidates(candidates, length = 5) {
|
||||
return candidates.sort((a, b) => b.count - a.count).splice(0, length);
|
||||
}
|
||||
function identifyIntervals(peaks) {
|
||||
const intervals = [];
|
||||
for (let n = 0; n < peaks.length; n++) {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const peak = peaks[n];
|
||||
const peakIndex = n + i;
|
||||
const interval = peaks[peakIndex] - peak;
|
||||
const foundInterval = intervals.some((intervalCount) => {
|
||||
if (intervalCount.interval === interval) {
|
||||
intervalCount.count += 1;
|
||||
return intervalCount.count;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (!foundInterval) {
|
||||
const item = {
|
||||
interval,
|
||||
count: 1
|
||||
};
|
||||
intervals.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return intervals;
|
||||
}
|
||||
function groupByTempo(audioSampleRate, intervalCounts) {
|
||||
const tempoCounts = [];
|
||||
for (const intervalCount of intervalCounts) {
|
||||
if (intervalCount.interval === 0) {
|
||||
continue;
|
||||
}
|
||||
intervalCount.interval = Math.abs(intervalCount.interval);
|
||||
let theoreticalTempo = 60 / (intervalCount.interval / audioSampleRate);
|
||||
while (theoreticalTempo < 90) {
|
||||
theoreticalTempo *= 2;
|
||||
}
|
||||
while (theoreticalTempo > 180) {
|
||||
theoreticalTempo /= 2;
|
||||
}
|
||||
theoreticalTempo = Math.round(theoreticalTempo);
|
||||
const foundTempo = tempoCounts.some((tempoCount) => {
|
||||
if (tempoCount.tempo === theoreticalTempo) {
|
||||
tempoCount.count += intervalCount.count;
|
||||
return tempoCount.count;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (!foundTempo) {
|
||||
const tempo = {
|
||||
tempo: theoreticalTempo,
|
||||
count: intervalCount.count,
|
||||
confidence: 0
|
||||
};
|
||||
tempoCounts.push(tempo);
|
||||
}
|
||||
}
|
||||
return tempoCounts;
|
||||
}
|
||||
|
||||
// src/realtime-bpm-analyzer.ts
|
||||
var initialValue = {
|
||||
minValidThreshold: () => minValidThreshold,
|
||||
timeoutStabilization: () => 0,
|
||||
validPeaks: () => generateValidPeaksModel(),
|
||||
nextIndexPeaks: () => generateNextIndexPeaksModel(),
|
||||
skipIndexes: () => 1
|
||||
};
|
||||
var RealTimeBpmAnalyzer = class {
|
||||
constructor(config = {}) {
|
||||
this.options = {
|
||||
continuousAnalysis: false,
|
||||
computeBpmDelay: 1e4,
|
||||
stabilizationTime: 2e4,
|
||||
muteTimeInIndexes: 1e4
|
||||
};
|
||||
this.minValidThreshold = initialValue.minValidThreshold();
|
||||
this.timeoutStabilization = initialValue.timeoutStabilization();
|
||||
this.validPeaks = initialValue.validPeaks();
|
||||
this.nextIndexPeaks = initialValue.nextIndexPeaks();
|
||||
this.skipIndexes = initialValue.skipIndexes();
|
||||
Object.assign(this.options, config);
|
||||
}
|
||||
setAsyncConfiguration(parameters) {
|
||||
Object.assign(this.options, parameters);
|
||||
}
|
||||
reset() {
|
||||
this.minValidThreshold = initialValue.minValidThreshold();
|
||||
this.timeoutStabilization = initialValue.timeoutStabilization();
|
||||
this.validPeaks = initialValue.validPeaks();
|
||||
this.nextIndexPeaks = initialValue.nextIndexPeaks();
|
||||
this.skipIndexes = initialValue.skipIndexes();
|
||||
}
|
||||
clearValidPeaks(minThreshold) {
|
||||
return __async(this, null, function* () {
|
||||
console.log(`[clearValidPeaks] function: under ${minThreshold}, this.minValidThreshold has been setted to that threshold.`);
|
||||
this.minValidThreshold = Number.parseFloat(minThreshold.toFixed(2));
|
||||
yield descendingOverThresholds((threshold) => __async(this, null, function* () {
|
||||
if (threshold < minThreshold) {
|
||||
delete this.validPeaks[threshold];
|
||||
delete this.nextIndexPeaks[threshold];
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
});
|
||||
}
|
||||
analyzeChunck(channelData, audioSampleRate, bufferSize, postMessage) {
|
||||
return __async(this, null, function* () {
|
||||
const currentMaxIndex = bufferSize * this.skipIndexes;
|
||||
const currentMinIndex = currentMaxIndex - bufferSize;
|
||||
yield this.findPeaks(channelData, bufferSize, currentMinIndex, currentMaxIndex);
|
||||
this.skipIndexes++;
|
||||
const result = yield computeBpm(this.validPeaks, audioSampleRate);
|
||||
const { threshold } = result;
|
||||
postMessage({ message: "BPM", result });
|
||||
if (this.minValidThreshold < threshold) {
|
||||
postMessage({ message: "BPM_STABLE", result });
|
||||
yield this.clearValidPeaks(threshold);
|
||||
}
|
||||
if (this.options.continuousAnalysis) {
|
||||
clearTimeout(this.timeoutStabilization);
|
||||
this.timeoutStabilization = window.setTimeout(() => {
|
||||
console.log("[timeoutStabilization] setTimeout: Fired !");
|
||||
this.options.computeBpmDelay = 0;
|
||||
this.reset();
|
||||
}, this.options.stabilizationTime);
|
||||
}
|
||||
});
|
||||
}
|
||||
findPeaks(channelData, bufferSize, currentMinIndex, currentMaxIndex) {
|
||||
return __async(this, null, function* () {
|
||||
yield descendingOverThresholds((threshold) => __async(this, null, function* () {
|
||||
if (this.nextIndexPeaks[threshold] >= currentMaxIndex) {
|
||||
return false;
|
||||
}
|
||||
const offsetForNextPeak = this.nextIndexPeaks[threshold] % bufferSize;
|
||||
const { peaks, threshold: atThreshold } = findPeaksAtThreshold(channelData, threshold, offsetForNextPeak);
|
||||
if (peaks.length === 0) {
|
||||
return false;
|
||||
}
|
||||
for (const relativeChunkPeak of peaks) {
|
||||
this.nextIndexPeaks[atThreshold] = currentMinIndex + relativeChunkPeak + this.options.muteTimeInIndexes;
|
||||
this.validPeaks[atThreshold].push(currentMinIndex + relativeChunkPeak);
|
||||
}
|
||||
return false;
|
||||
}), this.minValidThreshold);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// processor/realtime-bpm-processor.ts
|
||||
var RealTimeBpmProcessor = class extends AudioWorkletProcessor {
|
||||
constructor() {
|
||||
super();
|
||||
this.realTimeBpmAnalyzer = new RealTimeBpmAnalyzer();
|
||||
this.aggregate = chunckAggregator();
|
||||
this.port.addEventListener("message", this.onMessage.bind(this));
|
||||
this.port.start();
|
||||
}
|
||||
onMessage(event) {
|
||||
if (event.data.message === "ASYNC_CONFIGURATION") {
|
||||
this.realTimeBpmAnalyzer.setAsyncConfiguration(event.data.parameters);
|
||||
}
|
||||
}
|
||||
process(inputs, _outputs, _parameters) {
|
||||
const currentChunk = inputs[0][0];
|
||||
if (!currentChunk) {
|
||||
return true;
|
||||
}
|
||||
const { isBufferFull, buffer, bufferSize } = this.aggregate(currentChunk);
|
||||
if (isBufferFull) {
|
||||
this.realTimeBpmAnalyzer.analyzeChunck(buffer, sampleRate, bufferSize, (event) => {
|
||||
this.port.postMessage(event);
|
||||
}).catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
registerProcessor(realtimeBpmProcessorName, RealTimeBpmProcessor);
|
||||
var realtime_bpm_processor_default = {};
|
||||
})();
|
||||
//# sourceMappingURL=realtime-bpm-processor.js.map
|
Loading…
x
Reference in New Issue
Block a user