1da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com/*
2da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *
4da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *  Use of this source code is governed by a BSD-style license
5da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *  that can be found in the LICENSE file in the root of the source
6da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *  tree. An additional intellectual property rights grant can be found
7da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *  in the file PATENTS.  All contributing project authors may
8da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *  be found in the AUTHORS file in the root of the source tree.
9da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *
10da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *  This is a modification of omxSP_FFTInit_R_S32.c to support float
11da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *  instead of S32.
12da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com */
13da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
145537f70dff0bb4566ebb1ec645d2020974e93493turaj@webrtc.org#include <stdint.h>
155537f70dff0bb4566ebb1ec645d2020974e93493turaj@webrtc.org
16da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com#include "dl/api/omxtypes.h"
17da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com#include "dl/sp/api/omxSP.h"
18da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com#include "dl/sp/api/x86SP.h"
19da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
20da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com/**
21da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * Function: omxSP_FFTInit_R_F32
22da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *
23da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * Description:
24da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * Initialize the real forward-FFT specification information struct.
25da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *
26da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * Remarks:
27da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * This function is used to initialize the specification structures
28da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * for functions |omxSP_FFTFwd_RToCCS_F32_Sfs| and
29da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * |omxSP_FFTInv_CCSToR_F32_Sfs|. Memory for *pFFTSpec must be
30da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * allocated prior to calling this function. The number of bytes
31da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * required for *pFFTSpec can be determined using
32da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * |omxSP_FFTGetBufSize_R_F32|.
33da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *
34da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * Parameters:
35da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * [in]  order       base-2 logarithm of the desired block length;
36da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *                         valid in the range [1,12].  ([1,15] if
37da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *                         BIG_FFT_TABLE is defined.)
38da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * [out] pFFTFwdSpec pointer to the initialized specification structure.
39da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *
40da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * Return Value:
41da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com * Standard omxError result. See enumeration for possible result codes.
42da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com *
43da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com */
44da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
45da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.comOMXResult omxSP_FFTInit_R_F32(OMXFFTSpec_R_F32 *pFFTSpec, OMX_INT order)
46da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com{
47da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_F32 *pTwiddle;
48da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_F32 *pBuf;
49da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_INT i;
50da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_INT j;
51da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_INT N;
52da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_INT NBy2;
53da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_INT NBy4;
54da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_INT diff;
55da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_U32 pTmp;
56da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  X86FFTSpec_R_FC32  *pFFTStruct = (X86FFTSpec_R_FC32 *) pFFTSpec;
57da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_F32 real;
58da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  OMX_F32 imag;
59da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
60da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  if (!pFFTSpec || (order < 1) || (order > TWIDDLE_TABLE_ORDER))
61da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    return OMX_Sts_BadArgErr;
62da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
63da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  N = 1 << order;
64da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  NBy2 = N >> 1;
65da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
66da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  pTwiddle = (OMX_F32*) (sizeof(X86FFTSpec_R_FC32) + (OMX_S8*) pFFTSpec);
67da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
68da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  // Align to 32 byte boundary.
695537f70dff0bb4566ebb1ec645d2020974e93493turaj@webrtc.org  pTmp = ((uintptr_t)pTwiddle) & 31;
70da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  if (pTmp)
71da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    pTwiddle = (OMX_F32*) ((OMX_S8*)pTwiddle + (32 - pTmp));
72da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
73da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  pBuf = (OMX_F32*) (sizeof(OMX_F32) * (N << 1) + (OMX_S8*) pTwiddle);
74da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
75da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  // Align to 32 byte boundary.
765537f70dff0bb4566ebb1ec645d2020974e93493turaj@webrtc.org  pTmp = ((uintptr_t)pBuf) & 31;
77da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  if (pTmp)
78da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    pBuf = (OMX_F32*) ((OMX_S8*)pBuf + (32 - pTmp));
79da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
80da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  // Calculating Twiddle Factors.
81da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  diff = 1 << (TWIDDLE_TABLE_ORDER - order + 1);
82da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
83da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  // For SSE optimization, using twiddle with split format by which the real and
84da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  // imag data are stored into first and last halves of the buffer separately
85da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  // The negatives are moved when generating pTwiddle table.
86da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  if (order > 1) {
87da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    NBy4 = N >> 2;
88da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    for (i = 0, j = 0; i <= NBy4 >> 1; ++i, j += diff) {
89da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      real = armSP_FFT_F32TwiddleTable[j];
90da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      imag = armSP_FFT_F32TwiddleTable[j + 1];
91da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
92da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[i] = -real;
93da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[i + N] = -imag;
94da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
95da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy4 - i] = imag;
96da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy4 - i + N] = real;
97da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
98da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy4 + i] = -imag;
99da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy4 + i + N] = real;
100da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
101da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy2 - i] = real;
102da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy2 - i + N] = -imag;
103da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
104da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy2 + i] = real;
105da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy2 + i + N] = imag;
106da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
107da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy4 * 3 - i] = -imag;
108da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy4 * 3 - i + N] = -real;
109da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
110da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy4 * 3 + i] = imag;
111da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[NBy4 * 3 + i + N] = -real;
112da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
113da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[N - i - 1] = -real;
114da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com      pTwiddle[(N << 1) - i - 1] = imag;
115da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    }
116da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  } else {
117da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    pTwiddle[0] = armSP_FFT_F32TwiddleTable[0];
118da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    pTwiddle[2] = armSP_FFT_F32TwiddleTable[1];
119da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    pTwiddle[1] = -pTwiddle[0];
120da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com    pTwiddle[3] = pTwiddle[2];
121da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  }
122da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  pFFTStruct->N = N;
123da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  pFFTStruct->pTwiddle = pTwiddle;
124da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  pFFTStruct->pBuf1 = pBuf;
125da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  pFFTStruct->pBuf2 = pBuf + N + 4;
126da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com
127da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com  return OMX_Sts_NoErr;
128da04d4f8ef493ab7bf1fbdaffe206899f03681c2rtoy@google.com}
129