1333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com/* 2333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * 4333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * Use of this source code is governed by a BSD-style license 5333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * that can be found in the LICENSE file in the root of the source 6333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * tree. An additional intellectual property rights grant can be found 7333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * in the file PATENTS. All contributing project authors may 8333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * be found in the AUTHORS file in the root of the source tree. 9333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * 10333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com */ 11333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 12333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com#include <stdint.h> 13333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 14333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com#include "dl/api/omxtypes.h" 15333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com#include "dl/sp/api/mipsSP.h" 16333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 17333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.comOMXResult mips_FFTFwd_RToCCS_F32_real(const OMX_F32* pSrc, 18333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_F32* pDst, 19333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com const MIPSFFTSpec_R_FC32* pFFTSpec) { 20333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_U32 num_transforms, step; 21333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_FC32* p_dst = (OMX_FC32*)pDst; 22333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_FC32* p_buf = (OMX_FC32*)pFFTSpec->pBuf; 23333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_F32 tmp1, tmp2, tmp3, tmp4; 24333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_F32* w_re_ptr; 25333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_F32* w_im_ptr; 26333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 27333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com /* Transform for order = 2. */ 28333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com /* TODO: hard-code the offsets for p_src. */ 29333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com if (pFFTSpec->order == 2) { 30333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_U16* p_bitrev = pFFTSpec->pBitRev; 31333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 32333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = pSrc[p_bitrev[0]] + pSrc[p_bitrev[1]]; 33333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp2 = pSrc[p_bitrev[2]] + pSrc[p_bitrev[3]]; 34333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp3 = pSrc[p_bitrev[0]] - pSrc[p_bitrev[1]]; 35333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp4 = pSrc[p_bitrev[2]] - pSrc[p_bitrev[3]]; 36333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 37333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[0].Re = tmp1 + tmp2; 38333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[2].Re = tmp1 - tmp2; 39333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[0].Im = 0.0f; 40333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[2].Im = 0.0f; 41333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[1].Re = tmp3; 42333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[1].Im = -tmp4; 43333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 44333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com return OMX_Sts_NoErr; 45333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com } 46333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 47333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com /* 48333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * Loop performing sub-transforms of size 4, which contain two butterfly 49333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * operations. Reading the input signal from split-radix bitreverse offsets. 50333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com */ 51333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com num_transforms = (SUBTRANSFORM_CONST >> (16 - pFFTSpec->order)) | 1; 52333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com for (uint32_t n = 0; n < num_transforms; ++n) { 53333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_U32 offset = pFFTSpec->pOffset[n] << 2; 54333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_FC32* p_tmp = p_buf + offset; 55333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_U16* p_bitrev = pFFTSpec->pBitRev + offset; 56333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 57333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = pSrc[p_bitrev[0]] + pSrc[p_bitrev[1]]; 58333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp2 = pSrc[p_bitrev[2]] + pSrc[p_bitrev[3]]; 59333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp3 = pSrc[p_bitrev[0]] - pSrc[p_bitrev[1]]; 60333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp4 = pSrc[p_bitrev[2]] - pSrc[p_bitrev[3]]; 61333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 62333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[0].Re = tmp1 + tmp2; 63333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[2].Re = tmp1 - tmp2; 64333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[0].Im = 0.0f; 65333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[2].Im = 0.0f; 66333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[1].Re = tmp3; 67333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[3].Re = tmp3; 68333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[1].Im = -tmp4; 69333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[3].Im = tmp4; 70333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com } 71333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 72333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com /* 73333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * Loop performing sub-transforms of size 8, 74333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * which contain four butterfly operations. 75333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com */ 76333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com num_transforms >>= 1; 77333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com if (!num_transforms) { 78333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com /* 79333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * Means the FFT size is equal to 8, so this is the last stage. Place the 80333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * output to the destination buffer and avoid unnecessary computations. 81333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com */ 82333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_FC32* p_tmp = p_buf; 83333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_U16* p_bitrev = pFFTSpec->pBitRev; 84333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_F32 tmp5; 85333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 86333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = pSrc[p_bitrev[4]] + pSrc[p_bitrev[5]]; 87333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp2 = pSrc[p_bitrev[6]] + pSrc[p_bitrev[7]]; 88333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp3 = tmp1 + tmp2; 89333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp4 = tmp1 - tmp2; 90333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 91333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = pSrc[p_bitrev[4]] - pSrc[p_bitrev[5]]; 92333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp2 = pSrc[p_bitrev[6]] - pSrc[p_bitrev[7]]; 93333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp5 = SQRT1_2 * (tmp1 + tmp2); 94333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = SQRT1_2 * (tmp1 - tmp2); 95333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 96333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[4].Re = p_tmp[0].Re - tmp3; 97333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[0].Re = p_tmp[0].Re + tmp3; 98333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[0].Im = p_tmp[0].Im; 99333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[4].Im = p_tmp[0].Im; 100333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[2].Re = p_tmp[2].Re; 101333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[2].Im = p_tmp[2].Im - tmp4; 102333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[1].Re = p_tmp[1].Re + tmp5; 103333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[1].Im = p_tmp[1].Im - tmp1; 104333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[3].Re = p_tmp[3].Re - tmp5; 105333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[3].Im = p_tmp[3].Im - tmp1; 106333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 107333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com return OMX_Sts_NoErr; 108333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com } 109333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 110333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com num_transforms |= 1; 111333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 112333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com for (uint32_t n = 0; n < num_transforms; ++n) { 113333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_U32 offset = pFFTSpec->pOffset[n] << 3; 114333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_FC32* p_tmp = p_buf + offset; 115333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_U16* p_bitrev = pFFTSpec->pBitRev + offset; 116333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_F32 tmp5; 117333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 118333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = pSrc[p_bitrev[4]] + pSrc[p_bitrev[5]]; 119333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp2 = pSrc[p_bitrev[6]] + pSrc[p_bitrev[7]]; 120333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp3 = tmp1 + tmp2; 121333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp4 = tmp1 - tmp2; 122333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 123333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = pSrc[p_bitrev[4]] - pSrc[p_bitrev[5]]; 124333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp2 = pSrc[p_bitrev[6]] - pSrc[p_bitrev[7]]; 125333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp5 = SQRT1_2 * (tmp1 + tmp2); 126333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = SQRT1_2 * (tmp1 - tmp2); 127333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 128333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[4].Re = p_tmp[0].Re - tmp3; 129333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[0].Re = p_tmp[0].Re + tmp3; 130333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[4].Im = p_tmp[0].Im; 131333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[6].Re = p_tmp[2].Re; 132333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[6].Im = p_tmp[2].Im + tmp4; 133333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[2].Im = p_tmp[2].Im - tmp4; 134333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 135333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[5].Re = p_tmp[1].Re - tmp5; 136333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[1].Re = p_tmp[1].Re + tmp5; 137333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[5].Im = p_tmp[1].Im + tmp1; 138333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[1].Im = p_tmp[1].Im - tmp1; 139333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[7].Re = p_tmp[3].Re + tmp5; 140333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[3].Re = p_tmp[3].Re - tmp5; 141333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[7].Im = p_tmp[3].Im + tmp1; 142333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_tmp[3].Im = p_tmp[3].Im - tmp1; 143333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com } 144333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 145333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com step = 1 << (TWIDDLE_TABLE_ORDER - 4); 146333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com /* 147333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * Last FFT stage, performing sub-transforms of size 16. Place the output 148333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com * into the destination buffer and avoid unnecessary computations. 149333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com */ 150333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = p_buf[8].Re + p_buf[12].Re; 151333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp2 = p_buf[8].Re - p_buf[12].Re; 152333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp3 = p_buf[8].Im + p_buf[12].Im; 153333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp4 = p_buf[8].Im - p_buf[12].Im; 154333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 155333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[8].Re = p_buf[0].Re - tmp1; 156333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[0].Re = p_buf[0].Re + tmp1; 157333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[8].Im = p_buf[0].Im - tmp3; 158333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[0].Im = p_buf[0].Im + tmp3; 159333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[4].Re = p_buf[4].Re + tmp4; 160333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[4].Im = p_buf[4].Im - tmp2; 161333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 162333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com w_re_ptr = pFFTSpec->pTwiddle + step; 163333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com w_im_ptr = 164333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com pFFTSpec->pTwiddle + (OMX_U32)(1 << TWIDDLE_TABLE_ORDER - 2) - step; 165333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 166333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com /* Loop performing split-radix butterfly operations. */ 167333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com for (uint32_t n = 1; n < 4; ++n) { 168333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_F32 tmp5, tmp6; 169333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_F32 w_re = *w_re_ptr; 170333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com OMX_F32 w_im = *w_im_ptr; 171333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 172333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = w_re * p_buf[8 + n].Re + w_im * p_buf[8 + n].Im; 173333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp2 = w_re * p_buf[8 + n].Im - w_im * p_buf[8 + n].Re; 174333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp3 = w_re * p_buf[12 + n].Re - w_im * p_buf[12 + n].Im; 175333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp4 = w_re * p_buf[12 + n].Im + w_im * p_buf[12 + n].Re; 176333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 177333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp5 = tmp1 + tmp3; 178333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp1 = tmp1 - tmp3; 179333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp6 = tmp2 + tmp4; 180333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com tmp2 = tmp2 - tmp4; 181333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 182333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[n].Re = p_buf[n].Re + tmp5; 183333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[n].Im = p_buf[n].Im + tmp6; 184333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[4 + n].Re = p_buf[4 + n].Re + tmp2; 185333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com p_dst[4 + n].Im = p_buf[4 + n].Im - tmp1; 186333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com 187333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com w_re_ptr += step; 188333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com w_im_ptr -= step; 189333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com } 190333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com return OMX_Sts_NoErr; 191333c00b74820c9dc0022d124c5a10a788d74d5cartoy@google.com} 192