/* 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif


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

#include "_kiss_fft_guts_f64.h"
#include "kiss_fftr_f64.h"
#include "gstfft.h"
#include "gstfftf64.h"

/**
 * SECTION:gstfftf64
 * @short_description: FFT functions for 64 bit float samples
 *
 * #GstFFTF64 provides a FFT implementation and related functions for
 * 64 bit float samples. To use this call gst_fft_f64_new() for
 * allocating a #GstFFTF64 instance with the appropriate parameters and
 * then call gst_fft_f64_fft() or gst_fft_f64_inverse_fft() to perform the
 * FFT or inverse FFT on a buffer of samples.
 *
 * After use free the #GstFFTF64 instance with gst_fft_f64_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_f64_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_f64_window() can comfortably
 * be used.
 *
 * Be aware, that you can't simply run gst_fft_f32_inverse_fft() on the
 * resulting frequency data of gst_fft_f32_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.
 *
 */

struct _GstFFTF64
{
  void *cfg;
  gboolean inverse;
  gint len;
};

/**
 * gst_fft_f64_new:
 * @len: Length of the FFT in the time domain
 * @inverse: %TRUE if the #GstFFTF64 instance should be used for the inverse FFT
 *
 * This returns a new #GstFFTF64 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 #GstFFTF64 instance.
 */
GstFFTF64 *
gst_fft_f64_new (gint len, gboolean inverse)
{
  GstFFTF64 *self;
  gsize subsize = 0, memneeded;

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

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

  self = (GstFFTF64 *) g_malloc0 (memneeded);

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

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

  return self;
}

/**
 * gst_fft_f64_fft:
 * @self: #GstFFTF64 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 #GstFFTF64 instance with gst_fft_f64_new().
 *
 * @freqdata must be large enough to hold @len/2 + 1 #GstFFTF64Complex frequency
 * domain samples.
 *
 */
void
gst_fft_f64_fft (GstFFTF64 * self, const gdouble * timedata,
    GstFFTF64Complex * freqdata)
{
  g_return_if_fail (self);
  g_return_if_fail (!self->inverse);
  g_return_if_fail (timedata);
  g_return_if_fail (freqdata);

  kiss_fftr_f64 (self->cfg, timedata, (kiss_fft_f64_cpx *) freqdata);
}

/**
 * gst_fft_f64_inverse_fft:
 * @self: #GstFFTF64 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 #GstFFTF64 instance with gst_fft_f64_new().
 *
 * @timedata must be large enough to hold @len time domain samples.
 *
 */
void
gst_fft_f64_inverse_fft (GstFFTF64 * self, const GstFFTF64Complex * freqdata,
    gdouble * timedata)
{
  g_return_if_fail (self);
  g_return_if_fail (self->inverse);
  g_return_if_fail (timedata);
  g_return_if_fail (freqdata);

  kiss_fftri_f64 (self->cfg, (kiss_fft_f64_cpx *) freqdata, timedata);
}

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

/**
 * gst_fft_f64_window:
 * @self: #GstFFTF64 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_f64_window (GstFFTF64 * self, gdouble * 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;
  }
}
