gpt4 book ai didi

使用小数处理字节数组后的 Java Sound API 噪声

转载 作者:行者123 更新时间:2023-11-29 08:19:30 29 4
gpt4 key购买 nike

我正在尝试处理我从采样源数据行(Java Sound API)获得的字节数组。如果我将字节数组与小数相乘,播放流时会产生噪音。

在播放声音之前,我将立体声 wav 文件分成左右声道。这很好用。但是,如果我想使用取决于延迟因子的增益控制来处理 channel ,我会得到噪声。

for(int i=0; i<bufferSize; i++) { array[i] = (byte) (array[i] * gain); }

有谁知道如何解决这个问题?

//编辑:

我试图将这两个字节转换为带有位移的短字节(2 字节),例如:

short leftMask = 0xff00;
short rightMask = 0x00ff;
short sValue = (array[i] + array[i+1] <<8) * gain;

array[i] = (sValue & leftMask) >> 8;
array[i+1] = (sValue & rightMask);

但是当我将单个字节乘以增益值时,我得到了相同的结果。

//编辑

或者我应该像这样将两个数组值添加到一个 short 中吗?

short shortValue = array[i] + array[i+1];
shortValue *= gain;
array[i] = ???

但是如何在不丢失声音的情况下将这个 short 转换为 2 个单字节?

//从分离方法中编辑一些代码:

public static void channelManipulation(byte[] arrayComplete) {
int i=2;
char channel='L';
int j=0;

/**
* The stereo stream will be divided into his channels - the Left and the Right channel.
* Every 2 bytes the channel switches.
* While data is collected for the left channel the right channel will be set by 0. Vice versa.
*/
while(j<arrayComplete.length) {
//while we are in the left channel we are collecting 2 bytes into the arrayLeft


while(channel=='L') {
if(i==0) {
channel='R'; //switching to the right channel
i=2;
break;
}
arrayLeft[j] = (byte)(arrayComplete[j]);
arrayRight[j] = 0;
i--; j++;
}

//while we are in the right channel we are collecting 2 bytes into the arrayRight
while(channel=='R') {
if(i==0) {
channel='L'; //switching to the left channel
i=2;
break;
}
arrayRight[j] = (byte) (arrayComplete[j]);
arrayLeft[j] = 0;
i--; j++;
}
}

}

最佳答案

即使您的音频数据是字节数组的形式,您的真实音频是(我假设)一个短(2 字节)整数数组。当您将数组的每个单独字节乘以一个增益因子时,您会将 2 字节样本值变成乱码(又名噪音)。我不是 Java 程序员,但您的解决方案是将字节数组转换为 2 字节整数数组(无论您在 Java 中如何执行),然后将每个 2 字节整数值乘以增益因子(然后,我想,在播放之前将其转换回字节数组)。

更新:在 C# 中,如果我有音频数据的字节数组(例如,从实际格式为 2 字节整数的 WAV 文件中提取),我将应用增益使用像这样的 BitConverter 和 Array 类:

float gain = 0.5f;
for (int i = 0; i < audio.Length; i += 2)
{
short val = BitConverter.ToInt16(audio, i);
val = (short)((float)val * gain);
Array.Copy(BitConverter.GetBytes(val), 0, audio, i, 2);
}

这很笨拙,而且我真的不会这样做。在 C# 世界中,我总是将音频作为 16 位或 32 位整数数组,或者作为 32 位或 64 位浮点值。我真的不知道 java 音频是如何工作的,但是首先应该可以(并且更容易)在某个地方将音频作为 16 位整数数组获取 - 然后你就不必做任何事情像这样奇怪的转换来应用增益或做任何你想做的事情。

更新 2:另外,我不确定您的原始音频源是否真的包含 2 字节整数样本值。它实际上可能是 4 字节整数或(更有可能)4 字节浮点样本值,在这种情况下,我的示例代码仍会产生噪音。对于 4 字节 float ,正确的代码是:

float gain = 0.5f;
for (int i = 0; i < audio.Length; i += 4)
{
float val = BitConverter.ToSingle(audio, i);
val *= gain;
Array.Copy(BitConverter.GetBytes(val), 0, audio, i, 4);
}

关于使用小数处理字节数组后的 Java Sound API 噪声,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1373066/

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