var sampleRate = 44100;
var clockRate = 1750000;
var frameRate = 48.828;

var isrCounter = 0;

var isPlay = 0;

updateState = function(renderer, r) {
    renderer.setTone(0, (r[1] << 8) | r[0]);
    renderer.setTone(1, (r[3] << 8) | r[2]);
    renderer.setTone(2, (r[5] << 8) | r[4]);
    renderer.setNoise(r[6]);
    renderer.setMixer(0, r[7] & 1, (r[7] >> 3) & 1, r[8] >> 4);
    renderer.setMixer(1, (r[7] >> 1) & 1, (r[7] >> 4) & 1, r[9] >> 4);
    renderer.setMixer(2, (r[7] >> 2) & 1, (r[7] >> 5) & 1, r[10] >> 4);
    renderer.setVolume(0, r[8] & 0xf);
    renderer.setVolume(1, r[9] & 0xf);
    renderer.setVolume(2, r[10] & 0xf);
    renderer.setEnvelope((r[12] << 8) | r[11]);
    if (r[13] != 255) {
        renderer.setEnvelopeShape(r[13]);
    }
}
var regs = [];
var currReg13 = 0;
fillBuffer = function(e) {
    var isrStep = frameRate / sampleRate;
    var left = e.outputBuffer.getChannelData(0);
    var right = e.outputBuffer.getChannelData(1);
    for(var i = 0; i < left.length; i++) {
        isrCounter += isrStep;
        if(isrCounter >= 1) {
            isrCounter--;
            
            if (isPlay) {
                var nextRegs = fnPlayGetRegs();
                for (var r = 0; r < 13; r++) {
                    regs[r] = nextRegs[r];
                }
                if (currReg13 != nextRegs[13]) {
                    regs[13] = nextRegs[13];
                    currReg13 = nextRegs[13];
                } else {
                    regs[13] = 255;
                }                    
            }
            updateState(ayumi, regs);
        }
        ayumi.process();
        ayumi.removeDC();
        left[i] = ayumi.left;
        right[i] = ayumi.right;
    }
    return true;
}

function aymPlayer () {
    this.initialize();
}

aymPlayer.prototype.initialize = function() {
}
aymPlayer.prototype.play = function() {
    isPlay = true;
}
aymPlayer.prototype.stop = function() {
    isPlay = false;
    for(var r = 0; r < 14; r++) {
        regs[r] = 0;
    }
    updateState(ayumi, regs);
    currReg13 = 0;
}
