Reputation: 1913
How can I program events to happen once an oscillator has stopped playing using the webaudio API? I'm trying to get data to show up in the DOM while the note is playing, reactively, by updating my Vue component. My code looks like this:
<template>
<div id="player">
<div>{{ currentTime }}</div>
<button @click="start">play</button>
<div>{{ sequence }}</div>
</div>
</template>
<script>
var audioContext = new AudioContext()
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}
export default {
name: 'player',
data: function(){
return {
sequence: [],
toRecall: null,
frequencies: [110, 220, 440, 880],
lives: 3,
n: 2,
currentTime: null,
stop: false
}
},
methods: {
playNote: function(startTime, delay, duration){
var self=this
return new Promise(function(accept, reject){
var pitch = getRandomInt(-12, 13)
self.sequence.push(pitch)
var startTime = audioContext.currentTime + delay
var endTime = startTime + duration
var oscillator = audioContext.createOscillator()
oscillator.connect(audioContext.destination)
oscillator.type = 'sawtooth'
oscillator.start(startTime)
oscillator.stop(endTime)
accept()
})
},
start: function(){
var self=this
this.currentTime = audioContext.currentTime
this.playNote(0, 0, 1).then(function(){
// do once the note is done playing
self.sequence.pop()
})
}
}
}
Specifically, I want the sequence
of pitches (just one for now) to show up on the screen for the 1 second that the note plays, then disappear -- just to prove that pop
is only being called once the note is done playing. Can anyone help me with this? Thanks.
Upvotes: 1
Views: 536
Reputation: 6056
See https://webaudio.github.io/web-audio-api/#dom-audioscheduledsourcenode-onended. And since an OscillatorNode
is an AudioScheduledSourceNode
, you can do something like
oscillator.onended = function () {
/* Remove note from display, or whatever */
};
Upvotes: 1