将 16 位 PCM Wave 数据转换为浮点数的正确方法
我有一个 16 位 PCM 形式的波形文件。我有 byte[]
中的原始数据和提取样本的方法,我需要它们采用浮点格式,即 float[]
来执行傅立叶运算转换。这是我的代码,看起来正确吗?我正在 Android 上工作,因此 javax.sound.sampled
等不可用。
private static short getSample(byte[] buffer, int position) {
return (short) (((buffer[position + 1] & 0xff) << 8) | (buffer[position] & 0xff));
}
...
float[] samples = new float[samplesLength];
for (int i = 0;i<input.length/2;i+=2){
samples[i/2] = (float)getSample(input,i) / (float)Short.MAX_VALUE;
}
I have a wave file in 16bit PCM form. I've got the raw data in a byte[]
and a method for extracting samples, and I need them in float format, i.e. a float[]
to do a Fourier Transform. Here's my code, does this look right? I'm working on Android so javax.sound.sampled
etc. is not available.
private static short getSample(byte[] buffer, int position) {
return (short) (((buffer[position + 1] & 0xff) << 8) | (buffer[position] & 0xff));
}
...
float[] samples = new float[samplesLength];
for (int i = 0;i<input.length/2;i+=2){
samples[i/2] = (float)getSample(input,i) / (float)Short.MAX_VALUE;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我有一个类似的解决方案,但恕我直言,更干净一些。不幸的是,据我所知,没有好的库方法:*这假设偶数字节是较低字节
I had a similar solution, but IMHO a little cleaner. Unfortunately, there's no good library method as far as I'm aware: *This assumes the even bytes are the lower bytes
您可以尝试使用 ByteBuffer API。
http://developer.android.com/reference/java/nio/ByteBuffer .html#asFloatBuffer()
You may try using the ByteBuffer API.
http://developer.android.com/reference/java/nio/ByteBuffer.html#asFloatBuffer()
正如 jk 的回答 Hertzsprung 所指出的。仅适用于未签名的 PCM。在 Android 上,PCM16 是大端签名,因此您需要考虑潜在的负值,以 two 编码补充。这意味着我们需要检查高字节是否大于 127,如果是,则先减去 256,然后再乘以 256。
As indicated by hertzsprung the answer by jk. only works for unsigned PCM. On Android PCM16 is big-endian signed, so you need to account for the potentially negative value, encoded in two's complement. This means we need to check whether the high byte is greater than 127 and if so subtract 256 from it first before multiplying it by 256.