Accurate Timing
This commit is contained in:
parent
a5285a10e2
commit
012161c4d6
44
app.js
44
app.js
@ -1,7 +1,7 @@
|
|||||||
const MAX_LEVEL = 3
|
const MAX_LEVEL = 3
|
||||||
const DRAW_PERIOD = 0.04 // s
|
const DRAW_PERIOD = 0.04 // s
|
||||||
const UPDATE_PERIOD = 0.01 // s
|
const UPDATE_PERIOD = 0.01 // s
|
||||||
const FLOOR = 400 // px
|
const FLOOR = 386 // px
|
||||||
const FIRST_NOTE = 48 // C2
|
const FIRST_NOTE = 48 // C2
|
||||||
const LAST_NOTE = 73 // C4
|
const LAST_NOTE = 73 // C4
|
||||||
const FREQUENCIES = [
|
const FREQUENCIES = [
|
||||||
@ -180,8 +180,8 @@ class Note extends Sprite {
|
|||||||
return new Sprite(this.canvasCtx, "tiny-explosion.png", this.x, this.y, 16, 16, 7)
|
return new Sprite(this.canvasCtx, "tiny-explosion.png", this.x, this.y, 16, 16, 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
playNoise() {
|
playNoise(time) {
|
||||||
playNoise(0.3, 0.4, 1400)
|
playNoise(0.4, 1400, 0.3, time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,8 +213,8 @@ class Quarter extends Note {
|
|||||||
return new Sprite(this.canvasCtx, "little-explosion.png", this.x, this.y, 33, 33, 5)
|
return new Sprite(this.canvasCtx, "little-explosion.png", this.x, this.y, 33, 33, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
playNoise() {
|
playNoise(time) {
|
||||||
playNoise(0.5, 0.5, 1000)
|
playNoise(0.5, 1000, 0.5, time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,8 +233,8 @@ class Whole extends Note {
|
|||||||
return new Sprite(canvasCtx, "big-explosion.png", this.x, this.y, 48, 48, 8)
|
return new Sprite(canvasCtx, "big-explosion.png", this.x, this.y, 48, 48, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
playNoise() {
|
playNoise(time) {
|
||||||
playNoise(0.8, 0.7, 400)
|
playNoise(0.7, 400, 0.8, time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,7 +420,7 @@ async function nextLevel() {
|
|||||||
midiSong = await Midi.fromUrl(`midi/${level}.mid`)
|
midiSong = await Midi.fromUrl(`midi/${level}.mid`)
|
||||||
levelTitle.innerText = `Niveau ${level}`
|
levelTitle.innerText = `Niveau ${level}`
|
||||||
songNameTitle.innerText = midiSong.name
|
songNameTitle.innerText = midiSong.name
|
||||||
speed = UPDATE_PERIOD * FLOOR / midiSong.header.tempos[0].bpm
|
speed = 4 * UPDATE_PERIOD * FLOOR / midiSong.header.tempos[0].bpm
|
||||||
noteSprites = []
|
noteSprites = []
|
||||||
midiSong.tracks.forEach(track => {
|
midiSong.tracks.forEach(track => {
|
||||||
//console.log(track.name)
|
//console.log(track.name)
|
||||||
@ -456,7 +456,7 @@ function update(time) {
|
|||||||
let explosionSprite = noteSprite.explose()
|
let explosionSprite = noteSprite.explose()
|
||||||
explosionSprites.push(explosionSprite)
|
explosionSprites.push(explosionSprite)
|
||||||
explosionSprite.play().then(() => explosionSprites.remove(explosionSprite))
|
explosionSprite.play().then(() => explosionSprites.remove(explosionSprite))
|
||||||
noteSprite.playNoise()
|
noteSprite.playNoise(time)
|
||||||
})
|
})
|
||||||
noteSprites = noteSprites.filter(note => note.y < FLOOR)
|
noteSprites = noteSprites.filter(note => note.y < FLOOR)
|
||||||
|
|
||||||
@ -464,7 +464,7 @@ function update(time) {
|
|||||||
let noteSprite = noteSprites.find(noteSprite => noteSprite.note == cannonSprite.note)
|
let noteSprite = noteSprites.find(noteSprite => noteSprite.note == cannonSprite.note)
|
||||||
if (noteSprite) {
|
if (noteSprite) {
|
||||||
if (!noteSprite.shot) {
|
if (!noteSprite.shot) {
|
||||||
playNote(noteSprite.note, noteSprite.velocity, time + noteSprite.duration)
|
playNote(noteSprite.note, noteSprite.velocity, noteSprite.duration, time)
|
||||||
cannonSprite.impactY = noteSprite.y
|
cannonSprite.impactY = noteSprite.y
|
||||||
noteSprite.shot = true
|
noteSprite.shot = true
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
@ -480,7 +480,7 @@ function update(time) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function playNote(note, velocity=0.7, stopAt=0) {
|
function playNote(note, velocity=0.7, duration=0, time=0) {
|
||||||
if(oscillators[note]) return
|
if(oscillators[note]) return
|
||||||
|
|
||||||
var oscillator = audioCtx.createOscillator()
|
var oscillator = audioCtx.createOscillator()
|
||||||
@ -489,33 +489,33 @@ function playNote(note, velocity=0.7, stopAt=0) {
|
|||||||
|
|
||||||
oscillator.velocity = audioCtx.createGain()
|
oscillator.velocity = audioCtx.createGain()
|
||||||
oscillator.velocity.gain.value = 0
|
oscillator.velocity.gain.value = 0
|
||||||
oscillator.velocity.gain.linearRampToValueAtTime(velocity, audioCtx.currentTime + 0.05)
|
oscillator.velocity.gain.linearRampToValueAtTime(velocity, time + 0.05)
|
||||||
oscillator.connect(oscillator.velocity)
|
oscillator.connect(oscillator.velocity)
|
||||||
oscillator.start()
|
oscillator.start()
|
||||||
oscillator.velocity.connect(volume)
|
oscillator.velocity.connect(volume)
|
||||||
|
|
||||||
depth.connect(oscillator.detune)
|
depth.connect(oscillator.detune)
|
||||||
|
|
||||||
if (stopAt) {
|
if (duration) {
|
||||||
oscillator.velocity.gain.setValueCurveAtTime([velocity, velocity/10, velocity/20, 0], stopAt, 0.5)
|
oscillator.velocity.gain.setValueCurveAtTime([velocity, velocity/10, velocity/20, 0], time + duration, 0.5)
|
||||||
oscillator.stop(stopAt + 0.5)
|
oscillator.stop(time + duration + 0.5)
|
||||||
} else {
|
} else {
|
||||||
oscillators[note] = oscillator
|
oscillators[note] = oscillator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopNote(note, delay=0) {
|
function stopNote(note, time=0) {
|
||||||
if(!oscillators[note]) return
|
if(!oscillators[note]) return
|
||||||
|
|
||||||
velocity = oscillators[note].velocity.gain.value
|
velocity = oscillators[note].velocity.gain.value
|
||||||
oscillators[note].velocity.gain.setValueCurveAtTime([velocity, velocity/10, velocity/20, 0], audioCtx.currentTime + delay + 0.1, 0.5)
|
oscillators[note].velocity.gain.setValueCurveAtTime([velocity, velocity/10, velocity/20, 0], time, 0.5)
|
||||||
oscillators[note].stop(audioCtx.currentTime + delay + 0.6)
|
oscillators[note].stop(time + 0.5)
|
||||||
|
|
||||||
delete(oscillators[note])
|
delete(oscillators[note])
|
||||||
}
|
}
|
||||||
|
|
||||||
function playNoise(noiseDuration, startGain=0.5, bandHz=1000) {
|
function playNoise(startGain=0.5, bandHz=1000, duration, time) {
|
||||||
const bufferSize = audioCtx.sampleRate * noiseDuration
|
const bufferSize = audioCtx.sampleRate * duration
|
||||||
const noiseBuffer = new AudioBuffer({
|
const noiseBuffer = new AudioBuffer({
|
||||||
length: bufferSize,
|
length: bufferSize,
|
||||||
sampleRate: audioCtx.sampleRate,
|
sampleRate: audioCtx.sampleRate,
|
||||||
@ -532,10 +532,10 @@ function playNoise(noiseDuration, startGain=0.5, bandHz=1000) {
|
|||||||
frequency: bandHz,
|
frequency: bandHz,
|
||||||
})
|
})
|
||||||
const gain = new GainNode(audioCtx)
|
const gain = new GainNode(audioCtx)
|
||||||
gain.gain.setValueCurveAtTime([startGain, startGain/5, 0], audioCtx.currentTime, noiseDuration)
|
gain.gain.setValueCurveAtTime([startGain, startGain/5, 0], time, duration)
|
||||||
noise.connect(bandpass).connect(gain).connect(audioCtx.destination)
|
noise.connect(bandpass).connect(gain).connect(audioCtx.destination)
|
||||||
noise.start()
|
noise.start()
|
||||||
noise.stop(audioCtx.currentTime + noiseDuration)
|
noise.stop(time + duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
document.onkeydown = function(event) {
|
document.onkeydown = function(event) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user