feat: add phase audio test
This commit is contained in:
parent
9ae4b740e1
commit
1510c9661d
3 changed files with 111 additions and 0 deletions
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
91
src/routes/audio/phase.svelte
Normal file
91
src/routes/audio/phase.svelte
Normal 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>
|
Loading…
Reference in a new issue