Mixer with With Web Audio API + Vue.js
by bc_rikko
HTML
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<div
v-for="(o, i) in osc"
:key="o"
class="synth-group">
<h3>OSC {{ i+1 }}</h3>
<div class="field-group">
<label>Wave form</label>
<template v-for="form in waveForms">
<label>
<input type="radio" :value="form" v-model.number="osc[i].form">
{{ form }}
</label>
</template>
</div>
<div class="field-group">
<label>Frequency</label>
<input type="number" v-model.number="osc[i].freq">
</div>
<div class="field-group">
<label>Volume</label>
<input type="range" min="0" max="1" step="any" v-model.number="osc[i].volume">
</div>
</div>
<button type="button" @click="start">Start</button>
<button type="button" @click="stop">Stop</button>
</div>
CSS
label {
display: inline-block;
width: 100px;
}
JavaScript
new Vue({
el: '#app',
data() {
return {
waveForms: ['sine', 'square', 'sawtooth', 'triangle'],
ctx: new AudioContext(),
osc: [
// osc1
{
node: null,
gain: null,
form: 'sine',
freq: 523.25, // C5
volume: 0.3
},
// osc2
{
node: null,
gain: null,
form: 'sine',
freq: 659.25, // E5
volume: 0.3
},
// osc3
{
node: null,
gain: null,
form: 'sine',
freq: 783.99, // G5
volume: 0.3
}
]
}
},
methods: {
start() {
this.osc.forEach((o, i) => {
const gain = this.osc[i].gain = this.ctx.createGain();
gain.connect(this.ctx.destination);
gain.gain.value = o.volume;
const osc = this.osc[i].node = this.ctx.createOscillator();
osc.connect(gain);
osc.frequency.value = o.freq;
osc.type = o.form;
osc.start();
});
},
stop() {
this.osc.forEach(o => o.node.stop());
}
}
});