diff options
Diffstat (limited to 'arm-wt-22k/lib_src/eas_dlssynth.c')
-rw-r--r-- | arm-wt-22k/lib_src/eas_dlssynth.c | 754 |
1 files changed, 377 insertions, 377 deletions
diff --git a/arm-wt-22k/lib_src/eas_dlssynth.c b/arm-wt-22k/lib_src/eas_dlssynth.c index c1fa1ef..8606a29 100644 --- a/arm-wt-22k/lib_src/eas_dlssynth.c +++ b/arm-wt-22k/lib_src/eas_dlssynth.c @@ -52,19 +52,19 @@ static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel */ 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 */ + 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; @@ -80,18 +80,18 @@ void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoi /*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); - + 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; @@ -111,19 +111,19 @@ void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *p /*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; - + 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->voiceState = eVoiceStatePlay; pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF; #ifdef _DEBUG_SYNTH @@ -139,41 +139,41 @@ void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *p */ static EAS_I32 DLS_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents) { - EAS_I32 temp; + EAS_I32 temp; - /* start with base mod LFO modulation */ - temp = pDLSArt->modLFOToPitch; + /* 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 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 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); + /* add total mod LFO effect */ + pitchCents += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue); - /* start with base vib LFO modulation */ - temp = pDLSArt->vibLFOToPitch; + /* 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 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 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 total vibrato LFO effect */ + pitchCents += FMUL_15x15(temp, pWTVoice->vibLFO.lfoValue); - /* add EG2 effect */ - pitchCents += FMUL_15x15(pDLSArt->eg2ToPitch, pWTVoice->eg2Value); + /* add EG2 effect */ + pitchCents += FMUL_15x15(pDLSArt->eg2ToPitch, pWTVoice->eg2Value); - /* convert from cents to linear phase increment */ - return EAS_Calculate2toX(pitchCents); + /* convert from cents to linear phase increment */ + return EAS_Calculate2toX(pitchCents); } /*---------------------------------------------------------------------------- @@ -184,58 +184,58 @@ static EAS_I32 DLS_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATIO */ 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; + EAS_I32 temp; - /* start with base mod LFO modulation */ - temp = pDLSArt->modLFOToGain; + /* 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 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 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; + /* 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 */ + /* 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); + 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); + 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; + } + 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; } /*---------------------------------------------------------------------------- @@ -246,54 +246,54 @@ static EAS_I32 DLS_UpdateGain (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *p */ 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); + 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); } /*---------------------------------------------------------------------------- @@ -304,69 +304,69 @@ static void DLS_UpdateFilter (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, S_WT_ */ 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; - + 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); */ } + { /* 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); + 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; + 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: + * Purpose: * Synthesize a block of samples for the given voice. * Use linear interpolation. * - * Inputs: + * Inputs: * pEASData - pointer to overall EAS data structure - * + * * Outputs: * number of samples actually written to buffer * @@ -377,84 +377,84 @@ EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOIC */ 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; + 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; + if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted)) + done = EAS_TRUE; - return done; -} + return done; +} /*---------------------------------------------------------------------------- * DLS_UpdateEnvelope() *---------------------------------------------------------------------------- - * Purpose: + * Purpose: * Synthesize a block of samples for the given voice. * Use linear interpolation. * - * Inputs: + * Inputs: * pEASData - pointer to overall EAS data structure - * + * * Outputs: * number of samples actually written to buffer * @@ -466,113 +466,113 @@ EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE /*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; - } + 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; + } } |