#ifndef __ASFXDSP_H #define __ASFXDSP_H #include "../../../src/fmod_settings.h" #include "../../../src/fmod_types.h" #include struct DspValues { short reinitialize; // 0 means in progress. 1 means settings have changed, start over }; struct coeff2ndorder { float a0, a1, a2, b1, b2; }; #define kNumLateReverbDelays 8 // Only feed the first 8 or so late reverb inputs at first? #define kNumMatrixStages 3 // 2 ^ kNumMatrixStages should equal kNumLateReverbDelays #define kNumEarly_EarlyLateDelayTaps 1 #define kNumLate_EarlyLateDelayTaps 8 // Should equal kNumLateReverbDelays #define kNumEarlyLateDelayTaps (kNumEarly_EarlyLateDelayTaps + kNumLate_EarlyLateDelayTaps) #define kNumEarlyDelayTaps 7 #define kNumAllpassDelays 2 #define kSFXREVERB_MAXCHANNELS 8 #define kEarlyLateDelayLen 65536 // Delete #define kEarlyDelayLenSamples 16384 // Delete #define kAllpassLengthSamples 2048 // Delete // Main late delays #define LOWEST_DELAY_LINE_LENGTH_SEC (0.061f) #define DELAY_LINE_RATIO (1.32f) #define LOWEST_DELAY_LINE_LENGTH_B_SEC (0.0015f) #define DELAY_LINE_RATIO_B (1.47f) // Allpass delays #define kAllpassDelayLenSec0 (0.0059f) #define kAllpassDelayLenSec1 (0.0077f) // EarlyLate delays #define kEarlyLateNextLengthSec (0.0187f) #define kEarlyLateDelayRatio (1.29f) // Early delays #define kEarlyFirstDelaySec (0.005f) #define kEarlyDelayRatio (1.59f) // Error codes #define REVERB_ALLPASS_ALLOCATION_ERR 4500 #define REVERB_EARLYLATE_ALLOCATION_ERR 4501 #define REVERB_EARLY_ALLOCATION_ERR 4502 #define REVERB_LATE_ALLOCATION_ERR 4503 #define REVERB_PARAMETER_ERROR 4504 #define REVERB_INBUFF_ALLOCATION_ERR 4505 namespace FMOD { class SystemI; } class ASfxDsp { public: int init(float rate); void close(); int UpdateBufferSize(int newMaxBlockSize); // possibly reallocate mInBuff buffers to new MaxBlockSize void ClearBuffers(); // zero the audio buffers void ClearInBuff(); void ClearReverbInternalBuffers(); int AllocateEarlyLateDelay(float *delaySec, float sampleRate); int AllocateAllpassDelays(int numDelays, float *delaySec, float sampleRate); int AllocateEarlyDelay(float delaySec, float sampleRate); int AllocateLateDelays(int numDelays, float *delaySec, float sampleRate); int NextPowerOf2(int delaySamples); void DoDSPProcessing (float *inAudio, float *outAudio, int channels, unsigned int sampleframes, float rate, float drymix, unsigned short speakermask); void BlockProcessInput(unsigned int sampframes, int channels, float *inAudio, float rate); public: void SetAllpassDelays(float rate); void SetLate_EarlyLateDelayTaps(float refPlusRevDelaySec, float nextLengthSec, float delayRatio, float rate); void SetEarlyDelay(float nextLengthSec, float delayRatio, float rate); void SetLateDelays(float nextLengthSec, float delayRatio, float nextLengthBSec, float delayRatioB, float rate); void DeallocateLateDelays(); void DeallocateAllpassDelays(); void DeallocateEarlyLateDelay(); void DeallocateEarlyDelay(); void ZeroWritePointers(); #if defined(PLATFORM_PS3) //|| defined(PLATFORM_WINDOWS_PS3MODE) float mInBuffMemory[256 + 4]; /* +4 = 16bytes extra for alignment */ #else float *mInBuffMemory; #endif float *mInBuff; int mNumAllocatedInBuffSamples; // the number of samples per mInBuff currently allocated // (varies according to MaxBlockSize) #if defined(PLATFORM_PS3) //|| defined(PLATFORM_WINDOWS_PS3MODE) float FMOD_PPCALIGN16(mTempbuff[(9*256) + 4]); // 8k #endif FMOD::SystemI *mSystem; float mRoomHF; bool mRoomHFChanged; float mLatchRoomHF; // Latch it for safety float mPrevRoomHF; // For our interpolation float mOldRoomHF; // For next time float mzRoomHF0, mzRoomHF1; struct coeff2ndorder mRoomLFcoeffs; float mRoomLF; float mzRoomLF0, mzRoomLF1; float FMOD_PPCALIGN16(mDecayHF[kNumLateReverbDelays]); bool FMOD_PPCALIGN16(mDecayHFChanged[kNumLateReverbDelays]); float FMOD_PPCALIGN16(mLatchDecayHF[kNumLateReverbDelays]); // Latch it for safety. float FMOD_PPCALIGN16(mLatchOneMinusDecayHF[kNumLateReverbDelays]); float FMOD_PPCALIGN16(mPrevDecayHF[kNumLateReverbDelays]); // Latch previous one float FMOD_PPCALIGN16(mOldDecayHF[kNumLateReverbDelays]); // Save current one for next time... float FMOD_PPCALIGN16(mMatrixMem[kNumMatrixStages * kNumLateReverbDelays + 16]); float FMOD_PPCALIGN16(mzDecayHFMem[kNumLateReverbDelays + 16]); float *FMOD_PPCALIGN16(mzDecayHF); float *FMOD_PPCALIGN16(mMatrix); float FMOD_PPCALIGN16(mFeedback[kNumLateReverbDelays]); float FMOD_PPCALIGN16(mLatchFeedback[kNumLateReverbDelays]); // Latch it for safety float FMOD_PPCALIGN16(mOldFeedback[kNumLateReverbDelays]); // Save for next buffer float FMOD_PPCALIGN16(mPrevFeedback[kNumLateReverbDelays]); // Use previous value for crossfade float mHadamard; bool mHadamardChanged; float mLatchHadamard; // Latch it for safety float mPrevHadamard; // For our interpolation float mOldHadamard; // For next time float mERgain, mLRgain; bool mLRgainChanged; float mLatchLRgain; // Latch it for safety float mPrevLRgain; // For our interpolation float mOldLRgain; // For next time bool mERgainChanged; float mLatchERgain; // Latch it for safety float mPrevERgain; // For our interpolation float mOldERgain; // For next time float mDiffusionScale; bool mDiffusionScaleChanged; float mLatchDiffusionScale; // Latch it for safety float mPrevDiffusionScale; // For our interpolation float mOldDiffusionScale; // For next time float mAllpassGain; int mNumLateReverbDelays; // Late delays #if defined(PLATFORM_PS3) //|| defined(PLATFORM_WINDOWS_PS3MODE) float *FMOD_PPCALIGN16(mLateDelaysMemory[kNumLateReverbDelays]); #endif float *FMOD_PPCALIGN16(mLateDelays[kNumLateReverbDelays]); // Array of delay lines float FMOD_PPCALIGN16(mLateDelayLenSec[kNumLateReverbDelays]); // Seconds int FMOD_PPCALIGN16(mLateDelayLenSamples[kNumLateReverbDelays]); // Samples used int FMOD_PPCALIGN16(mOldLateDelayLenSamples[kNumLateReverbDelays]); int FMOD_PPCALIGN16(mLateDelayLenBSamples[kNumLateReverbDelays]); // Samples used int FMOD_PPCALIGN16(mLateDelaySamplesAllocated[kNumLateReverbDelays]); // Samples allocated bool FMOD_PPCALIGN16(mLateChanged[kNumLateReverbDelays]); // Either the delay lengths or mFeedback changed int FMOD_PPCALIGN16(mLateMask[kNumLateReverbDelays]); int FMOD_PPCALIGN16(mLateWritePointer[kNumLateReverbDelays]); int FMOD_PPCALIGN16(mLateReadPointer[kNumLateReverbDelays]); int FMOD_PPCALIGN16(mOldLateReadPointer[kNumLateReverbDelays]); int FMOD_PPCALIGN16(mLateReadPointerB[kNumLateReverbDelays]); // Short (~10 ms) reads to avoid cancellations // EarlyLate delay float *FMOD_PPCALIGN16(mEarlyLateDelay); float *FMOD_PPCALIGN16(mEarlyLateDelayMemory); float FMOD_PPCALIGN16(mEarlyLateSec[kNumEarlyLateDelayTaps]); int FMOD_PPCALIGN16(mEarlyLateSamples[kNumEarlyLateDelayTaps]); int FMOD_PPCALIGN16(mOldEarlyLateSamples[kNumEarlyLateDelayTaps]); bool FMOD_PPCALIGN16(mEarlyLateChanged[kNumEarlyLateDelayTaps]); int FMOD_PPCALIGN16(mEarlyLateSamplesAllocated); int FMOD_PPCALIGN16(mEarlyLateMask); int FMOD_PPCALIGN16(mEarlyLateWritePointer); int FMOD_PPCALIGN16(mEarlyLateReadPointer[kNumEarlyLateDelayTaps]); int FMOD_PPCALIGN16(mOldEarlyLateReadPointer[kNumEarlyLateDelayTaps]); // Early delay #if defined(PLATFORM_PS3) //|| defined(PLATFORM_WINDOWS_PS3MODE) float FMOD_PPCALIGN16(mEarlyDelay[4096]); #else float *mEarlyDelay; #endif float FMOD_PPCALIGN16(mEarlyDelayLenSec[kNumEarlyDelayTaps]); int FMOD_PPCALIGN16(mEarlyDelayLenSamples[kNumEarlyDelayTaps]); int FMOD_PPCALIGN16(mEarlyDelaySamplesAllocated); int FMOD_PPCALIGN16(mEarlyMask); int FMOD_PPCALIGN16(mEarlyWritePointer); int FMOD_PPCALIGN16(mEarlyReadPointer[kNumEarlyDelayTaps]); // Allpass delays #if defined(PLATFORM_PS3) //|| defined(PLATFORM_WINDOWS_PS3MODE) float FMOD_PPCALIGN16(mAllpassDelays[kNumAllpassDelays][512]); #else float *mAllpassDelays[kNumAllpassDelays]; #endif float FMOD_PPCALIGN16(mAllpassDelayLenSec[kNumAllpassDelays]); int FMOD_PPCALIGN16(mAllpassDelayLenSamples[kNumAllpassDelays]); int FMOD_PPCALIGN16(mAllpassSamplesAllocated[kNumAllpassDelays]); int FMOD_PPCALIGN16(mAllpassMask[kNumAllpassDelays]); int FMOD_PPCALIGN16(mAllpassWritePointer[kNumAllpassDelays]); int FMOD_PPCALIGN16(mAllpassReadPointer[kNumAllpassDelays]); int mNumMatrixStages; }; #endif // __ASFXDSP_H