/*
* Copyright 2006-2007 Columbia University.
*
* This file is part of MEAPsoft.
*
* MEAPsoft is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* MEAPsoft 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MEAPsoft; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* See the file "COPYING" for the text of the license.
*/
package com.meapsoft;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import com.meapsoft.disgraced.DataDisplayPanel;
/*
* Library of basic DSP algorithms. Most of these have analogs in Matlab with
* the same name.
*
* This code only operates on real valued data.
*
* @author Ron Weiss (ronw@ee.columbia.edu)
*/
public class DSP
{
/**
* Convolves sequences a and b. The resulting convolution has length
* a.length+b.length-1.
*/
public static double[] conv(double[] a, double[] b)
{
double[] y = new double[a.length + b.length - 1];
// make sure that a is the shorter sequence
if (a.length > b.length)
{
double[] tmp = a;
a = b;
b = tmp;
}
for (int lag = 0; lag < y.length; lag++)
{
y[lag] = 0;
// where do the two signals overlap?
int start = 0;
// we can't go past the left end of (time reversed) a
if (lag > a.length - 1)
start = lag - a.length + 1;
int end = lag;
// we can't go past the right end of b
if (end > b.length - 1)
end = b.length - 1;
// System.out.println("lag = " + lag +": "+ start+" to " + end);
for (int n = start; n <= end; n++)
{
// System.out.println(" ai = " + (lag-n) + ", bi = " + n);
y[lag] += b[n] * a[lag - n];
}
}
return (y);
}
/**
* Computes the cross correlation between sequences a and b.
*/
public static double[] xcorr(double[] a, double[] b)
{
int len = a.length;
if (b.length > a.length)
len = b.length;
return xcorr(a, b, len - 1);
// // reverse b in time
// double[] brev = new double[b.length];
// for(int x = 0; x < b.length; x++)
// brev[x] = b[b.length-x-1];
//
// return conv(a, brev);
}
/**
* Computes the auto correlation of a.
*/
public static double[] xcorr(double[] a)
{
return xcorr(a, a);
}
/**
* Computes the cross correlation between sequences a and b. maxlag is the
* maximum lag to
*/
public static double[] xcorr(double[] a, double[] b, int maxlag)
{
double[] y = new double[2 * maxlag + 1];
Arrays.fill(y, 0);
for (int lag = b.length - 1, idx = maxlag - b.length + 1; lag > -a.length; lag--, idx++)
{
if (idx < 0)
continue;
if (idx >= y.length)
break;
// where do the two signals overlap?
int start = 0;
// we can't start past the left end of b
if (lag < 0)
{
// System.out.println("b");
start = -lag;
}
int end = a.length - 1;
// we can't go past the right end of b
if (end > b.length - lag - 1)
{
end = b.length - lag - 1;
// System.out.println("a "+end);
}
// System.out.println("lag = " + lag +": "+ start+" to " + end+" idx
// = "+idx);
for (int n = start; n <= end; n++)
{
// System.out.println(" bi = " + (lag+n) + ", ai = " + n);
y[idx] += a[n] * b[lag + n];
}
// System.out.println(y[idx]);
}
return (y);
}
/**
* Filters x by the IIR filter defined by a and b. Similar to Matlab's
* filter().
*
* This is a direct implementation of the corresponding difference equation.
*/
public static double[] filter(double[] b, double[] a, double[] x)
{
double[] y = new double[x.length];
// factor out a[0]
if (a[0] != 1)
{
for (int ia = 1; ia < a.length; ia++)
a[ia] = a[ia] / a[0];
for (int ib = 0; ib < b.length; ib++)
b[ib] = b[ib] / a[0];
}
for (int t = 0; t < x.length; t++)
{
y[t] = 0;
// input terms
int len = b.length - 1 < t ? b.length - 1 : t;
for (int ib = 0; ib <= len; ib++)
y[t] += b[ib] * x[t - ib];
// output terms
len = a.length - 1 < t ? a.length - 1 : t;
for (int ia = 1; ia <= len; ia++)
y[t] -= a[ia] * y[t - ia];
}
return y;
}
/**
* Returns an n point symmetric Hanning window.
*
* Like the Matlab hanning() function (and unlike the version included in
* Octave), this drops the first and last zero samples. So hanning(10) in
* Octave is the same as hanning(8) in Matlab and DSP.hanning(8).
*/
public static double[] hanning(int n)
{
double[] wind = new double[n];
if (n == 1)
wind[0] = 1;
else
for (int x = 1; x < n + 1; x++)
wind[x - 1] = 0.5 * (1 - Math.cos(2 * Math.PI * x / (n + 1)));
return wind;
}
/**
* Returns the inner product of a and b. a and b should be the same length
* or bad things will happen.
*/
public static double dot(double[] a, double[] b)
{
double y = 0;
for (int x = 0; x < a.length; x++)
y += a[x] * b[x];
return y;
}
/**
* Matrix times vector
*/
public static double[] times(double[][] a, double[] b) // throws Exception
{
double[] y = new double[a.length];
// if (a[0].length != b.length) {
// throw new Exception("matrix vector mismatch");
// }
for (int i = 0; i < a.length; ++i) {
double x = 0;
for (int j = 0; j < b.length; ++j) {
x += a[i][j]*b[j];
}
y[i] = x;
}
return y;
}
/**
* Multiplies each element of a by b.
*/
public static double[] times(double[] a, double b)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = a[x] * b;
return y;
}
public static double[] times(double b, double[] a)
{
return times(a,b);
}
/**
* Returns the elementwise product of a and b. a and b should be
* the same length or bad things will happen.
*/
public static double[] times(double[] a, double[] b)
{
double[] y = new double[a.length];
for(int x = 0; x < y.length; x++)
y[x] = a[x]*b[x];
return y;
}
/**
* Returns the elementwise quotient of a divided by b (a./b). a and b should
* be the same length or bad things will happen.
*/
public static double[] rdivide(double[] a, double[] b)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = a[x] / b[x];
return y;
}
/**
* Divides each element of a by b.
*/
public static double[] rdivide(double[] a, double b)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = a[x] / b;
return y;
}
/**
* Returns the elementwise sum of a and b. a and b should be the same length
* or bad things will happen.
*/
public static double[] plus(double[] a, double[] b)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = a[x] + b[x];
return y;
}
/**
* Adds b to each element of a.
*/
public static double[] plus(double[] a, double b)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = a[x] + b;
return y;
}
/**
* Returns the elementwise difference of a and b. a and b should be the same
* length or bad things will happen.
*/
public static double[] minus(double[] a, double[] b)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = a[x] - b[x];
return y;
}
/**
* Subtracts b from each element of a (y[x] = a[x]-b).
*/
public static double[] minus(double[] a, double b)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = a[x] - b;
return y;
}
/**
* Subtracts b from each element of A (Y[x][y] = A[x][y]-b).
*/
public static double[][] minus(double[][] A, double b)
{
double[][] Y = new double[A.length][A[0].length];
for (int x = 0; x < Y.length; x++)
for (int y = 0; x < Y[x].length; y++)
Y[x][y] = A[x][y] - b;
return Y;
}
/**
* Subtracts each element of b from a (y[x] = a - b[x]).
*/
public static double[] minus(double a, double[] b)
{
double[] y = new double[b.length];
for (int x = 0; x < y.length; x++)
y[x] = a - b[x];
return y;
}
/**
* Returns the sum of the contents of a.
*/
public static double sum(double[] a)
{
double y = 0;
for (int x = 0; x < a.length; x++)
y += a[x];
return y;
}
/**
* Returns A such that A[x] = sum(a[0:x])
*/
public static double[] cumsum(double[] a)
{
double[] A = new double[a.length];
A[0] = a[0];
for (int x = 1; x < a.length; x++)
A[x] = A[x - 1] + a[x];
return A;
}
/**
* Returns the max element of a.
*/
public static double max(double[] a)
{
double y = Double.MIN_VALUE;
for (int x = 0; x < a.length; x++)
if (a[x] > y)
y = a[x];
return y;
}
/**
* Returns a new array where each element is the maximum of a[i] and b[i]. a
* and b should be the same length.
*/
public static double[] max(double[] a, double[] b)
{
double[] y = new double[a.length];
for (int x = 0; x < a.length; x++)
{
if (a[x] > b[x])
y[x] = a[x];
else
y[x] = b[x];
}
return y;
}
/**
* Returns a new array where each element is the maximum of a[i] and b.
*/
public static double[] max(double[] a, double b)
{
double[] y = new double[a.length];
for (int x = 0; x < a.length; x++)
{
if (a[x] > b)
y[x] = a[x];
else
y[x] = b;
}
return y;
}
/**
* Returns a new array where each element is the maximum of a[i][j] and b.
*/
public static double[][] max(double[][] a, double b)
{
double[][] y = new double[a.length][a[0].length];
for (int r = 0; r < a.length; r++)
{
for (int c = 0; c < a[r].length; c++)
{
if (a[r][c] > b)
y[r][c] = a[r][c];
else
y[r][c] = b;
}
}
return y;
}
/**
* Returns an array of the max elements of each column of a.
*/
public static double[] max(double[][] a)
{
double[] y = new double[a.length];
Arrays.fill(y, Double.MIN_VALUE);
for (int r = 0; r < a.length; r++)
for (int c = 0; c < a[r].length; c++)
if (a[r][c] > y[r])
y[r] = a[r][c];
return y;
}
/**
* Returns the min element of a.
*/
public static double min(double[] a)
{
double y = Double.MAX_VALUE;
for (int x = 0; x < a.length; x++)
if (a[x] < y)
y = a[x];
return y;
}
/**
* Returns a new array where each element is the minimum of a[i] and b[i]. a
* and b should be the same length.
*/
public static double[] min(double[] a, double[] b)
{
double[] y = new double[a.length];
for (int x = 0; x < a.length; x++)
{
if (a[x] < b[x])
y[x] = a[x];
else
y[x] = b[x];
}
return y;
}
/**
* Returns a new array where each element is the minimum of a[i] and b.
*/
public static double[] min(double[] a, double b)
{
double[] y = new double[a.length];
for (int x = 0; x < a.length; x++)
{
if (a[x] < b)
y[x] = a[x];
else
y[x] = b;
}
return y;
}
/**
* Returns a new array where each element is the minimum of a[i][j] and b.
*/
public static double[][] min(double[][] a, double b)
{
double[][] y = new double[a.length][a[0].length];
for (int r = 0; r < a.length; r++)
{
for (int c = 0; c < a[r].length; c++)
{
if (a[r][c] < b)
y[r][c] = a[r][c];
else
y[r][c] = b;
}
}
return y;
}
/**
* Returns an array of the min elements of each column of a.
*/
public static double[] min(double[][] a)
{
double[] y = new double[a.length];
Arrays.fill(y, Double.MAX_VALUE);
for (int r = 0; r < a.length; r++)
for (int c = 0; c < a[r].length; c++)
if (a[r][c] < y[r])
y[r] = a[r][c];
return y;
}
/**
* Returns the index of the max element of a.
*/
public static int argmax(double[] a)
{
double y = Double.MIN_VALUE;
int idx = -1;
for (int x = 0; x < a.length; x++)
{
if (a[x] > y)
{
y = a[x];
idx = x;
}
}
return idx;
}
/**
* Returns the index of the min element of a.
*/
public static int argmin(double[] a)
{
double y = Double.MAX_VALUE;
int idx = -1;
for (int x = 0; x < a.length; x++)
{
if (a[x] < y)
{
y = a[x];
idx = x;
}
}
return idx;
}
/**
* Returns the slice of array a between start and end inclusive.
*/
public static double[] slice(double[] a, int start, int end)
{
start = Math.max(start, 0);
end = Math.min(end, a.length - 1);
double[] y = new double[end - start + 1];
for (int x = start, iy = 0; x <= end; x++, iy++)
y[iy] = a[x];
return y;
}
/**
* Returns an array as follows: {start, start+1, ... , end-1, end}
*/
public static double[] range(int start, int end)
{
return range(start, end, 1);
// double[] y = new double[end-start+1];
//
// for(int x = 0, num = start; x < y.length; x++, num++)
// y[x] = num;
//
// return y;
}
/**
* Returns an array as follows: {start, start+increment, ... ,
* end-increment, end}
*/
public static double[] range(int start, int end, int increment)
{
double[] y = new double[1 + (end - start) / increment];
for (int x = 0, num = start; x < y.length; x++, num += increment)
y[x] = num;
return y;
}
/**
* Returns an array of ints as follows: {start, start+increment, ... ,
* end-increment, end}
*/
public static int[] irange(int start, int end, int increment)
{
int[] y = new int[1 + (end - start) / increment];
for (int x = 0, num = start; x < y.length; x++, num += increment)
y[x] = num;
return y;
}
/**
* Returns an array of ints as follows: {start, start+1, ... , end-1, end}
*/
public static int[] irange(int start, int end)
{
return irange(start, end, 1);
}
/**
* Index into array a using the indices listed in idx.
*/
public static double[] subsref(double[] a, int[] idx)
{
double[] y = new double[idx.length];
for (int x = 0; x < idx.length; x++)
y[x] = a[idx[x]];
return y;
}
/**
* Index into array a using the binary array idx.
*/
public static double[] subsref(double[] a, byte[] idx)
{
return subsref(a, find(idx));
}
/**
* Returns an array containing the indices into a that contain 1s.
*/
public static int[] find(byte[] a)
{
int[] v = new int[20];
int idx = 0;
for (int x = 0; x < a.length; x++)
{
if (a[x] == 1)
{
// System.out.println(x+" "+a[x]+" "+v.length);
v[idx++] = x;
if (idx == v.length)
{
int[] tmp = new int[2 * v.length];
for (int i = 0; i < v.length; i++)
tmp[i] = v[i];
v = tmp;
}
}
}
// but v might be too big:
int[] tmp = new int[idx];
for (int i = 0; i < tmp.length; i++)
tmp[i] = v[i];
// System.out.println(tmp.length);
return tmp;
}
/**
* Returns a binary array with 1s where a[idx] < b[idx] and zeros elsewhere.
* a and b should be the same length.
*/
public static byte[] lt(double[] a, double[] b)
{
byte[] y = new byte[a.length];
for (int x = 0; x < y.length; x++)
{
if (a[x] < b[x])
y[x] = 1;
else
y[x] = 0;
}
return y;
}
/**
* Returns a binary array with 1s where a[idx] < b and zeros elsewhere. a
* and b should be the same length.
*/
public static byte[] lt(double[] a, double b)
{
byte[] y = new byte[a.length];
for (int x = 0; x < y.length; x++)
{
if (a[x] < b)
y[x] = 1;
else
y[x] = 0;
}
return y;
}
/**
* Returns a binary array with 1s where a[idx] <= b[idx] and zeros
* elsewhere. a and b should be the same length.
*/
public static byte[] le(double[] a, double[] b)
{
byte[] y = new byte[a.length];
for (int x = 0; x < y.length; x++)
{
if (a[x] <= b[x])
y[x] = 1;
else
y[x] = 0;
}
return y;
}
/**
* Returns a binary array with 1s where a[idx] <= b and zeros elsewhere. a
* and b should be the same length.
*/
public static byte[] le(double[] a, double b)
{
byte[] y = new byte[a.length];
for (int x = 0; x < y.length; x++)
{
if (a[x] <= b)
y[x] = 1;
else
y[x] = 0;
}
return y;
}
/**
* Returns a binary array with 1s where a[idx] > b[idx] and zeros elsewhere.
* a and b should be the same length.
*/
public static byte[] gt(double[] a, double[] b)
{
byte[] y = new byte[a.length];
for (int x = 0; x < y.length; x++)
{
if (a[x] > b[x])
y[x] = 1;
else
y[x] = 0;
}
return y;
}
/**
* Returns a binary array with 1s where a[idx] > b and zeros elsewhere. a
* and b should be the same length.
*/
public static byte[] gt(double[] a, double b)
{
byte[] y = new byte[a.length];
for (int x = 0; x < y.length; x++)
{
if (a[x] > b)
y[x] = 1;
else
y[x] = 0;
}
return y;
}
/**
* Returns a binary array with 1s where a[idx] >= b[idx] and zeros
* elsewhere. a and b should be the same length.
*/
public static byte[] ge(double[] a, double[] b)
{
byte[] y = new byte[a.length];
for (int x = 0; x < y.length; x++)
{
if (a[x] >= b[x])
y[x] = 1;
else
y[x] = 0;
}
return y;
}
/**
* Returns a binary array with 1s where a[idx] >= b and zeros elsewhere. a
* and b should be the same length.
*/
public static byte[] ge(double[] a, double b)
{
byte[] y = new byte[a.length];
for (int x = 0; x < y.length; x++)
{
if (a[x] >= b)
y[x] = 1;
else
y[x] = 0;
}
return y;
}
/**
* Returns the lower median value contained in a.
*/
public static double median(double[] a)
{
// I don't want to sort the original array... DSP.slice will
// copy it.
double[] tmp = slice(a, 0, a.length - 1);
Arrays.sort(tmp);
return tmp[(int) tmp.length / 2];
}
/**
* Returns the mean of a.
*/
public static double mean(double[] a)
{
return sum(a) / a.length;
}
/**
* Returns the mean of each column of A.
*/
public static double[] mean(double[][] A)
{
double[] m = new double[A.length];
int ncols = A[0].length;
for (int x = 0; x < A.length; x++)
for (int y = 0; y < A[x].length; y++)
m[x] += A[x][y] / ncols;
return m;
}
/**
* Returns the transpose of the matrix a.
*/
public static double[][] transpose(double[][] a)
{
double[][] y = new double[a[0].length][a.length];
for (int i = 0; i < a.length; i++)
for (int j = 0; j < a[i].length; j++)
y[j][i] = a[i][j];
return y;
}
/**
* Round each element of a.
*/
public static double[] round(double[] a)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = Math.round(a[x]);
return y;
}
/**
* Returns the absolute value of each element of a.
*/
public static double[] abs(double[] a)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = Math.abs(a[x]);
return y;
}
/**
* Cosine of each element of a.
*/
public static double[] cos(double[] a)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = Math.cos(a[x]);
return y;
}
/**
* Sine of each element of a.
*/
public static double[] sin(double[] a)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = Math.sin(a[x]);
return y;
}
/**
* Raise each element of a to the b'th power. Like MATLAB's .^ operator.
*/
public static double[] power(double[] a, double b)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = Math.pow(a[x], b);
return y;
}
/**
* Take the natural log of each element of a.
*/
public static double[] log(double[] a)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = Math.log(a[x]);
return y;
}
/**
* Take the log base 10 of each element of a.
*/
public static double[] log10(double[] a)
{
double[] y = new double[a.length];
double log10 = Math.log(10);
for (int x = 0; x < y.length; x++)
y[x] = Math.log(a[x]) / log10;
return y;
}
/**
* Take the natural exp of each element of a.
*/
public static double[] exp(double[] a)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = Math.exp(a[x]);
return y;
}
public static double[] todouble(byte[] a)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = (double) a[x];
return y;
}
public static double[] todouble(int[] a)
{
double[] y = new double[a.length];
for (int x = 0; x < y.length; x++)
y[x] = (double) a[x];
return y;
}
/**
* Set n'th column of matrix A to b
*/
public static void setColumn(double[][] A, int n, double[] b)
{
for (int i = 0; i < b.length; i++)
A[i][n] = b[i];
}
/**
* Returns the n'th column of matrix A
*/
public static double[] getColumn(double[][] A, int n)
{
double[] y = new double[A.length];
for (int i = 0; i < A.length; i++)
y[i] = A[i][n];
return y;
}
/**
* Pop up a window containing an image representation of a.
*/
public static void imagesc(double[][] a)
{
DataDisplayPanel.spawnWindow(a);
}
/**
* Pop up a window containing an image representation of a.
*/
public static void imagesc(double[][] a, String s)
{
DataDisplayPanel.spawnWindow(a, s);
}
/**
* Pop up a window containing an image representation of a.
*/
public static void imagesc(double[] a)
{
double[][] d = new double[1][a.length];
d[0] = a;
imagesc(transpose(d));
}
/**
* Pop up a window containing an image representation of a.
*/
public static void imagesc(double[] a, String s)
{
// double[][] d = new double[a.length][1];
// for(int x = 0; x < a.length; x++)
// d[x][0] = a[x];
double[][] d = new double[1][a.length];
d[0] = a;
imagesc(transpose(d), s);
}
/**
* Write the data in d to a mono wavefile.
*/
public static void wavwrite(double[] d, int sr, String filename)
{
try
{
AudioWriter aw = new AudioWriter(new File(filename),
new AudioFormat((int) sr, 16, 1, true, false),
AudioFileFormat.Type.WAVE);
aw.write(d, d.length);
aw.close();
}
catch (IOException e)
{
System.out.println(e);
}
}
public static void printArray(double[] a)
{
for (int x = 0; x < a.length; x++)
System.out.print(a[x] + " ");
System.out.println("");
}
public static void printArray(double[] a, String name)
{
System.out.print("name = ");
printArray(a);
}
public static double[] preEmphasis(double[] inSamps)
{
//double[] origSamples = stft.getSamples(startFrame, startFrame + length);
double[] preEmphSamples = new double[inSamps.length];
preEmphSamples[0] = inSamps[0];
for (int i = 1; i < inSamps.length; i++)
{
preEmphSamples[i] = inSamps[i] - (0.97 * inSamps[i-1]);
}
return preEmphSamples;
}
public static void main(String[] args)
{
double[] y = null;
double[] a = { -31, 1, 0, 1 };
// double[] a = {-31, 1, 0, 1, 0, 1, 0, 1, 0, 1};
// double[] b = {1, 331};
double[] b = { 1, 331 };
int n = 10;
// java.util.Random rand = new java.util.Random();
// double[] a = new double[rand.nextInt(100)+1];
// double[] b = new double[rand.nextInt(100)+1];
// System.out.println("a.length = "+a.length);
// System.out.println("b.length = "+b.length);
// //java.util.Arrays.fill(a, 1);
// //java.util.Arrays.fill(b, 1);
// for(int x = 0; x < a.length; x++)
// a[x] = rand.nextDouble();
// for(int x = 0; x < b.length; x++)
// b[x] = rand.nextDouble();
String cmd = args[0];
if (cmd.equals("conv") || cmd.equals("xcorr"))
{
if (cmd.equals("conv"))
y = DSP.conv(a, b);
else
{
if (args.length == 1)
y = DSP.xcorr(b, a);
else
y = DSP.xcorr(b, a, Integer.parseInt(args[1]));
System.out.print("xcorr(b,a) = ");
for (int x = 0; x < y.length; x++)
System.out.print(y[x] + " ");
System.out.println("");
if (args.length == 1)
y = DSP.xcorr(a, b);
else
y = DSP.xcorr(a, b, Integer.parseInt(args[1]));
System.out.print("xcorr(a,b) = ");
}
}
else if (cmd.equals("filter"))
{
// double[] b = {1, -1};
// double[] a = {1, -.99};
double[] x = DSP.hanning(20);
y = DSP.filter(b, a, x);
}
else if (cmd.equals("hanning"))
{
if (args.length > 1)
n = Integer.parseInt(args[1]);
y = DSP.hanning(n);
}
for (int x = 0; x < y.length; x++)
System.out.print(y[x] + " ");
System.out.println("");
}
}