[ create a new paste ] login | about

Link: http://codepad.org/7U4OhpcD    [ raw code | fork ]

C++, pasted on Jul 17:
#ifndef SCHPUNE_VRC7AUDIO_H_INCLUDED
#define SCHPUNE_VRC7AUDIO_H_INCLUDED

namespace schpune
{

class AudioBuilder;

class Vrc7Audio
{
public:
    void            Reset(bool hard);
    void            Write( uint16_t a, uint8_t v );
    void            Run( AudioBuilder& builder, int sampleoffset, int ticks );

private:
    uint8_t         mAddr;
    uint8_t         mInstData[0x80];

    enum Adsr
    {
        Idle        = 0,
        Attack,
        Decay,
        Sustain,
        Release
    };

    class AmUnit
    {
    public:
        void            Reset(bool hard);
        void            Clock();
        uint32_t        Output()        { return mOut;  }

    private:
        uint32_t        mPhase;
        uint32_t        mOut;
    };
    
    class FmUnit
    {
    public:
        void            Reset(bool hard);
        void            Clock();
        double          Output()        { return mOut;  }

    private:
        uint32_t        mPhase;
        double          mOut;
    };

    class Slot
    {
    public:
        void            Reset(bool hard,int iscarrier, const uint8_t* instdata, AmUnit* am, FmUnit* fm);
        void            Write(uint8_t a, uint8_t v);
        int             Clock(uint32_t mod);
        void            RefreshInstZero();

    private:
        // helper function
        void            RefreshInst();
        void            UpdateFreqRate();
        void            RecalcKeyScale();
        uint32_t        ClockEnvelope();
        int             DoClock(uint32_t mod);
        void            KeyOn();
        void            KeyOff();
        void            SetInstrument(int inst);

        // slot type
        int             mSlotIndex;     // 0=Modulator, 1=Carrier

        // instrument data
        const uint8_t*  mRawInstData;
        uint8_t         mInstData[8];

        // am/fm units
        AmUnit*         mAm;
        FmUnit*         mFm;

        // phase generator
        int             mFNum;          // 9-bit F number
        int             mBlock;         // 3-bit block (octave)
        int             mFreqRate;      // value to add to phase counter (based on FNum,block,Multi)
        uint32_t        mPhase;         // phase counter
        int             mRectify;       // 0 if half-sine, -1 if full sine
        int             mFeedback;      // Feedback value as written to reg (0 = no feedback)

        // envelope generator
        int             mSustainBit;    // nonzero if sustain bit in channel is set (reg $2x.5)
        uint32_t        mLevelAtten;    // Base attenuation level (TL or volume)
        uint32_t        mKslAtten;      // attenuation level (KSL)
        int             mVolume;        // Volume (bits as written to $3x, << 2) - only used on Carrier
        Adsr            mAdsr;          // ADSR mode
        uint32_t        mEnvPhase;      // envelope phase counter  (rate = adsr rate)

        uint32_t        mRate_Attack;   // Attack rate
        uint32_t        mRate_Decay;    // Decay rate
        uint32_t        mRate_Sustain;  // Sustain rate
        uint32_t        mRate_Release;  // Release rate
        uint32_t        mSustainLevel;  // Sustain Level

        // previous output
        int             mFeedbackOutput;
        int             mOutput[2];
    };

    class Channel
    {
    public:
        void            Reset(bool hard, const uint8_t* instdata, AmUnit* am, FmUnit* fm);
        void            Write(int a,uint8_t v);
        void            RefreshInstZero();
        int             Clock();

    private:
        Slot            mCar;
        Slot            mMod;
    };
    
    AmUnit          mAmUnit;
    FmUnit          mFmUnit;
    int             mTicksToNextClock;
    int             mPrevOut;
    Channel         mChannel[6];
};

} // schpune

#endif //  SCHPUNE_VRC7AUDIO_H_INCLUDED


Create a new paste based on this one


Comments: