我有一个.au音频文件,我试图复制到另一个音频文件,我希望复制的音频文件有一半的音量。我编写了以下代码,它生成以下音频文件:
for (int i = 24; i < bytes.length; i++) {
// bytes is a byte[] array containing every byte in the .au file
if (i % 2 == 0) {
short byteFrame = (short) (((bytes[i - 0]&0xFF) << 8) | ((bytes[i - 1]&0xFF)));
byteFrame >>= 1;
bytes[i - 0] = (byte) (byteFrame);
bytes[i - 1] = (byte) (byteFrame >>> 8);
}
}
我从该代码获得的数据是这样的:
以下代码与上述代码相同,仅为&#39; bytes [i-0]&#39;和&#39; bytes [i - 1]&#39;换了个地方。当我这样做时,通道中的信息将被交换到另一个通道。
for (int i = 24; i < bytes.length; i++) {
// bytes is a byte[] array containing every byte in the .au file
if (i % 2 == 0) {
short byteFrame = (short) (((bytes[i - 0]&0xFF) << 8) | ((bytes[i - 1]&0xFF)));
byteFrame *= 0.5;
bytes[i - 1] = (byte) (byteFrame);
bytes[i - 0] = (byte) (byteFrame >>> 8);
}
}
我从该代码获得的数据是这样的(通道中的信息已被交换):
我需要将两个频道的音量减少一半。下面是au文件格式的维基百科页面。有关如何使其在减少音量方面正常工作的任何想法?此文件编码为1(8位G.711 mu-law),2个通道,每帧2个字节,采样率为48000.(它在编码3上正常工作,但不能编码1.)在此先感谢任何帮助提供。
答案 0 :(得分:0)
使用ByteBuffer
。您似乎以小端顺序使用16位数量,并且您希望将它们右移1。
因此:
final ByteBuffer orig = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN)
.asReadOnlyBuffer();
final ByteBuffer transformed = ByteBuffer.wrap(bytes.length)
.order(ByteOrder.LITTLE_ENDIAN);
while (orig.hasRemaining())
transformed.putShort(orig.getShort() >>> 1);
return transformed.array();
请注意,>>>
是必要的;否则你带着标志位。
即尝试使用>> 1
:
1001 0111
会给:
1100 1011
即,携带符号位(最高有效位)。这就是Java中存在>>>
的原因,它不带符号位,因此在上面使用>>> 1
会给出:
0100 1011
在进行位移时似乎合乎逻辑!