コード例 #1
0
ファイル: alcEcho.c プロジェクト: LighFusion/surreal
static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot)
{
    ALechoState *state = (ALechoState*)effect;
    ALuint frequency = Device->Frequency;
    ALfloat lrpan, cw, g, gain;
    ALfloat dirGain;
    ALuint i;

    state->Tap[0].delay = fastf2u(Slot->effect.Echo.Delay * frequency) + 1;
    state->Tap[1].delay = fastf2u(Slot->effect.Echo.LRDelay * frequency);
    state->Tap[1].delay += state->Tap[0].delay;

    lrpan = Slot->effect.Echo.Spread;

    state->FeedGain = Slot->effect.Echo.Feedback;

    cw = aluCos(F_PI*2.0f * LOWPASSFREQREF / frequency);
    g = 1.0f - Slot->effect.Echo.Damping;
    state->iirFilter.coeff = lpCoeffCalc(g, cw);

    gain = Slot->Gain;
    for(i = 0;i < MAXCHANNELS;i++)
    {
        state->Gain[0][i] = 0.0f;
        state->Gain[1][i] = 0.0f;
    }

    dirGain = aluFabs(lrpan);

    /* First tap panning */
    ComputeAngleGains(Device, aluAtan2(-lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[0]);

    /* Second tap panning */
    ComputeAngleGains(Device, aluAtan2(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]);
}
コード例 #2
0
ファイル: alcEcho.c プロジェクト: LighFusion/surreal
static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
{
    ALechoState *state = (ALechoState*)effect;
    ALuint maxlen, i;

    // Use the next power of 2 for the buffer length, so the tap offsets can be
    // wrapped using a mask instead of a modulo
    maxlen  = fastf2u(AL_ECHO_MAX_DELAY * Device->Frequency) + 1;
    maxlen += fastf2u(AL_ECHO_MAX_LRDELAY * Device->Frequency) + 1;
    maxlen  = NextPowerOf2(maxlen);

    if(maxlen != state->BufferLength)
    {
        void *temp;

        temp = realloc(state->SampleBuffer, maxlen * sizeof(ALfloat));
        if(!temp)
            return AL_FALSE;
        state->SampleBuffer = temp;
        state->BufferLength = maxlen;
    }
    for(i = 0;i < state->BufferLength;i++)
        state->SampleBuffer[i] = 0.0f;

    return AL_TRUE;
}
コード例 #3
0
ファイル: hrtf.c プロジェクト: dapetcu21/openal-soft
/* Calculate the azimuth indices given the polar azimuth in radians.  This
 * will return two indices between 0 and (Hrtf->azCount[ei] - 1) and an
 * interpolation factor between 0.0 and 1.0.
 */
static void CalcAzIndices(const struct Hrtf *Hrtf, ALuint evidx, ALfloat az, ALuint *azidx, ALfloat *azmu)
{
    az = (F_PI*2.0f + az) * Hrtf->azCount[evidx] / (F_PI*2.0f);
    azidx[0] = fastf2u(az) % Hrtf->azCount[evidx];
    azidx[1] = (azidx[0] + 1) % Hrtf->azCount[evidx];
    *azmu = az - floorf(az);
}
コード例 #4
0
ファイル: hrtf.c プロジェクト: 24BitGames/LoomSDK
// Calculate the azimuth indices given the polar azimuth in radians.  This
// will return two indices between 0 and (azCount [ei] - 1) and an
// interpolation factor between 0.0 and 1.0.
static void CalcAzIndices(ALuint evidx, ALfloat az, ALuint *azidx, ALfloat *azmu)
{
    az = (F_PI*2.0f + az) * azCount[evidx] / (F_PI*2.0f);
    azidx[0] = fastf2u(az) % azCount[evidx];
    azidx[1] = (azidx[0] + 1) % azCount[evidx];
    *azmu = az - aluFloor(az);
}
コード例 #5
0
ファイル: modulator.c プロジェクト: Kingsquee/crown
static ALvoid ALmodulatorState_update(ALmodulatorState *state, ALCdevice *Device, const ALeffectslot *Slot)
{
    ALfloat cw, a;

    if(Slot->EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SINUSOID)
        state->Waveform = SINUSOID;
    else if(Slot->EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH)
        state->Waveform = SAWTOOTH;
    else if(Slot->EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SQUARE)
        state->Waveform = SQUARE;

    state->step = fastf2u(Slot->EffectProps.Modulator.Frequency*WAVEFORM_FRACONE /
                          Device->Frequency);
    if(state->step == 0) state->step = 1;

    /* Custom filter coeffs, which match the old version instead of a low-shelf. */
    cw = cosf(F_TAU * Slot->EffectProps.Modulator.HighPassCutoff / Device->Frequency);
    a = (2.0f-cw) - sqrtf(powf(2.0f-cw, 2.0f) - 1.0f);

    state->Filter.b[0] = a;
    state->Filter.b[1] = -a;
    state->Filter.b[2] = 0.0f;
    state->Filter.a[0] = 1.0f;
    state->Filter.a[1] = -a;
    state->Filter.a[2] = 0.0f;

    ComputeAmbientGains(Device, Slot->Gain, state->Gain);
}
コード例 #6
0
ファイル: hrtf.c プロジェクト: 24BitGames/LoomSDK
// Calculate the elevation indices given the polar elevation in radians.
// This will return two indices between 0 and (ELEV_COUNT-1) and an
// interpolation factor between 0.0 and 1.0.
static void CalcEvIndices(ALfloat ev, ALuint *evidx, ALfloat *evmu)
{
    ev = (F_PI_2 + ev) * (ELEV_COUNT-1) / F_PI;
    evidx[0] = fastf2u(ev);
    evidx[1] = minu(evidx[0] + 1, ELEV_COUNT-1);
    *evmu = ev - evidx[0];
}
コード例 #7
0
static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Device)
{
    ALuint maxlen;
    ALuint it;

    maxlen = fastf2u(AL_CHORUS_MAX_DELAY * 3.0f * Device->Frequency) + 1;
    maxlen = NextPowerOf2(maxlen);

    if(maxlen != state->BufferLength)
    {
        void *temp;

        temp = realloc(state->SampleBuffer[0], maxlen * sizeof(ALfloat) * 2);
        if(!temp) return AL_FALSE;
        state->SampleBuffer[0] = temp;
        state->SampleBuffer[1] = state->SampleBuffer[0] + maxlen;

        state->BufferLength = maxlen;
    }

    for(it = 0;it < state->BufferLength;it++)
    {
        state->SampleBuffer[0][it] = 0.0f;
        state->SampleBuffer[1][it] = 0.0f;
    }

    return AL_TRUE;
}
コード例 #8
0
static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot)
{
    ALmodulatorState *state = (ALmodulatorState*)effect;
    ALfloat gain, cw, a = 0.0f;
    ALuint index;

    if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SINUSOID)
        state->Waveform = SINUSOID;
    else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH)
        state->Waveform = SAWTOOTH;
    else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SQUARE)
        state->Waveform = SQUARE;

    state->step = fastf2u(Slot->effect.Modulator.Frequency*WAVEFORM_FRACONE /
                          Device->Frequency);
    if(state->step == 0) state->step = 1;

    cw = cosf(F_PI*2.0f * Slot->effect.Modulator.HighPassCutoff /
                          Device->Frequency);
    a = (2.0f-cw) - sqrtf(powf(2.0f-cw, 2.0f) - 1.0f);
    state->iirFilter.coeff = a;

    gain = sqrtf(1.0f/Device->NumChan);
    gain *= Slot->Gain;
    for(index = 0;index < MaxChannels;index++)
        state->Gain[index] = 0.0f;
    for(index = 0;index < Device->NumChan;index++)
    {
        enum Channel chan = Device->Speaker2Chan[index];
        state->Gain[chan] = gain;
    }
}
コード例 #9
0
// Given an input sample, this function produces modulation for the late
// reverb.
static __inline ALfloat EAXModulation(ALverbState *State, ALfloat in)
{
    ALfloat sinus, frac;
    ALuint offset;
    ALfloat out0, out1;

    // Calculate the sinus rythm (dependent on modulation time and the
    // sampling rate).  The center of the sinus is moved to reduce the delay
    // of the effect when the time or depth are low.
    sinus = 1.0f - cosf(F_PI*2.0f * State->Mod.Index / State->Mod.Range);

    // The depth determines the range over which to read the input samples
    // from, so it must be filtered to reduce the distortion caused by even
    // small parameter changes.
    State->Mod.Filter = lerp(State->Mod.Filter, State->Mod.Depth,
                             State->Mod.Coeff);

    // Calculate the read offset and fraction between it and the next sample.
    frac   = (1.0f + (State->Mod.Filter * sinus));
    offset = fastf2u(frac);
    frac  -= offset;

    // Get the two samples crossed by the offset, and feed the delay line
    // with the next input sample.
    out0 = DelayLineOut(&State->Mod.Delay, State->Offset - offset);
    out1 = DelayLineOut(&State->Mod.Delay, State->Offset - offset - 1);
    DelayLineIn(&State->Mod.Delay, State->Offset, in);

    // Step the modulation index forward, keeping it bound to its range.
    State->Mod.Index = (State->Mod.Index + 1) % State->Mod.Range;

    // The output is obtained by linearly interpolating the two samples that
    // were acquired above.
    return lerp(out0, out1, frac);
}
コード例 #10
0
ファイル: hrtf.c プロジェクト: dapetcu21/openal-soft
/* Calculate the elevation indices given the polar elevation in radians.
 * This will return two indices between 0 and (Hrtf->evCount - 1) and an
 * interpolation factor between 0.0 and 1.0.
 */
static void CalcEvIndices(const struct Hrtf *Hrtf, ALfloat ev, ALuint *evidx, ALfloat *evmu)
{
    ev = (F_PI_2 + ev) * (Hrtf->evCount-1) / F_PI;
    evidx[0] = fastf2u(ev);
    evidx[1] = minu(evidx[0] + 1, Hrtf->evCount-1);
    *evmu = ev - evidx[0];
}
コード例 #11
0
ファイル: eax.c プロジェクト: gena-moscow/wine-patched
static void UpdateLateLines(float reverbGain, float lateGain, float xMix, float density, float decayTime,
                            float diffusion, float hfRatio, float cw, unsigned int frequency, eax_buffer_info *State)
{
    float length;
    unsigned int index;

    /* Calculate the late reverb gain (from the master effect gain, and late
     * reverb gain parameters).  Since the output is tapped prior to the
     * application of the next delay line coefficients, this gain needs to be
     * attenuated by the 'x' mixing matrix coefficient as well.
     */
    State->Late.Gain = reverbGain * lateGain * xMix;

    /* To compensate for changes in modal density and decay time of the late
     * reverb signal, the input is attenuated based on the maximal energy of
     * the outgoing signal.  This approximation is used to keep the apparent
     * energy of the signal equal for all ranges of density and decay time.
     *
     * The average length of the cyclcical delay lines is used to calculate
     * the attenuation coefficient.
     */
    length = (LATE_LINE_LENGTH[0] + LATE_LINE_LENGTH[1] +
              LATE_LINE_LENGTH[2] + LATE_LINE_LENGTH[3]) / 4.0f;
    length *= 1.0f + (density * LATE_LINE_MULTIPLIER);
    State->Late.DensityGain = CalcDensityGain(CalcDecayCoeff(length,
                                                             decayTime));

    /* Calculate the all-pass feed-back and feed-forward coefficient. */
    State->Late.ApFeedCoeff = 0.5f * powf(diffusion, 2.0f);

    for(index = 0; index < 4; index++)
    {
        /* Calculate the gain (coefficient) for each all-pass line. */
        State->Late.ApCoeff[index] = CalcDecayCoeff(ALLPASS_LINE_LENGTH[index],
                                                    decayTime);

        /* Calculate the length (in seconds) of each cyclical delay line. */
        length = LATE_LINE_LENGTH[index] * (1.0f + (density * LATE_LINE_MULTIPLIER));

        /* Calculate the delay offset for each cyclical delay line. */
        State->Late.Offset[index] = fastf2u(length * frequency);

        /* Calculate the gain (coefficient) for each cyclical line. */
        State->Late.Coeff[index] = CalcDecayCoeff(length, decayTime);

        /* Calculate the damping coefficient for each low-pass filter. */
        State->Late.LpCoeff[index] = CalcDampingCoeff(hfRatio, length, decayTime,
                             State->Late.Coeff[index], cw);

        /* Attenuate the cyclical line coefficients by the mixing coefficient
         * (x). */
        State->Late.Coeff[index] *= xMix;
    }
}
コード例 #12
0
static ALvoid ALchorusState_update(ALchorusState *state, const ALCdevice *Device, const ALeffectslot *Slot)
{
    ALfloat frequency = (ALfloat)Device->Frequency;
    ALfloat coeffs[MAX_AMBI_COEFFS];
    ALfloat rate;
    ALint phase;

    switch(Slot->EffectProps.Chorus.Waveform)
    {
        case AL_CHORUS_WAVEFORM_TRIANGLE:
            state->waveform = CWF_Triangle;
            break;
        case AL_CHORUS_WAVEFORM_SINUSOID:
            state->waveform = CWF_Sinusoid;
            break;
    }
    state->depth = Slot->EffectProps.Chorus.Depth;
    state->feedback = Slot->EffectProps.Chorus.Feedback;
    state->delay = fastf2i(Slot->EffectProps.Chorus.Delay * frequency);

    /* Gains for left and right sides */
    CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, coeffs);
    ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Slot->Gain, state->Gain[0]);
    CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, coeffs);
    ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Slot->Gain, state->Gain[1]);

    phase = Slot->EffectProps.Chorus.Phase;
    rate = Slot->EffectProps.Chorus.Rate;
    if(!(rate > 0.0f))
    {
        state->lfo_scale = 0.0f;
        state->lfo_range = 1;
        state->lfo_disp = 0;
    }
    else
    {
        /* Calculate LFO coefficient */
        state->lfo_range = fastf2u(frequency/rate + 0.5f);
        switch(state->waveform)
        {
            case CWF_Triangle:
                state->lfo_scale = 4.0f / state->lfo_range;
                break;
            case CWF_Sinusoid:
                state->lfo_scale = F_TAU / state->lfo_range;
                break;
        }

        /* Calculate lfo phase displacement */
        state->lfo_disp = fastf2i(state->lfo_range * (phase/360.0f));
    }
}
コード例 #13
0
ファイル: modulator.c プロジェクト: IsemanTech/openal-soft
static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props)
{
    aluMatrixf matrix;
    ALfloat cw, a;
    ALuint i;

    if(props->Modulator.Waveform == AL_RING_MODULATOR_SINUSOID)
        state->Process = ModulateSin;
    else if(props->Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH)
        state->Process = ModulateSaw;
    else /*if(Slot->Params.EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SQUARE)*/
        state->Process = ModulateSquare;

    state->step = fastf2u(props->Modulator.Frequency*WAVEFORM_FRACONE /
                          Device->Frequency);
    if(state->step == 0) state->step = 1;

    /* Custom filter coeffs, which match the old version instead of a low-shelf. */
    cw = cosf(F_TAU * props->Modulator.HighPassCutoff / Device->Frequency);
    a = (2.0f-cw) - sqrtf(powf(2.0f-cw, 2.0f) - 1.0f);

    for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
    {
        state->Filter[i].a1 = -a;
        state->Filter[i].a2 = 0.0f;
        state->Filter[i].b1 = -a;
        state->Filter[i].b2 = 0.0f;
        state->Filter[i].input_gain = a;
        state->Filter[i].process = ALfilterState_processC;
    }

    aluMatrixfSet(&matrix,
        1.0f, 0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 0.0f, 1.0f
    );

    STATIC_CAST(ALeffectState,state)->OutBuffer = Device->FOAOut.Buffer;
    STATIC_CAST(ALeffectState,state)->OutChannels = Device->FOAOut.NumChannels;
    for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
        ComputeFirstOrderGains(Device->FOAOut, matrix.m[i], Slot->Params.Gain,
                               state->Gain[i]);
}
コード例 #14
0
ファイル: eax.c プロジェクト: gena-moscow/wine-patched
static void UpdateDecorrelator(float density, unsigned int frequency, eax_buffer_info *State)
{
    unsigned int index;
    float length;

    /* The late reverb inputs are decorrelated to smooth the reverb tail and
     * reduce harsh echos.  The first tap occurs immediately, while the
     * remaining taps are delayed by multiples of a fraction of the smallest
     * cyclical delay time.
     *
     * offset[index] = (FRACTION (MULTIPLIER^index)) smallest_delay
     */
    for (index = 0; index < 3; index++)
    {
        length = (DECO_FRACTION * powf(DECO_MULTIPLIER, (float)index)) *
                 LATE_LINE_LENGTH[0] * (1.0f + (density * LATE_LINE_MULTIPLIER));
        State->DecoTap[index] = fastf2u(length * frequency);
    }
}
コード例 #15
0
ファイル: chorus.c プロジェクト: BitPuffin/NeoEditor
static ALvoid ALchorusState_update(ALchorusState *state, ALCdevice *Device, const ALeffectslot *Slot)
{
    ALfloat frequency = (ALfloat)Device->Frequency;
    ALfloat rate;
    ALint phase;

    state->waveform = Slot->EffectProps.Chorus.Waveform;
    state->depth = Slot->EffectProps.Chorus.Depth;
    state->feedback = Slot->EffectProps.Chorus.Feedback;
    state->delay = fastf2i(Slot->EffectProps.Chorus.Delay * frequency);

    /* Gains for left and right sides */
    ComputeAngleGains(Device, atan2f(-1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[0]);
    ComputeAngleGains(Device, atan2f(+1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[1]);

    phase = Slot->EffectProps.Chorus.Phase;
    rate = Slot->EffectProps.Chorus.Rate;
    if(!(rate > 0.0f))
    {
        state->lfo_scale = 0.0f;
        state->lfo_range = 1;
        state->lfo_disp = 0;
    }
    else
    {
        /* Calculate LFO coefficient */
        state->lfo_range = fastf2u(frequency/rate + 0.5f);
        switch(state->waveform)
        {
            case AL_CHORUS_WAVEFORM_TRIANGLE:
                state->lfo_scale = 4.0f / state->lfo_range;
                break;
            case AL_CHORUS_WAVEFORM_SINUSOID:
                state->lfo_scale = F_2PI / state->lfo_range;
                break;
        }

        /* Calculate lfo phase displacement */
        state->lfo_disp = fastf2i(state->lfo_range * (phase/360.0f));
    }
}
コード例 #16
0
ファイル: hrtf.c プロジェクト: 24BitGames/LoomSDK
// Calculates static HRIR coefficients and delays for the given polar
// elevation and azimuth in radians.  Linear interpolation is used to
// increase the apparent resolution of the HRIR dataset.  The coefficients
// are also normalized and attenuated by the specified gain.
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays)
{
    ALuint evidx[2], azidx[2];
    ALfloat mu[3];
    ALuint lidx[4], ridx[4];
    ALuint i;

    // Claculate elevation indices and interpolation factor.
    CalcEvIndices(elevation, evidx, &mu[2]);

    // Calculate azimuth indices and interpolation factor for the first
    // elevation.
    CalcAzIndices(evidx[0], azimuth, azidx, &mu[0]);

    // Calculate the first set of linear HRIR indices for left and right
    // channels.
    lidx[0] = evOffset[evidx[0]] + azidx[0];
    lidx[1] = evOffset[evidx[0]] + azidx[1];
    ridx[0] = evOffset[evidx[0]] + ((azCount[evidx[0]]-azidx[0]) % azCount[evidx[0]]);
    ridx[1] = evOffset[evidx[0]] + ((azCount[evidx[0]]-azidx[1]) % azCount[evidx[0]]);

    // Calculate azimuth indices and interpolation factor for the second
    // elevation.
    CalcAzIndices(evidx[1], azimuth, azidx, &mu[1]);

    // Calculate the second set of linear HRIR indices for left and right
    // channels.
    lidx[2] = evOffset[evidx[1]] + azidx[0];
    lidx[3] = evOffset[evidx[1]] + azidx[1];
    ridx[2] = evOffset[evidx[1]] + ((azCount[evidx[1]]-azidx[0]) % azCount[evidx[1]]);
    ridx[3] = evOffset[evidx[1]] + ((azCount[evidx[1]]-azidx[1]) % azCount[evidx[1]]);

    // Calculate the normalized and attenuated HRIR coefficients using linear
    // interpolation when there is enough gain to warrant it.  Zero the
    // coefficients if gain is too low.
    if(gain > 0.0001f)
    {
        gain *= 1.0f/32767.0f;
        for(i = 0;i < HRIR_LENGTH;i++)
        {
            coeffs[i][0] = lerp(lerp(Hrtf->coeffs[lidx[0]][i], Hrtf->coeffs[lidx[1]][i], mu[0]),
                                lerp(Hrtf->coeffs[lidx[2]][i], Hrtf->coeffs[lidx[3]][i], mu[1]),
                                mu[2]) * gain;
            coeffs[i][1] = lerp(lerp(Hrtf->coeffs[ridx[0]][i], Hrtf->coeffs[ridx[1]][i], mu[0]),
                                lerp(Hrtf->coeffs[ridx[2]][i], Hrtf->coeffs[ridx[3]][i], mu[1]),
                                mu[2]) * gain;
        }
    }
    else
    {
        for(i = 0;i < HRIR_LENGTH;i++)
        {
            coeffs[i][0] = 0.0f;
            coeffs[i][1] = 0.0f;
        }
    }

    // Calculate the HRIR delays using linear interpolation.
    delays[0] = fastf2u(lerp(lerp(Hrtf->delays[lidx[0]], Hrtf->delays[lidx[1]], mu[0]),
                             lerp(Hrtf->delays[lidx[2]], Hrtf->delays[lidx[3]], mu[1]),
                             mu[2]) * 65536.0f);
    delays[1] = fastf2u(lerp(lerp(Hrtf->delays[ridx[0]], Hrtf->delays[ridx[1]], mu[0]),
                             lerp(Hrtf->delays[ridx[2]], Hrtf->delays[ridx[3]], mu[1]),
                             mu[2]) * 65536.0f);
}
コード例 #17
0
ファイル: hrtf.c プロジェクト: dapetcu21/openal-soft
/* Calculates the moving HRIR target coefficients, target delays, and
 * stepping values for the given polar elevation and azimuth in radians.
 * Linear interpolation is used to increase the apparent resolution of the
 * HRIR data set.  The coefficients are also normalized and attenuated by the
 * specified gain.  Stepping resolution and count is determined using the
 * given delta factor between 0.0 and 1.0.
 */
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep)
{
    ALuint evidx[2], azidx[2];
    ALuint lidx[4], ridx[4];
    ALfloat mu[3], blend[4];
    ALfloat left, right;
    ALfloat step;
    ALuint i;

    // Claculate elevation indices and interpolation factor.
    CalcEvIndices(Hrtf, elevation, evidx, &mu[2]);

    // Calculate azimuth indices and interpolation factor for the first
    // elevation.
    CalcAzIndices(Hrtf, evidx[0], azimuth, azidx, &mu[0]);

    // Calculate the first set of linear HRIR indices for left and right
    // channels.
    lidx[0] = Hrtf->evOffset[evidx[0]] + azidx[0];
    lidx[1] = Hrtf->evOffset[evidx[0]] + azidx[1];
    ridx[0] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[0]) % Hrtf->azCount[evidx[0]]);
    ridx[1] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[1]) % Hrtf->azCount[evidx[0]]);

    // Calculate azimuth indices and interpolation factor for the second
    // elevation.
    CalcAzIndices(Hrtf, evidx[1], azimuth, azidx, &mu[1]);

    // Calculate the second set of linear HRIR indices for left and right
    // channels.
    lidx[2] = Hrtf->evOffset[evidx[1]] + azidx[0];
    lidx[3] = Hrtf->evOffset[evidx[1]] + azidx[1];
    ridx[2] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[0]) % Hrtf->azCount[evidx[1]]);
    ridx[3] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[1]) % Hrtf->azCount[evidx[1]]);

    // Calculate the stepping parameters.
    delta = maxf(floorf(delta*(Hrtf->sampleRate*0.015f) + 0.5f), 1.0f);
    step = 1.0f / delta;

    /* Calculate 4 blending weights for 2D bilinear interpolation. */
    blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]);
    blend[1] = (     mu[0]) * (1.0f-mu[2]);
    blend[2] = (1.0f-mu[1]) * (     mu[2]);
    blend[3] = (     mu[1]) * (     mu[2]);

    /* Calculate the HRIR delays using linear interpolation.  Then calculate
     * the delay stepping values using the target and previous running
     * delays.
     */
    left = (ALfloat)(delays[0] - (delayStep[0] * counter));
    right = (ALfloat)(delays[1] - (delayStep[1] * counter));

    delays[0] = fastf2u(Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] +
                        Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3] +
                        0.5f) << HRTFDELAY_BITS;
    delays[1] = fastf2u(Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] +
                        Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3] +
                        0.5f) << HRTFDELAY_BITS;

    delayStep[0] = fastf2i(step * (delays[0] - left));
    delayStep[1] = fastf2i(step * (delays[1] - right));

    /* Calculate the sample offsets for the HRIR indices. */
    lidx[0] *= Hrtf->irSize;
    lidx[1] *= Hrtf->irSize;
    lidx[2] *= Hrtf->irSize;
    lidx[3] *= Hrtf->irSize;
    ridx[0] *= Hrtf->irSize;
    ridx[1] *= Hrtf->irSize;
    ridx[2] *= Hrtf->irSize;
    ridx[3] *= Hrtf->irSize;

    /* Calculate the normalized and attenuated target HRIR coefficients using
     * linear interpolation when there is enough gain to warrant it.  Zero
     * the target coefficients if gain is too low.  Then calculate the
     * coefficient stepping values using the target and previous running
     * coefficients.
     */
    if(gain > 0.0001f)
    {
        gain *= 1.0f/32767.0f;
        for(i = 0;i < HRIR_LENGTH;i++)
        {
            left = coeffs[i][0] - (coeffStep[i][0] * counter);
            right = coeffs[i][1] - (coeffStep[i][1] * counter);

            coeffs[i][0] = (Hrtf->coeffs[lidx[0]+i]*blend[0] +
                            Hrtf->coeffs[lidx[1]+i]*blend[1] +
                            Hrtf->coeffs[lidx[2]+i]*blend[2] +
                            Hrtf->coeffs[lidx[3]+i]*blend[3]) * gain;
            coeffs[i][1] = (Hrtf->coeffs[ridx[0]+i]*blend[0] +
                            Hrtf->coeffs[ridx[1]+i]*blend[1] +
                            Hrtf->coeffs[ridx[2]+i]*blend[2] +
                            Hrtf->coeffs[ridx[3]+i]*blend[3]) * gain;

            coeffStep[i][0] = step * (coeffs[i][0] - left);
            coeffStep[i][1] = step * (coeffs[i][1] - right);
        }
    }
    else
    {
        for(i = 0;i < HRIR_LENGTH;i++)
        {
            left = coeffs[i][0] - (coeffStep[i][0] * counter);
            right = coeffs[i][1] - (coeffStep[i][1] * counter);

            coeffs[i][0] = 0.0f;
            coeffs[i][1] = 0.0f;

            coeffStep[i][0] = step * -left;
            coeffStep[i][1] = step * -right;
        }
    }

    /* The stepping count is the number of samples necessary for the HRIR to
     * complete its transition.  The mixer will only apply stepping for this
     * many samples.
     */
    return fastf2u(delta);
}
コード例 #18
0
ファイル: hrtf.c プロジェクト: dapetcu21/openal-soft
/* Calculates static HRIR coefficients and delays for the given polar
 * elevation and azimuth in radians.  Linear interpolation is used to
 * increase the apparent resolution of the HRIR data set.  The coefficients
 * are also normalized and attenuated by the specified gain.
 */
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays)
{
    ALuint evidx[2], azidx[2];
    ALuint lidx[4], ridx[4];
    ALfloat mu[3], blend[4];
    ALuint i;

    // Claculate elevation indices and interpolation factor.
    CalcEvIndices(Hrtf, elevation, evidx, &mu[2]);

    // Calculate azimuth indices and interpolation factor for the first
    // elevation.
    CalcAzIndices(Hrtf, evidx[0], azimuth, azidx, &mu[0]);

    // Calculate the first set of linear HRIR indices for left and right
    // channels.
    lidx[0] = Hrtf->evOffset[evidx[0]] + azidx[0];
    lidx[1] = Hrtf->evOffset[evidx[0]] + azidx[1];
    ridx[0] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[0]) % Hrtf->azCount[evidx[0]]);
    ridx[1] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[1]) % Hrtf->azCount[evidx[0]]);

    // Calculate azimuth indices and interpolation factor for the second
    // elevation.
    CalcAzIndices(Hrtf, evidx[1], azimuth, azidx, &mu[1]);

    // Calculate the second set of linear HRIR indices for left and right
    // channels.
    lidx[2] = Hrtf->evOffset[evidx[1]] + azidx[0];
    lidx[3] = Hrtf->evOffset[evidx[1]] + azidx[1];
    ridx[2] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[0]) % Hrtf->azCount[evidx[1]]);
    ridx[3] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[1]) % Hrtf->azCount[evidx[1]]);

    /* Calculate 4 blending weights for 2D bilinear interpolation. */
    blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]);
    blend[1] = (     mu[0]) * (1.0f-mu[2]);
    blend[2] = (1.0f-mu[1]) * (     mu[2]);
    blend[3] = (     mu[1]) * (     mu[2]);

    /* Calculate the HRIR delays using linear interpolation. */
    delays[0] = fastf2u(Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] +
                        Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3] +
                        0.5f) << HRTFDELAY_BITS;
    delays[1] = fastf2u(Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] +
                        Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3] +
                        0.5f) << HRTFDELAY_BITS;

    /* Calculate the sample offsets for the HRIR indices. */
    lidx[0] *= Hrtf->irSize;
    lidx[1] *= Hrtf->irSize;
    lidx[2] *= Hrtf->irSize;
    lidx[3] *= Hrtf->irSize;
    ridx[0] *= Hrtf->irSize;
    ridx[1] *= Hrtf->irSize;
    ridx[2] *= Hrtf->irSize;
    ridx[3] *= Hrtf->irSize;

    /* Calculate the normalized and attenuated HRIR coefficients using linear
     * interpolation when there is enough gain to warrant it.  Zero the
     * coefficients if gain is too low.
     */
    if(gain > 0.0001f)
    {
        gain *= 1.0f/32767.0f;
        for(i = 0;i < Hrtf->irSize;i++)
        {
            coeffs[i][0] = (Hrtf->coeffs[lidx[0]+i]*blend[0] +
                            Hrtf->coeffs[lidx[1]+i]*blend[1] +
                            Hrtf->coeffs[lidx[2]+i]*blend[2] +
                            Hrtf->coeffs[lidx[3]+i]*blend[3]) * gain;
            coeffs[i][1] = (Hrtf->coeffs[ridx[0]+i]*blend[0] +
                            Hrtf->coeffs[ridx[1]+i]*blend[1] +
                            Hrtf->coeffs[ridx[2]+i]*blend[2] +
                            Hrtf->coeffs[ridx[3]+i]*blend[3]) * gain;
        }
    }
    else
    {
        for(i = 0;i < Hrtf->irSize;i++)
        {
            coeffs[i][0] = 0.0f;
            coeffs[i][1] = 0.0f;
        }
    }
}
コード例 #19
0
ファイル: eax.c プロジェクト: gena-moscow/wine-patched
static void UpdateDelayLine(float earlyDelay, float lateDelay, unsigned int frequency, eax_buffer_info *State)
{
    State->DelayTap[0] = fastf2u(earlyDelay * frequency);
    State->DelayTap[1] = fastf2u((earlyDelay + lateDelay) * frequency);
}
コード例 #20
0
ファイル: hrtf.c プロジェクト: 24BitGames/LoomSDK
// Calculates the moving HRIR target coefficients, target delays, and
// stepping values for the given polar elevation and azimuth in radians.
// Linear interpolation is used to increase the apparent resolution of the
// HRIR dataset.  The coefficients are also normalized and attenuated by the
// specified gain.  Stepping resolution and count is determined using the
// given delta factor between 0.0 and 1.0.
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep)
{
    ALuint evidx[2], azidx[2];
    ALuint lidx[4], ridx[4];
    ALfloat left, right;
    ALfloat mu[3];
    ALfloat step;
    ALuint i;

    // Claculate elevation indices and interpolation factor.
    CalcEvIndices(elevation, evidx, &mu[2]);

    // Calculate azimuth indices and interpolation factor for the first
    // elevation.
    CalcAzIndices(evidx[0], azimuth, azidx, &mu[0]);

    // Calculate the first set of linear HRIR indices for left and right
    // channels.
    lidx[0] = evOffset[evidx[0]] + azidx[0];
    lidx[1] = evOffset[evidx[0]] + azidx[1];
    ridx[0] = evOffset[evidx[0]] + ((azCount[evidx[0]]-azidx[0]) % azCount[evidx[0]]);
    ridx[1] = evOffset[evidx[0]] + ((azCount[evidx[0]]-azidx[1]) % azCount[evidx[0]]);

    // Calculate azimuth indices and interpolation factor for the second
    // elevation.
    CalcAzIndices(evidx[1], azimuth, azidx, &mu[1]);

    // Calculate the second set of linear HRIR indices for left and right
    // channels.
    lidx[2] = evOffset[evidx[1]] + azidx[0];
    lidx[3] = evOffset[evidx[1]] + azidx[1];
    ridx[2] = evOffset[evidx[1]] + ((azCount[evidx[1]]-azidx[0]) % azCount[evidx[1]]);
    ridx[3] = evOffset[evidx[1]] + ((azCount[evidx[1]]-azidx[1]) % azCount[evidx[1]]);

    // Calculate the stepping parameters.
    delta = maxf(aluFloor(delta*(Hrtf->sampleRate*0.015f) + 0.5f), 1.0f);
    step = 1.0f / delta;

    // Calculate the normalized and attenuated target HRIR coefficients using
    // linear interpolation when there is enough gain to warrant it.  Zero
    // the target coefficients if gain is too low.  Then calculate the
    // coefficient stepping values using the target and previous running
    // coefficients.
    if(gain > 0.0001f)
    {
        gain *= 1.0f/32767.0f;
        for(i = 0;i < HRIR_LENGTH;i++)
        {
            left = coeffs[i][0] - (coeffStep[i][0] * counter);
            right = coeffs[i][1] - (coeffStep[i][1] * counter);

            coeffs[i][0] = lerp(lerp(Hrtf->coeffs[lidx[0]][i], Hrtf->coeffs[lidx[1]][i], mu[0]),
                                lerp(Hrtf->coeffs[lidx[2]][i], Hrtf->coeffs[lidx[3]][i], mu[1]),
                                mu[2]) * gain;
            coeffs[i][1] = lerp(lerp(Hrtf->coeffs[ridx[0]][i], Hrtf->coeffs[ridx[1]][i], mu[0]),
                                lerp(Hrtf->coeffs[ridx[2]][i], Hrtf->coeffs[ridx[3]][i], mu[1]),
                                mu[2]) * gain;

            coeffStep[i][0] = step * (coeffs[i][0] - left);
            coeffStep[i][1] = step * (coeffs[i][1] - right);
        }
    }
    else
    {
        for(i = 0;i < HRIR_LENGTH;i++)
        {
            left = coeffs[i][0] - (coeffStep[i][0] * counter);
            right = coeffs[i][1] - (coeffStep[i][1] * counter);

            coeffs[i][0] = 0.0f;
            coeffs[i][1] = 0.0f;

            coeffStep[i][0] = step * -left;
            coeffStep[i][1] = step * -right;
        }
    }

    // Calculate the HRIR delays using linear interpolation.  Then calculate
    // the delay stepping values using the target and previous running
    // delays.
    left = (ALfloat)(delays[0] - (delayStep[0] * counter));
    right = (ALfloat)(delays[1] - (delayStep[1] * counter));

    delays[0] = fastf2u(lerp(lerp(Hrtf->delays[lidx[0]], Hrtf->delays[lidx[1]], mu[0]),
                             lerp(Hrtf->delays[lidx[2]], Hrtf->delays[lidx[3]], mu[1]),
                             mu[2]) * 65536.0f);
    delays[1] = fastf2u(lerp(lerp(Hrtf->delays[ridx[0]], Hrtf->delays[ridx[1]], mu[0]),
                             lerp(Hrtf->delays[ridx[2]], Hrtf->delays[ridx[3]], mu[1]),
                             mu[2]) * 65536.0f);

    delayStep[0] = fastf2i(step * (delays[0] - left));
    delayStep[1] = fastf2i(step * (delays[1] - right));

    // The stepping count is the number of samples necessary for the HRIR to
    // complete its transition.  The mixer will only apply stepping for this
    // many samples.
    return fastf2u(delta);
}