From 8c63da284fbc346cf2fc7b0ee882a2fb1b2f145f Mon Sep 17 00:00:00 2001 From: Jonathan Marler Date: Mon, 17 Jan 2022 08:45:30 -0700 Subject: [PATCH] An implementation of a new frequency mode, see issue #333 --- runtimes/web/src/apu.js | 19 +++++++++++++++++-- runtimes/web/src/constants.js | 1 + runtimes/web/src/runtime.js | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/runtimes/web/src/apu.js b/runtimes/web/src/apu.js index cc318b884..82212ab6b 100644 --- a/runtimes/web/src/apu.js +++ b/runtimes/web/src/apu.js @@ -20,11 +20,21 @@ const NOISE_LENGTH = 0x8000; // 440.0 / 44100, // ].reverse(); +const twelvth_root_of_2 = Math.pow(2, 1/12); +function midiToFreq(pitch, bend) { + // NOTE: we could use a 128-value table here if we have performance issues with Math.pow + const freq = 440 * Math.pow(twelvth_root_of_2, pitch - 69); + if (bend == 0) + return freq; + return freq * Math.pow(2, bend / 2048); +} + export class APU { constructor () { const ctx = new (window.AudioContext || window.webkitAudioContext)(); this.ctx = ctx; + this.frequency_mode = 0; this.nodes = new Array(4); this.gains = new Array(4); @@ -58,8 +68,13 @@ export class APU { } tone (frequency, duration, volume, flags) { - const freq1 = frequency & 0xffff; - const freq2 = (frequency >> 16) & 0xffff; + var freq1 = frequency & 0xffff; + var freq2 = (frequency >> 16) & 0xffff; + + if (this.frequency_mode == 1) { + freq1 = midiToFreq(freq1, (freq1 >> 8) & 0xff); + freq2 = midiToFreq(freq2, (freq2 >> 8) & 0xff); + } const sustain = (duration & 0xff) / 60; const release = ((duration >> 8) & 0xff) / 60; diff --git a/runtimes/web/src/constants.js b/runtimes/web/src/constants.js index 4e814c43a..1af898293 100644 --- a/runtimes/web/src/constants.js +++ b/runtimes/web/src/constants.js @@ -45,6 +45,7 @@ export const MOUSE_MIDDLE = 4; export const SYSTEM_PRESERVE_FRAMEBUFFER = 1; export const SYSTEM_HIDE_GAMEPAD_OVERLAY = 2; +export const SYSTEM_MIDI_FREQUENCY_MODE = 4; // Flags for Runtime.pauseState export const PAUSE_UNFOCUSED = 1; diff --git a/runtimes/web/src/runtime.js b/runtimes/web/src/runtime.js index 96c445622..d378941db 100644 --- a/runtimes/web/src/runtime.js +++ b/runtimes/web/src/runtime.js @@ -324,6 +324,7 @@ export class Runtime { if (!this.getSystemFlag(constants.SYSTEM_PRESERVE_FRAMEBUFFER)) { this.framebuffer.clear(); } + this.api.frequency_mode = this.getSystemFlag(constants.SYSTEM_MIDI_FREQUENCY_MODE) ? 1 : 0; this.safeCall(this.wasm.exports.update);