diff --git a/src/lib/visualizations/audio/AudioFrequency.svelte b/src/lib/visualizations/audio/AudioFrequency.svelte index b086e5a..290ec98 100644 --- a/src/lib/visualizations/audio/AudioFrequency.svelte +++ b/src/lib/visualizations/audio/AudioFrequency.svelte @@ -1,13 +1,28 @@ - + - + diff --git a/src/lib/visualizations/audio/CircleBarAudioVisualizer.svelte b/src/lib/visualizations/audio/CircleBarAudioVisualizer.svelte index 45a0793..88af341 100644 --- a/src/lib/visualizations/audio/CircleBarAudioVisualizer.svelte +++ b/src/lib/visualizations/audio/CircleBarAudioVisualizer.svelte @@ -7,9 +7,10 @@ export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null; export let glow: number | undefined = 3; export let detail: number | undefined = 50; + export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency'; - + diff --git a/src/lib/visualizations/audio/CircleCirclesAudioVisualizer.svelte b/src/lib/visualizations/audio/CircleCirclesAudioVisualizer.svelte index f059e75..c200d02 100644 --- a/src/lib/visualizations/audio/CircleCirclesAudioVisualizer.svelte +++ b/src/lib/visualizations/audio/CircleCirclesAudioVisualizer.svelte @@ -7,9 +7,10 @@ export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null; export let glow: number | undefined = 3; export let detail: number | undefined = 50; + export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency'; - + diff --git a/src/lib/visualizations/audio/DeformedCircleAudioVisualizer.svelte b/src/lib/visualizations/audio/DeformedCircleAudioVisualizer.svelte index 26862db..770764f 100644 --- a/src/lib/visualizations/audio/DeformedCircleAudioVisualizer.svelte +++ b/src/lib/visualizations/audio/DeformedCircleAudioVisualizer.svelte @@ -6,11 +6,12 @@ export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null; export let glow: number | undefined = 20; - export let detail: number | undefined = 50; + export let detail: number | undefined = 20; + export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency'; - + - + diff --git a/src/lib/visualizations/audio/InnerGlowAudioVisualizer.svelte b/src/lib/visualizations/audio/InnerGlowAudioVisualizer.svelte index 2c1ce05..b692599 100644 --- a/src/lib/visualizations/audio/InnerGlowAudioVisualizer.svelte +++ b/src/lib/visualizations/audio/InnerGlowAudioVisualizer.svelte @@ -7,9 +7,10 @@ export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null; export let glow: number | undefined = 10; export let detail: number | undefined = 50; + export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency'; - + diff --git a/src/lib/visualizations/audio/MicrophoneAudioVisualizer.svelte b/src/lib/visualizations/audio/MicrophoneAudioVisualizer.svelte index 50fcec5..609678c 100644 --- a/src/lib/visualizations/audio/MicrophoneAudioVisualizer.svelte +++ b/src/lib/visualizations/audio/MicrophoneAudioVisualizer.svelte @@ -6,9 +6,10 @@ export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null; export let glow: number | undefined = 3; + export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency'; - + diff --git a/src/lib/visualizations/audio/SpeakerAudioVisualizer.svelte b/src/lib/visualizations/audio/SpeakerAudioVisualizer.svelte index d1fa693..9a6e566 100644 --- a/src/lib/visualizations/audio/SpeakerAudioVisualizer.svelte +++ b/src/lib/visualizations/audio/SpeakerAudioVisualizer.svelte @@ -6,9 +6,10 @@ export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null; export let glow: number | undefined = 3; + export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency'; - + diff --git a/src/lib/visualizations/core/utils.ts b/src/lib/visualizations/core/utils.ts index 6cc7d65..b496737 100644 --- a/src/lib/visualizations/core/utils.ts +++ b/src/lib/visualizations/core/utils.ts @@ -6,8 +6,13 @@ export async function raf(callback: () => void) { let mounted = true; async function render() { - if (!mounted) return; - callback(); + if (!mounted || !callback) return; + + try { + callback(); + } catch (e) { + console.error(e); + } requestAnimationFrame(render); } diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index f805b32..fd9ee29 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -11,31 +11,50 @@ import BarAudioVisualizer from '$lib/visualizations/audio/BarAudioVisualizer.svelte'; import CircleCirclesAudioVisualizer from '$lib/visualizations/audio/CircleCirclesAudioVisualizer.svelte'; - let audio: WavRecorder | AudioFilePlayer | null = null; + + export let wavRecorder: WavRecorder = new WavRecorder({ sampleRate: 24000 }); + + export let player = new AudioFilePlayer(); + + export let currentlyPlaying: WavRecorder | AudioFilePlayer | null = null; + let state: 'recording' | 'music' | null = null; - //Stop playing music, if wrong state - $: if (state !== 'music' && audio instanceof WavRecorder) { - audio.end(); - audio = null; - } + let analysisType: 'music' | 'voice' = 'voice'; - //Stop recording, if wrong state - $: if (state !== 'recording' && audio instanceof AudioFilePlayer) { - audio.stop(); - audio = null; - } + $: analysisType = state === 'music' ? 'music' : 'voice'; + + async function microphone() { + if (state === 'recording') { + wavRecorder.end(); + state = null; + return; + } + player.stop(); - //Start playing music, if not playing already - $: if (state == 'music' && !audio) { - let player = (audio = new AudioFilePlayer()); - audio.loadFile('/svelte-audio-visualizations/music.mp3').then(() => player.play()); + await wavRecorder.begin(); + + wavRecorder.record(); + + currentlyPlaying = wavRecorder; + + state = 'recording'; } - //Start recording, if not recording already - $: if (state == 'recording' && !audio) { - let recorder = (audio = new WavRecorder({ sampleRate: 24000 })); - audio.begin().then(() => recorder.record()); + async function music() { + if (state === 'music') { + player.stop(); + state = null; + return; + } + if (wavRecorder.recording) wavRecorder.end(); + + await player.loadFile('/svelte-audio-visualizations/music.mp3'); + + player.play(); + currentlyPlaying = player; + + state = 'music'; } @@ -44,7 +63,7 @@ (state = state == 'recording' ? null : 'recording')} + on:click={microphone} class="rounded-full px-3 py-2 text-sm font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500 {state === 'recording' ? 'text-stone-500 bg-stone-500/10 border border-stone-500/20 hover:bg-stone-500/20' @@ -53,7 +72,7 @@ > (state = state == 'music' ? null : 'music')} + on:click={music} class="rounded-full px-3 py-2 text-sm font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500 {state === 'music' ? 'text-stone-500 bg-stone-500/10 border border-stone-500/20 hover:bg-stone-500/20' @@ -68,20 +87,20 @@ - + - + - + - + - + @@ -93,10 +112,10 @@ class="h-64 w-full rounded-xl border border-white/15 overflow-hidden flex items-center justify-center gap-4" > - + - +