gpt4 book ai didi

java - 从字节[]实时调整音频音量?

转载 作者:太空宇宙 更新时间:2023-11-04 07:35:23 25 4
gpt4 key购买 nike

我正在尝试编写一个简单的应用程序,它可以播放声音,并且可以在播放过程中随时改变声音的音量。我这样做的方法是将声音字节数组中的每对字节转换为 int,然后将该 int 乘以音量的增加或减少,然后将它们写回为两个字节(即 1 个样本)。然而,这会导致声音极度失真。有没有可能我的位移错了?我的声音格式是:

.wav 44100.0hz, 16bit, little-endian

目前,我传递给 adjustmentVolume 方法的字节数组表示十分之一秒的音频数据。即sampleRate/10

我在这里缺少什么东西导致它扭曲并且无法正确缩放音量吗?我是否写错了字节来回?

private byte[] adjustVolume(byte[] audioSamples, double volume) {
byte[] array = new byte[audioSamples.length];
for (int i = 0; i < array.length; i += 2) {
// convert byte pair to int
int audioSample = (int) (((audioSamples[i + 1] & 0xff) << 8) | (audioSamples[i] & 0xff));


audioSample = (int) (audioSample * volume);


// convert back
array[i] = (byte) audioSample;
array[i + 1] = (byte) (audioSample >> 16);

}
return array;
}

此代码基于:Audio: Change Volume of samples in byte array其中提问者试图做同样的事情。然而,使用了他的问题中的代码(我认为在他得到答案后没有更新)我无法让它工作,而且我不太确定它在做什么。

最佳答案

我建议您将字节数组包装在 ByteBuffer 中(不要忘记将其 .order() 设置为小端),读取 short,操作它,然后再次写入。

示例代码:

// Necessary in order to convert negative shorts!
private static final int USHORT_MASK = (1 << 16) - 1;

final ByteBuffer buf = ByteBuffer.wrap(audioSamples)
.order(ByteOrder.LITTLE_ENDIAN);
final ByteBuffer newBuf = ByteBuffer.allocate(audioSamples.length)
.order(ByteOrder.LITTLE_ENDIAN);

int sample;

while (buf.hasRemaining()) {
sample = (int) buf.getShort() & USHORT_MASK;
sample *= volume;
newBuf.putShort((short) (sample & USHORT_MASK));
}

return newBuf.array();

关于java - 从字节[]实时调整音频音量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16960890/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com