繁体   English   中英

Android-检测原始.wav文件和已过滤.wav文件之间的差异

[英]Android - Detect differences between original .wav file and filtered .wav file

我在左右声道上都有一个原始的.wav文件,其频率分别为18kHz和19kHz。

我还有另一个过滤的.wav文件,该文件使用带通滤波器的IIR滤波器对18kHz-20kHz进行滤波。

如何检测两者之间的差异? 就像在其中一样,如何检查通过过滤器实现的音频是否已成功过滤?

我正在使用我发现的库https://github.com/ddf/Minim/blob/master/src/ddf/minim/effects/BandPass.java https://github.com/DASAR/Minim-Android/blob /master/src/ddf/minim/effects/IIRFilter.java

以下是与过滤相关的代码。

float[][] deinterleaveData(float[] samples, int numChannels) {
    // assert(samples.length() % numChannels == 0);
    int numFrames = samples.length / numChannels;

    float[][] result = new float[numChannels][];
    for (int ch = 0; ch < numChannels; ch++) {
        result[ch] = new float[numFrames];
        for (int i = 0; i < numFrames; i++) {
            result[ch][i] = samples[numChannels * i + ch];
        }
    }
    return result;
}


float[] interleaveData(float[][] data) {
      int numChannels = data.length;
      int numFrames   = data[0].length;

      float[] result = new float[numFrames*numChannels];
      for (int i = 0; i < numFrames; i++) {
        for (int ch = 0; ch < numChannels; ch++) {
          result[numChannels * i + ch] = data[ch][i];
        }
      }
      return result;
    }

/**
  * Convert byte[] raw audio to 16 bit int format.
  * @param rawdata
  */
private int[] byteToShort(byte[] rawdata) {
  int[] converted = new int[rawdata.length / 2];

  for (int i = 0; i < converted.length; i++) {
    // Wave file data are stored in little-endian order
    int lo = rawdata[2*i];
    int hi = rawdata[2*i+1];
    converted[i] = ((hi&0xFF)<<8) | (lo&0xFF);
  }
  return converted;
}

private float[] byteToFloat(byte[] audio) {
  return shortToFloat(byteToShort(audio));
}

/**
* Convert int[] audio to 32 bit float format.
* From [-32768,32768] to [-1,1] 
* @param audio
*/
private float[] shortToFloat(int[] audio) {
    float[] converted = new float[audio.length];

    for (int i = 0; i < converted.length; i++) {
        // [-32768,32768] -> [-1,1]
        converted[i] = audio[i] / 32768f; /* default range for Android PCM audio buffers) */
    }

    return converted;
}

private void writeAudioDataToFile() throws IOException {
    int read = 0;
    byte data[] = new byte[bufferSize];
    String filename = getTempFilename();
    FileOutputStream os = null;
    FileOutputStream rs = null;
    try {
        os = new FileOutputStream(filename);
        rs = new FileOutputStream(getFilename().split(".wav")[0] + ".txt");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    if (null != os) {

        BandPass bandpass = new BandPass(19000,2000,44100);
        while (isRecording) {

            // decode and deinterleave stereo 16-bit per sample data
              float[][] signals = deinterleaveData(byteToFloat(data), 2);

              // filter data samples, updating the buffers with the filtered samples.
              bandpass.process(signals[0], signals[1]);

              // recombine signals for playback
              audioTrack.write(interleaveData(signals), 0, count, WRITE_NON_BLOCKING);
             // audioTrack.write(data, 0, count);   

                 read = recorder.read(data, 0, bufferSize);

            if (AudioRecord.ERROR_INVALID_OPERATION != read) {
                try {
                    os.write(data);
                    rs.write(data);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            os.close();
            rs.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如有必要,请参见此处的完整代码: http : //pastebin.com/23aS2A2w

是否找到原始.wav文件和过滤后的.wav文件的峰谷以检测差异? 如果没有,我将如何检测?

感谢您的所有回复和帮助。 感激不尽!

您可以使用两种技术来测量滤波器的频率响应。

第一种方法是使用各种频率的纯正弦波运行滤波器,然后测量输出的幅度。 例如,生成峰值振幅为1.0的1kHz音调并运行滤波器。 然后查看输出。 如果输出是振幅的一半,则可以说滤波器在1kHz处具有6dB的衰减。 如果为足够的频率执行此操作,则可以绘制频率响应,其中x轴为频率,y轴为输出电平。 但是,这是一种非常粗糙的方法,需要很多点才能获得详细的细节。 同样,在更改频率之后,您将需要跳过一些输出,以避免查看瞬态。

另一种方法是测量滤波器的脉冲响应。 为此,请输入一个信号,该信号具有一个1.0,后跟零。 对冲激响应进行FFT将为您提供频率响应。 不过,您需要注意向过滤器提供足够的样本,以使脉冲消失。 您可以通过查看输出样本并确定样本何时衰减到零来解决这一问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM