public void RenderFrame() { _FrameCounter++; if (buffer == null | buffer.Disposed) { IsRendering = false; return; } IsRendering = true; W_Pos = 0; var Seq = _PAL ? _FrameCounter % 5 : _FrameCounter % 4; #region Update channels depending on Seq tick. if (Seq == 0 | Seq == 2) { _Chn_REC1.UpdateEnvelope(); _Chn_REC1.UpdateEnvelope(); _Chn_REC1.UpdateSweep(); _Chn_REC2.UpdateEnvelope(); _Chn_REC2.UpdateEnvelope(); _Chn_REC2.UpdateSweep(); _Chn_NOZ.UpdateEnvelope(); _Chn_NOZ.UpdateEnvelope(); _Chn_NOZ.UpdateLengthCounter(); _Chn_TRL.UpdateEnvelope(); _Chn_TRL.UpdateEnvelope(); } else if (Seq == 1 | Seq == 3) { _Chn_REC1.UpdateEnvelope(); _Chn_REC1.UpdateEnvelope(); _Chn_REC1.UpdateSweep(); _Chn_REC1.UpdateLengthCounter(); _Chn_REC2.UpdateEnvelope(); _Chn_REC2.UpdateEnvelope(); _Chn_REC2.UpdateSweep(); _Chn_REC2.UpdateLengthCounter(); _Chn_NOZ.UpdateEnvelope(); _Chn_NOZ.UpdateEnvelope(); _Chn_TRL.UpdateEnvelope(); _Chn_TRL.UpdateEnvelope(); _Chn_TRL.UpdateLengthCounter(); if (Seq == 3) { if (FrameIRQEnabled) { FrameIRQPending = true; _engine.Cpu.IRQNextTime = true; } } } #endregion #region Write the buffer W_Pos = buffer.CurrentWritePosition; if (_FirstRender) { _FirstRender = false; D_Pos = buffer.CurrentWritePosition + (STEREO ? 0x2000 : 0x1000); L_Pos = buffer.CurrentWritePosition; } var po = W_Pos - L_Pos; if (po < 0) { po = (BufferSize - L_Pos) + W_Pos; } if (po != 0) { for (var i = 0; i < po; i += AD) { short OUT = 0; #region Mix !! if (_Enabled_REC1) { OUT += _Chn_REC1.RenderSample(); } if (_Enabled_REC2) { OUT += _Chn_REC2.RenderSample(); } if (_Enabled_NOZ) { OUT += _Chn_NOZ.RenderSample(); } if (_Enabled_TRL) { OUT += _Chn_TRL.RenderSample(); } if (_Enabled_DMC) { OUT += _Chn_DMC.RenderSample(); } if (_Enabled_VRC6Pulse1) { OUT += _Chn_VRC6Pulse1.RenderSample(); } if (_Enabled_VRC6Pulse2) { OUT += _Chn_VRC6Pulse2.RenderSample(); } if (_Enabled_VRC6SawTooth) { OUT += _Chn_VRC6Sawtooth.RenderSample(); } //Level up OUT *= 2; //Limit if needed to avoid overflow if (OUT > 110) { OUT = 110; } else if (OUT < -110) { OUT = -110; } //RECORD if (RECODER.IsRecording) { RECODER.AddSample(OUT); } #endregion if (D_Pos < DATA.Length) { DATA[D_Pos] = (byte)((OUT & 0xFF00) >> 8); DATA[D_Pos + 1] = (byte)(OUT & 0xFF); if (STEREO) //Add the same sample to the left channel { DATA[D_Pos + 2] = (byte)((OUT & 0xFF00) >> 8); DATA[D_Pos + 3] = (byte)(OUT & 0xFF); } } D_Pos += AD; D_Pos = D_Pos % BufferSize; } buffer.Write(DATA, 0, LockFlags.None); L_Pos = W_Pos; } IsRendering = false; #endregion }