如何在java(android)中通过将fft数据归零来过滤音频

如何在java(android)中通过将fft数据归零来过滤音频,android,audio,filter,filtering,fft,Android,Audio,Filter,Filtering,Fft,我正在为android平台开发一个基于音频的应用程序。在这段代码中,我首先以wav格式录制语音,然后获得fft(fftbegir方法)现在我想用归零fft数据过滤0-4khz的声音,然后执行ifft,但当我播放新的wav文件时,我可以听到质量非常差的声音,带有大量噪音。fft类在这里,下面是我的代码: private void filter(Complex[] x, int size) throws IOException { double d, b; String strI; byte[]

我正在为android平台开发一个基于音频的应用程序。在这段代码中,我首先以wav格式录制语音,然后获得fft(fftbegir方法)现在我想用归零fft数据过滤0-4khz的声音,然后执行ifft,但当我播放新的wav文件时,我可以听到质量非常差的声音,带有大量噪音。fft类在这里,下面是我的代码:

private void filter(Complex[] x, int size) throws IOException {

double d, b;
String strI;
byte[] bytes = new byte[2];
int i = 0;
double k = -3.14159;
Complex[] f = new Complex[size];
Complex[] iff;
byte[] ddd;
double[] kkk = new double[size];
FFT q = new FFT();
short shor;
double data9[] = new double[size];
d = 2 * 3.14159 / size;
totalAudioLen = size;
totalDataLen = totalAudioLen + 36;
while (i < size) {//////to make its lenght length power of 2
    data9[i] = k;
    k = k + d;
    i++;
}
i = 0;
while (i < (size / 2) - 2000) {
    f[i] = new Complex(x[i].re(), x[i].im());
    i++;
}
while (i < (size / 2) + 2000) {  ///i want to remov 2000 sample of fft 
    f[i] = new Complex(0, 0);
    i++;
}
while (i < size) {
    f[i] = new Complex(x[i].re(), x[i].im());
    i++;
}

iff = q.ifft(f);

try {
    out9 = new FileOutputStream(getridemal());
    out10 = new FileOutputStream(getwavfilter());
    out11 = new FileOutputStream(getkhodesh());

    WriteWaveFileHeader(out10, totalAudioLen, totalDataLen,
            longSampleRate, channels, byteRate);


    for (i = 0; i < size; i++) {
        b = iff[i].re();
        shor = (short) (b * 32768.0);
        bytes = ByteConvert.convertToByteArray(shor);
        out10.write(bytes, 0, 2);


    }



} finally {
    out9.close();
    out10.close();
    out11.close();
}
}



  private void fftbegir(String input, String output) {

double[] data8;

int i = 0;
int r, k, l;
double b;
int m = 2;


try {
    in5 = new FileInputStream(input);
    out5 = new FileOutputStream(output);

    AppLog.logString("File size: " + totalDataLen);
    totalAudioLen = in5.getChannel().size();

    data8 = SoundDataUtils.load16BitPCMRawDataFileAsDoubleArray();
    l = data8.length;

    while (l > m) {
        m = m * 2;
    }

    Complex[] x = new Complex[m];
    while (i < l) {
        x[i] = new Complex(data8[i], 0);
        i++;
    }
    in5.close();
    i--;

    for (i = l; i < m; i++) {
        x[i] = new Complex(0, 0);
    }
    FFT f = new FFT();
    Complex[] y = f.fft(x);
    filter(y, m);
    out5.close();
    }
   }
private void filter(复杂[]x,int size)引发IOException{
双d,b;
弦纹;
字节[]字节=新字节[2];
int i=0;
双k=-3.14159;
复合体[]f=新复合体[大小];
复杂[]敌我识别;
字节[]ddd;
double[]kkk=新的双精度[尺寸];
FFT q=新的FFT();
短鞋;
双精度数据9[]=新的双精度[尺寸];
d=2*3.14159/尺寸;
总听力=大小;
totalDataLen=totalAudioLen+36;
而(im){
m=m*2;
}
络合物[]x=新络合物[m];
而(i

谢谢:)

您正在进行的频域滤波效果不好

虽然对FFT的结果应用逆FFT会产生相同的样本(也就是说,它是可逆的),但当修改系数时,这不再成立

这里(至少)有几个问题:

  • 这是由于从通带到阻带的急剧转变而产生的
  • 事实上,FFT首先是一个相当糟糕的带通滤波器。阻带中的频率分量出现在几个相邻的频带中,因此保留在信号中
  • 每个FFT单元包含一个实部和虚部。
    (0,0)
    的复数值的幅值为
    0
    ,但也会在过程中丢失相位信息

  • 你最好使用带阻滤波器,它在时域中工作。除了按预期工作外,计算也要便宜得多

    您正在进行的频域滤波效果不佳

    虽然对FFT的结果应用逆FFT会产生相同的样本(也就是说,它是可逆的),但当修改系数时,这不再成立

    这里(至少)有几个问题:

  • 这是由于从通带到阻带的急剧转变而产生的
  • 事实上,FFT首先是一个相当糟糕的带通滤波器。阻带中的频率分量出现在几个相邻的频带中,因此保留在信号中
  • 每个FFT单元包含一个实部和虚部。
    (0,0)
    的复数值的幅值为
    0
    ,但也会在过程中丢失相位信息

  • 你最好使用带阻滤波器,它在时域中工作。除了按预期工作外,计算也要便宜得多

    当您执行且ifft(fft(数据))未修改任何fft bin系数时,音质是否较差?当您执行且ifft(fft(数据))未修改任何fft bin系数时,音质是否较差?