Emulate PC speaker beep sounds
This commit is contained in:
parent
818a6c211f
commit
eb736ab406
2
Makefile
2
Makefile
|
@ -79,7 +79,7 @@ CORE_FILES=const.js config.js io.js main.js lib.js fpu.js ide.js pci.js floppy.j
|
||||||
elf.js
|
elf.js
|
||||||
LIB_FILES=9p.js filesystem.js jor1k.js marshall.js utf8.js
|
LIB_FILES=9p.js filesystem.js jor1k.js marshall.js utf8.js
|
||||||
BROWSER_FILES=screen.js \
|
BROWSER_FILES=screen.js \
|
||||||
keyboard.js mouse.js serial.js \
|
keyboard.js mouse.js speaker.js serial.js \
|
||||||
network.js lib.js starter.js worker_bus.js dummy_screen.js
|
network.js lib.js starter.js worker_bus.js dummy_screen.js
|
||||||
|
|
||||||
CORE_FILES:=$(addprefix src/,$(CORE_FILES))
|
CORE_FILES:=$(addprefix src/,$(CORE_FILES))
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"memory.js dma.js pit.js vga.js ps2.js pic.js rtc.js uart.js acpi.js apic.js ioapic.js hpet.js " +
|
"memory.js dma.js pit.js vga.js ps2.js pic.js rtc.js uart.js acpi.js apic.js ioapic.js hpet.js " +
|
||||||
"ne2k.js state.js virtio.js bus.js elf.js";
|
"ne2k.js state.js virtio.js bus.js elf.js";
|
||||||
|
|
||||||
var BROWSER_FILES = "main.js screen.js keyboard.js mouse.js serial.js lib.js network.js starter.js worker_bus.js";
|
var BROWSER_FILES = "main.js screen.js keyboard.js mouse.js speaker.js serial.js lib.js network.js starter.js worker_bus.js";
|
||||||
//var LIB_FILES = "esprima.js walk.js";
|
//var LIB_FILES = "esprima.js walk.js";
|
||||||
var LIB_FILES = "";
|
var LIB_FILES = "";
|
||||||
|
|
||||||
|
|
67
src/browser/speaker.js
Executable file
67
src/browser/speaker.js
Executable file
|
@ -0,0 +1,67 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param {BusConnector} bus
|
||||||
|
* @suppress {deprecated}
|
||||||
|
*/
|
||||||
|
function SpeakerAdapter(bus)
|
||||||
|
{
|
||||||
|
if (typeof window === "undefined")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @const @type {BusConnector} */
|
||||||
|
this.bus = bus;
|
||||||
|
|
||||||
|
this.audio_context = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
|
|
||||||
|
this.beep_gain = this.audio_context.createGain();
|
||||||
|
this.beep_gain.gain.value = 0;
|
||||||
|
this.beep_gain.connect(this.audio_context.destination);
|
||||||
|
|
||||||
|
this.beep_oscillator = this.audio_context.createOscillator();
|
||||||
|
this.beep_oscillator.type = 'square';
|
||||||
|
this.beep_oscillator.frequency.value = 440;
|
||||||
|
this.beep_oscillator.connect(this.beep_gain);
|
||||||
|
this.beep_oscillator.start();
|
||||||
|
|
||||||
|
this.beep_playing = false;
|
||||||
|
this.beep_enable = false;
|
||||||
|
this.beep_frequency = 440;
|
||||||
|
this.pit_enabled = false;
|
||||||
|
|
||||||
|
bus.register("pcspeaker-enable", function(yesplease)
|
||||||
|
{
|
||||||
|
this.beep_enable = yesplease;
|
||||||
|
this.beep_update();
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
bus.register("pcspeaker-update", function(pit)
|
||||||
|
{
|
||||||
|
this.pit_enabled = pit.counter_mode[2] == 3;
|
||||||
|
this.beep_frequency = OSCILLATOR_FREQ * 1000 / pit.counter_reload[2];
|
||||||
|
this.beep_update();
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
SpeakerAdapter.prototype.beep_update = function()
|
||||||
|
{
|
||||||
|
var current_time = this.audio_context.currentTime;
|
||||||
|
|
||||||
|
if(this.pit_enabled && this.beep_enable)
|
||||||
|
{
|
||||||
|
this.beep_oscillator.frequency.setValueAtTime(this.beep_frequency, current_time);
|
||||||
|
if(!this.beep_playing)
|
||||||
|
{
|
||||||
|
this.beep_gain.gain.setValueAtTime(1, current_time);
|
||||||
|
this.beep_playing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(this.beep_playing)
|
||||||
|
{
|
||||||
|
this.beep_gain.gain.setValueAtTime(0, current_time);
|
||||||
|
this.beep_playing = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -151,6 +151,11 @@ function V86Starter(options)
|
||||||
this.serial_adapter = new SerialAdapter(options["serial_container"], adapter_bus);
|
this.serial_adapter = new SerialAdapter(options["serial_container"], adapter_bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!options["disable_speaker"])
|
||||||
|
{
|
||||||
|
this.speaker_adapter = new SpeakerAdapter(adapter_bus);
|
||||||
|
}
|
||||||
|
|
||||||
// ugly, but required for closure compiler compilation
|
// ugly, but required for closure compiler compilation
|
||||||
function put_on_settings(name, buffer)
|
function put_on_settings(name, buffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -736,7 +736,7 @@ CPU.prototype.init = function(settings, device_bus)
|
||||||
this.devices.hdb = new IDEDevice(this, settings.hdb, false, ide_device_count++, device_bus);
|
this.devices.hdb = new IDEDevice(this, settings.hdb, false, ide_device_count++, device_bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.devices.pit = new PIT(this);
|
this.devices.pit = new PIT(this, device_bus);
|
||||||
|
|
||||||
if(settings.enable_ne2k)
|
if(settings.enable_ne2k)
|
||||||
{
|
{
|
||||||
|
|
12
src/pit.js
12
src/pit.js
|
@ -11,11 +11,13 @@ var OSCILLATOR_FREQ = 1193.1816666; // 1.193182 MHz
|
||||||
*
|
*
|
||||||
* Programmable Interval Timer
|
* Programmable Interval Timer
|
||||||
*/
|
*/
|
||||||
function PIT(cpu)
|
function PIT(cpu, bus)
|
||||||
{
|
{
|
||||||
/** @const @type {CPU} */
|
/** @const @type {CPU} */
|
||||||
this.cpu = cpu;
|
this.cpu = cpu;
|
||||||
|
|
||||||
|
this.bus = bus;
|
||||||
|
|
||||||
this.counter_start_time = new Float64Array(3);
|
this.counter_start_time = new Float64Array(3);
|
||||||
this.counter_start_value = new Uint16Array(3);
|
this.counter_start_value = new Uint16Array(3);
|
||||||
|
|
||||||
|
@ -42,6 +44,10 @@ function PIT(cpu)
|
||||||
|
|
||||||
return ref_toggle << 4 | counter2_out << 5;
|
return ref_toggle << 4 | counter2_out << 5;
|
||||||
});
|
});
|
||||||
|
cpu.io.register_write(0x61, this, function(data)
|
||||||
|
{
|
||||||
|
this.bus.send("pcspeaker-enable", data & 1);
|
||||||
|
});
|
||||||
|
|
||||||
cpu.io.register_read(0x40, this, function() { return this.counter_read(0); });
|
cpu.io.register_read(0x40, this, function() { return this.counter_read(0); });
|
||||||
cpu.io.register_read(0x41, this, function() { return this.counter_read(1); });
|
cpu.io.register_read(0x41, this, function() { return this.counter_read(1); });
|
||||||
|
@ -228,6 +234,8 @@ PIT.prototype.counter_write = function(i, value)
|
||||||
{
|
{
|
||||||
this.counter_next_low[i] ^= 1;
|
this.counter_next_low[i] ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.bus.send("pcspeaker-update", this);
|
||||||
};
|
};
|
||||||
|
|
||||||
PIT.prototype.port43_write = function(reg_byte)
|
PIT.prototype.port43_write = function(reg_byte)
|
||||||
|
@ -303,4 +311,6 @@ PIT.prototype.port43_write = function(reg_byte)
|
||||||
|
|
||||||
this.counter_mode[i] = mode;
|
this.counter_mode[i] = mode;
|
||||||
this.counter_read_mode[i] = read_mode;
|
this.counter_read_mode[i] = read_mode;
|
||||||
|
|
||||||
|
this.bus.send("pcspeaker-update", this);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue