public string GeffeGenerator(int len) { string result = ""; for (int i = 0; i < len; i++) { bool reg1 = lfsr1.Shift(); bool reg2 = lfsr2.Shift(); bool reg3 = lfsr3.Shift(); bool bit = (reg1 & reg2) ^ (!reg2 & reg3); result += bit ? "1" : "0"; } return(result); }
////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// public void Update() { // called @ 512Hz m_tick++; byte b = 0; double curTime = m_curTime; byte nr41 = GameBoy.Ram.ReadByteAt(m_nrx1Adr); byte nr42 = GameBoy.Ram.ReadByteAt(m_nrx2Adr); byte nr43 = GameBoy.Ram.ReadByteAt(m_nrx3Adr); byte nr44 = GameBoy.Ram.ReadByteAt(m_nrx4Adr); b = GameBoy.Ram.ReadByteAt(m_nrx4Adr); if ((b & 0x80) != 0) { m_isConsecutive = (nr44 & 0x40) == 0; m_curTime = 0; m_enveloppeClockCnt = 0; m_initialVol = (nr42 & 0xF0) >> 4; m_curVol = m_initialVol; UpdateNR52Flag(true); b &= 0x7F; GameBoy.Ram.WriteByte(m_nrx4Adr, b); } //length is update at 256Hz (2 cycles) if (m_tick % 2 == 0) { m_lengthSec = nr41 & 0x3F; m_lengthSec = (64.0 - m_lengthSec) * (1.0 / 256.0); m_remainingTime = m_lengthSec - m_curTime; m_polynomialShiftClockFrequency = (nr43 & 0xF0) >> 4; m_polynomialCounterStep = (nr43 & 0x08) >> 3; m_polynomialDividerRatio = (nr43 & 0x03); } //enveloppe is updated at 64Hz (8 cycles) if (m_tick % 8 == 0) { m_enveloppeClockCnt++; m_bAttenuate = (nr42 & 0x8) == 0; m_numberVolumeSweep = (nr42 & 0x7); m_volLeft = (float)GetCurrentVol(curTime, eChannel.eChannel_Left); m_volRight = (float)GetCurrentVol(curTime, eChannel.eChannel_Right); } int divider = 0; switch (m_polynomialDividerRatio) { case 0: { divider = 8 / 8; break; } case 1: { divider = 16 / 8; break; } case 2: { divider = 32 / 8; break; } case 3: { divider = 48 / 8; break; } case 4: { divider = 64 / 8; break; } case 5: { divider = 80 / 8; break; } case 6: { divider = 96 / 8; break; } case 7: { divider = 112 / 8; break; } default: { divider = 0; break; } } if (m_tick % divider == 0) { m_Lfsr.Shift(); } double duration = 1.0 / 512.0; int nbSamplesToFill = (int)(duration * WaveFormat.SampleRate * 2); double dt = duration / (nbSamplesToFill / 2); int bufferPos = m_bufferWritingPos; float f = 0.0f; for (int n = 0; n < nbSamplesToFill; n += 2) { if (m_isConsecutive || curTime < m_lengthSec) { f = GetLfsrValue(); } else { f = 0.0f; UpdateNR52Flag(false); } m_buffer[bufferPos] = m_volLeft * f * MAX_AMPLITUDE; //m_wr.WriteSample(m_volLeft * frequency); bufferPos++; if (bufferPos >= m_buffer.Length) { bufferPos = 0; } m_buffer[bufferPos] = m_volRight * f * MAX_AMPLITUDE; //m_wr.WriteSample(m_volRight * frequency); bufferPos++; if (bufferPos >= m_buffer.Length) { bufferPos = 0; } curTime += dt; } m_bufferWritingPos += nbSamplesToFill; m_bufferWritingPos %= m_buffer.Length; m_curTime += duration; //m_wr.Flush(); }