diff options
Diffstat (limited to 'arm-wt-22k/lib_src/eas_dlssynth.c')
-rw-r--r-- | arm-wt-22k/lib_src/eas_dlssynth.c | 578 |
1 files changed, 578 insertions, 0 deletions
diff --git a/arm-wt-22k/lib_src/eas_dlssynth.c b/arm-wt-22k/lib_src/eas_dlssynth.c new file mode 100644 index 0000000..c1fa1ef --- /dev/null +++ b/arm-wt-22k/lib_src/eas_dlssynth.c @@ -0,0 +1,578 @@ +/*---------------------------------------------------------------------------- + * + * File: + * eas_dlssynth.c + * + * Contents and purpose: + * Implements the Mobile DLS synthesizer. + * + * 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: 795 $ + * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $ + *---------------------------------------------------------------------------- +*/ + +// includes +#include "eas_data.h" +#include "eas_report.h" +#include "eas_host.h" +#include "eas_math.h" +#include "eas_synth_protos.h" +#include "eas_wtsynth.h" +#include "eas_pan.h" +#include "eas_mdls.h" +#include "eas_dlssynth.h" + +#ifdef _METRICS_ENABLED +#include "eas_perf.h" +#endif + +static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, const S_DLS_ENVELOPE *pEnvParams, EAS_I16 *pValue, EAS_I16 *pIncrement, EAS_U8 *pState); + +/*---------------------------------------------------------------------------- + * DLS_MuteVoice() + *---------------------------------------------------------------------------- + * Mute the voice using shutdown time from the DLS articulation data + *---------------------------------------------------------------------------- +*/ +void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum) +{ + S_WT_VOICE *pWTVoice; + const S_DLS_ARTICULATION *pDLSArt; + + pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; + pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; + + /* clear deferred action flags */ + pVoice->voiceFlags &= + ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF | + VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF | + VOICE_FLAG_DEFER_MUTE); + + /* set the envelope state */ + pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateRelease; + pWTVoice->eg1Increment = pDLSArt->eg1ShutdownTime; + pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateRelease; + pWTVoice->eg2Increment = pDLSArt->eg2.releaseTime; +} + +/*---------------------------------------------------------------------------- + * DLS_ReleaseVoice() + *---------------------------------------------------------------------------- + * Release the selected voice. + *---------------------------------------------------------------------------- +*/ +/*lint -esym(715, pVoice) standard API, pVoice may be used by other synthesizers */ +void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum) +{ + S_WT_VOICE *pWTVoice; + const S_DLS_ARTICULATION *pDLSArt; + + pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; + pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; + + /* if still in attack phase, convert units to log */ + /*lint -e{732} eg1Value is never negative */ + /*lint -e{703} use shift for performance */ + if (pWTVoice->eg1State == eEnvelopeStateAttack) + pWTVoice->eg1Value = (EAS_I16) ((EAS_flog2(pWTVoice->eg1Value) << 1) + 2048); + + /* release EG1 */ + pWTVoice->eg1State = eEnvelopeStateRelease; + pWTVoice->eg1Increment = pDLSArt->eg1.releaseTime; + + /* release EG2 */ + pWTVoice->eg2State = eEnvelopeStateRelease; + pWTVoice->eg2Increment = pDLSArt->eg2.releaseTime; +} + +/*---------------------------------------------------------------------------- + * DLS_SustainPedal() + *---------------------------------------------------------------------------- + * The sustain pedal was just depressed. If the voice is still + * above the sustain level, catch the voice and continue holding. + *---------------------------------------------------------------------------- +*/ +/*lint -esym(715, pChannel) pChannel reserved for future use */ +void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum) +{ + S_WT_VOICE *pWTVoice; + const S_DLS_ARTICULATION *pDLSArt; + + pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; + pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; + + /* don't catch the voice if below the sustain level */ + if (pWTVoice->eg1Value < pDLSArt->eg1.sustainLevel) + return; + + /* defer releasing this note until the damper pedal is off */ + pWTVoice->eg1State = eEnvelopeStateDecay; + pVoice->voiceState = eVoiceStatePlay; + pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF; + +#ifdef _DEBUG_SYNTH + { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_SustainPedal: defer note off because sustain pedal is on\n"); */ } +#endif +} + +/*---------------------------------------------------------------------------- + * DLS_UpdatePhaseInc() + *---------------------------------------------------------------------------- + * Calculate the oscillator phase increment for the next frame + *---------------------------------------------------------------------------- +*/ +static EAS_I32 DLS_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents) +{ + EAS_I32 temp; + + /* start with base mod LFO modulation */ + temp = pDLSArt->modLFOToPitch; + + /* add mod wheel effect */ + /*lint -e{702} use shift for performance */ + temp += ((pDLSArt->modLFOCC1ToPitch * pChannel->modWheel) >> 7); + + /* add channel pressure effect */ + /*lint -e{702} use shift for performance */ + temp += ((pDLSArt->modLFOChanPressToPitch * pChannel->channelPressure) >> 7); + + /* add total mod LFO effect */ + pitchCents += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue); + + /* start with base vib LFO modulation */ + temp = pDLSArt->vibLFOToPitch; + + /* add mod wheel effect */ + /*lint -e{702} use shift for performance */ + temp += ((pDLSArt->vibLFOCC1ToPitch * pChannel->modWheel) >> 7); + + /* add channel pressure effect */ + /*lint -e{702} use shift for performance */ + temp += ((pDLSArt->vibLFOChanPressToPitch * pChannel->channelPressure) >> 7); + + /* add total vibrato LFO effect */ + pitchCents += FMUL_15x15(temp, pWTVoice->vibLFO.lfoValue); + + /* add EG2 effect */ + pitchCents += FMUL_15x15(pDLSArt->eg2ToPitch, pWTVoice->eg2Value); + + /* convert from cents to linear phase increment */ + return EAS_Calculate2toX(pitchCents); +} + +/*---------------------------------------------------------------------------- + * DLS_UpdateGain() + *---------------------------------------------------------------------------- + * Calculate the gain for the next frame + *---------------------------------------------------------------------------- +*/ +static EAS_I32 DLS_UpdateGain (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain, EAS_U8 velocity) +{ + EAS_I32 temp; + + /* start with base mod LFO modulation */ + temp = pDLSArt->modLFOToGain; + + /* add mod wheel effect */ + /*lint -e{702} use shift for performance */ + temp += ((pDLSArt->modLFOCC1ToGain * pChannel->modWheel) >> 7); + + /* add channel pressure effect */ + /*lint -e{702} use shift for performance */ + temp += ((pDLSArt->modLFOChanPressToGain * pChannel->channelPressure) >> 7); + + /* add total mod LFO effect */ + gain += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue); + if (gain > 0) + gain = 0; + + /* convert to linear gain including EG1 */ + if (pWTVoice->eg1State != eEnvelopeStateAttack) + { + gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT; + /*lint -e{702} use shift for performance */ +#if 1 + gain += (pWTVoice->eg1Value - 32767) >> 1; + gain = EAS_LogToLinear16(gain); +#else + gain = EAS_LogToLinear16(gain); + temp = EAS_LogToLinear16((pWTVoice->eg1Value - 32767) >> 1); + gain = FMUL_15x15(gain, temp); +#endif + } + else + { + gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT; + gain = EAS_LogToLinear16(gain); + gain = FMUL_15x15(gain, pWTVoice->eg1Value); + } + + /* include MIDI channel gain */ + gain = FMUL_15x15(gain, pChannel->staticGain); + + /* include velocity */ + if (pDLSArt->filterQandFlags & FLAG_DLS_VELOCITY_SENSITIVE) + { + temp = velocity << 8; + temp = FMUL_15x15(temp, temp); + gain = FMUL_15x15(gain, temp); + } + + /* return gain */ + return gain; +} + +/*---------------------------------------------------------------------------- + * DLS_UpdateFilter() + *---------------------------------------------------------------------------- + * Update the Filter parameters + *---------------------------------------------------------------------------- +*/ +static void DLS_UpdateFilter (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, S_SYNTH_CHANNEL *pChannel, const S_DLS_ARTICULATION *pDLSArt) +{ + EAS_I32 cutoff; + EAS_I32 temp; + + /* no need to calculate filter coefficients if it is bypassed */ + if (pDLSArt->filterCutoff == DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY) + { + pIntFrame->frame.k = 0; + return; + } + + /* start with base cutoff frequency */ + cutoff = pDLSArt->filterCutoff; + + /* get base mod LFO modulation */ + temp = pDLSArt->modLFOToFc; + + /* add mod wheel effect */ + /*lint -e{702} use shift for performance */ + temp += ((pDLSArt->modLFOCC1ToFc * pChannel->modWheel) >> 7); + + /* add channel pressure effect */ + /*lint -e{702} use shift for performance */ + temp += ((pDLSArt->modLFOChanPressToFc* pChannel->channelPressure) >> 7); + + /* add total mod LFO effect */ + cutoff += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue); + + /* add EG2 effect */ + cutoff += FMUL_15x15(pWTVoice->eg2Value, pDLSArt->eg2ToFc); + + /* add velocity effect */ + /*lint -e{702} use shift for performance */ + cutoff += (pVoice->velocity * pDLSArt->velToFc) >> 7; + + /* add velocity effect */ + /*lint -e{702} use shift for performance */ + cutoff += (pVoice->note * pDLSArt->keyNumToFc) >> 7; + + /* subtract the A5 offset and the sampling frequency */ + cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS; + + /* limit the cutoff frequency */ + if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS) + cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS; + else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS) + cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS; + + WT_SetFilterCoeffs(pIntFrame, cutoff, pDLSArt->filterQandFlags & FILTER_Q_MASK); +} + +/*---------------------------------------------------------------------------- + * DLS_StartVoice() + *---------------------------------------------------------------------------- + * Start up a DLS voice + *---------------------------------------------------------------------------- +*/ +EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex) +{ + S_WT_VOICE *pWTVoice; + const S_DLS_REGION *pDLSRegion; + const S_DLS_ARTICULATION *pDLSArt; + S_SYNTH_CHANNEL *pChannel; + +#ifdef _DEBUG_SYNTH + { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ } +#endif + + pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; + pChannel = &pSynth->channels[pVoice->channel & 15]; + pDLSRegion = &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK]; + pWTVoice->artIndex = pDLSRegion->wtRegion.artIndex; + pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; + + /* initialize the envelopes */ + pWTVoice->eg1State = eEnvelopeStateInit; + DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State); + pWTVoice->eg2State = eEnvelopeStateInit; + DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State); + + /* initialize the LFOs */ + pWTVoice->modLFO.lfoValue = 0; + pWTVoice->modLFO.lfoPhase = pDLSArt->modLFO.lfoDelay; + pWTVoice->vibLFO.lfoValue = 0; + pWTVoice->vibLFO.lfoPhase = pDLSArt->vibLFO.lfoDelay; + + /* initalize the envelopes and calculate initial gain */ + DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State); + DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State); + pVoice->gain = (EAS_I16) DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity); + +#if (NUM_OUTPUT_CHANNELS == 2) + EAS_CalcPanControl((EAS_INT) pChannel->pan - 64 + (EAS_INT) pDLSArt->pan, &pWTVoice->gainLeft, &pWTVoice->gainRight); +#endif + + /* initialize the filter states */ + pWTVoice->filter.z1 = 0; + pWTVoice->filter.z2 = 0; + + /* initialize the oscillator */ + pWTVoice->phaseAccum = (EAS_U32) pSynth->pDLS->pDLSSamples + pSynth->pDLS->pDLSSampleOffsets[pDLSRegion->wtRegion.waveIndex]; + if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED) + { + pWTVoice->loopStart = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopStart; + pWTVoice->loopEnd = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopEnd - 1; + } + else + pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pDLS->pDLSSampleLen[pDLSRegion->wtRegion.waveIndex] - 1; + + return EAS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + * DLS_UpdateVoice() + *---------------------------------------------------------------------------- + * Purpose: + * Synthesize a block of samples for the given voice. + * Use linear interpolation. + * + * Inputs: + * pEASData - pointer to overall EAS data structure + * + * Outputs: + * number of samples actually written to buffer + * + * Side Effects: + * - samples are added to the presently free buffer + * + *---------------------------------------------------------------------------- +*/ +EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples) +{ + S_WT_VOICE *pWTVoice; + S_SYNTH_CHANNEL *pChannel; + const S_DLS_REGION *pDLSRegion; + const S_DLS_ARTICULATION *pDLSArt; + S_WT_INT_FRAME intFrame; + EAS_I32 temp; + EAS_BOOL done = EAS_FALSE; + + /* establish pointers to critical data */ + pWTVoice = &pVoiceMgr->wtVoices[voiceNum]; + pDLSRegion = &pSynth->pDLS->pDLSRegions[pVoice->regionIndex & REGION_INDEX_MASK]; + pChannel = &pSynth->channels[pVoice->channel & 15]; + pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex]; + + /* update the envelopes */ + DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State); + DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State); + + /* update the LFOs using the EAS synth function */ + WT_UpdateLFO(&pWTVoice->modLFO, pDLSArt->modLFO.lfoFreq); + WT_UpdateLFO(&pWTVoice->vibLFO, pDLSArt->vibLFO.lfoFreq); + + /* calculate base frequency */ + temp = pDLSArt->tuning + pChannel->staticPitch + pDLSRegion->wtRegion.tuning + + (((EAS_I32) pVoice->note * (EAS_I32) pDLSArt->keyNumToPitch) >> 7); + + /* don't transpose rhythm channel */ + if ((pChannel ->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL) == 0) + temp += pSynth->globalTranspose * 100; + + /* calculate phase increment including modulation effects */ + intFrame.frame.phaseIncrement = DLS_UpdatePhaseInc(pWTVoice, pDLSArt, pChannel, temp); + + /* calculate gain including modulation effects */ + intFrame.frame.gainTarget = DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity); + intFrame.prevGain = pVoice->gain; + + DLS_UpdateFilter(pVoice, pWTVoice, &intFrame, pChannel, pDLSArt); + + /* call into engine to generate samples */ + intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer; + intFrame.pMixBuffer = pMixBuffer; + intFrame.numSamples = numSamples; + if (numSamples < 0) + return EAS_FALSE; + + /* check for end of sample */ + if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd)) + done = WT_CheckSampleEnd(pWTVoice, &intFrame, EAS_FALSE); + + WT_ProcessVoice(pWTVoice, &intFrame); + + /* clear flag */ + pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET; + + /* if the update interval has elapsed, then force the current gain to the next + * gain since we never actually reach the next gain when ramping -- we just get + * very close to the target gain. + */ + pVoice->gain = (EAS_I16) intFrame.frame.gainTarget; + + /* if voice has finished, set flag for voice manager */ + if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted)) + done = EAS_TRUE; + + return done; +} + +/*---------------------------------------------------------------------------- + * DLS_UpdateEnvelope() + *---------------------------------------------------------------------------- + * Purpose: + * Synthesize a block of samples for the given voice. + * Use linear interpolation. + * + * Inputs: + * pEASData - pointer to overall EAS data structure + * + * Outputs: + * number of samples actually written to buffer + * + * Side Effects: + * - samples are added to the presently free buffer + * + *---------------------------------------------------------------------------- +*/ +/*lint -esym(715, pChannel) pChannel not used in this instance */ +static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, const S_DLS_ENVELOPE *pEnvParams, EAS_I16 *pValue, EAS_I16 *pIncrement, EAS_U8 *pState) +{ + EAS_I32 temp; + + switch (*pState) + { + /* initial state */ + case eEnvelopeStateInit: + *pState = eEnvelopeStateDelay; + *pValue = 0; + *pIncrement = pEnvParams->delayTime; + if (*pIncrement != 0) + return; + /*lint -e{825} falls through to next case */ + + case eEnvelopeStateDelay: + if (*pIncrement) + { + *pIncrement = *pIncrement - 1; + return; + } + + /* calculate attack rate */ + *pState = eEnvelopeStateAttack; + if (pEnvParams->attackTime != ZERO_TIME_IN_CENTS) + { + /*lint -e{702} use shift for performance */ + temp = pEnvParams->attackTime + ((pEnvParams->velToAttack * pVoice->velocity) >> 7); + *pIncrement = ConvertRate(temp); + return; + } + + *pValue = SYNTH_FULL_SCALE_EG1_GAIN; + /*lint -e{825} falls through to next case */ + + case eEnvelopeStateAttack: + if (*pValue < SYNTH_FULL_SCALE_EG1_GAIN) + { + temp = *pValue + *pIncrement; + *pValue = (EAS_I16) (temp < SYNTH_FULL_SCALE_EG1_GAIN ? temp : SYNTH_FULL_SCALE_EG1_GAIN); + return; + } + + /* calculate hold time */ + *pState = eEnvelopeStateHold; + if (pEnvParams->holdTime != ZERO_TIME_IN_CENTS) + { + /*lint -e{702} use shift for performance */ + temp = pEnvParams->holdTime + ((pEnvParams->keyNumToHold * pVoice->note) >> 7); + *pIncrement = ConvertDelay(temp); + return; + } + else + *pIncrement = 0; + /*lint -e{825} falls through to next case */ + + case eEnvelopeStateHold: + if (*pIncrement) + { + *pIncrement = *pIncrement - 1; + return; + } + + /* calculate decay rate */ + *pState = eEnvelopeStateDecay; + if (pEnvParams->decayTime != ZERO_TIME_IN_CENTS) + { + /*lint -e{702} use shift for performance */ + temp = pEnvParams->decayTime + ((pEnvParams->keyNumToDecay * pVoice->note) >> 7); + *pIncrement = ConvertRate(temp); + return; + } + +// *pValue = pEnvParams->sustainLevel; + /*lint -e{825} falls through to next case */ + + case eEnvelopeStateDecay: + if (*pValue > pEnvParams->sustainLevel) + { + temp = *pValue - *pIncrement; + *pValue = (EAS_I16) (temp > pEnvParams->sustainLevel ? temp : pEnvParams->sustainLevel); + return; + } + + *pState = eEnvelopeStateSustain; + *pValue = pEnvParams->sustainLevel; + /*lint -e{825} falls through to next case */ + + case eEnvelopeStateSustain: + return; + + case eEnvelopeStateRelease: + temp = *pValue - *pIncrement; + if (temp <= 0) + { + *pState = eEnvelopeStateMuted; + *pValue = 0; + } + else + *pValue = (EAS_I16) temp; + break; + + case eEnvelopeStateMuted: + *pValue = 0; + return; + + default: + { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Envelope in invalid state %d\n", *pState); */ } + break; + } +} + |