5

我有一个 16 位 PCM 格式的波形文件。我在 a 中获得了原始数据byte[]和一个提取样本的方法,我需要它们以浮点格式,即 afloat[]来进行傅立叶变换。这是我的代码,这看起来对吗?我正在使用 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;
  }
4

3 回答 3

7

我有一个类似的解决方案,但恕我直言,更干净一点。不幸的是,据我所知,没有好的库方法:*这假设偶数字节是低字节

private 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] << 8);
    }
    return floats;
}
于 2011-01-07T21:52:18.413 回答
3

您可以尝试使用 ByteBuffer API。 http://developer.android.com/reference/java/nio/ByteBuffer.html#asFloatBuffer ()

于 2011-05-31T15:45:26.107 回答
2

正如 hertzsprung 所指出的,jk 的答案。仅适用于未签名的 PCM。在 Android 上,PCM16 是大端签名的,因此您需要考虑以二进制补码编码的潜在负值。这意味着我们需要检查高字节是否大于 127,如果是,则先从它减去 256,然后再乘以 256。

private 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;
}
于 2015-03-17T04:55:28.233 回答