mirror of
https://gitee.com/blackfox/geekai.git
synced 2025-12-07 01:08:24 +08:00
81 lines
2.3 KiB
JavaScript
81 lines
2.3 KiB
JavaScript
const dataMap = new WeakMap();
|
|
|
|
const normalizeArray = (data, m, downsamplePeaks = false, memoize = false) => {
|
|
let cache, mKey, dKey;
|
|
if (memoize) {
|
|
mKey = m.toString();
|
|
dKey = downsamplePeaks.toString();
|
|
cache = dataMap.has(data)? dataMap.get(data) : {};
|
|
dataMap.set(data, cache);
|
|
cache[mKey] = cache[mKey] || {};
|
|
if (cache[mKey][dKey]) {
|
|
return cache[mKey][dKey];
|
|
}
|
|
}
|
|
const n = data.length;
|
|
const result = new Array(m);
|
|
if (m <= n) {
|
|
// Downsampling
|
|
result.fill(0);
|
|
const count = new Array(m).fill(0);
|
|
for (let i = 0; i < n; i++) {
|
|
const index = Math.floor(i * (m / n));
|
|
if (downsamplePeaks) {
|
|
// take highest result in the set
|
|
result[index] = Math.max(result[index], Math.abs(data[i]));
|
|
} else {
|
|
result[index] += Math.abs(data[i]);
|
|
}
|
|
count[index]++;
|
|
}
|
|
if (!downsamplePeaks) {
|
|
for (let i = 0; i < result.length; i++) {
|
|
result[i] = result[i] / count[i];
|
|
}
|
|
}
|
|
} else {
|
|
for (let i = 0; i < m; i++) {
|
|
const index = (i * (n - 1)) / (m - 1);
|
|
const low = Math.floor(index);
|
|
const high = Math.ceil(index);
|
|
const t = index - low;
|
|
if (high >= n) {
|
|
result[i] = data[n - 1];
|
|
} else {
|
|
result[i] = data[low] * (1 - t) + data[high] * t;
|
|
}
|
|
}
|
|
}
|
|
if (memoize) {
|
|
cache[mKey][dKey] = result;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
export const WavRenderer = {
|
|
drawBars: (canvas, ctx, data, color, pointCount = 0, barWidth = 0, barSpacing = 0, center = false) => {
|
|
pointCount = Math.floor(
|
|
Math.min(
|
|
pointCount,
|
|
(canvas.width - barSpacing) / (Math.max(barWidth, 1) + barSpacing)
|
|
)
|
|
);
|
|
if (!pointCount) {
|
|
pointCount = Math.floor(
|
|
(canvas.width - barSpacing) / (Math.max(barWidth, 1) + barSpacing)
|
|
);
|
|
}
|
|
if (!barWidth) {
|
|
barWidth = (canvas.width - barSpacing) / pointCount - barSpacing;
|
|
}
|
|
const points = normalizeArray(data, pointCount, true);
|
|
for (let i = 0; i < pointCount; i++) {
|
|
const amplitude = Math.abs(points[i]);
|
|
const height = Math.max(1, amplitude * canvas.height);
|
|
const x = barSpacing + i * (barWidth + barSpacing);
|
|
const y = center? (canvas.height - height) / 2 : canvas.height - height;
|
|
ctx.fillStyle = color;
|
|
ctx.fillRect(x, y, barWidth, height);
|
|
}
|
|
},
|
|
}; |