RenderSample() public method

public RenderSample ( ) : short
return short
コード例 #1
0
ファイル: Apu.cs プロジェクト: afonsof/nes-hd
        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
        }