Ejemplo n.º 1
0
void zvmul(const float* real1P, const float* imag1P, const float* real2P, const float* imag2P, float* realDestP, float* imagDestP, size_t framesToProcess)
{
    DSPSplitComplex sc1;
    DSPSplitComplex sc2;
    DSPSplitComplex dest;
    sc1.realp = const_cast<float*>(real1P);
    sc1.imagp = const_cast<float*>(imag1P);
    sc2.realp = const_cast<float*>(real2P);
    sc2.imagp = const_cast<float*>(imag2P);
    dest.realp = realDestP;
    dest.imagp = imagDestP;
#if defined(__ppc__) || defined(__i386__)
    ::zvmul(&sc1, 1, &sc2, 1, &dest, 1, framesToProcess, 1);
#else
    vDSP_zvmul(&sc1, 1, &sc2, 1, &dest, 1, framesToProcess, 1);
#endif
}
void FFTFrame::multiply(const FFTFrame& frame)
{
    FFTFrame& frame1 = *this;
    const FFTFrame& frame2 = frame;

    float* realP1 = frame1.realData();
    float* imagP1 = frame1.imagData();
    const float* realP2 = frame2.realData();
    const float* imagP2 = frame2.imagData();

    // Scale accounts for vecLib's peculiar scaling
    // This ensures the right scaling all the way back to inverse FFT
    float scale = 0.5f;

    // Multiply packed DC/nyquist component
    realP1[0] *= scale * realP2[0];
    imagP1[0] *= scale * imagP2[0];

    // Multiply the rest, skipping packed DC/Nyquist components
    DSPSplitComplex sc1 = frame1.dspSplitComplex();
    sc1.realp++;
    sc1.imagp++;

    DSPSplitComplex sc2 = frame2.dspSplitComplex();
    sc2.realp++;
    sc2.imagp++;

    unsigned halfSize = m_FFTSize / 2;

    // Complex multiply
    vDSP_zvmul(&sc1, 1, &sc2, 1, &sc1, 1, halfSize - 1, 1 /* normal multiplication */);

    // We've previously scaled the packed part, now scale the rest.....
    vDSP_vsmul(sc1.realp, 1, &scale, sc1.realp, 1, halfSize - 1);
    vDSP_vsmul(sc1.imagp, 1, &scale, sc1.imagp, 1, halfSize - 1);
}