feat: add phase audio test

main
Tomáš Mládek 2024-02-27 21:07:59 +01:00
parent 9ae4b740e1
commit 1510c9661d
3 changed files with 111 additions and 0 deletions

View File

@ -38,6 +38,23 @@ button, .button {
background: black;
color: white;
&:disabled {
opacity: 0.7;
}
}
input[type="number"] {
background: transparent;
color: white;
border: 1px solid white;
border-radius: 4px;
padding: 0.2em;
&:disabled {
opacity: 0.7;
pointer-events: none;
}
}
select {

View File

@ -1,5 +1,6 @@
<script lang="ts">
import StereoTest from './(channels)/stereo-test.svelte';
import PhaseTest from './phase.svelte';
</script>
<article>
@ -15,6 +16,8 @@
<li><a class="button" href="channels-7.1">7.1 Surround</a></li>
</ul>
</section>
<h3>Phase test</h3>
<PhaseTest />
</article>
<style>

View File

@ -0,0 +1,91 @@
<script lang="ts">
import { onMount } from 'svelte';
let frequency = 60;
let playing = false;
let audioCtx: AudioContext | undefined;
let oscillatorL: OscillatorNode | undefined;
let oscillatorR: OscillatorNode | undefined;
onMount(() => {
audioCtx = new window.AudioContext();
});
function start(mode: 'inPhase' | 'outOfPhase') {
if (!audioCtx) return;
oscillatorL?.stop();
oscillatorR?.stop();
oscillatorL = audioCtx.createOscillator();
oscillatorR = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();
const stereoPannerL = audioCtx.createStereoPanner();
const stereoPannerR = audioCtx.createStereoPanner();
oscillatorL.frequency.setValueAtTime(frequency, audioCtx.currentTime);
oscillatorR.frequency.setValueAtTime(frequency, audioCtx.currentTime);
stereoPannerL.pan.setValueAtTime(-1, audioCtx.currentTime);
stereoPannerR.pan.setValueAtTime(1, audioCtx.currentTime);
oscillatorL.connect(stereoPannerL).connect(audioCtx.destination);
oscillatorR.connect(gainNode).connect(stereoPannerR).connect(audioCtx.destination);
if (mode === 'inPhase') {
gainNode?.gain.setValueAtTime(1, audioCtx.currentTime); // Normal phase
} else {
gainNode?.gain.setValueAtTime(-1, audioCtx.currentTime); // Invert phase
}
oscillatorL?.start();
oscillatorR?.start();
playing = true;
}
async function stop() {
oscillatorL?.stop();
oscillatorR?.stop();
playing = false;
}
</script>
<div class="test">
<label>
Frequency <input
type="number"
bind:value={frequency}
min="20"
max="20000"
disabled={playing}
/>Hz
</label>
<div class="controls">
<button on:click={() => start('inPhase')}>In Phase</button>
<button on:click={() => start('outOfPhase')}>Out of Phase</button>
<button class="stop" on:click={stop} disabled={!playing}>Stop</button>
</div>
</div>
<style>
.test {
margin: 1em 0;
}
.controls {
margin-top: 0.5em;
}
.stop {
margin-left: 1em;
&:not(:disabled) {
background: darkred;
}
}
input {
width: 5em;
}
</style>