/* Copyright (c) 2015 Xiph.Org Foundation
   Written by Viswanath Puttagunta */
/**
   @file celt_ne10_fft.c
   @brief ARM Neon optimizations for fft using NE10 library
 */

/*
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef SKIP_CONFIG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif

#include <NE10_init.h>
#include <NE10_dsp.h>
#include "os_support.h"
#include "kiss_fft.h"
#include "stack_alloc.h"

#if !defined(FIXED_POINT)
# define NE10_FFT_ALLOC_C2C_TYPE_NEON ne10_fft_alloc_c2c_float32_neon
# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_float32_t
# define NE10_FFT_STATE_TYPE_T ne10_fft_state_float32_t
# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_float32
# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_float32_t
# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_float32_neon
#else
# define NE10_FFT_ALLOC_C2C_TYPE_NEON(nfft) ne10_fft_alloc_c2c_int32_neon(nfft)
# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_int32_t
# define NE10_FFT_STATE_TYPE_T ne10_fft_state_int32_t
# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_int32_t
# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_int32_neon
#endif

#if defined(CUSTOM_MODES)

/* nfft lengths in NE10 that support scaled fft */
# define NE10_FFTSCALED_SUPPORT_MAX 4
static const int ne10_fft_scaled_support[NE10_FFTSCALED_SUPPORT_MAX] = {
   480, 240, 120, 60
};

int opus_fft_alloc_arm_neon(kiss_fft_state *st)
{
   int i;
   size_t memneeded = sizeof(struct arch_fft_state);

   st->arch_fft = (arch_fft_state *)opus_alloc(memneeded);
   if (!st->arch_fft)
      return -1;

   for (i = 0; i < NE10_FFTSCALED_SUPPORT_MAX; i++) {
      if(st->nfft == ne10_fft_scaled_support[i])
         break;
   }
   if (i == NE10_FFTSCALED_SUPPORT_MAX) {
      /* This nfft length (scaled fft) is not supported in NE10 */
      st->arch_fft->is_supported = 0;
      st->arch_fft->priv = NULL;
   }
   else {
      st->arch_fft->is_supported = 1;
      st->arch_fft->priv = (void *)NE10_FFT_ALLOC_C2C_TYPE_NEON(st->nfft);
      if (st->arch_fft->priv == NULL) {
         return -1;
      }
   }
   return 0;
}

void opus_fft_free_arm_neon(kiss_fft_state *st)
{
   NE10_FFT_CFG_TYPE_T cfg;

   if (!st->arch_fft)
      return;

   cfg = (NE10_FFT_CFG_TYPE_T)st->arch_fft->priv;
   if (cfg)
      NE10_FFT_DESTROY_C2C_TYPE(cfg);
   opus_free(st->arch_fft);
}
#endif

void opus_fft_neon(const kiss_fft_state *st,
                   const kiss_fft_cpx *fin,
                   kiss_fft_cpx *fout)
{
   NE10_FFT_STATE_TYPE_T state;
   NE10_FFT_CFG_TYPE_T cfg = &state;
   VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
   SAVE_STACK;
   ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);

   if (!st->arch_fft->is_supported) {
      /* This nfft length (scaled fft) not supported in NE10 */
      opus_fft_c(st, fin, fout);
   }
   else {
      memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
      state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
#if !defined(FIXED_POINT)
      state.is_forward_scaled = 1;

      NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
                                (NE10_FFT_CPX_TYPE_T *)fin,
                                cfg, 0);
#else
      NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
                                (NE10_FFT_CPX_TYPE_T *)fin,
                                cfg, 0, 1);
#endif
   }
   RESTORE_STACK;
}

void opus_ifft_neon(const kiss_fft_state *st,
                    const kiss_fft_cpx *fin,
                    kiss_fft_cpx *fout)
{
   NE10_FFT_STATE_TYPE_T state;
   NE10_FFT_CFG_TYPE_T cfg = &state;
   VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
   SAVE_STACK;
   ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);

   if (!st->arch_fft->is_supported) {
      /* This nfft length (scaled fft) not supported in NE10 */
      opus_ifft_c(st, fin, fout);
   }
   else {
      memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
      state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
#if !defined(FIXED_POINT)
      state.is_backward_scaled = 0;

      NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
                                (NE10_FFT_CPX_TYPE_T *)fin,
                                cfg, 1);
#else
      NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
                                (NE10_FFT_CPX_TYPE_T *)fin,
                                cfg, 1, 0);
#endif
   }
   RESTORE_STACK;
}
