Android Open Source - renderScriptFFT Mel Filterbank






From Project

Back to project page renderScriptFFT.

License

The source code is released under:

Copyright (c) 2013 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided...

If you think the Android project renderScriptFFT listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.android.rs.mel;
//w w w .  ja  va  2s  .c o  m
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.MatrixUtils;
import org.apache.commons.math3.linear.RealMatrix;
import org.apache.commons.math3.util.FastMath;

import android.renderscript.Int2;

import com.android.rs.utils.MatrixMath;
import com.android.rs.utils.MelMath;
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.Range;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Floats;

public class MelFilterbank {

  private int numFilters, lengthFFT, numRows, numCols;
  private Int2 fftRange;
  private double sampleRateHz, freqLow, freqHigh;
  private double[] rowArray, colArray, valArray;
  private float[][] nonSparseFilterBank;
  private float[] flattenedFilterBank;
  /*
   * Inputs: p number of filters in filterbank or the filter spacing in
   * k-mel/bark/erb [ceil(4.6*log10(fs))] n length of fft fs sample rate in Hz
   * fl low end of the lowest filter as a fraction of fs [default = 0] fh high
   * end of highest filter as a fraction of fs [default = 0.5]
   */

  public MelFilterbank(int _numFilters, int _lengthFFT, double _sampleRateHz,
      double _freqLow, double _freqHigh) {
    numFilters = _numFilters;
    lengthFFT = _lengthFFT;
    sampleRateHz = _sampleRateHz;
    freqLow = _freqLow;
    freqHigh = _freqHigh;

    // Default Condition
    int sfact = 2; // 2-any(w=='s'); % 1 if single sided else 2

    // convert frequency limits into mel
    RealMatrix mflh = MelMath.frq2mel(new Array2DRowRealMatrix(
        new double[] { freqLow, freqHigh })
        .scalarMultiply(sampleRateHz).transpose());

    // mel range
    double melrng = mflh.multiply(
        new Array2DRowRealMatrix(new double[] { -1.0, 1.0 })).getEntry(
        0, 0);

    // bin index of highest positive frequency (Nyquist if n is even)
    int fn2 = (int) FastMath.floor(lengthFFT / 2);

    double melinc = melrng / (numFilters + 1);

    // Calculate the FFT bins corresponding to [filter#1-low filter#1-mid
    // filter#p-mid filter#p-high]
    RealMatrix blim = MelMath.mel2frq(
        new Array2DRowRealMatrix(new double[] { 0.0, 1.0, numFilters,
            numFilters + 1.0 }).transpose().scalarMultiply(melinc))
        .scalarMultiply(lengthFFT / sampleRateHz);

    // Mel centre frequencies
    double[] mc = new double[numFilters];
    for (int i = 0; i < numFilters; ++i) {
      mc[i] = mflh.getEntry(0, 0) + (i + 1) * melinc;
    }

    // lowest FFT bin_0 required might be negative
    int b1 = (int) FastMath.floor(blim.getEntry(0, 0)) + 1;

    // highest FFT bin_0 required
    int b4 = (int) FastMath
        .min(fn2, FastMath.ceil(blim.getEntry(0, 3) - 1));

    // now map all the useful FFT bins_0 to filter1 centres
    double[] pfa = new double[b4 - b1 + 1];
    for (int i = 0; i <= (b4 - b1); ++i) {
      pfa[i] = (b1 + i) * sampleRateHz / lengthFFT;
    }

    RealMatrix pf = MelMath
        .frq2mel(new Array2DRowRealMatrix(pfa).transpose())
        .scalarAdd(-mflh.getEntry(0, 0)).scalarMultiply(1.0 / melinc);

    // remove any incorrect entries in pf due to rounding errors
    int pfStart = 0;
    int pfEnd = pfa.length - 1;

    if (pf.getEntry(0, pfStart) < 0.0) {
      pfStart = 1;
    }

    if (pf.getEntry(0, pfEnd) >= numFilters + 1) {
      pfEnd -= 1;
      b4 -= 1;
    }

    pf = pf.getSubMatrix(0, 0, pfStart, pfEnd);

    // FFT bin_0 i contributes to filters_1 fp(1+i-b1)+[0 1]
    RealMatrix fp = MatrixMath.floor(pf);

    // multiplier for upper filter
    RealMatrix pm = pf.add(fp.scalarMultiply(-1.0));

    // FFT bin_1 k2+b1 is the first to contribute to both upper and lower
    // filters
    int k2 = MatrixMath.findFirstElementGreater(fp, 0.0)[1];

    // FFT bin_1 k3+b1 is the last to contribute to both upper and lower
    // filters
    int k3 = MatrixMath.findLastElementLessThan(fp, numFilters)[1];

    // FFT bin_1 k4+b1 is the last to contribute to any filters
    int k4 = pfEnd;

    // % filter number_1
    RealMatrix r = MatrixUtils.createRowRealMatrix(Doubles.concat(fp
        .getSubMatrix(0, 0, 0, k3).getRow(0),
        fp.getSubMatrix(0, 0, k2, k4).scalarAdd(-1.0).getRow(0)));
    

    // FFT bin_1 - b1
    RealMatrix c = MatrixUtils.createRowRealMatrix(Doubles.concat(
        Doubles.toArray(ContiguousSet.create(Range.closed(0, k3),
            DiscreteDomain.integers()).asList()),
        Doubles.toArray(ContiguousSet.create(Range.closed(k2, k4),
            DiscreteDomain.integers()).asList())));

    RealMatrix v = MatrixUtils.createRowRealMatrix(Doubles.concat(
        pm.getSubMatrix(0, 0, 0, k3).getRow(0),
        pm.getSubMatrix(0, 0, k2, k4).scalarMultiply(-1.0)
            .scalarAdd(1.0).getRow(0)));

    if (b1 < 0) {
      c = MatrixMath.abs(c.scalarAdd(b1 - 1)).scalarAdd(-b1 + 1);
    }

    if (sfact == 2) {
      v = MelMath.doubleAllExceptDCandNyquist(v, c, b1, lengthFFT, fn2);
    }

    rowArray = r.getRow(0);
    colArray = c.getRow(0);
    valArray = v.getRow(0);
    numRows = (int) (Doubles.max(rowArray) + 1);
    numCols = (int) (Doubles.max(colArray) + 1);
    nonSparseFilterBank = new float[numRows][numCols];
    for (int i = 0; i < valArray.length; ++i){
      nonSparseFilterBank[(int) rowArray[i]][(int) colArray[i]] = (float) valArray[i];
    }
    
    flattenedFilterBank = Floats.concat(nonSparseFilterBank);
    
    //Lowest fft bin b1, highest fft bin b4
    fftRange = new Int2(b1, b4);
  }
  
  
  public float[] getFlattenedFilterBank() {
    return flattenedFilterBank;
  }

  public int getNumRows() {
    return numRows;
  }


  public int getNumCols() {
    return numCols;
  }


  public Int2 getFFTRange(){
    return fftRange;
  }

  public float[][] getNonSparseFilterBank() {
    return nonSparseFilterBank;
  }

  public double[] getRowArray() {
    return rowArray;
  }

  public double[] getColArray() {
    return colArray;
  }

  public double[] getValArray() {
    return valArray;
  }

}




Java Source Code List

com.android.rs.MainActivity.java
com.android.rs.Mel_Test_MicroBench.java
com.android.rs.Mel_Test_Microphone.java
com.android.rs.Mel_Test.java
com.android.rs.mel.DCT.java
com.android.rs.mel.HammingFilter.java
com.android.rs.mel.MelFilterbank.java
com.android.rs.utils.ArrayConversion.java
com.android.rs.utils.MatrixMath.java
com.android.rs.utils.MelMath.java