/* GStreamer
 * Copyright (C) <2007> Sebastian Dröge <slomo@circular-chaos.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <glib.h>
#include <math.h>

#include "_kiss_fft_guts_s32.h"
#include "kiss_fftr_s32.h"
#include "gstfft.h"
#include "gstffts32.h"

/**
 * SECTION:gstffts32
 * @short_description: FFT functions for signed 32 bit integer samples
 *
 * #GstFFTS32 provides a FFT implementation and related functions for
 * signed 32 bit integer samples. To use this call gst_fft_s32_new() for
 * allocating a #GstFFTS32 instance with the appropriate parameters and
 * then call gst_fft_s32_fft() or gst_fft_s32_inverse_fft() to perform the
 * FFT or inverse FFT on a buffer of samples.
 *
 * After use free the #GstFFTS32 instance with gst_fft_s32_free().
 *
 * For the best performance use gst_fft_next_fast_length() to get a
 * number that is entirely a product of 2, 3 and 5 and use this as the
 * @len parameter for gst_fft_s32_new().
 *
 * The @len parameter specifies the number of samples in the time domain that
 * will be processed or generated. The number of samples in the frequency domain
 * is @len/2 + 1. To get n samples in the frequency domain use 2*n - 2 as @len.
 *
 * Before performing the FFT on time domain data it usually makes sense
 * to apply a window function to it. For this gst_fft_s32_window() can comfortably
 * be used.
 *
 * Be aware, that you can't simply run gst_fft_s32_inverse_fft() on the
 * resulting frequency data of gst_fft_s32_fft() to get the original data back.
 * The relation between them is iFFT (FFT (x)) = x / nfft where nfft is the
 * length of the FFT. This also has to be taken into account when calculation
 * the magnitude of the frequency data.
 */

/**
 * gst_fft_s32_new:
 * @len: Length of the FFT in the time domain
 * @inverse: %TRUE if the #GstFFTS32 instance should be used for the inverse FFT
 *
 * This returns a new #GstFFTS32 instance with the given parameters. It makes
 * sense to keep one instance for several calls for speed reasons.
 *
 * @len must be even and to get the best performance a product of
 * 2, 3 and 5. To get the next number with this characteristics use
 * gst_fft_next_fast_length().
 *
 * Returns: a new #GstFFTS32 instance.
 */
GstFFTS32 *
gst_fft_s32_new (gint len, gboolean inverse)
{
  GstFFTS32 *self;
  gsize subsize = 0, memneeded;

  g_return_val_if_fail (len > 0, NULL);
  g_return_val_if_fail (len % 2 == 0, NULL);

  kiss_fftr_s32_alloc (len, (inverse) ? 1 : 0, NULL, &subsize);
  memneeded = ALIGN_STRUCT (sizeof (GstFFTS32)) + subsize;

  self = (GstFFTS32 *) g_malloc0 (memneeded);

  self->cfg = (((guint8 *) self) + ALIGN_STRUCT (sizeof (GstFFTS32)));
  self->cfg = kiss_fftr_s32_alloc (len, (inverse) ? 1 : 0, self->cfg, &subsize);
  g_assert (self->cfg);

  self->inverse = inverse;
  self->len = len;

  return self;
}

/**
 * gst_fft_s32_fft:
 * @self: #GstFFTS32 instance for this call
 * @timedata: Buffer of the samples in the time domain
 * @freqdata: Target buffer for the samples in the frequency domain
 *
 * This performs the FFT on @timedata and puts the result in @freqdata.
 *
 * @timedata must have as many samples as specified with the @len parameter while
 * allocating the #GstFFTS32 instance with gst_fft_s32_new().
 *
 * @freqdata must be large enough to hold @len/2 + 1 #GstFFTS32Complex frequency
 * domain samples.
 *
 */
void
gst_fft_s32_fft (GstFFTS32 * self, const gint32 * timedata,
    GstFFTS32Complex * freqdata)
{
  g_return_if_fail (self);
  g_return_if_fail (!self->inverse);
  g_return_if_fail (timedata);
  g_return_if_fail (freqdata);

  kiss_fftr_s32 (self->cfg, timedata, (kiss_fft_s32_cpx *) freqdata);
}

/**
 * gst_fft_s32_inverse_fft:
 * @self: #GstFFTS32 instance for this call
 * @freqdata: Buffer of the samples in the frequency domain
 * @timedata: Target buffer for the samples in the time domain
 *
 * This performs the inverse FFT on @freqdata and puts the result in @timedata.
 *
 * @freqdata must have @len/2 + 1 samples, where @len is the parameter specified
 * while allocating the #GstFFTS32 instance with gst_fft_s32_new().
 *
 * @timedata must be large enough to hold @len time domain samples.
 *
 */
void
gst_fft_s32_inverse_fft (GstFFTS32 * self, const GstFFTS32Complex * freqdata,
    gint32 * timedata)
{
  g_return_if_fail (self);
  g_return_if_fail (self->inverse);
  g_return_if_fail (timedata);
  g_return_if_fail (freqdata);

  kiss_fftri_s32 (self->cfg, (kiss_fft_s32_cpx *) freqdata, timedata);
}

/**
 * gst_fft_s32_free:
 * @self: #GstFFTS32 instance for this call
 *
 * This frees the memory allocated for @self.
 *
 */
void
gst_fft_s32_free (GstFFTS32 * self)
{
  g_free (self);
}

/**
 * gst_fft_s32_window:
 * @self: #GstFFTS32 instance for this call
 * @timedata: Time domain samples
 * @window: Window function to apply
 *
 * This calls the window function @window on the @timedata sample buffer.
 *
 */
void
gst_fft_s32_window (GstFFTS32 * self, gint32 * timedata, GstFFTWindow window)
{
  gint i, len;

  g_return_if_fail (self);
  g_return_if_fail (timedata);

  len = self->len;

  switch (window) {
    case GST_FFT_WINDOW_RECTANGULAR:
      /* do nothing */
      break;
    case GST_FFT_WINDOW_HAMMING:
      for (i = 0; i < len; i++)
        timedata[i] *= (0.53836 - 0.46164 * cos (2.0 * G_PI * i / len));
      break;
    case GST_FFT_WINDOW_HANN:
      for (i = 0; i < len; i++)
        timedata[i] *= (0.5 - 0.5 * cos (2.0 * G_PI * i / len));
      break;
    case GST_FFT_WINDOW_BARTLETT:
      for (i = 0; i < len; i++)
        timedata[i] *= (1.0 - fabs ((2.0 * i - len) / len));
      break;
    case GST_FFT_WINDOW_BLACKMAN:
      for (i = 0; i < len; i++)
        timedata[i] *= (0.42 - 0.5 * cos ((2.0 * i) / len) +
            0.08 * cos ((4.0 * i) / len));
      break;
    default:
      g_assert_not_reached ();
      break;
  }
}
