gpt4 book ai didi

java - 通过直接更改字节来更改音频流的音量

转载 作者:行者123 更新时间:2023-12-02 02:02:48 25 4
gpt4 key购买 nike

对于点对点音频客户端,我需要能够将输出音量更改为所需的级别。就我而言,体积是一个介于 0 和 1 之间的 float 。

我这样修改音频流:

void play(byte[] buf)
{
for (int i = 0; i < buf.length; i += 2)
{
// sample size is 2 bytes, so convert to int and then back
int data = ((buf[i + 1] & 0xFF) << 8) | (buf[i] & 0xFF);
data = (int) (data * outputVolume);
buf[i] = (byte) (data & 0xFF);
buf[i + 1] = (byte) (data >> 8);
}
line.write(buf, 0, Math.min(buf.length, line.available()));
}

现在,当 outputVolume 设置为 0 时,输出将保持静音。当它设置为 1 时,它的行为正常并且质量很好(因为它没有被修改)。但是 0 到 1 之间的任何数字都会产生可怕的噪音,其声音比预期的流本身还要大。在 0.5 时,噪音达到最大声点。

我不想使用音频混音器本身的控件(例如增益控制或音量控制),因为这样我遇到了兼容性问题,后来,我想更多地修改字节流,所以我必须迭代无论如何都要通过流。

最佳答案

假设音频数据已签名(因为我认为未签名的 16 位样本是很不寻常的),则该代码中存在错误,因为您还需要对样本进行签名。

您可以从高字节中删除 & 0xFF,这将使符号扩展自动发生:

int data = (buf[i + 1] << 8) | (buf[i] & 0xFF);

如果由于某种原因你无法修改 and-shift-or 表达式,你可以像这样进行符号扩展:

int data = ((buf[i + 1] & 0xFF) << 8) | (buf[i] & 0xFF);
data = (data << 16) >> 16;

移位表达式的结果相当于:

if (data > 32767)
data -= 65536;

还有这个:

if ((i & 0x80_00) != 0)
i |= 0xFF_FF_00_00;

(这些也可以。)

但是,在您的情况下,您只需从高字节中删除 & 0xFF 即可。

<小时/>

为了快速解释,如果您有一些像这样的 16 位示例(即 -1):

11111111_11111111

如果您只是转换为 32 位而不进行符号扩展,您将得到:

00000000_00000000_11111111_11111111

但那是 65536,而不是 -1。如果设置了 16 位值中的 MSB,符号扩展将用 1 填充高位:

11111111_11111111_11111111_11111111

关于java - 通过直接更改字节来更改音频流的音量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51309639/

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