1 回答

TA貢獻1862條經驗 獲得超7個贊
你的randomiseOffset()方法是什么樣的?是否考慮到每個音頻樣本都是兩個字節長?如果randomiseOffset()給你奇怪的偏移量,你最終會混合一個樣本的低字節和另一個樣本的高字節,這聽起來像(通常是可怕的)噪音。也許這就是您識別為削波的聲音。
要做到這一點,您需要先解碼音頻,即考慮樣本長度(2 字節)和通道數(?),進行操作,然后將音頻再次編碼為字節流。
假設您只有一個通道并且字節順序是little-endian。然后您將兩個字節解碼為如下示例值:
private static int byteToShortLittleEndian(final byte[] buf, final int offset) {
int sample = (buf[offset] & 0xff) + ((buf[offset+1] & 0xff) << 8);
return (short)sample;
}
要進行編碼,您可以使用如下內容:
private static byte[] shortToByteLittleEndian(final int[] samples, final int offset) {
byte[] buf = new byte[2];
int sample = samples[offset];
buf[0] = sample & 0xFF;
buf[1] = (sample >> 8) & 0xFF;
return buf;
}
以下是在您的案例中使用這兩種方法的方式:
byte[] byteArray = ...; // your array
// DECODE: convert to sample values
int[] samples = byteArray.length / 2;
for (int i=0; i<samples.length; i++) {
samples[i] = byteToShortLittleEndian(byteArray, i*2);
}
// now do your manipulation on the samples array
[...]
// ENCODE: convert back to byte values
byte[] byteOut = new byte[byteArray.length];
for (int i=0; i<samples.length; i++) {
byte[] b = shortToByteLittleEndian(samples, i);
byteOut[2*i] = b[0];
byteOut[2*i+1] = b[1];
}
// do something with byteOut ...
(請注意,您可以通過批量解碼/編碼輕松提高效率,而不是如上所示處理單個樣本。我只是認為它更容易理解。)
在您的操作過程中,您必須注意您的樣本值。它們不得大于Short.MAX_VALUE或小于Short.MIN_VALUE。如果您檢測到您超出了有效范圍,只需縮放整個數組。這樣你就可以避免剪裁。
添加回答
舉報