Oscillator with With Web Audio API + Vue.js
by bc_rikko
HTML
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<form class="controller-form">
<div class="wave">
<h3>Wave form</h3>
<template v-for="wave in waveForms">
<label>
<input type="radio" :value="wave" v-model="form.waveForm">
{{ wave }}
</label>
</template>
<div v-if="form.waveForm === 'custom'" class="custom-form">
<table>
<thead>
<th>harmonic</th>
<th>real</th>
<th>imag</th>
</thead>
<tbody>
<!-- index0は0固定 -->
<tr v-for="i in 7">
<td>{{ i }}</td>
<td><input type="range" min="0" max="1" step="any" v-model="form.harmonics.real[i]"></td>
<td><input type="range" min="0" max="1" step="any" v-model="form.harmonics.imag[i]"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="frequency">
<h3>Frequency</h3>
<input type="number" min="0" max="20000" v-model="form.freq">
</div>
<div class="detune">
<h3>Detune</h3>
<input type="range" min="-100" max="100" step="any" v-model="form.detune">
</div>
</form>
<div class="osc-controller">
<button type="button" @click="start">Start</button>
<button type="button" @click="stop">Stop</button>
</div>
</div>
JavaScript
// import vue@2.5.3
new Vue({
el: '#app',
data() {
return {
ctx: new AudioContext(),
osc: null,
form: {
waveForm: 'sine',
detune: 0,
freq: 440,
harmonics: {
real: [0, 1, 0, 0, 0, 0, 0, 0],
imag: [0, 0, 0, 0, 0, 0, 0, 0]
}
},
waveForms: ['sine', 'square', 'sawtooth', 'triangle', 'custom']
}
},
methods: {
start() {
this.osc = this.ctx.createOscillator();
this.osc.connect(this.ctx.destination);
this.osc.frequency.value = this.form.freq;
this.osc.detune.value = this.form.detune;
if (this.form.waveForm === 'custom') {
// カスタム波形
const wave = this.ctx.createPeriodicWave([...this.form.harmonics.real], [...this.form.harmonics.imag]);
this.osc.setPeriodicWave(wave);
} else {
this.osc.type = this.form.waveForm;
}
this.osc.start();
},
stop() {
this.osc.stop();
}
}
});