我正在尝试对从audioRecord
获得的麦克风数据实施高通音频过滤器。
我从麦克风获得的数据是一个16位PCM音频字节数组。我试图使用TarsosDSP
来提供高通滤波的API。但是,作为输入,它需要一个浮点数组,所以我将字节转换为浮点数组并运行高通滤波器。为了确认结果,我将过滤后的数据保存在波形文件中,但听起来完全失真。
public static byte[] highPassFilter( byte[] buffer, WaveHeader waveHeader, float frequency) {
HighPass highPass = new HighPass(frequency, waveHeader.getSampleRate());
TarsosDSPAudioFormat format = new TarsosDSPAudioFormat(waveHeader.getSampleRate(),waveHeader.getBitsPerSample(),waveHeader.getChannels(),true, false);
AudioEvent audioEvent = new AudioEvent(format);
float[] f_buffer = bytesToFloats(buffer);
audioEvent.setFloatBuffer(f_buffer);
highPass.process(audioEvent);
buffer = audioEvent.getByteBuffer();
byte[] data = PCMtoWav(buffer, waveHeader.getSampleRate(), waveHeader.getChannels(), waveHeader.getBitsPerSample());
writeWavFile(data);
return buffer;
}
public static float[] bytesToFloats(byte[] bytes) {
float[] floats = new float[bytes.length / 2];
for(int i=0; i < bytes.length; i+=2) {
floats[i/2] = bytes[i] | (bytes[i+1] < 128 ? (bytes[i+1] << 8) : ((bytes[i+1] - 256) << 8));
}
return floats;
}
waveHeader
中的数据是:
Sample rate = 11025
getBitsPerSample = 16
getChannels = 1
我最好的猜测是bytesToFloats转换是错误的。为了验证这一点,我只使用audioEvent
设置audioEvent.setFloatBuffer
的浮动缓冲区,然后使用audioEvent.getByteBuffer
检索它,这也导致完全失真的音频文件。
从audioRecord中读取字节缓冲区:
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 11025, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 220500);
....
buffer = new byte[frameByteSize];
byte[] audioRecord.read(buffer, 0, frameByteSize);
任何人都知道如何修复此问题或建议我可以在android中的字节数组上使用不同的高通滤波器。
更新:我明白了。这是我更新的函数,可以从字节转换为浮点数:
public static float[] bytesToFloats(byte[] bytes) {
float[] floats = new float[bytes.length / 2];
short[] shorts = new short[bytes.length/2];
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
for(int i=0; i < bytes.length; i+=2) {
floats[i/2] = shorts[i/2] / 32768f;
}
return floats;
}
答案 0 :(得分:0)
两个字节样本是否代表浮点值?他们可以在-32,768到32,767的范围内签约。此外,对于样本的浮点表示,-1.0到1.0范围内的值是常见的。
我会尝试:
short sample = bytes[i] | (bytes[i+1] < 128 ? (bytes[i+1] << 8) : ((bytes[i+1] - 256) << 8));
floats[i/2] = (float)sample / 32,768f;
答案 1 :(得分:0)
您需要将字节对转换为有符号的short,然后将其缩放到-1.0到1.0范围内的float。
根据数据的字节顺序,以下行之一将转换为带符号的16位。
short shortSample = (short)(bytes[i]) | (short)(bytes[i+1]) << 8);
short shortSample = (short)(bytes[i] << 8) | (short)(bytes[i+1]));
然后缩放到浮动:
float sample = shortSample / 32768f;