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
}