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。如果您检测到您超出了有效范围,只需缩放整个数组。这样你就可以避免剪裁。
添加回答
举报