diff --git a/js/term_screen.js b/js/term_screen.js index d75b15f..d406739 100644 --- a/js/term_screen.js +++ b/js/term_screen.js @@ -677,7 +677,7 @@ window.TermScreen = class TermScreen extends EventEmitter { * @param {number} options.cellHeight - cell height in pixels * @param {number} options.bg - the background color */ - drawCellBackground ({ x, y, cellWidth, cellHeight, bg }) { + drawBackground ({ x, y, cellWidth, cellHeight, bg }) { const ctx = this.ctx ctx.fillStyle = this.getColor(bg) ctx.clearRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight) @@ -698,7 +698,7 @@ window.TermScreen = class TermScreen extends EventEmitter { * @param {number} options.fg - the foreground color * @param {number} options.attrs - the cell's attributes */ - drawCell ({ x, y, charSize, cellWidth, cellHeight, text, fg, attrs }) { + drawCharacter ({ x, y, charSize, cellWidth, cellHeight, text, fg, attrs }) { if (!text) return const ctx = this.ctx @@ -954,7 +954,7 @@ window.TermScreen = class TermScreen extends EventEmitter { if (attrs & (1 << 4) && !this.window.blinkStyleOn) { // blinking is enabled and blink style is off - // set text to nothing so drawCell doesn't draw anything + // set text to nothing so drawCharacter doesn't draw anything text = '' } @@ -1045,7 +1045,7 @@ window.TermScreen = class TermScreen extends EventEmitter { let [cell, x, y, text, fg, bg, attrs, isCursor] = data if (redrawMap.get(cell)) { - this.drawCellBackground({ x, y, cellWidth, cellHeight, bg }) + this.drawBackground({ x, y, cellWidth, cellHeight, bg }) if (this.window.debug && this._debug) { // set cell flags @@ -1074,7 +1074,7 @@ window.TermScreen = class TermScreen extends EventEmitter { let [cell, x, y, text, fg, bg, attrs, isCursor, inSelection] = data if (redrawMap.get(cell)) { - this.drawCell({ + this.drawCharacter({ x, y, charSize, cellWidth, cellHeight, text, fg, attrs }) @@ -1108,8 +1108,8 @@ window.TermScreen = class TermScreen extends EventEmitter { // HACK: ensure cursor is visible if (fg === bg) bg = fg === 0 ? 7 : 0 - this.drawCellBackground({ x, y, cellWidth, cellHeight, bg }) - this.drawCell({ + this.drawBackground({ x, y, cellWidth, cellHeight, bg }) + this.drawCharacter({ x, y, charSize, cellWidth, cellHeight, text, fg, attrs }) ctx.restore() @@ -1462,29 +1462,49 @@ window.TermScreen = class TermScreen extends EventEmitter { if (this._lastBeep && this._lastBeep > Date.now() - 50) return this._lastBeep = Date.now() - let osc, gain + if (!this._convolver) { + this._convolver = audioCtx.createConvolver() + let impulseLength = audioCtx.sampleRate * 0.8 + let impulse = audioCtx.createBuffer(2, impulseLength, audioCtx.sampleRate) + for (let i = 0; i < impulseLength; i++) { + impulse.getChannelData(0)[i] = (1 - i / impulseLength) ** (7 + Math.random()) + impulse.getChannelData(1)[i] = (1 - i / impulseLength) ** (7 + Math.random()) + } + this._convolver.buffer = impulse + this._convolver.connect(audioCtx.destination) + } // main beep - osc = audioCtx.createOscillator() - gain = audioCtx.createGain() - osc.connect(gain) - gain.connect(audioCtx.destination) - gain.gain.value = 0.5 - osc.frequency.value = 750 - osc.type = 'sine' - osc.start() - osc.stop(audioCtx.currentTime + 0.05) + const mainOsc = audioCtx.createOscillator() + const mainGain = audioCtx.createGain() + mainOsc.connect(mainGain) + mainGain.gain.value = 6 + mainOsc.frequency.value = 750 + mainOsc.type = 'sine' // surrogate beep (making it sound like 'oops') - osc = audioCtx.createOscillator() - gain = audioCtx.createGain() - osc.connect(gain) - gain.connect(audioCtx.destination) - gain.gain.value = 0.2 - osc.frequency.value = 400 - osc.type = 'sine' - osc.start(audioCtx.currentTime + 0.05) - osc.stop(audioCtx.currentTime + 0.08) + const surrOsc = audioCtx.createOscillator() + const surrGain = audioCtx.createGain() + surrOsc.connect(surrGain) + surrGain.gain.value = 4 + surrOsc.frequency.value = 400 + surrOsc.type = 'sine' + + mainGain.connect(this._convolver) + surrGain.connect(this._convolver) + + let startTime = audioCtx.currentTime + mainOsc.start() + mainOsc.stop(startTime + 0.5) + surrOsc.start(startTime + 0.05) + surrOsc.stop(startTime + 0.8) + + let loop = function () { + if (audioCtx.currentTime < startTime + 0.8) requestAnimationFrame(loop) + mainGain.gain.value *= 0.8 + surrGain.gain.value *= 0.8 + } + loop() } /**