2011-01-07 258 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; 
} 
相關問題