inline void IFFTDeinterleaved()

in XDSP/XDSP.h [790:865]


    inline void IFFTDeinterleaved(
        _Inout_updates_(((1 << uLog2Length) * uChannelCount) / 4) XMVECTOR* __restrict pReal,
        _In_reads_(((1 << uLog2Length) * uChannelCount) / 4) const XMVECTOR* __restrict pImaginary,
        _In_reads_(1 << uLog2Length) const XMVECTOR* __restrict pUnityTable,
        _In_ const size_t uChannelCount,
        _In_ const size_t uLog2Length) noexcept
    {
        using namespace DirectX;

        assert(pReal);
        assert(pImaginary);
        assert(pUnityTable);
        assert(reinterpret_cast<uintptr_t>(pReal) % 16 == 0);
        assert(reinterpret_cast<uintptr_t>(pImaginary) % 16 == 0);
        assert(reinterpret_cast<uintptr_t>(pUnityTable) % 16 == 0);
        assert(uChannelCount > 0 && uChannelCount <= 6);
        _Analysis_assume_(uChannelCount > 0 && uChannelCount <= 6);
        assert(uLog2Length >= 2 && uLog2Length <= 9);
        _Analysis_assume_(uLog2Length >= 2 && uLog2Length <= 9);

        XMVECTOR vRealTemp[768] = {};
        XMVECTOR vImaginaryTemp[768] = {};

        const size_t uLength = size_t(1) << uLog2Length;

        const XMVECTOR vRnp = XMVectorReplicate(1.0f / float(uLength));
        const XMVECTOR vRnm = XMVectorReplicate(-1.0f / float(uLength));
        for (size_t u = 0; u < uChannelCount * (uLength >> 2); u++)
        {
            vRealTemp[u] = XMVectorMultiply(pReal[u], vRnp);
            vImaginaryTemp[u] = XMVectorMultiply(pImaginary[u], vRnm);
        }

        if (uLength > 16)
        {
            for (size_t uChannel = 0; uChannel < uChannelCount; ++uChannel)
            {
                FFT(&vRealTemp[uChannel * (uLength >> 2)], &vImaginaryTemp[uChannel * (uLength >> 2)], pUnityTable, uLength);
            }
        }
        else if (uLength == 16)
        {
            for (size_t uChannel = 0; uChannel < uChannelCount; ++uChannel)
            {
                FFT16(&vRealTemp[uChannel * (uLength >> 2)], &vImaginaryTemp[uChannel * (uLength >> 2)]);
            }
        }
        else if (uLength == 8)
        {
            for (size_t uChannel = 0; uChannel < uChannelCount; ++uChannel)
            {
                FFT8(&vRealTemp[uChannel * (uLength >> 2)], &vImaginaryTemp[uChannel * (uLength >> 2)]);
            }
        }
        else if (uLength == 4)
        {
            for (size_t uChannel = 0; uChannel < uChannelCount; ++uChannel)
            {
                FFT4(&vRealTemp[uChannel * (uLength >> 2)], &vImaginaryTemp[uChannel * (uLength >> 2)]);
            }
        }

        for (size_t uChannel = 0; uChannel < uChannelCount; ++uChannel)
        {
            FFTUnswizzle(&vImaginaryTemp[uChannel * (uLength >> 2)], &vRealTemp[uChannel * (uLength >> 2)], uLog2Length);
        }

        if (uChannelCount > 1)
        {
            Interleave(pReal, vImaginaryTemp, uChannelCount, uLength);
        }
        else
        {
            memcpy_s(pReal, uLength * uChannelCount * sizeof(float), vImaginaryTemp, (uLength >> 2) * sizeof(XMVECTOR));
        }
    }