/*---------------------------------------------------------------------------- | |
* | |
* File: | |
* eas_reverb.c | |
* | |
* Contents and purpose: | |
* Contains the implementation of the Reverb effect. | |
* | |
* | |
* Copyright Sonic Network Inc. 2006 | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
* | |
*---------------------------------------------------------------------------- | |
* Revision Control: | |
* $Revision: 510 $ | |
* $Date: 2006-12-19 01:47:33 -0800 (Tue, 19 Dec 2006) $ | |
*---------------------------------------------------------------------------- | |
*/ | |
/*------------------------------------ | |
* includes | |
*------------------------------------ | |
*/ | |
#include "eas_data.h" | |
#include "eas_effects.h" | |
#include "eas_math.h" | |
#include "eas_reverbdata.h" | |
#include "eas_reverb.h" | |
#include "eas_config.h" | |
#include "eas_host.h" | |
#include "eas_report.h" | |
/* prototypes for effects interface */ | |
static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData); | |
static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples); | |
static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData); | |
static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); | |
static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); | |
/* common effects interface for configuration module */ | |
const S_EFFECTS_INTERFACE EAS_Reverb = | |
{ | |
ReverbInit, | |
ReverbProcess, | |
ReverbShutdown, | |
ReverbGetParam, | |
ReverbSetParam | |
}; | |
/*---------------------------------------------------------------------------- | |
* InitializeReverb() | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* | |
* Inputs: | |
* | |
* Outputs: | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_RESULT ReverbInit(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData) | |
{ | |
EAS_I32 i; | |
EAS_U16 nOffset; | |
EAS_INT temp; | |
S_REVERB_OBJECT *pReverbData; | |
S_REVERB_PRESET *pPreset; | |
/* check Configuration Module for data allocation */ | |
if (pEASData->staticMemoryModel) | |
pReverbData = EAS_CMEnumFXData(EAS_MODULE_REVERB); | |
/* allocate dynamic memory */ | |
else | |
pReverbData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_REVERB_OBJECT)); | |
if (pReverbData == NULL) | |
{ | |
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Reverb memory\n"); */ } | |
return EAS_ERROR_MALLOC_FAILED; | |
} | |
/* clear the structure */ | |
EAS_HWMemSet(pReverbData, 0, sizeof(S_REVERB_OBJECT)); | |
ReverbReadInPresets(pReverbData); | |
pReverbData->m_nMinSamplesToAdd = REVERB_UPDATE_PERIOD_IN_SAMPLES; | |
pReverbData->m_nRevOutFbkR = 0; | |
pReverbData->m_nRevOutFbkL = 0; | |
pReverbData->m_sAp0.m_zApIn = AP0_IN; | |
pReverbData->m_sAp0.m_zApOut = AP0_IN + DEFAULT_AP0_LENGTH; | |
pReverbData->m_sAp0.m_nApGain = DEFAULT_AP0_GAIN; | |
pReverbData->m_zD0In = DELAY0_IN; | |
pReverbData->m_sAp1.m_zApIn = AP1_IN; | |
pReverbData->m_sAp1.m_zApOut = AP1_IN + DEFAULT_AP1_LENGTH; | |
pReverbData->m_sAp1.m_nApGain = DEFAULT_AP1_GAIN; | |
pReverbData->m_zD1In = DELAY1_IN; | |
pReverbData->m_zLpf0 = 0; | |
pReverbData->m_zLpf1 = 0; | |
pReverbData->m_nLpfFwd = 8837; | |
pReverbData->m_nLpfFbk = 6494; | |
pReverbData->m_nSin = 0; | |
pReverbData->m_nCos = 0; | |
pReverbData->m_nSinIncrement = 0; | |
pReverbData->m_nCosIncrement = 0; | |
// set xfade parameters | |
pReverbData->m_nXfadeInterval = (EAS_U16)REVERB_XFADE_PERIOD_IN_SAMPLES; | |
pReverbData->m_nXfadeCounter = pReverbData->m_nXfadeInterval + 1; // force update on first iteration | |
pReverbData->m_nPhase = -32768; | |
pReverbData->m_nPhaseIncrement = REVERB_XFADE_PHASE_INCREMENT; | |
pReverbData->m_nNoise = (EAS_I16)0xABCD; | |
pReverbData->m_nMaxExcursion = 0x007F; | |
// set delay tap lengths | |
nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, | |
&pReverbData->m_nNoise ); | |
pReverbData->m_zD1Cross = | |
DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; | |
nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, | |
&pReverbData->m_nNoise ); | |
pReverbData->m_zD0Cross = | |
DELAY1_OUT - pReverbData->m_nMaxExcursion - nOffset; | |
nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, | |
&pReverbData->m_nNoise ); | |
pReverbData->m_zD0Self = | |
DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset; | |
nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, | |
&pReverbData->m_nNoise ); | |
pReverbData->m_zD1Self = | |
DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; | |
// for debugging purposes, allow noise generator | |
pReverbData->m_bUseNoise = EAS_FALSE; | |
// for debugging purposes, allow bypass | |
pReverbData->m_bBypass = EAS_TRUE; //EAS_FALSE; | |
pReverbData->m_nNextRoom = 1; | |
pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom + 1; // force update on first iteration | |
pReverbData->m_nWet = REVERB_DEFAULT_WET; | |
pReverbData->m_nDry = REVERB_DEFAULT_DRY; | |
// set base index into circular buffer | |
pReverbData->m_nBaseIndex = 0; | |
// set the early reflections, L | |
pReverbData->m_sEarlyL.m_nLpfFbk = 4915; | |
pReverbData->m_sEarlyL.m_nLpfFwd = 27852; | |
pReverbData->m_sEarlyL.m_zLpf = 0; | |
for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++) | |
{ | |
pReverbData->m_sEarlyL.m_nGain[i] = 0; | |
pReverbData->m_sEarlyL.m_zDelay[i] = 0; | |
} | |
// set the early reflections, R | |
pReverbData->m_sEarlyR.m_nLpfFbk = 4915; | |
pReverbData->m_sEarlyR.m_nLpfFwd = 27852; | |
pReverbData->m_sEarlyR.m_zLpf = 0; | |
for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++) | |
{ | |
pReverbData->m_sEarlyR.m_nGain[i] = 0; | |
pReverbData->m_sEarlyR.m_zDelay[i] = 0; | |
} | |
// clear the reverb delay line | |
for (i=0; i < REVERB_BUFFER_SIZE_IN_SAMPLES; i++) | |
{ | |
pReverbData->m_nDelayLine[i] = 0; | |
} | |
//////////////////////////////// | |
///code from the EAS DEMO Reverb | |
//now copy from the new preset into the reverb | |
pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom]; | |
pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk; | |
pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd; | |
pReverbData->m_nEarly = pPreset->m_nEarly; | |
pReverbData->m_nWet = pPreset->m_nWet; | |
pReverbData->m_nDry = pPreset->m_nDry; | |
pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion; | |
//stored as time based, convert to sample based | |
temp = pPreset->m_nXfadeInterval; | |
/*lint -e{702} shift for performance */ | |
temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; | |
pReverbData->m_nXfadeInterval = (EAS_U16) temp; | |
//gsReverbObject.m_nXfadeInterval = pPreset->m_nXfadeInterval; | |
pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain; | |
//stored as time based, convert to absolute sample value | |
temp = pPreset->m_nAp0_ApOut; | |
/*lint -e{702} shift for performance */ | |
temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; | |
pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp); | |
//gsReverbObject.m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut; | |
pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain; | |
//stored as time based, convert to absolute sample value | |
temp = pPreset->m_nAp1_ApOut; | |
/*lint -e{702} shift for performance */ | |
temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; | |
pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp); | |
//gsReverbObject.m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut; | |
///code from the EAS DEMO Reverb | |
//////////////////////////////// | |
*pInstData = pReverbData; | |
return EAS_SUCCESS; | |
} /* end InitializeReverb */ | |
/*---------------------------------------------------------------------------- | |
* ReverbProcess() | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* Reverberate the requested number of samples (block based processing) | |
* | |
* Inputs: | |
* pInputBuffer - src buffer | |
* pOutputBuffer - dst buffer | |
* nNumSamplesToAdd - number of samples to write to buffer | |
* | |
* Outputs: | |
* number of samples actually written to buffer | |
* | |
* Side Effects: | |
* - samples are added to the presently free buffer | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static void ReverbProcess(EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples) | |
{ | |
S_REVERB_OBJECT *pReverbData; | |
pReverbData = (S_REVERB_OBJECT*) pInstData; | |
//if bypassed or the preset forces the signal to be completely dry | |
if (pReverbData->m_bBypass || | |
(pReverbData->m_nWet == 0 && pReverbData->m_nDry == 32767)) | |
{ | |
if (pSrc != pDst) | |
EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM)); | |
return; | |
} | |
if (pReverbData->m_nNextRoom != pReverbData->m_nCurrentRoom) | |
{ | |
ReverbUpdateRoom(pReverbData); | |
} | |
ReverbUpdateXfade(pReverbData, numSamples); | |
Reverb(pReverbData, numSamples, pDst, pSrc); | |
/* check if update counter needs to be reset */ | |
if (pReverbData->m_nUpdateCounter >= REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES) | |
{ | |
/* update interval has elapsed, so reset counter */ | |
pReverbData->m_nUpdateCounter = 0; | |
} /* end if m_nUpdateCounter >= update interval */ | |
/* increment update counter */ | |
pReverbData->m_nUpdateCounter += (EAS_I16)numSamples; | |
} /* end ComputeReverb */ | |
/*---------------------------------------------------------------------------- | |
* ReverbUpdateXfade | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* Update the xfade parameters as required | |
* | |
* Inputs: | |
* nNumSamplesToAdd - number of samples to write to buffer | |
* | |
* Outputs: | |
* | |
* | |
* Side Effects: | |
* - xfade parameters will be changed | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd) | |
{ | |
EAS_U16 nOffset; | |
EAS_I16 tempCos; | |
EAS_I16 tempSin; | |
if (pReverbData->m_nXfadeCounter >= pReverbData->m_nXfadeInterval) | |
{ | |
/* update interval has elapsed, so reset counter */ | |
pReverbData->m_nXfadeCounter = 0; | |
// Pin the sin,cos values to min / max values to ensure that the | |
// modulated taps' coefs are zero (thus no clicks) | |
if (pReverbData->m_nPhaseIncrement > 0) | |
{ | |
// if phase increment > 0, then sin -> 1, cos -> 0 | |
pReverbData->m_nSin = 32767; | |
pReverbData->m_nCos = 0; | |
// reset the phase to match the sin, cos values | |
pReverbData->m_nPhase = 32767; | |
// modulate the cross taps because their tap coefs are zero | |
nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); | |
pReverbData->m_zD1Cross = | |
DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; | |
nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); | |
pReverbData->m_zD0Cross = | |
DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset; | |
} | |
else | |
{ | |
// if phase increment < 0, then sin -> 0, cos -> 1 | |
pReverbData->m_nSin = 0; | |
pReverbData->m_nCos = 32767; | |
// reset the phase to match the sin, cos values | |
pReverbData->m_nPhase = -32768; | |
// modulate the self taps because their tap coefs are zero | |
nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); | |
pReverbData->m_zD0Self = | |
DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset; | |
nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); | |
pReverbData->m_zD1Self = | |
DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; | |
} // end if-else (pReverbData->m_nPhaseIncrement > 0) | |
// Reverse the direction of the sin,cos so that the | |
// tap whose coef was previously increasing now decreases | |
// and vice versa | |
pReverbData->m_nPhaseIncrement = -pReverbData->m_nPhaseIncrement; | |
} // end if counter >= update interval | |
//compute what phase will be next time | |
pReverbData->m_nPhase += pReverbData->m_nPhaseIncrement; | |
//calculate what the new sin and cos need to reach by the next update | |
ReverbCalculateSinCos(pReverbData->m_nPhase, &tempSin, &tempCos); | |
//calculate the per-sample increment required to get there by the next update | |
/*lint -e{702} shift for performance */ | |
pReverbData->m_nSinIncrement = | |
(tempSin - pReverbData->m_nSin) >> REVERB_UPDATE_PERIOD_IN_BITS; | |
/*lint -e{702} shift for performance */ | |
pReverbData->m_nCosIncrement = | |
(tempCos - pReverbData->m_nCos) >> REVERB_UPDATE_PERIOD_IN_BITS; | |
/* increment update counter */ | |
pReverbData->m_nXfadeCounter += (EAS_U16) nNumSamplesToAdd; | |
return EAS_SUCCESS; | |
} /* end ReverbUpdateXfade */ | |
/*---------------------------------------------------------------------------- | |
* ReverbCalculateNoise | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* Calculate a noise sample and limit its value | |
* | |
* Inputs: | |
* nMaxExcursion - noise value is limited to this value | |
* pnNoise - return new noise sample in this (not limited) | |
* | |
* Outputs: | |
* new limited noise value | |
* | |
* Side Effects: | |
* - *pnNoise noise value is updated | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise) | |
{ | |
// calculate new noise value | |
*pnNoise = (EAS_I16) (*pnNoise * 5 + 1); | |
#if 0 // 1xxx, test | |
*pnNoise = 0; | |
#endif // 1xxx, test | |
// return the limited noise value | |
return (nMaxExcursion & (*pnNoise)); | |
} /* end ReverbCalculateNoise */ | |
/*---------------------------------------------------------------------------- | |
* ReverbCalculateSinCos | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* Calculate a new sin and cosine value based on the given phase | |
* | |
* Inputs: | |
* nPhase - phase angle | |
* pnSin - input old value, output new value | |
* pnCos - input old value, output new value | |
* | |
* Outputs: | |
* | |
* Side Effects: | |
* - *pnSin, *pnCos are updated | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos) | |
{ | |
EAS_I32 nTemp; | |
EAS_I32 nNetAngle; | |
// -1 <= nPhase < 1 | |
// However, for the calculation, we need a value | |
// that ranges from -1/2 to +1/2, so divide the phase by 2 | |
/*lint -e{702} shift for performance */ | |
nNetAngle = nPhase >> 1; | |
/* | |
Implement the following | |
sin(x) = (2-4*c)*x^2 + c + x | |
cos(x) = (2-4*c)*x^2 + c - x | |
where c = 1/sqrt(2) | |
using the a0 + x*(a1 + x*a2) approach | |
*/ | |
/* limit the input "angle" to be between -0.5 and +0.5 */ | |
if (nNetAngle > EG1_HALF) | |
{ | |
nNetAngle = EG1_HALF; | |
} | |
else if (nNetAngle < EG1_MINUS_HALF) | |
{ | |
nNetAngle = EG1_MINUS_HALF; | |
} | |
/* calculate sin */ | |
nTemp = EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle); | |
nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle); | |
*pnSin = (EAS_I16) SATURATE_EG1(nTemp); | |
/* calculate cos */ | |
nTemp = -EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle); | |
nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle); | |
*pnCos = (EAS_I16) SATURATE_EG1(nTemp); | |
return EAS_SUCCESS; | |
} /* end ReverbCalculateSinCos */ | |
/*---------------------------------------------------------------------------- | |
* Reverb | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* apply reverb to the given signal | |
* | |
* Inputs: | |
* nNu | |
* pnSin - input old value, output new value | |
* pnCos - input old value, output new value | |
* | |
* Outputs: | |
* number of samples actually reverberated | |
* | |
* Side Effects: | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_RESULT Reverb(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer) | |
{ | |
EAS_I32 i; | |
EAS_I32 nDelayOut; | |
EAS_U16 nBase; | |
EAS_U32 nAddr; | |
EAS_I32 nTemp1; | |
EAS_I32 nTemp2; | |
EAS_I32 nApIn; | |
EAS_I32 nApOut; | |
EAS_I32 j; | |
EAS_I32 nEarlyOut; | |
EAS_I32 tempValue; | |
// get the base address | |
nBase = pReverbData->m_nBaseIndex; | |
for (i=0; i < nNumSamplesToAdd; i++) | |
{ | |
// ********** Left Allpass - start | |
// left input = (left dry/4) + right feedback from previous period | |
/*lint -e{702} use shift for performance */ | |
nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkR; | |
// nApIn = *pInputBuffer++; // 1xxx test and debug ap | |
// fetch allpass delay line out | |
//nAddr = CIRCULAR(nBase, psAp0->m_zApOut, REVERB_BUFFER_MASK); | |
nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApOut, REVERB_BUFFER_MASK); | |
nDelayOut = pReverbData->m_nDelayLine[nAddr]; | |
// calculate allpass feedforward; subtract the feedforward result | |
nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp0.m_nApGain); | |
nApOut = SATURATE(nDelayOut - nTemp1); // allpass output | |
// calculate allpass feedback; add the feedback result | |
nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp0.m_nApGain); | |
nTemp1 = SATURATE(nApIn + nTemp1); | |
// inject into allpass delay | |
nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApIn, REVERB_BUFFER_MASK); | |
pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1; | |
// inject allpass output into delay line | |
nAddr = CIRCULAR(nBase, pReverbData->m_zD0In, REVERB_BUFFER_MASK); | |
pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut; | |
// ********** Left Allpass - end | |
// ********** Right Allpass - start | |
// right input = (right dry/4) + left feedback from previous period | |
/*lint -e{702} use shift for performance */ | |
nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkL; | |
// nApIn = *pInputBuffer++; // 1xxx test and debug ap | |
// fetch allpass delay line out | |
nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApOut, REVERB_BUFFER_MASK); | |
nDelayOut = pReverbData->m_nDelayLine[nAddr]; | |
// calculate allpass feedforward; subtract the feedforward result | |
nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp1.m_nApGain); | |
nApOut = SATURATE(nDelayOut - nTemp1); // allpass output | |
// calculate allpass feedback; add the feedback result | |
nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp1.m_nApGain); | |
nTemp1 = SATURATE(nApIn + nTemp1); | |
// inject into allpass delay | |
nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApIn, REVERB_BUFFER_MASK); | |
pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1; | |
// inject allpass output into delay line | |
nAddr = CIRCULAR(nBase, pReverbData->m_zD1In, REVERB_BUFFER_MASK); | |
pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut; | |
// ********** Right Allpass - end | |
// ********** D0 output - start | |
// fetch delay line self out | |
nAddr = CIRCULAR(nBase, pReverbData->m_zD0Self, REVERB_BUFFER_MASK); | |
nDelayOut = pReverbData->m_nDelayLine[nAddr]; | |
// calculate delay line self out | |
nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin); | |
// fetch delay line cross out | |
nAddr = CIRCULAR(nBase, pReverbData->m_zD1Cross, REVERB_BUFFER_MASK); | |
nDelayOut = pReverbData->m_nDelayLine[nAddr]; | |
// calculate delay line self out | |
nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos); | |
// calculate unfiltered delay out | |
nDelayOut = SATURATE(nTemp1 + nTemp2); | |
// calculate lowpass filter (mixer scale factor included in LPF feedforward) | |
nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd); | |
nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf0, pReverbData->m_nLpfFbk); | |
// calculate filtered delay out and simultaneously update LPF state variable | |
// filtered delay output is stored in m_zLpf0 | |
pReverbData->m_zLpf0 = (EAS_PCM) SATURATE(nTemp1 + nTemp2); | |
// ********** D0 output - end | |
// ********** D1 output - start | |
// fetch delay line self out | |
nAddr = CIRCULAR(nBase, pReverbData->m_zD1Self, REVERB_BUFFER_MASK); | |
nDelayOut = pReverbData->m_nDelayLine[nAddr]; | |
// calculate delay line self out | |
nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin); | |
// fetch delay line cross out | |
nAddr = CIRCULAR(nBase, pReverbData->m_zD0Cross, REVERB_BUFFER_MASK); | |
nDelayOut = pReverbData->m_nDelayLine[nAddr]; | |
// calculate delay line self out | |
nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos); | |
// calculate unfiltered delay out | |
nDelayOut = SATURATE(nTemp1 + nTemp2); | |
// calculate lowpass filter (mixer scale factor included in LPF feedforward) | |
nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd); | |
nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf1, pReverbData->m_nLpfFbk); | |
// calculate filtered delay out and simultaneously update LPF state variable | |
// filtered delay output is stored in m_zLpf1 | |
pReverbData->m_zLpf1 = (EAS_PCM)SATURATE(nTemp1 + nTemp2); | |
// ********** D1 output - end | |
// ********** mixer and feedback - start | |
// sum is fedback to right input (R + L) | |
pReverbData->m_nRevOutFbkL = | |
(EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 + (EAS_I32)pReverbData->m_zLpf0); | |
// difference is feedback to left input (R - L) | |
/*lint -e{685} lint complains that it can't saturate negative */ | |
pReverbData->m_nRevOutFbkR = | |
(EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 - (EAS_I32)pReverbData->m_zLpf0); | |
// ********** mixer and feedback - end | |
// ********** start early reflection generator, left | |
//psEarly = &(pReverbData->m_sEarlyL); | |
nEarlyOut = 0; | |
for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) | |
{ | |
// fetch delay line out | |
//nAddr = CIRCULAR(nBase, psEarly->m_zDelay[j], REVERB_BUFFER_MASK); | |
nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyL.m_zDelay[j], REVERB_BUFFER_MASK); | |
nDelayOut = pReverbData->m_nDelayLine[nAddr]; | |
// calculate reflection | |
//nTemp1 = MULT_EG1_EG1(nDelayOut, psEarly->m_nGain[j]); | |
nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyL.m_nGain[j]); | |
nEarlyOut = SATURATE(nEarlyOut + nTemp1); | |
} // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) | |
// apply lowpass to early reflections | |
//nTemp1 = MULT_EG1_EG1(nEarlyOut, psEarly->m_nLpfFwd); | |
nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyL.m_nLpfFwd); | |
//nTemp2 = MULT_EG1_EG1(psEarly->m_zLpf, psEarly->m_nLpfFbk); | |
nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyL.m_zLpf, pReverbData->m_sEarlyL.m_nLpfFbk); | |
// calculate filtered out and simultaneously update LPF state variable | |
// filtered output is stored in m_zLpf1 | |
//psEarly->m_zLpf = SATURATE(nTemp1 + nTemp2); | |
pReverbData->m_sEarlyL.m_zLpf = (EAS_PCM) SATURATE(nTemp1 + nTemp2); | |
// combine filtered early and late reflections for output | |
//*pOutputBuffer++ = inL; | |
//tempValue = SATURATE(psEarly->m_zLpf + pReverbData->m_nRevOutFbkL); | |
tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyL.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkL); | |
//scale reverb output by wet level | |
/*lint -e{701} use shift for performance */ | |
tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet<<1)); | |
//sum with output buffer | |
tempValue += *pOutputBuffer; | |
*pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue); | |
// ********** end early reflection generator, left | |
// ********** start early reflection generator, right | |
//psEarly = &(pReverbData->m_sEarlyR); | |
nEarlyOut = 0; | |
for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) | |
{ | |
// fetch delay line out | |
nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyR.m_zDelay[j], REVERB_BUFFER_MASK); | |
nDelayOut = pReverbData->m_nDelayLine[nAddr]; | |
// calculate reflection | |
nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyR.m_nGain[j]); | |
nEarlyOut = SATURATE(nEarlyOut + nTemp1); | |
} // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) | |
// apply lowpass to early reflections | |
nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyR.m_nLpfFwd); | |
nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyR.m_zLpf, pReverbData->m_sEarlyR.m_nLpfFbk); | |
// calculate filtered out and simultaneously update LPF state variable | |
// filtered output is stored in m_zLpf1 | |
pReverbData->m_sEarlyR.m_zLpf = (EAS_PCM)SATURATE(nTemp1 + nTemp2); | |
// combine filtered early and late reflections for output | |
//*pOutputBuffer++ = inR; | |
tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyR.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkR); | |
//scale reverb output by wet level | |
/*lint -e{701} use shift for performance */ | |
tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet << 1)); | |
//sum with output buffer | |
tempValue = tempValue + *pOutputBuffer; | |
*pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue); | |
// ********** end early reflection generator, right | |
// decrement base addr for next sample period | |
nBase--; | |
pReverbData->m_nSin += pReverbData->m_nSinIncrement; | |
pReverbData->m_nCos += pReverbData->m_nCosIncrement; | |
} // end for (i=0; i < nNumSamplesToAdd; i++) | |
// store the most up to date version | |
pReverbData->m_nBaseIndex = nBase; | |
return EAS_SUCCESS; | |
} /* end Reverb */ | |
/*---------------------------------------------------------------------------- | |
* ReverbShutdown() | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* Initializes the Reverb effect. | |
* | |
* Inputs: | |
* pInstData - handle to instance data | |
* | |
* Outputs: | |
* | |
* | |
* Side Effects: | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData) | |
{ | |
/* check Configuration Module for static memory allocation */ | |
if (!pEASData->staticMemoryModel) | |
EAS_HWFree(pEASData->hwInstData, pInstData); | |
return EAS_SUCCESS; | |
} /* end ReverbShutdown */ | |
/*---------------------------------------------------------------------------- | |
* ReverbGetParam() | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* Get a Reverb parameter | |
* | |
* Inputs: | |
* pInstData - handle to instance data | |
* param - parameter index | |
* *pValue - pointer to variable to hold retrieved value | |
* | |
* Outputs: | |
* | |
* | |
* Side Effects: | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) | |
{ | |
S_REVERB_OBJECT *p; | |
p = (S_REVERB_OBJECT*) pInstData; | |
switch (param) | |
{ | |
case EAS_PARAM_REVERB_BYPASS: | |
*pValue = (EAS_I32) p->m_bBypass; | |
break; | |
case EAS_PARAM_REVERB_PRESET: | |
*pValue = (EAS_I8) p->m_nCurrentRoom; | |
break; | |
case EAS_PARAM_REVERB_WET: | |
*pValue = p->m_nWet; | |
break; | |
case EAS_PARAM_REVERB_DRY: | |
*pValue = p->m_nDry; | |
break; | |
default: | |
return EAS_ERROR_INVALID_PARAMETER; | |
} | |
return EAS_SUCCESS; | |
} /* end ReverbGetParam */ | |
/*---------------------------------------------------------------------------- | |
* ReverbSetParam() | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* Set a Reverb parameter | |
* | |
* Inputs: | |
* pInstData - handle to instance data | |
* param - parameter index | |
* *pValue - new paramter value | |
* | |
* Outputs: | |
* | |
* | |
* Side Effects: | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) | |
{ | |
S_REVERB_OBJECT *p; | |
p = (S_REVERB_OBJECT*) pInstData; | |
switch (param) | |
{ | |
case EAS_PARAM_REVERB_BYPASS: | |
p->m_bBypass = (EAS_BOOL) value; | |
break; | |
case EAS_PARAM_REVERB_PRESET: | |
if(value!=EAS_PARAM_REVERB_LARGE_HALL && value!=EAS_PARAM_REVERB_HALL && | |
value!=EAS_PARAM_REVERB_CHAMBER && value!=EAS_PARAM_REVERB_ROOM) | |
return EAS_ERROR_INVALID_PARAMETER; | |
p->m_nNextRoom = (EAS_I16)value; | |
break; | |
case EAS_PARAM_REVERB_WET: | |
if(value>EAS_REVERB_WET_MAX || value<EAS_REVERB_WET_MIN) | |
return EAS_ERROR_INVALID_PARAMETER; | |
p->m_nWet = (EAS_I16)value; | |
break; | |
case EAS_PARAM_REVERB_DRY: | |
if(value>EAS_REVERB_DRY_MAX || value<EAS_REVERB_DRY_MIN) | |
return EAS_ERROR_INVALID_PARAMETER; | |
p->m_nDry = (EAS_I16)value; | |
break; | |
default: | |
return EAS_ERROR_INVALID_PARAMETER; | |
} | |
return EAS_SUCCESS; | |
} /* end ReverbSetParam */ | |
/*---------------------------------------------------------------------------- | |
* ReverbUpdateRoom | |
*---------------------------------------------------------------------------- | |
* Purpose: | |
* Update the room's preset parameters as required | |
* | |
* Inputs: | |
* | |
* Outputs: | |
* | |
* | |
* Side Effects: | |
* - reverb paramters (fbk, fwd, etc) will be changed | |
* - m_nCurrentRoom := m_nNextRoom | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT *pReverbData) | |
{ | |
EAS_INT temp; | |
S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom]; | |
pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd; | |
pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk; | |
pReverbData->m_nEarly = pPreset->m_nEarly; | |
pReverbData->m_nWet = pPreset->m_nWet; | |
pReverbData->m_nDry = pPreset->m_nDry; | |
pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion; | |
//stored as time based, convert to sample based | |
temp = pPreset->m_nXfadeInterval; | |
/*lint -e{702} shift for performance */ | |
temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; | |
pReverbData->m_nXfadeInterval = (EAS_U16) temp; | |
//gpsReverbObject->m_nXfadeInterval = pPreset->m_nXfadeInterval; | |
pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain; | |
//stored as time based, convert to absolute sample value | |
temp = pPreset->m_nAp0_ApOut; | |
/*lint -e{702} shift for performance */ | |
temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; | |
pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp); | |
//gpsReverbObject->m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut; | |
pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain; | |
//stored as time based, convert to absolute sample value | |
temp = pPreset->m_nAp1_ApOut; | |
/*lint -e{702} shift for performance */ | |
temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; | |
pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp); | |
//gpsReverbObject->m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut; | |
pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom; | |
return EAS_SUCCESS; | |
} /* end ReverbUpdateRoom */ | |
/*---------------------------------------------------------------------------- | |
* ReverbReadInPresets() | |
*---------------------------------------------------------------------------- | |
* Purpose: sets global reverb preset bank to defaults | |
* | |
* Inputs: | |
* | |
* Outputs: | |
* | |
*---------------------------------------------------------------------------- | |
*/ | |
static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT *pReverbData) | |
{ | |
int preset = 0; | |
int defaultPreset = 0; | |
//now init any remaining presets to defaults | |
for (defaultPreset = preset; defaultPreset < REVERB_MAX_ROOM_TYPE; defaultPreset++) | |
{ | |
S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[defaultPreset]; | |
if (defaultPreset == 0 || defaultPreset > REVERB_MAX_ROOM_TYPE-1) | |
{ | |
pPreset->m_nLpfFbk = 8307; | |
pPreset->m_nLpfFwd = 14768; | |
pPreset->m_nEarly = 0; | |
pPreset->m_nWet = 27690; | |
pPreset->m_nDry = 32767; | |
pPreset->m_nEarlyL_LpfFbk = 3692; | |
pPreset->m_nEarlyL_LpfFwd = 29075; | |
pPreset->m_nEarlyL_Delay0 = 922; | |
pPreset->m_nEarlyL_Gain0 = 22152; | |
pPreset->m_nEarlyL_Delay1 = 1462; | |
pPreset->m_nEarlyL_Gain1 = 17537; | |
pPreset->m_nEarlyL_Delay2 = 0; | |
pPreset->m_nEarlyL_Gain2 = 14768; | |
pPreset->m_nEarlyL_Delay3 = 1221; | |
pPreset->m_nEarlyL_Gain3 = 14307; | |
pPreset->m_nEarlyL_Delay4 = 0; | |
pPreset->m_nEarlyL_Gain4 = 13384; | |
pPreset->m_nEarlyR_Delay0 = 502; | |
pPreset->m_nEarlyR_Gain0 = 20306; | |
pPreset->m_nEarlyR_Delay1 = 1762; | |
pPreset->m_nEarlyR_Gain1 = 17537; | |
pPreset->m_nEarlyR_Delay2 = 0; | |
pPreset->m_nEarlyR_Gain2 = 14768; | |
pPreset->m_nEarlyR_Delay3 = 0; | |
pPreset->m_nEarlyR_Gain3 = 16153; | |
pPreset->m_nEarlyR_Delay4 = 0; | |
pPreset->m_nEarlyR_Gain4 = 13384; | |
pPreset->m_nMaxExcursion = 127; | |
pPreset->m_nXfadeInterval = 6388; | |
pPreset->m_nAp0_ApGain = 15691; | |
pPreset->m_nAp0_ApOut = 711; | |
pPreset->m_nAp1_ApGain = 17999; | |
pPreset->m_nAp1_ApOut = 1113; | |
pPreset->m_rfu4 = 0; | |
pPreset->m_rfu5 = 0; | |
pPreset->m_rfu6 = 0; | |
pPreset->m_rfu7 = 0; | |
pPreset->m_rfu8 = 0; | |
pPreset->m_rfu9 = 0; | |
pPreset->m_rfu10 = 0; | |
} | |
else if (defaultPreset == 1) | |
{ | |
pPreset->m_nLpfFbk = 6461; | |
pPreset->m_nLpfFwd = 14307; | |
pPreset->m_nEarly = 0; | |
pPreset->m_nWet = 27690; | |
pPreset->m_nDry = 32767; | |
pPreset->m_nEarlyL_LpfFbk = 3692; | |
pPreset->m_nEarlyL_LpfFwd = 29075; | |
pPreset->m_nEarlyL_Delay0 = 922; | |
pPreset->m_nEarlyL_Gain0 = 22152; | |
pPreset->m_nEarlyL_Delay1 = 1462; | |
pPreset->m_nEarlyL_Gain1 = 17537; | |
pPreset->m_nEarlyL_Delay2 = 0; | |
pPreset->m_nEarlyL_Gain2 = 14768; | |
pPreset->m_nEarlyL_Delay3 = 1221; | |
pPreset->m_nEarlyL_Gain3 = 14307; | |
pPreset->m_nEarlyL_Delay4 = 0; | |
pPreset->m_nEarlyL_Gain4 = 13384; | |
pPreset->m_nEarlyR_Delay0 = 502; | |
pPreset->m_nEarlyR_Gain0 = 20306; | |
pPreset->m_nEarlyR_Delay1 = 1762; | |
pPreset->m_nEarlyR_Gain1 = 17537; | |
pPreset->m_nEarlyR_Delay2 = 0; | |
pPreset->m_nEarlyR_Gain2 = 14768; | |
pPreset->m_nEarlyR_Delay3 = 0; | |
pPreset->m_nEarlyR_Gain3 = 16153; | |
pPreset->m_nEarlyR_Delay4 = 0; | |
pPreset->m_nEarlyR_Gain4 = 13384; | |
pPreset->m_nMaxExcursion = 127; | |
pPreset->m_nXfadeInterval = 6391; | |
pPreset->m_nAp0_ApGain = 15230; | |
pPreset->m_nAp0_ApOut = 708; | |
pPreset->m_nAp1_ApGain = 9692; | |
pPreset->m_nAp1_ApOut = 1113; | |
pPreset->m_rfu4 = 0; | |
pPreset->m_rfu5 = 0; | |
pPreset->m_rfu6 = 0; | |
pPreset->m_rfu7 = 0; | |
pPreset->m_rfu8 = 0; | |
pPreset->m_rfu9 = 0; | |
pPreset->m_rfu10 = 0; | |
} | |
else if (defaultPreset == 2) | |
{ | |
pPreset->m_nLpfFbk = 5077; | |
pPreset->m_nLpfFwd = 12922; | |
pPreset->m_nEarly = 0; | |
pPreset->m_nWet = 24460; | |
pPreset->m_nDry = 32767; | |
pPreset->m_nEarlyL_LpfFbk = 3692; | |
pPreset->m_nEarlyL_LpfFwd = 29075; | |
pPreset->m_nEarlyL_Delay0 = 922; | |
pPreset->m_nEarlyL_Gain0 = 22152; | |
pPreset->m_nEarlyL_Delay1 = 1462; | |
pPreset->m_nEarlyL_Gain1 = 17537; | |
pPreset->m_nEarlyL_Delay2 = 0; | |
pPreset->m_nEarlyL_Gain2 = 14768; | |
pPreset->m_nEarlyL_Delay3 = 1221; | |
pPreset->m_nEarlyL_Gain3 = 14307; | |
pPreset->m_nEarlyL_Delay4 = 0; | |
pPreset->m_nEarlyL_Gain4 = 13384; | |
pPreset->m_nEarlyR_Delay0 = 502; | |
pPreset->m_nEarlyR_Gain0 = 20306; | |
pPreset->m_nEarlyR_Delay1 = 1762; | |
pPreset->m_nEarlyR_Gain1 = 17537; | |
pPreset->m_nEarlyR_Delay2 = 0; | |
pPreset->m_nEarlyR_Gain2 = 14768; | |
pPreset->m_nEarlyR_Delay3 = 0; | |
pPreset->m_nEarlyR_Gain3 = 16153; | |
pPreset->m_nEarlyR_Delay4 = 0; | |
pPreset->m_nEarlyR_Gain4 = 13384; | |
pPreset->m_nMaxExcursion = 127; | |
pPreset->m_nXfadeInterval = 6449; | |
pPreset->m_nAp0_ApGain = 15691; | |
pPreset->m_nAp0_ApOut = 774; | |
pPreset->m_nAp1_ApGain = 15691; | |
pPreset->m_nAp1_ApOut = 1113; | |
pPreset->m_rfu4 = 0; | |
pPreset->m_rfu5 = 0; | |
pPreset->m_rfu6 = 0; | |
pPreset->m_rfu7 = 0; | |
pPreset->m_rfu8 = 0; | |
pPreset->m_rfu9 = 0; | |
pPreset->m_rfu10 = 0; | |
} | |
else if (defaultPreset == 3) | |
{ | |
pPreset->m_nLpfFbk = 5077; | |
pPreset->m_nLpfFwd = 11076; | |
pPreset->m_nEarly = 0; | |
pPreset->m_nWet = 23075; | |
pPreset->m_nDry = 32767; | |
pPreset->m_nEarlyL_LpfFbk = 3692; | |
pPreset->m_nEarlyL_LpfFwd = 29075; | |
pPreset->m_nEarlyL_Delay0 = 922; | |
pPreset->m_nEarlyL_Gain0 = 22152; | |
pPreset->m_nEarlyL_Delay1 = 1462; | |
pPreset->m_nEarlyL_Gain1 = 17537; | |
pPreset->m_nEarlyL_Delay2 = 0; | |
pPreset->m_nEarlyL_Gain2 = 14768; | |
pPreset->m_nEarlyL_Delay3 = 1221; | |
pPreset->m_nEarlyL_Gain3 = 14307; | |
pPreset->m_nEarlyL_Delay4 = 0; | |
pPreset->m_nEarlyL_Gain4 = 13384; | |
pPreset->m_nEarlyR_Delay0 = 502; | |
pPreset->m_nEarlyR_Gain0 = 20306; | |
pPreset->m_nEarlyR_Delay1 = 1762; | |
pPreset->m_nEarlyR_Gain1 = 17537; | |
pPreset->m_nEarlyR_Delay2 = 0; | |
pPreset->m_nEarlyR_Gain2 = 14768; | |
pPreset->m_nEarlyR_Delay3 = 0; | |
pPreset->m_nEarlyR_Gain3 = 16153; | |
pPreset->m_nEarlyR_Delay4 = 0; | |
pPreset->m_nEarlyR_Gain4 = 13384; | |
pPreset->m_nMaxExcursion = 127; | |
pPreset->m_nXfadeInterval = 6470; //6483; | |
pPreset->m_nAp0_ApGain = 14768; | |
pPreset->m_nAp0_ApOut = 792; | |
pPreset->m_nAp1_ApGain = 15783; | |
pPreset->m_nAp1_ApOut = 1113; | |
pPreset->m_rfu4 = 0; | |
pPreset->m_rfu5 = 0; | |
pPreset->m_rfu6 = 0; | |
pPreset->m_rfu7 = 0; | |
pPreset->m_rfu8 = 0; | |
pPreset->m_rfu9 = 0; | |
pPreset->m_rfu10 = 0; | |
} | |
} | |
return EAS_SUCCESS; | |
} |