All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ddf.minim.analysis.DFT Maven / Gradle / Ivy

There is a newer version: 2.1
Show newest version
/*
 *  Copyright (c) 2007 - 2008 by Damien Di Fede 
 *
 *   This program 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 program 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 program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package ddf.minim.analysis;


/**
 * DFT stands for Discrete Fourier Transform and is the most widely used Fourier
 * Transform. You will never want to use this class due to the fact that it is a
 * brute force implementation of the DFT and as such is quite slow. Use an FFT
 * instead. This exists primarily as a way to ensure that other implementations
 * of the DFT are working properly. This implementation expects an even
 * timeSize and will throw and IllegalArgumentException if this is
 * not the case.
 * 
 * @author Damien Di Fede
 * 
 * @see FourierTransform
 * @see FFT
 * @see The Discrete Fourier
 *      Transform
 * 
 */
public class DFT extends FourierTransform {
  /**
   * Constructs a DFT that expects audio buffers of length timeSize
   * that have been recorded with a sample rate of sampleRate. Will
   * throw an IllegalArgumentException if timeSize is not even.
   * 
   * @param timeSize
   *          the length of the audio buffers you plan to analyze
   * @param sampleRate
   *          the sample rate of the audio samples you plan to analyze
   */
  public DFT(int timeSize, double sampleRate) {
    super(timeSize, sampleRate);
    if (timeSize % 2 != 0) throw new IllegalArgumentException("DFT: timeSize must be even.");
    buildTrigTables();
  }

  protected void allocateArrays() {
    spectrum = new double[timeSize / 2 + 1];
    real = new double[timeSize / 2 + 1];
    imag = new double[timeSize / 2 + 1];
  }

  /**
   * Not currently implemented.
   */
  public void scaleBand(int i, double s) {
  }

  /**
   * Not currently implemented.
   */
  public void setBand(int i, double a) {
  }

  public void forward(double[] samples) {
    if (samples.length != timeSize) {
      throw new RuntimeException("DFT.forward: The length of the passed sample buffer must be equal to DFT.timeSize().");
    }
    doWindow(samples);
    int N = samples.length;
    for (int f = 0; f <= N / 2; f++) {
      real[f] = 0.0f;
      imag[f] = 0.0f;
      for (int t = 0; t < N; t++) {
        real[f] += samples[t] * cos(t * f);
        imag[f] += samples[t] * -sin(t * f);
      }
    }
    fillSpectrum();
  }

  public void inverse(double[] buffer) {
    int N = buffer.length;
    real[0] /= N;
    imag[0] = -imag[0] / (N / 2);
    real[N / 2] /= N;
    imag[N / 2] = -imag[0] / (N / 2);
    for (int i = 0; i < N / 2; i++) {
      real[i] /= (N / 2);
      imag[i] = -imag[i] / (N / 2);
    }
    for (int t = 0; t < N; t++) {
      buffer[t] = 0.0f;
      for (int f = 0; f < N / 2; f++) {
        buffer[t] += real[f] * cos(t * f) + imag[f] * sin(t * f);
      }
    }
  }

  // lookup table data and functions

  private double[] sinlookup;
  private double[] coslookup;

  private void buildTrigTables() {
    int N = spectrum.length * timeSize;
    sinlookup = new double[N];
    coslookup = new double[N];
    for (int i = 0; i < N; i++) {
      sinlookup[i] = (double) Math.sin(i * TWO_PI / timeSize);
      coslookup[i] = (double) Math.cos(i * TWO_PI / timeSize);
    }
  }

  private double sin(int i) {
    return sinlookup[i];
  }

  private double cos(int i) {
    return coslookup[i];
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy