| /*---------------------------------------------------------------------------- |
| * |
| * 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; |
| } |