我在左右声道上有一个频率为18kHz和19kHz的原始.wav文件。
我有另一个过滤的.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文件的峰值和谷值来检测差异?如果没有,我将如何检测?
感谢所有回复和帮助。赞赏它!
答案 0 :(得分:0)
您可以使用几种技术来测量滤波器的频率响应。
第一种方法是使用不同频率的纯正弦波运行滤波器,然后测量输出的幅度。例如,在1kHz产生一个峰值幅度为1.0的音调并运行滤波器。然后看看输出。如果输出是幅度的一半,那么可以说滤波器在1kHz时具有6dB的衰减。如果在足够频率下执行此操作,则可以绘制频率响应图,其中x轴为频率,y轴为输出电平。这是一个非常粗略的方法,需要很多点来获得精细的细节。此外,在更改频率后,您需要跳过一些输出以避免查看瞬态。
另一种方法是测量滤波器的脉冲响应。您可以通过输入一个1.0后跟剩余零的信号来完成此操作。对脉冲响应进行FFT可以得到频率响应。你需要小心,但要为过滤器提供足够的样品,以便让冲动消失。您可以通过查看输出样本并确定样本何时衰减到零来解决这个问题。