Some changes to the main visualizer
This commit is contained in:
@@ -31,7 +31,6 @@
|
|||||||
glowIntensity: 0.6,
|
glowIntensity: 0.6,
|
||||||
logoSpin: false,
|
logoSpin: false,
|
||||||
logoSpinSpeed: 5,
|
logoSpinSpeed: 5,
|
||||||
autoSubtitle: false,
|
|
||||||
titlePosition: "top",
|
titlePosition: "top",
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,9 +71,7 @@
|
|||||||
let glowIntensity = saved.glowIntensity;
|
let glowIntensity = saved.glowIntensity;
|
||||||
let logoSpin = saved.logoSpin;
|
let logoSpin = saved.logoSpin;
|
||||||
let logoSpinSpeed = saved.logoSpinSpeed;
|
let logoSpinSpeed = saved.logoSpinSpeed;
|
||||||
let autoSubtitle = saved.autoSubtitle;
|
|
||||||
let titlePosition = saved.titlePosition;
|
let titlePosition = saved.titlePosition;
|
||||||
let capturedTrackLabel = "";
|
|
||||||
let visualizerComponent;
|
let visualizerComponent;
|
||||||
let toggleHidden = false;
|
let toggleHidden = false;
|
||||||
let hideTimer;
|
let hideTimer;
|
||||||
@@ -102,10 +99,6 @@
|
|||||||
clearTimeout(hideTimer);
|
clearTimeout(hideTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (autoSubtitle && capturedTrackLabel) {
|
|
||||||
subtitle = capturedTrackLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
const settings = {
|
const settings = {
|
||||||
selectedPreset,
|
selectedPreset,
|
||||||
@@ -133,7 +126,6 @@
|
|||||||
glowIntensity,
|
glowIntensity,
|
||||||
logoSpin,
|
logoSpin,
|
||||||
logoSpinSpeed,
|
logoSpinSpeed,
|
||||||
autoSubtitle,
|
|
||||||
titlePosition,
|
titlePosition,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
@@ -191,7 +183,6 @@
|
|||||||
glowIntensity = defaults.glowIntensity;
|
glowIntensity = defaults.glowIntensity;
|
||||||
logoSpin = defaults.logoSpin;
|
logoSpin = defaults.logoSpin;
|
||||||
logoSpinSpeed = defaults.logoSpinSpeed;
|
logoSpinSpeed = defaults.logoSpinSpeed;
|
||||||
autoSubtitle = defaults.autoSubtitle;
|
|
||||||
titlePosition = defaults.titlePosition;
|
titlePosition = defaults.titlePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,7 +311,6 @@
|
|||||||
{glowIntensity}
|
{glowIntensity}
|
||||||
{logoSpin}
|
{logoSpin}
|
||||||
{logoSpinSpeed}
|
{logoSpinSpeed}
|
||||||
bind:capturedTrackLabel
|
|
||||||
bind:isListening
|
bind:isListening
|
||||||
bind:fileCurrentTime
|
bind:fileCurrentTime
|
||||||
bind:fileDuration
|
bind:fileDuration
|
||||||
@@ -391,7 +381,6 @@
|
|||||||
bind:glowIntensity
|
bind:glowIntensity
|
||||||
bind:logoSpin
|
bind:logoSpin
|
||||||
bind:logoSpinSpeed
|
bind:logoSpinSpeed
|
||||||
bind:autoSubtitle
|
|
||||||
bind:titlePosition
|
bind:titlePosition
|
||||||
{isListening}
|
{isListening}
|
||||||
{colorPresets}
|
{colorPresets}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
const DEFAULT_SIZE = 250;
|
const DEFAULT_SIZE = 250;
|
||||||
const LINE_LIFT = 8;
|
const LINE_LIFT = 8;
|
||||||
const FREQ_RANGE = 0.55;
|
const FREQ_RANGE = 0.28;
|
||||||
const INV_255 = 1 / 255;
|
const INV_255 = 1 / 255;
|
||||||
const SMOOTH_FACTOR = 0.45;
|
const SMOOTH_FACTOR = 0.45;
|
||||||
const SCALE_SMOOTH = 0.15;
|
const SCALE_SMOOTH = 0.15;
|
||||||
@@ -39,9 +39,6 @@
|
|||||||
let currentStream = null;
|
let currentStream = null;
|
||||||
let audioElement = null;
|
let audioElement = null;
|
||||||
let audioSourceNode = null;
|
let audioSourceNode = null;
|
||||||
let capturedAudioTrack = null;
|
|
||||||
let tabTitleInterval = null;
|
|
||||||
export let capturedTrackLabel = "";
|
|
||||||
let dataArray = new Uint8Array(128);
|
let dataArray = new Uint8Array(128);
|
||||||
let bufferLength = 128;
|
let bufferLength = 128;
|
||||||
|
|
||||||
@@ -277,16 +274,6 @@
|
|||||||
// Stop the video track immediately — we only need audio
|
// Stop the video track immediately — we only need audio
|
||||||
stream.getVideoTracks().forEach((t) => t.stop());
|
stream.getVideoTracks().forEach((t) => t.stop());
|
||||||
|
|
||||||
// Store audio track for label polling (tab title)
|
|
||||||
capturedAudioTrack = audioTracks[0];
|
|
||||||
tabTitleInterval = setInterval(() => {
|
|
||||||
if (capturedAudioTrack && capturedAudioTrack.readyState === "live") {
|
|
||||||
capturedTrackLabel = capturedAudioTrack.label || "";
|
|
||||||
} else {
|
|
||||||
capturedTrackLabel = "";
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
// Handle stream ending (user clicks "Stop sharing")
|
// Handle stream ending (user clicks "Stop sharing")
|
||||||
stream.addEventListener("inactive", () => stopListening());
|
stream.addEventListener("inactive", () => stopListening());
|
||||||
audioTracks.forEach((track) =>
|
audioTracks.forEach((track) =>
|
||||||
@@ -322,11 +309,8 @@
|
|||||||
|
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
for (let i = 0; i < halfBars; i++) {
|
for (let i = 0; i < halfBars; i++) {
|
||||||
const t = i / halfBars;
|
const t = i / (halfBars - 1 || 1);
|
||||||
const binIdx = Math.min(
|
const binIdx = Math.min(usableBins - 1, (t * (usableBins - 1)) | 0);
|
||||||
usableBins - 1,
|
|
||||||
(Math.pow(t, 1.15) * usableBins) | 0,
|
|
||||||
);
|
|
||||||
const lo = Math.max(0, binIdx - 1);
|
const lo = Math.max(0, binIdx - 1);
|
||||||
const hi = Math.min(usableBins - 1, binIdx + 1);
|
const hi = Math.min(usableBins - 1, binIdx + 1);
|
||||||
const raw =
|
const raw =
|
||||||
@@ -334,11 +318,13 @@
|
|||||||
(dataArray[binIdx] || 0) +
|
(dataArray[binIdx] || 0) +
|
||||||
(dataArray[hi] || 0)) /
|
(dataArray[hi] || 0)) /
|
||||||
3;
|
3;
|
||||||
// Bass emphasis controlled by prop
|
// Normalize and apply sensitivity
|
||||||
const bassBoost = 1 + (1 - t) * bassEmphasis;
|
const normalized = Math.min(1, (raw * sensitivity) / 255);
|
||||||
// Sensitivity multiplier
|
// Gentle curve to keep activity spread evenly
|
||||||
const normalized = Math.min(1, (raw * bassBoost * sensitivity) / 255);
|
const curved = Math.pow(normalized, 8);
|
||||||
const spiked = Math.pow(normalized, 16.0) * 255;
|
// Optional bass emphasis as additive boost for lower bars
|
||||||
|
const bassBoost = (1 - t) * bassEmphasis * normalized * 0.3;
|
||||||
|
const spiked = Math.min(1, curved + bassBoost) * 255;
|
||||||
smoothedValues[i] += (spiked - smoothedValues[i]) * SMOOTH_FACTOR;
|
smoothedValues[i] += (spiked - smoothedValues[i]) * SMOOTH_FACTOR;
|
||||||
}
|
}
|
||||||
// Spatial smoothing: blend adjacent bars for a more unified shape
|
// Spatial smoothing: blend adjacent bars for a more unified shape
|
||||||
@@ -734,12 +720,6 @@
|
|||||||
audioContext = null;
|
audioContext = null;
|
||||||
}
|
}
|
||||||
audioSourceNode = null;
|
audioSourceNode = null;
|
||||||
capturedAudioTrack = null;
|
|
||||||
if (tabTitleInterval) {
|
|
||||||
clearInterval(tabTitleInterval);
|
|
||||||
tabTitleInterval = null;
|
|
||||||
}
|
|
||||||
capturedTrackLabel = "";
|
|
||||||
isListening = false;
|
isListening = false;
|
||||||
dataArray = new Uint8Array(bufferLength);
|
dataArray = new Uint8Array(bufferLength);
|
||||||
draw();
|
draw();
|
||||||
@@ -812,7 +792,6 @@
|
|||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (animationId) cancelAnimationFrame(animationId);
|
if (animationId) cancelAnimationFrame(animationId);
|
||||||
if (audioContext) audioContext.close();
|
if (audioContext) audioContext.close();
|
||||||
if (tabTitleInterval) clearInterval(tabTitleInterval);
|
|
||||||
window.removeEventListener("resize", updateSize);
|
window.removeEventListener("resize", updateSize);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -57,7 +57,6 @@
|
|||||||
export let logoSpin = false;
|
export let logoSpin = false;
|
||||||
export let logoSpinSpeed = 5;
|
export let logoSpinSpeed = 5;
|
||||||
export let titlePosition = "top";
|
export let titlePosition = "top";
|
||||||
export let autoSubtitle = false;
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
@@ -611,13 +610,7 @@
|
|||||||
bind:value={subtitle}
|
bind:value={subtitle}
|
||||||
placeholder="Subtitle..."
|
placeholder="Subtitle..."
|
||||||
style="margin-top: 0.35rem"
|
style="margin-top: 0.35rem"
|
||||||
disabled={autoSubtitle}
|
|
||||||
/>
|
/>
|
||||||
<div class="slider-row" style="margin-top: 0.35rem">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" bind:checked={autoSubtitle} /> Auto (Tab Title)
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="inline-row" style="margin-top: 0.5rem">
|
<div class="inline-row" style="margin-top: 0.5rem">
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
|
|||||||
Reference in New Issue
Block a user