/*----------------------------------------------------------------------------
 * WT_UpdatePhaseInc()
 *----------------------------------------------------------------------------
 * Purpose:
 * Calculate the phase increment
 *
 * Inputs:
 * pVoice - pointer to the voice being updated
 * psRegion - pointer to the region
 * psArticulation - pointer to the articulation
 * nChannelPitchForThisVoice - the portion of the pitch that is fixed for this
 *                  voice during the duration of this synthesis
 * pEASData - pointer to overall EAS data structure
 *
 * Outputs:
 *
 * Side Effects:
 * set the phase increment for this voice
 *----------------------------------------------------------------------------
*/
static EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents)
{
    EAS_I32 temp;

    /*pitchCents due to CC1 = LFO * (CC1 / 128) * DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS */
    temp = MULT_EG1_EG1(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
        ((pChannel->modWheel) << (NUM_EG1_FRAC_BITS -7)));

    /* pitchCents due to channel pressure = LFO * (channel pressure / 128) * DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS */
    temp += MULT_EG1_EG1(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
         ((pChannel->channelPressure) << (NUM_EG1_FRAC_BITS -7)));

    /* now multiply the (channel pressure + CC1) pitch values by the LFO value */
    temp = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, temp);

    /*
    add in the LFO pitch due to
    channel pressure and CC1 along with
    the LFO pitch, the EG2 pitch, and the
    "static" pitch for this voice on this channel
    */
    temp += pitchCents +
        (MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToPitch)) +
        (MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToPitch));

    /* convert from cents to linear phase increment */
    return EAS_Calculate2toX(temp);
}
/*----------------------------------------------------------------------------
 * WT_UpdateGain()
 *----------------------------------------------------------------------------
 * Purpose:
 * Calculate and assign static voice parameters as part of WT_UpdateVoice()
 *
 * Inputs:
 * pVoice - ptr to the synth voice that we want to synthesize
 * pEASData - pointer to overall EAS data structure
 *
 * Outputs:
 *
 * Side Effects:
 * - various voice parameters are calculated and assigned
 *
 *----------------------------------------------------------------------------
*/
static EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain)
{
    EAS_I32 lfoGain;
    EAS_I32 temp;

    /*
    If this voice was stolen, then the velocity is actually
    for the new note, not the note that we are currently ramping down.
    So we really shouldn't use this velocity. However, that would require
    more memory to store the velocity value, and the improvement may
    not be sufficient to warrant the added memory.
    */
    /* velocity is fixed at note start for a given voice and must be squared */
    temp = (pVoice->velocity) << (NUM_EG1_FRAC_BITS - 7);
    temp = MULT_EG1_EG1(temp, temp);

    /* region gain is fixed as part of the articulation */
    temp = MULT_EG1_EG1(temp, gain);

    /* include the channel gain */
    temp = MULT_EG1_EG1(temp, pChannel->staticGain);

    /* calculate LFO gain using an approximation for 10^x */
    lfoGain = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToGain);
    lfoGain = MULT_EG1_EG1(lfoGain, LFO_GAIN_TO_CENTS);

    /* convert from a dB-like value to linear gain */
    lfoGain = EAS_Calculate2toX(lfoGain);
    temp = MULT_EG1_EG1(temp, lfoGain);

    /* calculate the voice's gain */
    temp = (EAS_I16)MULT_EG1_EG1(temp, pWTVoice->eg1Value);

    return temp;
}
/*----------------------------------------------------------------------------
 * WT_SetFilterCoeffs()
 *----------------------------------------------------------------------------
 * Purpose:
 * Update the Filter parameters
 *
 * Inputs:
 * pVoice - ptr to the voice whose filter we want to update
 * pEASData - pointer to overall EAS data structure
 *
 * Outputs:
 *
 * Side Effects:
 * - updates Filter values for the given voice
 *----------------------------------------------------------------------------
*/
void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance)
{
    EAS_I32 temp;

    /*
    Convert the cutoff, which has had A5 subtracted, using the 2^x approx
    Note, this cutoff is related to theta cutoff by
    theta = k * 2^x
    We use 2^x and incorporate k in the power series coefs instead
    */
    cutoff = EAS_Calculate2toX(cutoff);

    /* calculate b2 coef */
    temp = k2g1[resonance] + MULT_AUDIO_COEF(cutoff, k2g2[resonance]);
    temp = k2g0 + MULT_AUDIO_COEF(cutoff, temp);
    pIntFrame->frame.b2 = temp;

    /* calculate b1 coef */
    temp = MULT_AUDIO_COEF(cutoff, nk1g2);
    temp = nk1g0 + MULT_AUDIO_COEF(cutoff, temp);
    temp += MULT_AUDIO_COEF(temp, pIntFrame->frame.b2);
    pIntFrame->frame.b1 = temp >> 1;

    /* calculate K coef */
    temp = n1g2[resonance] + MULT_AUDIO_COEF(cutoff, n1g3[resonance]);
    temp = MULT_AUDIO_COEF(cutoff, temp);
    temp = MULT_AUDIO_COEF(cutoff, temp);
    pIntFrame->frame.k = temp;
}
示例#4
0
/*----------------------------------------------------------------------------
 * 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);
}