123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605 |
- /*----------------------------------------------------------------------------
- *
- * File:
- * eas_chorus.c
- *
- * Contents and purpose:
- * Contains the implementation of the Chorus 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: 499 $
- * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
- *----------------------------------------------------------------------------
- */
- #include "eas_data.h"
- #include "eas_effects.h"
- #include "eas_math.h"
- #include "eas_chorusdata.h"
- #include "eas_chorus.h"
- #include "eas_config.h"
- #include "eas_host.h"
- #include "eas_report.h"
- /* prototypes for effects interface */
- static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
- static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
- static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
- static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
- static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
- /* common effects interface for configuration module */
- const S_EFFECTS_INTERFACE EAS_Chorus =
- {
- ChorusInit,
- ChorusProcess,
- ChorusShutdown,
- ChorusGetParam,
- ChorusSetParam
- };
- //LFO shape table used by the chorus, larger table would sound better
- //this is a sine wave, where 32767 = 1.0
- static const EAS_I16 EAS_chorusShape[CHORUS_SHAPE_SIZE] = {
- 0, 1608, 3212, 4808, 6393, 7962, 9512, 11309, 12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005, 23170,
- 24279, 25329, 26319, 27245, 28105, 28898, 29621, 30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728,
- 32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852, 30273, 29621, 28898, 28105, 27245, 26319, 25329,
- 24279, 23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010, 12539, 11039, 9512, 7962, 6393, 4808, 3212,
- 1608, 0, -1608, -3212, -4808, -6393, -7962, -9512, -11309, -12539, -14010, -15446, -16846, -18204, -19519,
- -20787, -22005, -23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621, -30273, -30852, -31356, -31785,
- -32137, -32412, -32609, -32728, -32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852, -30273, -29621,
- -28898, -28105, -27245, -26319, -25329, -24279, -23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
- -12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608
- };
- /*----------------------------------------------------------------------------
- * InitializeChorus()
- *----------------------------------------------------------------------------
- * Purpose: Initializes chorus parameters
- *
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
- */
- static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
- {
- S_CHORUS_OBJECT *pChorusData;
- S_CHORUS_PRESET *pPreset;
- EAS_I32 index;
- /* check Configuration Module for data allocation */
- if (pEASData->staticMemoryModel)
- pChorusData = EAS_CMEnumFXData(EAS_MODULE_CHORUS);
- /* allocate dynamic memory */
- else
- pChorusData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_CHORUS_OBJECT));
- if (pChorusData == NULL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Chorus memory\n"); */ }
- return EAS_ERROR_MALLOC_FAILED;
- }
- /* clear the structure */
- EAS_HWMemSet(pChorusData, 0, sizeof(S_CHORUS_OBJECT));
- ChorusReadInPresets(pChorusData);
- /* set some default values */
- pChorusData->bypass = EAS_CHORUS_BYPASS_DEFAULT;
- pChorusData->preset = EAS_CHORUS_PRESET_DEFAULT;
- pChorusData->m_nLevel = EAS_CHORUS_LEVEL_DEFAULT;
- pChorusData->m_nRate = EAS_CHORUS_RATE_DEFAULT;
- pChorusData->m_nDepth = EAS_CHORUS_DEPTH_DEFAULT;
- //chorus rate and depth need some massaging from preset value (which is sample rate independent)
- //convert rate from steps of .05 Hz to value which can be used as phase increment,
- //with current CHORUS_SHAPE_SIZE and rate limits, this fits into 16 bits
- //want to compute ((shapeSize * 65536) * (storedRate/20))/sampleRate;
- //computing it as below allows rate steps to be evenly spaced
- //uses 32 bit divide, but only once when new value is selected
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
- //convert depth from steps of .05 ms, to samples, with 16 bit whole part, discard fraction
- //want to compute ((depth * sampleRate)/20000)
- //use the following approximation since 105/32 is roughly 65536/20000
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
- pChorusData->m_nLevel = pChorusData->m_nLevel;
- //zero delay memory for chorus
- for (index = CHORUS_L_SIZE - 1; index >= 0; index--)
- {
- pChorusData->chorusDelayL[index] = 0;
- }
- for (index = CHORUS_R_SIZE - 1; index >= 0; index--)
- {
- pChorusData->chorusDelayR[index] = 0;
- }
- //init delay line index, these are used to implement circular delay buffer
- pChorusData->chorusIndexL = 0;
- pChorusData->chorusIndexR = 0;
- //init LFO phase
- //16 bit whole part, 16 bit fraction
- pChorusData->lfoLPhase = 0;
- pChorusData->lfoRPhase = (CHORUS_SHAPE_SIZE << 16) >> 2; // 1/4 of total, i.e. 90 degrees out of phase;
- //init chorus delay position
- //right now chorus delay is a compile-time value, as is sample rate
- pChorusData->chorusTapPosition = (EAS_I16)((CHORUS_DELAY_MS * _OUTPUT_SAMPLE_RATE)/1000);
- //now copy from the new preset into Chorus
- pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
- pChorusData->m_nLevel = pPreset->m_nLevel;
- pChorusData->m_nRate = pPreset->m_nRate;
- pChorusData->m_nDepth = pPreset->m_nDepth;
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
- *pInstData = pChorusData;
- return EAS_SUCCESS;
- } /* end ChorusInit */
- /*----------------------------------------------------------------------------
- * WeightedTap()
- *----------------------------------------------------------------------------
- * Purpose: Does fractional array look-up using linear interpolation
- *
- * first convert indexDesired to actual desired index by taking into account indexReference
- * then do linear interpolation between two actual samples using fractional part
- *
- * Inputs:
- * array: pointer to array of signed 16 bit values, typically either PCM data or control data
- * indexReference: the circular buffer relative offset
- * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
- * indexLimit: the total size of the array, used to compute buffer wrap
- *
- * Outputs:
- * Value from the input array, linearly interpolated between two actual data values
- *
- *----------------------------------------------------------------------------
- */
- static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit)
- {
- EAS_I16 index;
- EAS_I16 fraction;
- EAS_I16 val1;
- EAS_I16 val2;
- //separate indexDesired into whole and fractional parts
- /*lint -e{704} use shift for performance */
- index = (EAS_I16)(indexDesired >> 16);
- /*lint -e{704} use shift for performance */
- fraction = (EAS_I16)((indexDesired>>1) & 0x07FFF); //just use 15 bits of fractional part
- //adjust whole part by indexReference
- index = indexReference - index;
- //make sure we stay within array bounds, this implements circular buffer
- while (index < 0)
- {
- index += indexLimit;
- }
- //get two adjacent values from the array
- val1 = array[index];
- //handle special case when index == 0, else typical case
- if (index == 0)
- {
- val2 = array[indexLimit-1]; //get last value from array
- }
- else
- {
- val2 = array[index-1]; //get previous value from array
- }
- //compute linear interpolation as (val1 + ((val2-val1)*fraction))
- return(val1 + (EAS_I16)MULT_EG1_EG1(val2-val1,fraction));
- }
- /*----------------------------------------------------------------------------
- * ChorusProcess()
- *----------------------------------------------------------------------------
- * Purpose: compute the chorus on the input buffer, and mix into output buffer
- *
- *
- * Inputs:
- * src: pointer to input buffer of PCM values to be processed
- * dst: pointer to output buffer of PCM values we are to sume the result with
- * bufSize: the number of sample frames (i.e. stereo samples) in the buffer
- *
- * Outputs:
- * None
- *
- *----------------------------------------------------------------------------
- */
- //compute the chorus, and mix into output buffer
- static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
- {
- EAS_I32 ix;
- EAS_I32 nChannelNumber;
- EAS_I16 lfoValueLeft;
- EAS_I16 lfoValueRight;
- EAS_I32 positionOffsetL;
- EAS_I32 positionOffsetR;
- EAS_PCM tapL;
- EAS_PCM tapR;
- EAS_I32 tempValue;
- EAS_PCM nInputSample;
- EAS_I32 nOutputSample;
- EAS_PCM *pIn;
- EAS_PCM *pOut;
- S_CHORUS_OBJECT *pChorusData;
- pChorusData = (S_CHORUS_OBJECT*) pInstData;
- //if the chorus is disabled or turned all the way down
- if (pChorusData->bypass == EAS_TRUE || pChorusData->m_nLevel == 0)
- {
- if (pSrc != pDst)
- EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
- return;
- }
- if (pChorusData->m_nNextChorus != pChorusData->m_nCurrentChorus)
- {
- ChorusUpdate(pChorusData);
- }
- for (nChannelNumber = 0; nChannelNumber < NUM_OUTPUT_CHANNELS; nChannelNumber++)
- {
- pIn = pSrc + nChannelNumber;
- pOut = pDst + nChannelNumber;
- if(nChannelNumber==0)
- {
- for (ix = 0; ix < numSamples; ix++)
- {
- nInputSample = *pIn;
- pIn += NUM_OUTPUT_CHANNELS;
- //feed input into chorus delay line
- pChorusData->chorusDelayL[pChorusData->chorusIndexL] = nInputSample;
- //compute chorus lfo value using phase as fractional index into chorus shape table
- //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
- lfoValueLeft = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoLPhase, CHORUS_SHAPE_SIZE);
- //scale chorus depth by lfo value to get relative fractional sample index
- //index is expressed as 32 bit number with 16 bit fractional part
- /*lint -e{703} use shift for performance */
- positionOffsetL = pChorusData->m_nDepth * (((EAS_I32)lfoValueLeft) << 1);
- //add fixed chorus delay to get actual fractional sample index
- positionOffsetL += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
- //get tap value from chorus delay using fractional sample index
- tapL = WeightedTap(pChorusData->chorusDelayL, pChorusData->chorusIndexL, positionOffsetL, CHORUS_L_SIZE);
- //scale by chorus level, then sum with input buffer contents and saturate
- tempValue = MULT_EG1_EG1(tapL, pChorusData->m_nLevel);
- nOutputSample = SATURATE(tempValue + nInputSample);
- *pOut = (EAS_I16)SATURATE(nOutputSample);
- pOut += NUM_OUTPUT_CHANNELS;
- //increment chorus delay index and make it wrap as needed
- //this implements circular buffer
- if ((pChorusData->chorusIndexL+=1) >= CHORUS_L_SIZE)
- pChorusData->chorusIndexL = 0;
- //increment fractional lfo phase, and make it wrap as needed
- pChorusData->lfoLPhase += pChorusData->m_nRate;
- while (pChorusData->lfoLPhase >= (CHORUS_SHAPE_SIZE<<16))
- {
- pChorusData->lfoLPhase -= (CHORUS_SHAPE_SIZE<<16);
- }
- }
- }
- else
- {
- for (ix = 0; ix < numSamples; ix++)
- {
- nInputSample = *pIn;
- pIn += NUM_OUTPUT_CHANNELS;
- //feed input into chorus delay line
- pChorusData->chorusDelayR[pChorusData->chorusIndexR] = nInputSample;
- //compute chorus lfo value using phase as fractional index into chorus shape table
- //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
- lfoValueRight = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoRPhase, CHORUS_SHAPE_SIZE);
- //scale chorus depth by lfo value to get relative fractional sample index
- //index is expressed as 32 bit number with 16 bit fractional part
- /*lint -e{703} use shift for performance */
- positionOffsetR = pChorusData->m_nDepth * (((EAS_I32)lfoValueRight) << 1);
- //add fixed chorus delay to get actual fractional sample index
- positionOffsetR += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
- //get tap value from chorus delay using fractional sample index
- tapR = WeightedTap(pChorusData->chorusDelayR, pChorusData->chorusIndexR, positionOffsetR, CHORUS_R_SIZE);
- //scale by chorus level, then sum with output buffer contents and saturate
- tempValue = MULT_EG1_EG1(tapR, pChorusData->m_nLevel);
- nOutputSample = SATURATE(tempValue + nInputSample);
- *pOut = (EAS_I16)SATURATE(nOutputSample);
- pOut += NUM_OUTPUT_CHANNELS;
- //increment chorus delay index and make it wrap as needed
- //this implements circular buffer
- if ((pChorusData->chorusIndexR+=1) >= CHORUS_R_SIZE)
- pChorusData->chorusIndexR = 0;
- //increment fractional lfo phase, and make it wrap as needed
- pChorusData->lfoRPhase += pChorusData->m_nRate;
- while (pChorusData->lfoRPhase >= (CHORUS_SHAPE_SIZE<<16))
- {
- pChorusData->lfoRPhase -= (CHORUS_SHAPE_SIZE<<16);
- }
- }
- }
- }
- } /* end ChorusProcess */
- /*----------------------------------------------------------------------------
- * ChorusShutdown()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the Chorus effect.
- *
- * Inputs:
- * pInstData - handle to instance data
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
- */
- static EAS_RESULT ChorusShutdown (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 ChorusShutdown */
- /*----------------------------------------------------------------------------
- * ChorusGetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Get a Chorus parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - pointer to variable to hold retrieved value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
- */
- static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
- {
- S_CHORUS_OBJECT *p;
- p = (S_CHORUS_OBJECT*) pInstData;
- switch (param)
- {
- case EAS_PARAM_CHORUS_BYPASS:
- *pValue = (EAS_I32) p->bypass;
- break;
- case EAS_PARAM_CHORUS_PRESET:
- *pValue = (EAS_I8) p->m_nCurrentChorus;
- break;
- case EAS_PARAM_CHORUS_RATE:
- *pValue = (EAS_I32) p->m_nRate;
- break;
- case EAS_PARAM_CHORUS_DEPTH:
- *pValue = (EAS_I32) p->m_nDepth;
- break;
- case EAS_PARAM_CHORUS_LEVEL:
- *pValue = (EAS_I32) p->m_nLevel;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
- } /* end ChorusGetParam */
- /*----------------------------------------------------------------------------
- * ChorusSetParam()
- *----------------------------------------------------------------------------
- * Purpose:
- * Set a Chorus parameter
- *
- * Inputs:
- * pInstData - handle to instance data
- * param - parameter index
- * *pValue - new paramter value
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
- */
- static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
- {
- S_CHORUS_OBJECT *p;
- p = (S_CHORUS_OBJECT*) pInstData;
- switch (param)
- {
- case EAS_PARAM_CHORUS_BYPASS:
- p->bypass = (EAS_BOOL) value;
- break;
- case EAS_PARAM_CHORUS_PRESET:
- if(value!=EAS_PARAM_CHORUS_PRESET1 && value!=EAS_PARAM_CHORUS_PRESET2 &&
- value!=EAS_PARAM_CHORUS_PRESET3 && value!=EAS_PARAM_CHORUS_PRESET4)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nNextChorus = (EAS_I8)value;
- break;
- case EAS_PARAM_CHORUS_RATE:
- if(value<EAS_CHORUS_RATE_MIN || value>EAS_CHORUS_RATE_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nRate = (EAS_I16) value;
- break;
- case EAS_PARAM_CHORUS_DEPTH:
- if(value<EAS_CHORUS_DEPTH_MIN || value>EAS_CHORUS_DEPTH_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nDepth = (EAS_I16) value;
- break;
- case EAS_PARAM_CHORUS_LEVEL:
- if(value<EAS_CHORUS_LEVEL_MIN || value>EAS_CHORUS_LEVEL_MAX)
- return EAS_ERROR_INVALID_PARAMETER;
- p->m_nLevel = (EAS_I16) value;
- break;
- default:
- return EAS_ERROR_INVALID_PARAMETER;
- }
- return EAS_SUCCESS;
- } /* end ChorusSetParam */
- /*----------------------------------------------------------------------------
- * ChorusReadInPresets()
- *----------------------------------------------------------------------------
- * Purpose: sets global Chorus preset bank to defaults
- *
- * Inputs:
- *
- * Outputs:
- *
- *----------------------------------------------------------------------------
- */
- static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData)
- {
- int preset = 0;
- int defaultPreset = 0;
- //now init any remaining presets to defaults
- for (defaultPreset = preset; defaultPreset < CHORUS_MAX_TYPE; defaultPreset++)
- {
- S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[defaultPreset];
- if (defaultPreset == 0 || defaultPreset > CHORUS_MAX_TYPE-1)
- {
- pPreset->m_nDepth = 39;
- pPreset->m_nRate = 30;
- pPreset->m_nLevel = 32767;
- }
- else if (defaultPreset == 1)
- {
- pPreset->m_nDepth = 21;
- pPreset->m_nRate = 45;
- pPreset->m_nLevel = 25000;
- }
- else if (defaultPreset == 2)
- {
- pPreset->m_nDepth = 53;
- pPreset->m_nRate = 25;
- pPreset->m_nLevel = 32000;
- }
- else if (defaultPreset == 3)
- {
- pPreset->m_nDepth = 32;
- pPreset->m_nRate = 37;
- pPreset->m_nLevel = 29000;
- }
- }
- return EAS_SUCCESS;
- }
- /*----------------------------------------------------------------------------
- * ChorusUpdate
- *----------------------------------------------------------------------------
- * Purpose:
- * Update the Chorus preset parameters as required
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- * - chorus paramters will be changed
- * - m_nCurrentRoom := m_nNextRoom
- *----------------------------------------------------------------------------
- */
- static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT *pChorusData)
- {
- S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
- pChorusData->m_nLevel = pPreset->m_nLevel;
- pChorusData->m_nRate = pPreset->m_nRate;
- pChorusData->m_nDepth = pPreset->m_nDepth;
- pChorusData->m_nRate = (EAS_I16)
- ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
- /*lint -e{704} use shift for performance */
- pChorusData->m_nDepth = (EAS_I16)
- (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
- pChorusData->m_nCurrentChorus = pChorusData->m_nNextChorus;
- return EAS_SUCCESS;
- } /* end ChorusUpdate */
|