fixed NES audio; use setTimeout for animation loop; famitracker

This commit is contained in:
Steven Hugg 2018-08-16 10:13:09 -04:00
parent 14442e9201
commit 9589f401ff
7 changed files with 2657 additions and 34 deletions

1242
presets/nes/famitone2.asm Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

1179
presets/nes/musicdemo.asm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -391,10 +391,10 @@ void draw_next_row() {
#define FLIPXY 0xc0
const byte DIR_TO_CODE[32] = {
0, 1, 2, 3, 4, 5, 6, 6,
6|FLIPY, 6|FLIPY, 5|FLIPY, 4|FLIPY, 3|FLIPY, 2|FLIPY, 1|FLIPY, 0|FLIPY,
0|FLIPXY, 1|FLIPXY, 2|FLIPXY, 3|FLIPXY, 4|FLIPXY, 5|FLIPXY, 6|FLIPXY, 6|FLIPXY,
6|FLIPX, 6|FLIPX, 5|FLIPX, 4|FLIPX, 3|FLIPX, 2|FLIPX, 1|FLIPX, 0|FLIPX,
0, 1, 2, 3, 4, 5, 6, 6,
6|FLIPY, 6|FLIPY, 5|FLIPY, 4|FLIPY, 3|FLIPY, 2|FLIPY, 1|FLIPY, 0|FLIPY,
};
const byte SINTBL[32] = {

View File

@ -299,7 +299,7 @@ var SampleAudio = function(clockfreq) {
}
self.context = new AudioContext();
self.sr=self.context.sampleRate;
self.bufferlen=(self.sr > 44100) ? 4096 : 2048;
self.bufferlen=2048;
// Amiga 500 fixed filter at 6kHz. WebAudio lowpass is 12dB/oct, whereas
// older Amigas had a 6dB/oct filter at 4900Hz.
@ -361,9 +361,9 @@ var SampleAudio = function(clockfreq) {
bufpos = 0;
bufferlist[ifill] = buffer;
var inext = (ifill + 1) % bufferlist.length;
//if (inext != idrain) ifill = inext;
if (inext == idrain) {
ifill = (idrain + bufferlist.length/2) % bufferlist.length;
ifill = Math.floor(idrain + nbuffers/2) % bufferlist.length;
//console.log('audio skipped', idrain, ifill);
} else {
ifill = inext;
}
@ -375,7 +375,7 @@ var SampleAudio = function(clockfreq) {
while (count-- > 0) {
accum += value;
sfrac += sinc;
if (sfrac >= 1) {
while (sfrac >= 1) {
sfrac -= 1;
value *= sfrac;
this.addSingleSample(accum - value);

View File

@ -216,21 +216,27 @@ var AnimationTimer = function(frequencyHz:number, callback:() => void) {
var intervalMsec = 1000.0 / frequencyHz;
var running;
var lastts = 0;
var useReqAnimFrame = window.requestAnimationFrame ? (frequencyHz>40) : false;
var useReqAnimFrame = false; //window.requestAnimationFrame ? (frequencyHz>40) : false;
var nframes, startts; // for FPS calc
this.frameRate = frequencyHz;
function scheduleFrame() {
function scheduleFrame(msec:number) {
if (useReqAnimFrame)
window.requestAnimationFrame(nextFrame);
else
setTimeout(nextFrame, intervalMsec);
setTimeout(nextFrame, msec);
}
function nextFrame(ts) {
if (running) {
scheduleFrame();
function nextFrame(ts:number) {
if (!ts) ts = Date.now();
if (ts - lastts < intervalMsec*10) {
lastts += intervalMsec;
} else {
lastts = ts + intervalMsec; // frames skipped, catch up
}
if (!useReqAnimFrame || ts - lastts > intervalMsec/2) {
if (running) {
scheduleFrame(lastts - ts);
}
if (!useReqAnimFrame || lastts - ts > intervalMsec/2) {
if (running) {
try {
callback();
@ -239,11 +245,6 @@ var AnimationTimer = function(frequencyHz:number, callback:() => void) {
throw e;
}
}
if (ts - lastts < intervalMsec*30) {
lastts += intervalMsec;
} else {
lastts = ts;
}
if (nframes == 0) startts = ts;
if (nframes++ == 300) {
console.log("Avg framerate: " + nframes*1000/(ts-startts) + " fps");
@ -258,7 +259,7 @@ var AnimationTimer = function(frequencyHz:number, callback:() => void) {
running = true;
lastts = 0;
nframes = 0;
scheduleFrame();
scheduleFrame(0);
}
}
this.stop = function() {

View File

@ -12,6 +12,7 @@ var JSNES_PRESETS = [
{id:'neslib4.c', name:'Metasprites'},
{id:'neslib5.c', name:'RLE Unpack'},
{id:'music.c', name:'Music Player'},
{id:'musicdemo.asm', name:'Famitone Demo'},
{id:'siegegame.c', name:'Siege Game'},
{id:'shoot2.c', name:'Solarian Game'},
];
@ -61,8 +62,9 @@ var JSNESPlatform = function(mainElement) {
var nes;
var rom;
var video, audio, timer;
var audioFrequency = 44100;
var audioFrequency = 44030; //44100
var frameindex = 0;
var nsamples = 0;
this.getPresets = function() { return JSNES_PRESETS; }
@ -78,17 +80,19 @@ var JSNESPlatform = function(mainElement) {
video.updateFrame();
self.restartDebugState();
frameindex++;
//if (frameindex == 2000) console.log(nsamples*60/frameindex,'Hz');
},
onAudioSample: function(left, right) {
if (frameindex < 10)
audio.feedSample(0, 1); // avoid popping at powerup
else
audio.feedSample(left+right, 1);
//nsamples++;
},
onStatusUpdate: function(s) {
console.log(s);
},
//onBatteryRamWrite
//TODO: onBatteryRamWrite
});
nes.stop = function() {
// TODO: trigger breakpoint