2011-01-07 323 views
4

我有一个16位PCM格式的波形文件。我得到了byte[]中的原始数据和提取样本的方法,我需要它们的浮点格式,即float[]做傅里叶变换。这是我的代码,这是否正确?我正在开发Android,因此javax.sound.sampled等无法使用。将16位PCM波形数据转换为浮点数的正确方法

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; 
    } 
+0

看到它减去256乘以首先它之前也:http://stackoverflow.com/questions/15087668/how -to-convert-pcm-samples-in-byte-array-as-floating-point-numbers-in-the-range – Brad 2013-12-27 05:03:56

回答

6

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

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; 
} 
+0

这只适用于未签名的PCM,对吗?否则,你需要屏蔽每对字节中的第二个符号位。 – hertzsprung 2011-10-29 20:25:38

2

正如hertzsprung所示,jk的答案。仅适用于未签名的PCM。在Android PCM16上是经过big-endian签名的,因此您需要考虑潜在的负值,编码为two's complement。这意味着我们需要检查的高字节是否大于127,如果是由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; 
}