diff --git a/.gitignore b/.gitignore
index b6261c9..7de43c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
.*~
+.checked-*.js
diff --git a/apple2js.html b/apple2js.html
index 679596c..5dcd06e 100644
--- a/apple2js.html
+++ b/apple2js.html
@@ -57,6 +57,7 @@
+
@@ -286,114 +287,12 @@ function updateKHz() {
lastFrames = frames;
}
-/*
- * Audio Handling
- */
-
-// 8000 = 0x1f40 = 64, 31
-// 16000 = 0x3e80 = 128, 62
-
-var wavHeader =
- ['R','I','F','F',68 ,3 ,0 ,0 ,'W','A','V','E','f','m','t',' ',
- 16 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,128,62 ,0 ,0 ,128,62 ,0 ,0 ,
- 1 ,0 ,8 ,0 ,'d','a','t','a',32 ,3 ,0 ,0 ];
-
-function percentEncode(ary) {
- var buf = "";
- for (var idx = 0; idx < ary.length; idx++) {
- buf += "%" + toHex(ary[idx])
- }
- return buf;
-}
-
-wavHeader = $.map(wavHeader, function(n, i) {
- return typeof(n) == "string" ? n.charCodeAt(0) : n;
- });
-
-wavHeaderStr = percentEncode(wavHeader);
-
-var audioAPI = false;
-var audioMoz = false;
-var audioContext;
-var audioNode;
-var audio, audio2;
-
-if (typeof webkitAudioContext != "undefined") {
- debug("Using Web Audio API");
-
- audioAPI = true;
- audioContext = new webkitAudioContext();
- audioNode = audioContext.createJavaScriptNode(4096, 1, 1);
- io.floatAudio(audioContext.sampleRate);
-
- audioNode.onaudioprocess = function(event) {
- var data = event.outputBuffer.getChannelData(0);
- var sample = io.getSample();
- for (var idx = 0; idx < data.length; idx++) {
- if (idx < sample.length) {
- data[idx] = sample[idx];
- } else {
- data[idx] = 0;
- }
- }
- }
-} else {
- audio = document.createElement("audio");
-
- if (audio.mozSetup) {
- debug("Using Mozilla Audio API");
- audio.mozSetup(1, 16000);
- io.floatAudio(16000);
- audioMoz = true;
- } else {
- audio2 = document.createElement("audio");
- }
-}
-
-function playSample() {
- // [audio,audio2] = [audio2,audio];
-
- var sample = io.getSample();
-
- if (audioMoz) {
- audio.mozWriteAudio(sample);
- return;
- }
-
- var tmp = audio;
- audio = audio2;
- audio2 = tmp;
-
- if (sample && sample.length) {
- var len = sample.length,
- buf = sample.join(""),
- o1 = percentEncode([(len + 36) & 0xff, (len + 36) >> 8]),
- o2 = percentEncode([len & 0xff, len >> 8]),
- header = wavHeaderStr.replace("%44%03",o1).replace("%20%03", o2);
-
- audio.src = "data:audio/x-wav," + header + buf;
- // debug(audio.src);
- audio.play();
- }
-}
+/* Audio Handling */
+initAudio();
function updateSound()
{
- var sound = $("#enable_sound").attr("checked");
- if (audioAPI) {
- if (sound) {
- audioNode.connect(audioContext.destination);
- } else {
- audioNode.disconnect();
- }
- } else {
- if (sound) {
- if (audio) audio.volume = 0.5;
- if (audio2) audio2.volume = 0.5;
- } else {
- io.getSample(false);
- }
- }
+ enableSound($("#enable_sound").attr("checked"));
}
function dumpDisk(drive) {
@@ -478,7 +377,7 @@ function run(pc) {
running = false;
vm.blit();
if (now - lastSample >= 200) {
- if (!audioAPI && sound) {
+ if (!audioAPI) {
playSample();
}
lastSample = now;
diff --git a/apple2jse.html b/apple2jse.html
index d00a611..d7e9cb6 100644
--- a/apple2jse.html
+++ b/apple2jse.html
@@ -284,114 +284,12 @@ function updateKHz() {
lastFrames = frames;
}
-/*
- * Audio Handling
- */
-
-// 8000 = 0x1f40 = 64, 31
-// 16000 = 0x3e80 = 128, 62
-
-var wavHeader =
- ['R','I','F','F',68 ,3 ,0 ,0 ,'W','A','V','E','f','m','t',' ',
- 16 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,128,62 ,0 ,0 ,128,62 ,0 ,0 ,
- 1 ,0 ,8 ,0 ,'d','a','t','a',32 ,3 ,0 ,0 ];
-
-function percentEncode(ary) {
- var buf = "";
- for (var idx = 0; idx < ary.length; idx++) {
- buf += "%" + toHex(ary[idx])
- }
- return buf;
-}
-
-wavHeader = $.map(wavHeader, function(n, i) {
- return typeof(n) == "string" ? n.charCodeAt(0) : n;
- });
-
-wavHeaderStr = percentEncode(wavHeader);
-
-var audioAPI = false;
-var audioMoz = false;
-var audioContext;
-var audioNode;
-var audio, audio2;
-
-if (typeof webkitAudioContext != "undefined") {
- debug("Using Web Audio API");
-
- audioAPI = true;
- audioContext = new webkitAudioContext();
- audioNode = audioContext.createJavaScriptNode(4096, 1, 1);
- io.floatAudio(audioContext.sampleRate);
-
- audioNode.onaudioprocess = function(event) {
- var data = event.outputBuffer.getChannelData(0);
- var sample = io.getSample();
- for (var idx = 0; idx < data.length; idx++) {
- if (idx < sample.length) {
- data[idx] = sample[idx];
- } else {
- data[idx] = 0;
- }
- }
- }
-} else {
- audio = document.createElement("audio");
-
- if (audio.mozSetup) {
- debug("Using Mozilla Audio API");
- audio.mozSetup(1, 16000);
- io.floatAudio(16000);
- audioMoz = true;
- } else {
- audio2 = document.createElement("audio");
- }
-}
-
-function playSample() {
- // [audio,audio2] = [audio2,audio];
-
- var sample = io.getSample();
-
- if (audioMoz) {
- audio.mozWriteAudio(sample);
- return;
- }
-
- var tmp = audio;
- audio = audio2;
- audio2 = tmp;
-
- if (sample && sample.length) {
- var len = sample.length,
- buf = sample.join(""),
- o1 = percentEncode([(len + 36) & 0xff, (len + 36) >> 8]),
- o2 = percentEncode([len & 0xff, len >> 8]),
- header = wavHeaderStr.replace("%44%03",o1).replace("%20%03", o2);
-
- audio.src = "data:audio/x-wav," + header + buf;
- // debug(audio.src);
- audio.play();
- }
-}
+/* Audio Handling */
+initAudio();
function updateSound()
{
- var sound = $("#enable_sound").attr("checked");
- if (audioAPI) {
- if (sound) {
- audioNode.connect(audioContext.destination);
- } else {
- audioNode.disconnect();
- }
- } else {
- if (sound) {
- if (audio) audio.volume = 0.5;
- if (audio2) audio2.volume = 0.5;
- } else {
- io.getSample(false);
- }
- }
+ enableSound($("#enable_sound").attr("checked"));
}
function dumpDisk(drive) {
@@ -477,7 +375,7 @@ function run(pc) {
running = false;
vm.blit();
if (now - lastSample >= 200) {
- if (!audioAPI && sound) {
+ if (!audioAPI) {
playSample();
}
lastSample = now;
diff --git a/js/disk2.js b/js/disk2.js
index f92e74b..f037472 100644
--- a/js/disk2.js
+++ b/js/disk2.js
@@ -725,7 +725,7 @@ function DiskII(io, callbacks, slot)
if (fmt === "2mg") {
// Standard header size is 64 bytes. Make assumptions.
var prefix = new Uint8Array(data.slice(0, 64));
- var data = data.slice(64);
+ data = data.slice(64);
// Check image format.
// Sure, it's really 64 bits. But only 2 are actually used.
diff --git a/js/ui/Makefile b/js/ui/Makefile
index 04779d2..bedfe49 100644
--- a/js/ui/Makefile
+++ b/js/ui/Makefile
@@ -1,8 +1,8 @@
JSLINT = jshint
-JSFILES = copyright.js keyboard2.js printer.js
+JSFILES = copyright.js audio.js keyboard2.js gamepad.js printer.js
-JSFILES2E = copyright.js keyboard2e.js printer.js
+JSFILES2E = copyright.js audio.js keyboard2e.js gamepad.js printer.js
ALLJS = ${JSFILES} ${JSFILES2E}
CHECKEDJS := $(patsubst %.js,.checked-%.js,${ALLJS})
diff --git a/js/ui/audio.js b/js/ui/audio.js
new file mode 100644
index 0000000..2bfabfc
--- /dev/null
+++ b/js/ui/audio.js
@@ -0,0 +1,135 @@
+/* -*- mode: JavaScript; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* Copyright 2010-2014 Will Scullin
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+/*jshint jquery: true, browser: true */
+/*globals io: false, toHex:false, debug: false */
+/*exported playSample, enableSound, initAudio */
+
+/*
+ * Audio Handling
+ */
+
+var sound = true;
+
+// 8000 = 0x1f40 = 64, 31
+// 16000 = 0x3e80 = 128, 62
+
+var wavHeader =
+ ['R','I','F','F',68 ,3 ,0 ,0 ,'W','A','V','E','f','m','t',' ',
+ 16 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,128,62 ,0 ,0 ,128,62 ,0 ,0 ,
+ 1 ,0 ,8 ,0 ,'d','a','t','a',32 ,3 ,0 ,0 ];
+
+function percentEncode(ary) {
+ var buf = "";
+ for (var idx = 0; idx < ary.length; idx++) {
+ buf += "%" + toHex(ary[idx]);
+ }
+ return buf;
+}
+
+wavHeader = $.map(wavHeader, function(n) {
+ return typeof(n) == "string" ? n.charCodeAt(0) : n;
+ });
+
+var wavHeaderStr = percentEncode(wavHeader);
+
+var audioAPI = false;
+var audioMoz = false;
+var audioContext;
+var audioNode;
+var audio, audio2;
+
+function initAudio() {
+ if (typeof window.webkitAudioContext != "undefined") {
+ debug("Using Web Audio API");
+
+ audioAPI = true;
+ audioContext = new window.webkitAudioContext();
+ audioNode = audioContext.createScriptProcessor(2048, 1, 1);
+ io.floatAudio(audioContext.sampleRate);
+
+ audioNode.onaudioprocess = function(event) {
+ var data = event.outputBuffer.getChannelData(0);
+ var sample = io.getSample();
+ for (var idx = 0; idx < data.length; idx++) {
+ if (idx < sample.length) {
+ data[idx] = sample[idx];
+ } else {
+ data[idx] = 0;
+ }
+ }
+ };
+ } else {
+ audio = document.createElement("audio");
+
+ if (audio.mozSetup) {
+ debug("Using Mozilla Audio API");
+ audio.mozSetup(1, 16000);
+ io.floatAudio(16000);
+ audioMoz = true;
+ } else {
+ audio2 = document.createElement("audio");
+ }
+ }
+}
+
+function playSample() {
+ // [audio,audio2] = [audio2,audio];
+
+ var sample = io.getSample();
+
+ if (!sound) {
+ return;
+ }
+
+ if (audioMoz) {
+ audio.mozWriteAudio(sample);
+ return;
+ }
+
+ var tmp = audio;
+ audio = audio2;
+ audio2 = tmp;
+
+ if (sample && sample.length) {
+ var len = sample.length,
+ buf = sample.join(""),
+ o1 = percentEncode([(len + 36) & 0xff, (len + 36) >> 8]),
+ o2 = percentEncode([len & 0xff, len >> 8]),
+ header = wavHeaderStr.replace("%44%03",o1).replace("%20%03", o2);
+
+ audio.src = "data:audio/x-wav," + header + buf;
+ // debug(audio.src);
+ audio.play();
+ }
+}
+
+function enableSound(on)
+{
+ sound = on;
+
+ if (audioAPI) {
+ if (sound) {
+ audioNode.connect(audioContext.destination);
+ } else {
+ audioNode.disconnect();
+ }
+ } else {
+ if (sound) {
+ if (audio) audio.volume = 0.5;
+ if (audio2) audio2.volume = 0.5;
+ } else {
+ io.getSample(true);
+ }
+ }
+}
+