refactor(fmod): move all original files into fmod directory
This commit is contained in:
parent
50fb3c6b1c
commit
35569faecc
544 changed files with 0 additions and 0 deletions
218
fmod/lib/sfx/foreverb/3dl2.h
Executable file
218
fmod/lib/sfx/foreverb/3dl2.h
Executable file
|
|
@ -0,0 +1,218 @@
|
|||
// 3DL2.H
|
||||
//
|
||||
|
||||
// #ifndef 3DL2_H_INCLUDED
|
||||
// #define 3DL2_H_INCLUDED
|
||||
|
||||
#ifndef __3DL2_H
|
||||
#define __3DL2_H
|
||||
|
||||
// #include <dsound.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/*
|
||||
#pragma pack(push, 4)
|
||||
|
||||
// I3DL2 listener property set {DA0F0520-300A-11D3-8A2B-0060970DB011}
|
||||
DEFINE_GUID(DSPROPSETID_I3DL2_ListenerProperties,
|
||||
0xDA0F0520,
|
||||
0x300A,
|
||||
0x11D3,
|
||||
0x8A2B,
|
||||
0x0060970DB011);
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_I3DL2LISTENER_ALL, // sets all I3DL2 listener properties
|
||||
DSPROPERTY_I3DL2LISTENER_ROOM, // room effect level at low frequencies
|
||||
DSPROPERTY_I3DL2LISTENER_ROOMHF, // room effect high-frequency level re. low frequency level
|
||||
DSPROPERTY_I3DL2LISTENER_ROOMROLLOFFFACTOR, // like DS3D flRolloffFactor but for room effect
|
||||
DSPROPERTY_I3DL2LISTENER_DECAYTIME, // reverberation decay time at low-frequencies
|
||||
DSPROPERTY_I3DL2LISTENER_DECAYHFRATIO, // high-frequency to low-frequency decay time ratio
|
||||
DSPROPERTY_I3DL2LISTENER_REFLECTIONS, // early reflections level relative to room effect
|
||||
DSPROPERTY_I3DL2LISTENER_REFLECTIONSDELAY, // delay time of first reflection
|
||||
DSPROPERTY_I3DL2LISTENER_REVERB, // late reverberation level relative to room effect
|
||||
DSPROPERTY_I3DL2LISTENER_REVERBDELAY, // late reverberation delay time relative to first reflection
|
||||
DSPROPERTY_I3DL2LISTENER_DIFFUSION, // reverberation diffusion (echo density)
|
||||
DSPROPERTY_I3DL2LISTENER_DENSITY, // reverberation density (modal density)
|
||||
DSPROPERTY_I3DL2LISTENER_HFREFERENCE // reference high frequency
|
||||
} DSPROPERTY_I3DL2_LISTENERPROPERTY;
|
||||
|
||||
// use this structure for DSPROPERTY_I3DL2LISTENER_ALL
|
||||
// - all levels are hundredths of decibels (mB)
|
||||
// - all times are in seconds (s)
|
||||
typedef struct _I3DL2_LISTENERPROPERTIES
|
||||
{
|
||||
long lRoom; // [-10000, 0] default: -10000 mB
|
||||
long lRoomHF; // [-10000, 0] default: 0 mB
|
||||
float flRoomRolloffFactor; // [0.0, 10.0] default: 0.0
|
||||
float flDecayTime; // [0.1, 20.0] default: 1.0 s
|
||||
float flDecayHFRatio; // [0.1, 2.0] default: 0.5
|
||||
long lReflections; // [-10000, 1000] default: -10000 mB
|
||||
float flReflectionsDelay; // [0.0, 0.3] default: 0.02 s
|
||||
long lReverb; // [-10000, 2000] default: -10000 mB
|
||||
float flReverbDelay; // [0.0, 0.1] default: 0.04 s
|
||||
float flDiffusion ; // [0.0, 100.0] default: 100.0 %
|
||||
float flDensity; // [0.0, 100.0] default: 100.0 %
|
||||
float flHFReference; // [20.0, 20000.0] default: 5000.0 Hz
|
||||
} I3DL2_LISTENERPROPERTIES, *LPI3DL2_LISTENERPROPERTIES;
|
||||
|
||||
// property ranges and defaults:
|
||||
|
||||
#define I3DL2LISTENER_MINROOM -10000
|
||||
#define I3DL2LISTENER_MAXROOM 0
|
||||
#define I3DL2LISTENER_DEFAULTROOM -10000
|
||||
|
||||
#define I3DL2LISTENER_MINROOMHF -10000
|
||||
#define I3DL2LISTENER_MAXROOMHF 0
|
||||
#define I3DL2LISTENER_DEFAULTROOMHF 0
|
||||
|
||||
#define I3DL2LISTENER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define I3DL2LISTENER_MAXROOMROLLOFFFACTOR 10.0f
|
||||
#define I3DL2LISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define I3DL2LISTENER_MINDECAYTIME 0.1f
|
||||
#define I3DL2LISTENER_MAXDECAYTIME 20.0f
|
||||
#define I3DL2LISTENER_DEFAULTDECAYTIME 1.0f
|
||||
|
||||
#define I3DL2LISTENER_MINDECAYHFRATIO 0.1f
|
||||
#define I3DL2LISTENER_MAXDECAYHFRATIO 2.0f
|
||||
#define I3DL2LISTENER_DEFAULTDECAYHFRATIO 0.5f
|
||||
|
||||
#define I3DL2LISTENER_MINREFLECTIONS -10000
|
||||
#define I3DL2LISTENER_MAXREFLECTIONS 1000
|
||||
#define I3DL2LISTENER_DEFAULTREFLECTIONS -10000
|
||||
|
||||
#define I3DL2LISTENER_MINREFLECTIONSDELAY 0.0f
|
||||
#define I3DL2LISTENER_MAXREFLECTIONSDELAY 0.3f
|
||||
#define I3DL2LISTENER_DEFAULTREFLECTIONSDELAY 0.02f
|
||||
|
||||
#define I3DL2LISTENER_MINREVERB -10000
|
||||
#define I3DL2LISTENER_MAXREVERB 2000
|
||||
#define I3DL2LISTENER_DEFAULTREVERB 0 // -10000
|
||||
|
||||
#define I3DL2LISTENER_MINREVERBDELAY 0.0f
|
||||
#define I3DL2LISTENER_MAXREVERBDELAY 0.1f
|
||||
#define I3DL2LISTENER_DEFAULTREVERBDELAY 0.04f
|
||||
|
||||
#define I3DL2LISTENER_MINDIFFUSION 0.0f
|
||||
#define I3DL2LISTENER_MAXDIFFUSION 100.0f
|
||||
#define I3DL2LISTENER_DEFAULTDIFFUSION 100.0f
|
||||
|
||||
#define I3DL2LISTENER_MINDENSITY 0.0f
|
||||
#define I3DL2LISTENER_MAXDENSITY 100.0f
|
||||
#define I3DL2LISTENER_DEFAULTDENSITY 100.0f
|
||||
|
||||
#define I3DL2LISTENER_MINHFREFERENCE 20.0f
|
||||
#define I3DL2LISTENER_MAXHFREFERENCE 20000.0f
|
||||
#define I3DL2LISTENER_DEFAULTHFREFERENCE 5000.0f
|
||||
|
||||
// I3DL2 buffer property set {DA0F0521-300A-11D3-8A2B-0060970DB011}
|
||||
/*
|
||||
DEFINE_GUID(DSPROPSETID_I3DL2_BufferProperties,
|
||||
0xDA0F0521,
|
||||
0x300A,
|
||||
0x11D3,
|
||||
0x8A2B,
|
||||
0x0060970DB011);
|
||||
*/
|
||||
|
||||
/*
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_I3DL2BUFFER_ALL, // sets all I3DL2 buffer properties
|
||||
DSPROPERTY_I3DL2BUFFER_OBSTRUCTIONALL, // sets both obstruction properties
|
||||
DSPROPERTY_I3DL2BUFFER_OCCLUSIONALL, // sets both occlusion properties
|
||||
DSPROPERTY_I3DL2BUFFER_DIRECT, // additional direct path level correction
|
||||
DSPROPERTY_I3DL2BUFFER_DIRECTHF, // additional direct path high-frequency re. low-frequency level correction
|
||||
DSPROPERTY_I3DL2BUFFER_ROOM, // additional room effect level correction
|
||||
DSPROPERTY_I3DL2BUFFER_ROOMHF, // additional room effect high-frequency re. low-frequency level correction
|
||||
DSPROPERTY_I3DL2BUFFER_ROOMROLLOFFFACTOR, // like DS3D flRolloffFactor but for room effect
|
||||
DSPROPERTY_I3DL2BUFFER_OBSTRUCTION, // main obstruction control (attenuation at high frequencies)
|
||||
DSPROPERTY_I3DL2BUFFER_OBSTRUCTIONLFRATIO, // obstruction low-frequency re. high-frequency ratio
|
||||
DSPROPERTY_I3DL2BUFFER_OCCLUSION, // main occlusion control (attenuation at high frequencies)
|
||||
DSPROPERTY_I3DL2BUFFER_OCCLUSIONLFRATIO // occlusion low-frequency re. high-frequency ratio
|
||||
} DSPROPERTY_I3DL2_BUFFERPROPERTY;
|
||||
*/
|
||||
|
||||
/*
|
||||
// use this structure for DSPROPERTY_I3DL2BUFFER_OBSTRUCTIONALL
|
||||
// - all levels are hundredths of decibels (mB)
|
||||
typedef struct _I3DL2_OBSTRUCTIONPROPERTIES
|
||||
{
|
||||
LONG lHFLevel; // [-10000, 0] default: 0 mB
|
||||
FLOAT flLFRatio; // [0.0, 1.0] default: 0.0
|
||||
} I3DL2_OBSTRUCTIONPROPERTIES, *LPI3DL2_OBSTRUCTIONPROPERTIES;
|
||||
|
||||
// use this structure for DSPROPERTY_I3DL2BUFFER_OCCLUSIONALL
|
||||
// - all levels are hundredths of decibels (mB)
|
||||
typedef struct _I3DL2_OCCLUSIONPROPERTIES
|
||||
{
|
||||
LONG lHFLevel; // [-10000, 0] default: 0 mB
|
||||
FLOAT flLFRatio; // [0.0, 1.0] default: 0.25
|
||||
} I3DL2_OCCLUSIONPROPERTIES, *LPI3DL2_OCCLUSIONPROPERTIES;
|
||||
|
||||
// use this structure for DSPROPERTY_I3DL2BUFFER_ALL
|
||||
// - all levels are hundredths of decibels (mB)
|
||||
typedef struct _I3DL2_BUFFERPROPERTIES
|
||||
{
|
||||
LONG lDirect; // [-10000, 1000] default: 0 mB
|
||||
LONG lDirectHF; // [-10000, 0] default: 0 mB
|
||||
LONG lRoom; // [-10000, 1000] default: 0 mB
|
||||
LONG lRoomHF; // [-10000, 0] default: 0 mB
|
||||
FLOAT flRoomRolloffFactor; // [0.0, 10.0] default: 0.0
|
||||
I3DL2BUFFER_OBSTRUCTIONPROPERTIES Obstruction;
|
||||
I3DL2BUFFER_OCCLUSIONPROPERTIES Occlusion;
|
||||
} I3DL2_BUFFERPROPERTIES, *LPI3DL2_BUFFERPROPERTIES;
|
||||
|
||||
// property ranges and defaults:
|
||||
|
||||
#define I3DL2BUFFER_MINDIRECT -10000
|
||||
#define I3DL2BUFFER_MAXDIRECT 1000
|
||||
#define I3DL2BUFFER_DEFAULTDIRECT 0
|
||||
|
||||
#define I3DL2BUFFER_MINDIRECTHF -10000
|
||||
#define I3DL2BUFFER_MAXDIRECTHF 0
|
||||
#define I3DL2BUFFER_DEFAULTDIRECTHF 0
|
||||
|
||||
#define I3DL2BUFFER_MINROOM -10000
|
||||
#define I3DL2BUFFER_MAXROOM 1000
|
||||
#define I3DL2BUFFER_DEFAULTROOM 0
|
||||
|
||||
#define I3DL2BUFFER_MINROOMHF -10000
|
||||
#define I3DL2BUFFER_MAXROOMHF 0
|
||||
#define I3DL2BUFFER_DEFAULTROOMHF 0
|
||||
|
||||
#define I3DL2BUFFER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define I3DL2BUFFER_MAXROOMROLLOFFFACTOR 10.f
|
||||
#define I3DL2BUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define I3DL2BUFFER_MINOBSTRUCTION -10000
|
||||
#define I3DL2BUFFER_MAXOBSTRUCTION 0
|
||||
#define I3DL2BUFFER_DEFAULTOBSTRUCTION 0
|
||||
|
||||
#define I3DL2BUFFER_MINOBSTRUCTIONLFRATIO 0.0f
|
||||
#define I3DL2BUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
|
||||
#define I3DL2BUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
|
||||
|
||||
#define I3DL2BUFFER_MINOCCLUSION -10000
|
||||
#define I3DL2BUFFER_MAXOCCLUSION 0
|
||||
#define I3DL2BUFFER_DEFAULTOCCLUSION 0
|
||||
|
||||
#define I3DL2BUFFER_MINOCCLUSIONLFRATIO 0.0f
|
||||
#define I3DL2BUFFER_MAXOCCLUSIONLFRATIO 1.0f
|
||||
#define I3DL2BUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
|
||||
*/
|
||||
|
||||
// #pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
#endif
|
||||
967
fmod/lib/sfx/foreverb/aSfxDsp.cpp
Executable file
967
fmod/lib/sfx/foreverb/aSfxDsp.cpp
Executable file
|
|
@ -0,0 +1,967 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "aSfxDsp.hpp"
|
||||
#include "3dl2.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h> // for memmove and FMOD_memcpy
|
||||
|
||||
#include "../../../src/fmod_memory.h"
|
||||
#include "../../../src/fmod_types.h"
|
||||
|
||||
#define ADD_ANTI_DENORMALS_TO_INPUT
|
||||
|
||||
#define SfxDataMove(source, dest, bytes) memmove(dest, source, (unsigned)bytes)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int ASfxDsp::init(float rate)
|
||||
{
|
||||
int delayLine;
|
||||
int error = 0;
|
||||
|
||||
mEarlyLateDelay = NULL;
|
||||
mEarlyDelay = NULL;
|
||||
|
||||
ZeroWritePointers();
|
||||
|
||||
mEarlyLateSec[0] = 0.040f;
|
||||
mEarlyLateSamples[0] = (int)(mEarlyLateSec[0] * rate);
|
||||
SetLate_EarlyLateDelayTaps(0.060f, kEarlyLateNextLengthSec, kEarlyLateDelayRatio, rate);
|
||||
|
||||
|
||||
for (delayLine=0; delayLine<kNumEarlyLateDelayTaps; delayLine++)
|
||||
{
|
||||
mOldEarlyLateSamples[delayLine] = mEarlyLateSamples[delayLine];
|
||||
}
|
||||
for (delayLine=0; delayLine<kNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
mLateMask[delayLine] = 0;
|
||||
}
|
||||
|
||||
SetEarlyDelay(kEarlyFirstDelaySec, kEarlyDelayRatio, rate);
|
||||
SetAllpassDelays(rate);
|
||||
SetLateDelays(LOWEST_DELAY_LINE_LENGTH_SEC, DELAY_LINE_RATIO, LOWEST_DELAY_LINE_LENGTH_B_SEC, DELAY_LINE_RATIO_B, rate);
|
||||
|
||||
for (delayLine=0; delayLine<kNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
mOldLateDelayLenSamples[delayLine] = mLateDelayLenSamples[delayLine];
|
||||
mLateChanged[delayLine] = false;
|
||||
mDecayHFChanged[delayLine] = false;
|
||||
}
|
||||
|
||||
if (error = AllocateLateDelays(kNumLateReverbDelays, mLateDelayLenSec, rate)) // assignment, not comparison!
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
if (error = AllocateEarlyLateDelay(mEarlyLateSec, rate))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
if (error = AllocateAllpassDelays(kNumAllpassDelays, mAllpassDelayLenSec, rate))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
if (error = AllocateEarlyDelay(mEarlyDelayLenSec[kNumEarlyDelayTaps-1], rate))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
mNumAllocatedInBuffSamples = 0;
|
||||
|
||||
mInBuff = mInBuffMemory = 0;
|
||||
mMatrix = (float *)FMOD_ALIGNPOINTER(mMatrixMem, 16);
|
||||
mzDecayHF = (float *)FMOD_ALIGNPOINTER(mzDecayHFMem, 16);
|
||||
|
||||
for (delayLine=0; delayLine<kNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
mOldFeedback[delayLine] = mPrevFeedback[delayLine] = mLatchFeedback[delayLine] = mFeedback[delayLine] = 0.32f;
|
||||
mLatchDecayHF[delayLine] = mPrevDecayHF[delayLine] = mOldDecayHF[delayLine] = mDecayHF[delayLine] = 0.40f;
|
||||
mLatchOneMinusDecayHF[delayLine] = 1.0f - mDecayHF[delayLine];
|
||||
}
|
||||
|
||||
mOldHadamard = mPrevHadamard = mLatchHadamard = mHadamard = 1.0f;
|
||||
mOldDiffusionScale = mPrevDiffusionScale = mLatchDiffusionScale = mDiffusionScale = 1.0f;
|
||||
mOldRoomHF = mPrevRoomHF = mLatchRoomHF = mRoomHF = 0.98f;
|
||||
mRoomHFChanged = false;
|
||||
|
||||
//FMOD_memset(&mOldRoomLF, 0, sizeof(struct coeff2ndorder));
|
||||
//FMOD_memset(&mPrevRoomLF, 0, sizeof(struct coeff2ndorder));
|
||||
//FMOD_memset(&mLatchRoomLF, 0, sizeof(struct coeff2ndorder));
|
||||
FMOD_memset(&mRoomLFcoeffs, 0, sizeof(struct coeff2ndorder));
|
||||
// mOldRoomLF.a0 = mPrevRoomLF.a0 = mLatchRoomLF.a0 =
|
||||
mRoomLFcoeffs.a0 = 1.0f;
|
||||
mRoomLF = 0.0f;
|
||||
//mRoomLFChanged = false;
|
||||
|
||||
mDiffusionScale = 0.25f; // 0.3535; // cos^4(PI/4)
|
||||
mAllpassGain = 0.63f; // ?
|
||||
mPrevLRgain = mOldLRgain = mLatchLRgain = mLRgain = 0.0f; // ?
|
||||
mLRgainChanged = false;
|
||||
mPrevERgain = mOldERgain = mLatchERgain = mERgain = 0.0f; // ?
|
||||
mERgainChanged = false;
|
||||
ClearReverbInternalBuffers();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ASfxDsp::close()
|
||||
{
|
||||
if (mInBuffMemory)
|
||||
{
|
||||
FMOD_Memory_Free(mInBuffMemory);
|
||||
mInBuffMemory = mInBuff = 0;
|
||||
}
|
||||
|
||||
DeallocateLateDelays();
|
||||
DeallocateEarlyLateDelay();
|
||||
DeallocateAllpassDelays();
|
||||
DeallocateEarlyDelay();
|
||||
}
|
||||
|
||||
|
||||
int ASfxDsp::AllocateLateDelays(int numDelays, float *delaySec, float sampleRate)
|
||||
{
|
||||
int delaySamples;
|
||||
|
||||
DeallocateLateDelays(); // *** But if it hasn't changed, we may want to skip all this... ***
|
||||
|
||||
for (int delayLine=0; delayLine<kNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
delaySamples = (int)(delaySec[delayLine] * sampleRate) + 1;
|
||||
|
||||
delaySamples = NextPowerOf2(delaySamples);
|
||||
|
||||
// Allocate delay
|
||||
|
||||
if ((mLateDelays[delayLine] = (float*) FMOD_Memory_Calloc(delaySamples * sizeof(float))) == NULL)
|
||||
{
|
||||
return REVERB_LATE_ALLOCATION_ERR;
|
||||
}
|
||||
|
||||
mLateDelaySamplesAllocated[delayLine] = delaySamples;
|
||||
mLateMask[delayLine] = delaySamples - 1;
|
||||
mLateWritePointer[delayLine] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASfxDsp::AllocateEarlyLateDelay(float *delaySec, float sampleRate)
|
||||
{
|
||||
// Allocate it to the max Ref & Rev delays, so we don't have to reallocate it if the delays change.
|
||||
float maxDelaySec = I3DL2LISTENER_MAXREFLECTIONSDELAY + I3DL2LISTENER_MAXREVERBDELAY
|
||||
+ delaySec[kNumEarlyLateDelayTaps-1] - delaySec[kNumEarly_EarlyLateDelayTaps];
|
||||
|
||||
int delaySamples = (int)(maxDelaySec * sampleRate) + 1;
|
||||
|
||||
delaySamples = NextPowerOf2(delaySamples);
|
||||
|
||||
DeallocateEarlyLateDelay(); // *** But if it hasn't changed, we may want to skip all this... ***
|
||||
|
||||
// Allocate delay
|
||||
|
||||
if ((mEarlyLateDelay = (float*) FMOD_Memory_Calloc(delaySamples * sizeof(float))) == NULL)
|
||||
{
|
||||
return REVERB_EARLYLATE_ALLOCATION_ERR;
|
||||
}
|
||||
|
||||
mEarlyLateSamplesAllocated = delaySamples;
|
||||
mEarlyLateMask = delaySamples - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASfxDsp::AllocateAllpassDelays(int numDelays, float *delaySec, float sampleRate)
|
||||
{
|
||||
int delaySamples;
|
||||
|
||||
DeallocateAllpassDelays(); // *** But if it hasn't changed, we may want to skip all this... ***
|
||||
|
||||
for (int delayLine=0; delayLine<kNumAllpassDelays; delayLine++)
|
||||
{
|
||||
delaySamples = (int)(delaySec[delayLine] * sampleRate) + 1;
|
||||
delaySamples = NextPowerOf2(delaySamples);
|
||||
|
||||
// Allocate delay
|
||||
|
||||
if ((mAllpassDelays[delayLine] = (float*) FMOD_Memory_Calloc(delaySamples * sizeof(float))) == NULL)
|
||||
{
|
||||
return REVERB_ALLPASS_ALLOCATION_ERR;
|
||||
}
|
||||
|
||||
mAllpassSamplesAllocated[delayLine] = delaySamples;
|
||||
mAllpassMask[delayLine] = delaySamples - 1;
|
||||
mAllpassWritePointer[delayLine] = 0; // Do this here?
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASfxDsp::AllocateEarlyDelay(float delaySec, float sampleRate)
|
||||
{
|
||||
int delaySamples = (int)(delaySec * sampleRate) + 1;
|
||||
|
||||
delaySamples = NextPowerOf2(delaySamples);
|
||||
|
||||
DeallocateEarlyDelay(); // *** But if it hasn't changed, we may want to skip all this... ***
|
||||
|
||||
// Allocate delay
|
||||
|
||||
if ((mEarlyDelay = (float*) FMOD_Memory_Calloc(delaySamples * sizeof(float))) == NULL)
|
||||
{
|
||||
return REVERB_EARLY_ALLOCATION_ERR;
|
||||
}
|
||||
|
||||
mEarlyDelaySamplesAllocated = delaySamples;
|
||||
mEarlyMask = delaySamples - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASfxDsp::NextPowerOf2(int delaySamples)
|
||||
{
|
||||
return 1 << ((int)(FMOD_LOG((float)delaySamples) / FMOD_LOG(2.0f)) + 1);
|
||||
}
|
||||
|
||||
|
||||
void ASfxDsp::DeallocateLateDelays()
|
||||
{
|
||||
for (int delayLine=0; delayLine<kNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
if (mLateDelays[delayLine])
|
||||
{
|
||||
FMOD_Memory_Free(mLateDelays[delayLine]);
|
||||
}
|
||||
|
||||
mLateDelays[delayLine] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ASfxDsp::DeallocateAllpassDelays()
|
||||
{
|
||||
for (int delayLine=0; delayLine<kNumAllpassDelays; delayLine++)
|
||||
{
|
||||
if (mAllpassDelays[delayLine])
|
||||
{
|
||||
FMOD_Memory_Free(mAllpassDelays[delayLine]);
|
||||
}
|
||||
|
||||
mAllpassDelays[delayLine] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ASfxDsp::DeallocateEarlyDelay()
|
||||
{
|
||||
if (mEarlyDelay)
|
||||
{
|
||||
FMOD_Memory_Free(mEarlyDelay);
|
||||
}
|
||||
|
||||
mEarlyDelay = NULL;
|
||||
}
|
||||
|
||||
void ASfxDsp::DeallocateEarlyLateDelay()
|
||||
{
|
||||
if (mEarlyLateDelay)
|
||||
{
|
||||
FMOD_Memory_Free(mEarlyLateDelay);
|
||||
}
|
||||
|
||||
mEarlyLateDelay = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//#pragma export(UpdateBufferSize)
|
||||
int ASfxDsp::UpdateBufferSize(int newMaxBlockSize)
|
||||
{
|
||||
// nothing to do if the maximum number of samples per processing block hasn't changed
|
||||
if (newMaxBlockSize == mNumAllocatedInBuffSamples)
|
||||
{
|
||||
return 0; // buffer size wasn't changed
|
||||
}
|
||||
|
||||
// update with the new value
|
||||
mNumAllocatedInBuffSamples = newMaxBlockSize;
|
||||
|
||||
// (re)allocate audio buffers in mInBuff
|
||||
if (mInBuffMemory != NULL)
|
||||
{
|
||||
FMOD_Memory_Free(mInBuffMemory);
|
||||
}
|
||||
|
||||
mInBuffMemory = (float*) FMOD_Memory_Alloc((newMaxBlockSize * sizeof(float)) + 16);
|
||||
if (!mInBuffMemory)
|
||||
{
|
||||
return REVERB_INBUFF_ALLOCATION_ERR;
|
||||
}
|
||||
mInBuff = (float *)FMOD_ALIGNPOINTER(mInBuffMemory, 16);
|
||||
|
||||
return 0; // buffer size changed
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//#pragma export (ASfxDsp::ClearBuffers)
|
||||
void ASfxDsp::ClearBuffers()
|
||||
{
|
||||
ClearInBuff();
|
||||
ClearReverbInternalBuffers();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ASfxDsp::ClearInBuff()
|
||||
{
|
||||
if (mInBuff != NULL)
|
||||
{
|
||||
// CHANGE THIS TO A BLOCK MOVE
|
||||
for (int i=0; i < mNumAllocatedInBuffSamples; i++)
|
||||
{
|
||||
mInBuff[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ASfxDsp::ClearReverbInternalBuffers()
|
||||
{
|
||||
int delayLine;
|
||||
|
||||
if (mLateDelays)
|
||||
{
|
||||
for (delayLine=0; delayLine<kNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
if (mLateDelays[delayLine])
|
||||
{
|
||||
// *** CHANGE THESE TO BLOCK MOVES FOR BETTER EFFICIENCY ***
|
||||
for (int samp=0; samp<mLateDelaySamplesAllocated[delayLine]; samp++)
|
||||
{
|
||||
mLateDelays[delayLine][samp] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear earlyLate delay line.
|
||||
// Replace this with a block move.
|
||||
int samp;
|
||||
for (samp=0; samp<mEarlyLateSamplesAllocated; samp++)
|
||||
{
|
||||
mEarlyLateDelay[samp] = 0.0f;
|
||||
}
|
||||
|
||||
// Clear early delay line.
|
||||
// Replace this with a block move.
|
||||
for (samp=0; samp<mEarlyDelaySamplesAllocated; samp++)
|
||||
{
|
||||
mEarlyDelay[samp] = 0.0f;
|
||||
}
|
||||
|
||||
// Clear allpass delays
|
||||
for (delayLine=0; delayLine<kNumAllpassDelays; delayLine++)
|
||||
{
|
||||
for (int samp=0; samp<mAllpassSamplesAllocated[delayLine]; samp++)
|
||||
{
|
||||
mAllpassDelays[delayLine][samp] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Zero the internal variables
|
||||
FMOD_memset(mzDecayHF, 0, kNumLateReverbDelays * sizeof(float));
|
||||
FMOD_memset(mMatrix, 0, kNumMatrixStages * kNumLateReverbDelays * sizeof(float));
|
||||
mzRoomHF0 = 0.0f;
|
||||
mzRoomHF1 = 0.0f;
|
||||
mzRoomLF0 = 0.0f;
|
||||
mzRoomLF1 = 0.0f;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ DoDSPProcessing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
void ASfxDsp::DoDSPProcessing (float * inAudio, float * outAudio, int channels, unsigned int l_sampframes,
|
||||
float rate, float drymix, unsigned short speakermask)
|
||||
{
|
||||
unsigned int i;
|
||||
int ch;
|
||||
float eruOut[kNumEarlyDelayTaps + 1];
|
||||
float val, oldVal;
|
||||
int delayLine, delayTap;
|
||||
unsigned int sampframes = (unsigned int)l_sampframes;
|
||||
unsigned int sampframesmi; // sampframes - i
|
||||
float invSampframes = 1.0f / (float)sampframes;
|
||||
|
||||
#ifdef ADD_ANTI_DENORMALS_TO_INPUT
|
||||
#define VERY_SMALL_BUT_NOT_DENORMAL_VALUE (1.0e-15f)
|
||||
// mix very quiet noise (-300 dB) into the input signal to hopefully avoid any denormal values
|
||||
for (ch=0; ch < channels; ch++)
|
||||
{
|
||||
for (i=0; i < sampframes; i += 2)
|
||||
{
|
||||
outAudio[ch+channels*i] = inAudio[ch+channels*i] + VERY_SMALL_BUT_NOT_DENORMAL_VALUE;
|
||||
}
|
||||
for (i=1; i < sampframes; i += 2)
|
||||
{
|
||||
outAudio[ch+channels*i] = inAudio[ch+channels*i] - VERY_SMALL_BUT_NOT_DENORMAL_VALUE;
|
||||
}
|
||||
}
|
||||
#undef VERY_SMALL_BUT_NOT_DENORMAL_VALUE
|
||||
#endif
|
||||
|
||||
// Copy input into our input buffer. This may be faster than doing it inside the big loop.
|
||||
BlockProcessInput(sampframes, channels, outAudio, rate);
|
||||
|
||||
// Adjust the EarlyLate read pointers in case Ref or Rev delays have changed
|
||||
for (delayTap=0; delayTap<kNumEarlyLateDelayTaps; delayTap++)
|
||||
{
|
||||
mEarlyLateReadPointer[delayTap] = (mEarlyLateSamples[delayTap] + mEarlyLateWritePointer - 1) & mEarlyLateMask;
|
||||
|
||||
if (mEarlyLateSamples[delayTap] == mOldEarlyLateSamples[delayTap])
|
||||
{
|
||||
mEarlyLateChanged[delayTap] = false;
|
||||
}
|
||||
else // If the delay has changed, we need to do two reads and crossfade them.
|
||||
{
|
||||
mEarlyLateChanged[delayTap] = true;
|
||||
mOldEarlyLateReadPointer[delayTap] = (mOldEarlyLateSamples[delayTap] + mEarlyLateWritePointer - 1) & mEarlyLateMask;
|
||||
mOldEarlyLateSamples[delayTap] = mEarlyLateSamples[delayTap]; // For next time...
|
||||
}
|
||||
}
|
||||
// Deal with interpolations and crossfades
|
||||
for (delayLine=0; delayLine<kNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
// Adjust the Late read pointers in case late delay sizes have changed
|
||||
mLateReadPointer[delayLine] = (mLateDelayLenSamples[delayLine] + mLateWritePointer[delayLine] - 1)
|
||||
& mLateMask[delayLine];
|
||||
mLateReadPointerB[delayLine] = (mLateDelayLenBSamples[delayLine] + mLateWritePointer[delayLine] - 1)
|
||||
& mLateMask[delayLine];
|
||||
if (mLateDelayLenSamples[delayLine] == mOldLateDelayLenSamples[delayLine])
|
||||
{
|
||||
mLateChanged[delayLine] = false;
|
||||
}
|
||||
else // If the late delays changed, we need to do two reads and crossfade them.
|
||||
{
|
||||
mLateChanged[delayLine] = true;
|
||||
mOldLateReadPointer[delayLine] = (mOldLateDelayLenSamples[delayLine] + mLateWritePointer[delayLine] - 1)
|
||||
& mLateMask[delayLine];
|
||||
mOldLateDelayLenSamples[delayLine] = mLateDelayLenSamples[delayLine]; // For next time...
|
||||
}
|
||||
|
||||
mLatchFeedback[delayLine] = mFeedback[delayLine]; // Latch it in case it changes in the interim.
|
||||
|
||||
if (mLatchFeedback[delayLine] == mOldFeedback[delayLine])
|
||||
{
|
||||
mPrevFeedback[delayLine] = mLatchFeedback[delayLine]; // Use it for our crossfade (in case mFeedback hasn't changed)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mLateChanged[delayLine]) // if we haven't made these changes above
|
||||
{
|
||||
mLateChanged[delayLine] = true;
|
||||
mOldLateReadPointer[delayLine] = (mOldLateDelayLenSamples[delayLine] + mLateWritePointer[delayLine] - 1)
|
||||
& mLateMask[delayLine];
|
||||
// We do this inside the 'if', because mOldLateDelayLenSamples gets changed above,
|
||||
// which would change mOldLateReadPointer back to mLateReadPointer.
|
||||
}
|
||||
|
||||
mPrevFeedback[delayLine] = mOldFeedback[delayLine]; // For our crossfade
|
||||
mOldFeedback[delayLine] = mLatchFeedback[delayLine]; // For next time...
|
||||
}
|
||||
|
||||
mLatchDecayHF[delayLine] = mDecayHF[delayLine]; // Latch it for our interpolation.
|
||||
mLatchOneMinusDecayHF[delayLine] = 1.0f - mLatchDecayHF[delayLine];
|
||||
|
||||
if (mLatchDecayHF[delayLine] == mOldDecayHF[delayLine])
|
||||
{
|
||||
mDecayHFChanged[delayLine] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDecayHFChanged[delayLine] = true;
|
||||
mPrevDecayHF[delayLine] = mOldDecayHF[delayLine]; // For our interpolation
|
||||
mOldDecayHF[delayLine] = mLatchDecayHF[delayLine]; // For next time...
|
||||
}
|
||||
}
|
||||
|
||||
mLatchLRgain = mLRgain;
|
||||
|
||||
if (mLatchLRgain == mOldLRgain)
|
||||
{
|
||||
mLRgainChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLRgainChanged = true;
|
||||
mPrevLRgain = mOldLRgain; // For our interpolation
|
||||
mOldLRgain = mLatchLRgain; // For next time
|
||||
}
|
||||
|
||||
mLatchERgain = mERgain;
|
||||
|
||||
if (mLatchERgain == mOldERgain)
|
||||
{
|
||||
mERgainChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mERgainChanged = true;
|
||||
mPrevERgain = mOldERgain; // For our interpolation
|
||||
mOldERgain = mLatchERgain; // For next time
|
||||
}
|
||||
|
||||
mLatchRoomHF = mRoomHF;
|
||||
|
||||
if (mLatchRoomHF == mOldRoomHF)
|
||||
{
|
||||
mRoomHFChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRoomHFChanged = true;
|
||||
mPrevRoomHF = mOldRoomHF; // For our interpolation
|
||||
mOldRoomHF = mLatchRoomHF; // For next time
|
||||
}
|
||||
|
||||
mLatchHadamard = mHadamard;
|
||||
|
||||
if (mLatchHadamard == mOldHadamard)
|
||||
{
|
||||
mHadamardChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mHadamardChanged = true;
|
||||
mPrevHadamard = mOldHadamard; // For our interpolation
|
||||
mOldHadamard = mLatchHadamard; // For next time
|
||||
}
|
||||
|
||||
mLatchDiffusionScale = mDiffusionScale;
|
||||
|
||||
if (mLatchDiffusionScale == mOldDiffusionScale)
|
||||
{
|
||||
mDiffusionScaleChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDiffusionScaleChanged = true;
|
||||
mPrevDiffusionScale = mOldDiffusionScale; // For our interpolation
|
||||
mOldDiffusionScale = mLatchDiffusionScale; // For next time
|
||||
}
|
||||
|
||||
/*
|
||||
mLatchRoomLF = mRoomLF;
|
||||
|
||||
if (mLatchRoomLF == mOldRoomLF)
|
||||
{
|
||||
mRoomLFChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRoomLFChanged = true;
|
||||
mPrevRoomLF = mOldRoomLF; // For our interpolation
|
||||
mOldRoomLF = mLatchRoomLF; // For next time
|
||||
}
|
||||
*/
|
||||
|
||||
// Now start the Big DSP Loop...
|
||||
for (i=0; i<sampframes; i++) // for each sample
|
||||
{
|
||||
sampframesmi = sampframes - i;
|
||||
val = (float)mInBuff[i];
|
||||
|
||||
// Room HF low-pass filters
|
||||
float roomHF, hadamard, diffusionscale;
|
||||
|
||||
if (mRoomHFChanged)
|
||||
{
|
||||
roomHF = ((mPrevRoomHF * sampframesmi) + (mLatchRoomHF * i)) * invSampframes;
|
||||
}
|
||||
else
|
||||
{
|
||||
roomHF = mLatchRoomHF;
|
||||
}
|
||||
|
||||
if (mHadamardChanged)
|
||||
{
|
||||
hadamard = ((mPrevHadamard * sampframesmi) + (mLatchHadamard * i)) * invSampframes;
|
||||
}
|
||||
else
|
||||
{
|
||||
hadamard = mLatchHadamard;
|
||||
}
|
||||
|
||||
if (mDiffusionScaleChanged)
|
||||
{
|
||||
diffusionscale = ((mPrevDiffusionScale * sampframesmi) + (mLatchDiffusionScale * i)) * invSampframes;
|
||||
}
|
||||
else
|
||||
{
|
||||
diffusionscale = mLatchDiffusionScale;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Room LF - 2nd order high pass filter, don't interpolate yet
|
||||
|
||||
if(mRoomLFChanged)
|
||||
{
|
||||
roomLF = ((mPrevRoomLF * sampframesmi) + (mLatchRoomLF * i)) * invSampframes;
|
||||
}
|
||||
else
|
||||
{
|
||||
roomLF = mLatchRoomLF;
|
||||
}
|
||||
*/
|
||||
|
||||
float oneMinusRoomHF = 1.0f - roomHF;
|
||||
mzRoomHF0 = val*roomHF + mzRoomHF0*oneMinusRoomHF;
|
||||
mzRoomHF1 = mzRoomHF0*roomHF + mzRoomHF1*oneMinusRoomHF;
|
||||
|
||||
float fout;
|
||||
if(mRoomLF != 0.0f)
|
||||
{
|
||||
fout = mzRoomHF1 * mRoomLFcoeffs.a0 + mzRoomLF0;
|
||||
mzRoomLF0 = mzRoomHF1 * mRoomLFcoeffs.a1 + mzRoomLF1 + fout * mRoomLFcoeffs.b1;
|
||||
mzRoomLF1 = mzRoomHF1 * mRoomLFcoeffs.a2 + fout * mRoomLFcoeffs.b2;
|
||||
}
|
||||
else
|
||||
{
|
||||
fout = mzRoomHF1;
|
||||
}
|
||||
|
||||
// Insert Delay here
|
||||
mEarlyLateWritePointer = --mEarlyLateWritePointer & mEarlyLateMask;
|
||||
mEarlyLateDelay[mEarlyLateWritePointer] = fout;
|
||||
|
||||
// ================== Early Reflections ==================
|
||||
|
||||
mEarlyLateReadPointer[0] = --mEarlyLateReadPointer[0] & mEarlyLateMask;
|
||||
float input, output, ERgain;
|
||||
|
||||
if (mERgainChanged)
|
||||
{
|
||||
ERgain = ((mPrevERgain * sampframesmi) + (mLatchERgain * i)) * invSampframes;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERgain = mLatchERgain;
|
||||
}
|
||||
|
||||
input = mEarlyLateDelay[mEarlyLateReadPointer[0]] * ERgain;
|
||||
|
||||
if (mEarlyLateChanged[0]) // Crossfade the old and new reads
|
||||
{
|
||||
mOldEarlyLateReadPointer[0] = --mOldEarlyLateReadPointer[0] & mEarlyLateMask;
|
||||
float oldInput = mEarlyLateDelay[mOldEarlyLateReadPointer[0]] * ERgain;
|
||||
input = ((oldInput * sampframesmi) + (input * i)) * invSampframes;
|
||||
}
|
||||
|
||||
// 2 Allpasses in series
|
||||
|
||||
for (delayLine=0; delayLine<kNumAllpassDelays; delayLine++)
|
||||
{
|
||||
mAllpassWritePointer[delayLine] = --mAllpassWritePointer[delayLine] & mAllpassMask[delayLine];
|
||||
|
||||
mAllpassReadPointer[delayLine] = --mAllpassReadPointer[delayLine] & mAllpassMask[delayLine];
|
||||
output = mAllpassDelays[delayLine][mAllpassReadPointer[delayLine]]
|
||||
- input * mAllpassGain; // feedforward loop
|
||||
|
||||
mAllpassDelays[delayLine][mAllpassWritePointer[delayLine]] =
|
||||
input + output * mAllpassGain; // feedback loop
|
||||
input = output;
|
||||
}
|
||||
|
||||
// Early Delay FIR
|
||||
|
||||
eruOut[0] = output;
|
||||
|
||||
mEarlyWritePointer = --mEarlyWritePointer & mEarlyMask;
|
||||
mEarlyDelay[mEarlyWritePointer] = output;
|
||||
|
||||
for (delayTap=0; delayTap<kNumEarlyDelayTaps; delayTap++)
|
||||
{
|
||||
mEarlyReadPointer[delayTap] = --mEarlyReadPointer[delayTap] & mEarlyMask;
|
||||
eruOut[delayTap+1] = mEarlyDelay[mEarlyReadPointer[delayTap]];
|
||||
}
|
||||
|
||||
|
||||
// ================== Late Reverb ====================
|
||||
|
||||
// This assumes mNumLateReverbDelays = kNumLate_EarlyLateDelayTaps.
|
||||
for (delayLine=0; delayLine<mNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
delayTap = kNumEarly_EarlyLateDelayTaps + delayLine;
|
||||
|
||||
mEarlyLateReadPointer[delayTap] = --mEarlyLateReadPointer[delayTap] & mEarlyLateMask;
|
||||
val = mEarlyLateDelay[mEarlyLateReadPointer[delayTap]];
|
||||
|
||||
if (mEarlyLateChanged[delayTap]) // Crossfade the old and new reads
|
||||
{
|
||||
mOldEarlyLateReadPointer[delayTap] = --mOldEarlyLateReadPointer[delayTap] & mEarlyLateMask;
|
||||
oldVal = mEarlyLateDelay[mOldEarlyLateReadPointer[delayTap]];
|
||||
val = ((oldVal * sampframesmi) + (val * i)) * invSampframes;
|
||||
}
|
||||
|
||||
if (mLRgainChanged)
|
||||
{
|
||||
float LRgain = ((mPrevLRgain * sampframesmi) + (mLatchLRgain * i)) * invSampframes;
|
||||
val *= LRgain;
|
||||
}
|
||||
else
|
||||
{
|
||||
val *= mLatchLRgain;
|
||||
}
|
||||
|
||||
mLateReadPointer[delayLine] = --mLateReadPointer[delayLine] & mLateMask[delayLine];
|
||||
if (mLateChanged[delayLine]) // Crossfade
|
||||
{
|
||||
mOldLateReadPointer[delayLine] = --mOldLateReadPointer[delayLine] & mLateMask[delayLine];
|
||||
oldVal = mPrevFeedback[delayLine] * mLateDelays[delayLine][mOldLateReadPointer[delayLine]];
|
||||
float thisVal = mLatchFeedback[delayLine] * mLateDelays[delayLine][mLateReadPointer[delayLine]];
|
||||
val += (((oldVal * sampframesmi) + (thisVal * i)) * invSampframes);
|
||||
}
|
||||
else
|
||||
{
|
||||
val += (mLatchFeedback[delayLine] * mLateDelays[delayLine][mLateReadPointer[delayLine]]);
|
||||
}
|
||||
|
||||
// Gain to compensate for one matrix gain, based on the diffusion.
|
||||
// val *= mDiffusionScale;
|
||||
val *= diffusionscale;
|
||||
|
||||
// Low-pass filter for HF Decay ratio
|
||||
if (mDecayHFChanged[delayLine])
|
||||
{
|
||||
// Interpolate decayHF
|
||||
float decayHF = ((mPrevDecayHF[delayLine] * sampframesmi) + (mLatchDecayHF[delayLine] * i)) * invSampframes;
|
||||
float oneMinusDecayHF = 1.0f - decayHF;
|
||||
mzDecayHF[delayLine] = val * decayHF + mzDecayHF[delayLine] * oneMinusDecayHF;
|
||||
}
|
||||
else
|
||||
{
|
||||
mzDecayHF[delayLine] = val * mLatchDecayHF[delayLine] + mzDecayHF[delayLine] * mLatchOneMinusDecayHF[delayLine];
|
||||
}
|
||||
|
||||
mLateWritePointer[delayLine] = --mLateWritePointer[delayLine] & mLateMask[delayLine];
|
||||
}
|
||||
|
||||
|
||||
mMatrix[0 * kNumLateReverbDelays + 0] = mzDecayHF[0] + mzDecayHF[1] * hadamard;
|
||||
mMatrix[0 * kNumLateReverbDelays + 1] = mzDecayHF[1] - mzDecayHF[0] * hadamard;
|
||||
mMatrix[0 * kNumLateReverbDelays + 2] = mzDecayHF[2] + mzDecayHF[3] * hadamard;
|
||||
mMatrix[0 * kNumLateReverbDelays + 3] = mzDecayHF[3] - mzDecayHF[2] * hadamard;
|
||||
mMatrix[0 * kNumLateReverbDelays + 4] = mzDecayHF[4] + mzDecayHF[5] * hadamard;
|
||||
mMatrix[0 * kNumLateReverbDelays + 5] = mzDecayHF[5] - mzDecayHF[4] * hadamard;
|
||||
mMatrix[0 * kNumLateReverbDelays + 6] = mzDecayHF[6] + mzDecayHF[7] * hadamard;
|
||||
mMatrix[0 * kNumLateReverbDelays + 7] = mzDecayHF[7] - mzDecayHF[6] * hadamard;
|
||||
|
||||
mMatrix[1 * kNumLateReverbDelays + 0] = mMatrix[0 * kNumLateReverbDelays + 0] + mMatrix[0 * kNumLateReverbDelays + 2] * hadamard;
|
||||
mMatrix[1 * kNumLateReverbDelays + 1] = mMatrix[0 * kNumLateReverbDelays + 1] + mMatrix[0 * kNumLateReverbDelays + 3] * hadamard;
|
||||
mMatrix[1 * kNumLateReverbDelays + 2] = mMatrix[0 * kNumLateReverbDelays + 2] - mMatrix[0 * kNumLateReverbDelays + 0] * hadamard;
|
||||
mMatrix[1 * kNumLateReverbDelays + 3] = mMatrix[0 * kNumLateReverbDelays + 3] - mMatrix[0 * kNumLateReverbDelays + 1] * hadamard;
|
||||
mMatrix[1 * kNumLateReverbDelays + 4] = mMatrix[0 * kNumLateReverbDelays + 4] + mMatrix[0 * kNumLateReverbDelays + 6] * hadamard;
|
||||
mMatrix[1 * kNumLateReverbDelays + 5] = mMatrix[0 * kNumLateReverbDelays + 5] + mMatrix[0 * kNumLateReverbDelays + 7] * hadamard;
|
||||
mMatrix[1 * kNumLateReverbDelays + 6] = mMatrix[0 * kNumLateReverbDelays + 6] - mMatrix[0 * kNumLateReverbDelays + 4] * hadamard;
|
||||
mMatrix[1 * kNumLateReverbDelays + 7] = mMatrix[0 * kNumLateReverbDelays + 7] - mMatrix[0 * kNumLateReverbDelays + 5] * hadamard;
|
||||
|
||||
mMatrix[2 * kNumLateReverbDelays + 0] = mMatrix[1 * kNumLateReverbDelays + 0] + mMatrix[1 * kNumLateReverbDelays + 4] * hadamard;
|
||||
mMatrix[2 * kNumLateReverbDelays + 1] = mMatrix[1 * kNumLateReverbDelays + 1] + mMatrix[1 * kNumLateReverbDelays + 5] * hadamard;
|
||||
mMatrix[2 * kNumLateReverbDelays + 2] = mMatrix[1 * kNumLateReverbDelays + 2] + mMatrix[1 * kNumLateReverbDelays + 6] * hadamard;
|
||||
mMatrix[2 * kNumLateReverbDelays + 3] = mMatrix[1 * kNumLateReverbDelays + 3] + mMatrix[1 * kNumLateReverbDelays + 7] * hadamard;
|
||||
mMatrix[2 * kNumLateReverbDelays + 4] = mMatrix[1 * kNumLateReverbDelays + 4] - mMatrix[1 * kNumLateReverbDelays + 0] * hadamard;
|
||||
mMatrix[2 * kNumLateReverbDelays + 5] = mMatrix[1 * kNumLateReverbDelays + 5] - mMatrix[1 * kNumLateReverbDelays + 1] * hadamard;
|
||||
mMatrix[2 * kNumLateReverbDelays + 6] = mMatrix[1 * kNumLateReverbDelays + 6] - mMatrix[1 * kNumLateReverbDelays + 2] * hadamard;
|
||||
mMatrix[2 * kNumLateReverbDelays + 7] = mMatrix[1 * kNumLateReverbDelays + 7] - mMatrix[1 * kNumLateReverbDelays + 3] * hadamard;
|
||||
|
||||
// Write to the lateDelays
|
||||
mLateDelays[0][mLateWritePointer[0]] = mMatrix[2 * kNumLateReverbDelays + 1];
|
||||
mLateDelays[1][mLateWritePointer[1]] = mMatrix[2 * kNumLateReverbDelays + 2];
|
||||
mLateDelays[2][mLateWritePointer[2]] = mMatrix[2 * kNumLateReverbDelays + 3];
|
||||
mLateDelays[3][mLateWritePointer[3]] = mMatrix[2 * kNumLateReverbDelays + 4];
|
||||
mLateDelays[4][mLateWritePointer[4]] = mMatrix[2 * kNumLateReverbDelays + 5];
|
||||
mLateDelays[5][mLateWritePointer[5]] = mMatrix[2 * kNumLateReverbDelays + 6];
|
||||
mLateDelays[6][mLateWritePointer[6]] = mMatrix[2 * kNumLateReverbDelays + 7];
|
||||
mLateDelays[7][mLateWritePointer[7]] = mMatrix[2 * kNumLateReverbDelays + 0];
|
||||
|
||||
for (ch=0; ch<channels; ch++) // for each channel
|
||||
{
|
||||
if (!((1 << ch) & speakermask))
|
||||
{
|
||||
outAudio[i*channels+ch] = inAudio[i*channels+ch];
|
||||
}
|
||||
else
|
||||
{
|
||||
float lruSum = 0.0f;
|
||||
float eruSum = 0.0f;
|
||||
int nextDelay = ch;
|
||||
|
||||
for (int delay=0; delay<(kNumLateReverbDelays/channels); delay++)
|
||||
{
|
||||
mLateReadPointerB[nextDelay] = --mLateReadPointerB[nextDelay] & mLateMask[nextDelay];
|
||||
lruSum += mLateDelays[nextDelay][mLateReadPointerB[nextDelay]];
|
||||
|
||||
eruSum += eruOut[nextDelay];
|
||||
nextDelay += channels;
|
||||
}
|
||||
|
||||
if (drymix == 0.0f)
|
||||
{
|
||||
outAudio[i*channels+ch] = eruSum + lruSum;
|
||||
}
|
||||
else
|
||||
{
|
||||
outAudio[i*channels+ch] = (inAudio[i*channels+ch] * drymix) + eruSum + lruSum;
|
||||
}
|
||||
}
|
||||
|
||||
} // end for each channel
|
||||
} // end for each sample
|
||||
|
||||
} // end DoDSPProcessing
|
||||
|
||||
|
||||
// Copy input into our input buffer. This may be faster than doing it inside the big loop (?).
|
||||
void ASfxDsp::BlockProcessInput(unsigned int sampframes, int channels, float *inAudio, float rate)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (channels == 1) // mono
|
||||
{
|
||||
SfxDataMove(inAudio, mInBuff, sampframes*sizeof(float));
|
||||
}
|
||||
else if (channels == 6)
|
||||
{
|
||||
float *inptr = inAudio;
|
||||
float *outptr = mInBuff;
|
||||
|
||||
for (i = 0; i < sampframes / 4; i++) // for each sample
|
||||
{
|
||||
outptr[0] = inptr[0] + inptr[1] + inptr[2] + inptr[3] + inptr[4] + inptr[5];
|
||||
outptr[1] = inptr[6] + inptr[7] + inptr[8] + inptr[9] + inptr[10] + inptr[11];
|
||||
outptr[2] = inptr[12] + inptr[13] + inptr[14] + inptr[15] + inptr[16] + inptr[17];
|
||||
outptr[3] = inptr[18] + inptr[19] + inptr[20] + inptr[21] + inptr[22] + inptr[23];
|
||||
inptr += 24;
|
||||
outptr += 4;
|
||||
}
|
||||
}
|
||||
else if (channels == 8)
|
||||
{
|
||||
float *inptr = inAudio;
|
||||
float *outptr = mInBuff;
|
||||
|
||||
for (i = 0; i < sampframes / 4; i++) // for each sample
|
||||
{
|
||||
outptr[0] = inptr[0] + inptr[1] + inptr[2] + inptr[3] + inptr[4] + inptr[5] + inptr[6] + inptr[7];
|
||||
outptr[1] = inptr[8] + inptr[9] + inptr[10] + inptr[11] + inptr[12] + inptr[13] + inptr[14] + inptr[15];
|
||||
outptr[2] = inptr[16] + inptr[17] + inptr[18] + inptr[19] + inptr[20] + inptr[21] + inptr[22] + inptr[23];
|
||||
outptr[3] = inptr[24] + inptr[25] + inptr[26] + inptr[27] + inptr[28] + inptr[29] + inptr[30] + inptr[31];
|
||||
inptr += 32;
|
||||
outptr += 4;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int ch;
|
||||
|
||||
for (i=0; i<sampframes; i++) // for each sample
|
||||
{
|
||||
mInBuff[i] = 0.0f;
|
||||
for (ch=0; ch<channels; ++ch) // for each channel
|
||||
{
|
||||
mInBuff[i] += inAudio[i*channels+ch]; // *** Would it be more efficient to reverse the loops? ***
|
||||
}
|
||||
// mInBuff[i] /= (float)channels; // Don't average them!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ASfxDsp::SetLate_EarlyLateDelayTaps(float refPlusRevDelaySec, float nextLengthSec, float delayRatio, float rate)
|
||||
{
|
||||
mEarlyLateSec[kNumEarly_EarlyLateDelayTaps] = refPlusRevDelaySec; // Tap 1 = Ref+Rev delay
|
||||
int earlyLateSamples = (int)(refPlusRevDelaySec * rate);
|
||||
if (earlyLateSamples == 0)
|
||||
{
|
||||
earlyLateSamples++; // Avoid long wrap-around delay.
|
||||
}
|
||||
mEarlyLateSamples[kNumEarly_EarlyLateDelayTaps] = earlyLateSamples;
|
||||
|
||||
// Set the remaining EarlyLate delay taps (2 - 8)
|
||||
for (int delayTap=kNumEarly_EarlyLateDelayTaps+1; delayTap<kNumEarlyLateDelayTaps; delayTap++)
|
||||
{
|
||||
mEarlyLateSec[delayTap] = refPlusRevDelaySec + nextLengthSec;
|
||||
mEarlyLateSamples[delayTap] = (int)(mEarlyLateSec[delayTap] * rate);
|
||||
nextLengthSec *= delayRatio;
|
||||
}
|
||||
}
|
||||
|
||||
void ASfxDsp::SetAllpassDelays(float rate)
|
||||
{
|
||||
mAllpassDelayLenSec[0] = kAllpassDelayLenSec0;
|
||||
mAllpassDelayLenSec[1] = kAllpassDelayLenSec1;
|
||||
|
||||
for (int delayLine = 0; delayLine<kNumAllpassDelays; delayLine++)
|
||||
{
|
||||
mAllpassDelayLenSamples[delayLine] = (int)(mAllpassDelayLenSec[delayLine] * rate);
|
||||
mAllpassReadPointer[delayLine] = mAllpassDelayLenSamples[delayLine] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ASfxDsp::SetEarlyDelay(float nextLengthSec, float delayRatio, float rate)
|
||||
{
|
||||
// Set the early delay taps (0 - 6)
|
||||
for (int delayLine=0; delayLine<kNumEarlyDelayTaps; delayLine++)
|
||||
{
|
||||
mEarlyDelayLenSec[delayLine] = nextLengthSec;
|
||||
mEarlyDelayLenSamples[delayLine] = (int)(nextLengthSec * rate);
|
||||
nextLengthSec *= delayRatio;
|
||||
|
||||
mEarlyReadPointer[delayLine] = mEarlyDelayLenSamples[delayLine] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ASfxDsp::SetLateDelays(float nextLengthSec, float delayRatio, float nextLengthBSec, float delayRatioB, float rate)
|
||||
{
|
||||
float nextLengthSamples;
|
||||
|
||||
float nextLengthBSamples = nextLengthBSec * rate;
|
||||
|
||||
for (int delayLine=0; delayLine<kNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
// Set main delay line lengths
|
||||
mLateDelayLenSec[delayLine] = nextLengthSec;
|
||||
nextLengthSamples = nextLengthSec * rate;
|
||||
mLateDelayLenSamples[delayLine] = (int)(nextLengthSamples + 0.5);
|
||||
nextLengthSec *= delayRatio;
|
||||
mLateReadPointer[delayLine] = (mLateDelayLenSamples[delayLine] + mLateWritePointer[delayLine] - 1)
|
||||
& mLateMask[delayLine];
|
||||
|
||||
// Set delay line lengths for B reads
|
||||
mLateDelayLenBSamples[delayLine] = (int)(nextLengthBSamples + 0.5); // Short delays to keep outputs from cancelling.
|
||||
nextLengthBSamples *= delayRatioB;
|
||||
mLateReadPointerB[delayLine] = (mLateDelayLenBSamples[delayLine] + mLateWritePointer[delayLine] - 1)
|
||||
& mLateMask[delayLine];
|
||||
}
|
||||
}
|
||||
|
||||
void ASfxDsp::ZeroWritePointers()
|
||||
{
|
||||
int delayLine;
|
||||
|
||||
mEarlyWritePointer = 0;
|
||||
mEarlyLateWritePointer = 0;
|
||||
|
||||
for (delayLine=0; delayLine<kNumAllpassDelays; delayLine++)
|
||||
{
|
||||
mAllpassWritePointer[delayLine] = 0;
|
||||
}
|
||||
|
||||
for (delayLine=0; delayLine<kNumLateReverbDelays; delayLine++)
|
||||
{
|
||||
mLateWritePointer[delayLine] = 0;
|
||||
}
|
||||
}
|
||||
223
fmod/lib/sfx/foreverb/aSfxDsp.hpp
Executable file
223
fmod/lib/sfx/foreverb/aSfxDsp.hpp
Executable file
|
|
@ -0,0 +1,223 @@
|
|||
#ifndef __ASFXDSP_H
|
||||
#define __ASFXDSP_H
|
||||
|
||||
#include "../../../src/fmod_settings.h"
|
||||
#include "../../../src/fmod_types.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
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
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue