Skip to content

Commit

Permalink
fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
flo-bit committed Oct 16, 2024
1 parent 0cad2ff commit b74e5d0
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 43 deletions.
19 changes: 17 additions & 2 deletions src/lib/visualizations/audio/AudioFrequency.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
<script lang="ts">
import type { WavRecorder, AudioFilePlayer, WavStreamPlayer } from '$lib/visualizations/wavtools';
import { WavRecorder, AudioFilePlayer, WavStreamPlayer } from '$lib/visualizations/wavtools';
import { raf, normalizeArray } from '../core/utils';
export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null;
export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency';
export let minDecibels: number = -100;
export let maxDecibels: number = -30;
let values: Float32Array = new Float32Array([0]);
//Update frequency values every render frame
raf(() => (values = audio ? audio.getFrequencies('music').values : new Float32Array([0])));
raf(() => {
if(!audio) {
values = new Float32Array([0]);
return;
}
if(audio instanceof WavRecorder && !audio.recording) {
values = new Float32Array([0]);
return;
}
values = audio.getFrequencies(analysisType, minDecibels, maxDecibels).values;
});
//Recreate the getValues function when values changes (to trigger reactivity)
$: getValues = (detail: number) => normalizeArray(values, detail);
Expand Down
7 changes: 4 additions & 3 deletions src/lib/visualizations/audio/BarAudioVisualizer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null;
export let glow: number | undefined = 3;
export let detail: number | undefined = 50;
export let detail: number | undefined = 20;
export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency';
</script>

<AudioFrequency {audio} let:getValues>
<AudioFrequency {audio} {analysisType} let:getValues>
<Glow {glow}>
<BarVisualizer values={getValues(detail || 50)} {...$$restProps} />
<BarVisualizer values={getValues(detail || 20)} {...$$restProps} />
</Glow>
</AudioFrequency>
3 changes: 2 additions & 1 deletion src/lib/visualizations/audio/CircleBarAudioVisualizer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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';
</script>

<AudioFrequency {audio} let:getValues>
<AudioFrequency {audio} {analysisType} let:getValues>
<Glow {glow}>
<CircleBarVisualizer values={getValues(detail || 50)} {...$$restProps} />
</Glow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
</script>

<AudioFrequency {audio} let:getValues>
<AudioFrequency {audio} {analysisType} let:getValues>
<Glow {glow}>
<CircleCirclesVisualizer values={getValues(detail || 50)} {...$$restProps} />
</Glow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
</script>

<AudioFrequency {audio} let:getValues>
<AudioFrequency {audio} {analysisType} let:getValues>
<Glow {glow}>
<DeformedCircleVisualizer values={getValues(detail || 50)} {...$$restProps} />
<DeformedCircleVisualizer values={getValues(detail || 20)} {...$$restProps} />
</Glow>
</AudioFrequency>
3 changes: 2 additions & 1 deletion src/lib/visualizations/audio/InnerGlowAudioVisualizer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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';
</script>

<AudioFrequency {audio} let:getValues>
<AudioFrequency {audio} {analysisType} let:getValues>
<Glow {glow}>
<InnerGlowVisualizer values={getValues(detail || 50)} {...$$restProps} />
</Glow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null;
export let glow: number | undefined = 3;
export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency';
</script>

<AudioFrequency {audio} let:getValues>
<AudioFrequency {audio} {analysisType} let:getValues>
<Glow {glow}>
<MicrophoneVisualizer value={getValues(1)[0]} {...$$restProps} />
</Glow>
Expand Down
3 changes: 2 additions & 1 deletion src/lib/visualizations/audio/SpeakerAudioVisualizer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
export let audio: AudioFilePlayer | WavRecorder | WavStreamPlayer | null;
export let glow: number | undefined = 3;
export let analysisType: 'music' | 'voice' | 'frequency' = 'frequency';
</script>

<AudioFrequency {audio} let:getValues>
<AudioFrequency {audio} {analysisType} let:getValues>
<Glow {glow}>
<SpeakerVisualizer value={getValues(1)[0]} {...$$restProps} />
</Glow>
Expand Down
9 changes: 7 additions & 2 deletions src/lib/visualizations/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
75 changes: 47 additions & 28 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
</script>

Expand All @@ -44,7 +63,7 @@
<div class="flex gap-2 flex-col sm:flex-row">
<button
type="button"
on:click={() => (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'
Expand All @@ -53,7 +72,7 @@
>
<button
type="button"
on:click={() => (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'
Expand All @@ -68,20 +87,20 @@

<div class="grid grid-cols-1 sm:grid-cols-3 gap-4 mt-8">
<div class="h-64 w-full rounded-xl border border-white/15 p-4">
<CircleBarAudioVisualizer {audio} startHue={0} endHue={50} rotate={2} />
<CircleBarAudioVisualizer audio={currentlyPlaying} startHue={0} endHue={50} rotate={2} {analysisType} />
</div>
<div class="h-64 w-full rounded-xl border border-white/15 p-4">
<BarAudioVisualizer {audio} barSpacing={8} startHue={0} endHue={50} center />
<BarAudioVisualizer audio={currentlyPlaying} barSpacing={8} startHue={0} endHue={50} center {analysisType} />
</div>

<div class="h-64 w-full rounded-xl border border-white/15 p-4">
<CircleCirclesAudioVisualizer {audio} startHue={0} endHue={50} />
<CircleCirclesAudioVisualizer audio={currentlyPlaying} startHue={0} endHue={50} {analysisType} />
</div>

<AudioFrequency {audio} let:getValues>
<AudioFrequency audio={currentlyPlaying} let:getValues {analysisType}>
<div class="h-64 w-full rounded-xl border border-white/15 p-4">
<Glow glow={20}>
<DeformedCircleVisualizer values={getValues(16)} startHue={0} endHue={50} />
<DeformedCircleVisualizer values={getValues(8)} startHue={0} endHue={50} />
</Glow>
</div>
<div class="h-64 w-full rounded-xl border border-white/15 overflow-hidden">
Expand All @@ -93,10 +112,10 @@
class="h-64 w-full rounded-xl border border-white/15 overflow-hidden flex items-center justify-center gap-4"
>
<div class="size-20">
<MicrophoneVisualizer value={getValues(1)[0]} />
<MicrophoneVisualizer value={getValues(3)[1]} />
</div>
<div class="size-20">
<SpeakerVisualizer value={getValues(1)[0]} />
<SpeakerVisualizer value={getValues(3)[1]} />
</div>
</div>
</AudioFrequency>
Expand Down

0 comments on commit b74e5d0

Please sign in to comment.