处理带有分数的字节数组后的Java Sound API噪波
我正在尝试处理从采样的sourcedataline(JavaSoundAPI)获得的字节数组。如果将字节数组与分数相乘,则在播放流时会出现噪声 在播放声音之前,我将立体声wav文件分为左声道和右声道。这个很好用。但是如果我想用增益控制来处理通道,这取决于延迟因子,我会得到噪声处理带有分数的字节数组后的Java Sound API噪波,java,api,audio,wav,Java,Api,Audio,Wav,我正在尝试处理从采样的sourcedataline(JavaSoundAPI)获得的字节数组。如果将字节数组与分数相乘,则在播放流时会出现噪声 在播放声音之前,我将立体声wav文件分为左声道和右声道。这个很好用。但是如果我想用增益控制来处理通道,这取决于延迟因子,我会得到噪声 for(int i=0; i<bufferSize; i++) { array[i] = (byte) (array[i] * gain); } 但是,我如何将这个简短的内容转换成2个单字节而不丢失声音呢 //从分
for(int i=0; i<bufferSize; i++) { array[i] = (byte) (array[i] * gain); }
但是,我如何将这个简短的内容转换成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++;
}
}
}
公共静态无效通道操作(字节[]数组完成){
int i=2;
char channel='L';
int j=0;
/**
*立体声流将被分为他的声道-左声道和右声道。
*通道每2个字节切换一次。
*为左通道收集数据时,右通道将设置为0。反之亦然。
*/
而(j您需要应用一些剪裁。假设您有一个值为100的样本,并且您应用的增益为2。乘法的结果将是200,然后将其截断为
-73
尝试:
作为一项测试——如果你使用的增益实际上是一个“静音”增益(例如0.5),那么此时你不应该得到噪声
编辑:如果“原始”值实际上不是单字节,您应该首先从字节数组转换为这些值,然后应用增益,然后再转换回单字节。否则您确实会得到一些奇怪的结果…特别是如果本机格式实际上将字节视为无符号值…您需要应用一些剪裁。假设y如果样本值为100,则应用的增益为2。乘法结果将为200,然后将其截断为
-73
尝试:
作为一项测试——如果你使用的增益实际上是一个“静音”增益(例如0.5),那么此时你不应该得到噪声
编辑:如果“原始”值实际上不是单字节,您应该首先将字节数组转换为这些值,然后应用增益,然后再转换回单字节。否则您确实会得到一些奇怪的结果…特别是如果本机格式实际上将字节视为无符号值…不起作用。我有以下代码片段:
for(int c=0; c<Constants.getBufferlength()-4; c+=4) {
arrayLeft[c] = (byte) Math.min(Math.max((arrayLeft[c]*leftGain), -128), 127);
arrayRight[c] = (byte) Math.min(Math.max((arrayRight[c]*rightGain),-128),127);
}
for(int c=0;c不起作用。我有以下代码片段:
for(int c=0; c<Constants.getBufferlength()-4; c+=4) {
arrayLeft[c] = (byte) Math.min(Math.max((arrayLeft[c]*leftGain), -128), 127);
arrayRight[c] = (byte) Math.min(Math.max((arrayRight[c]*rightGain),-128),127);
}
for(int c=0;c即使您的音频数据是字节数组的形式,但您的真实音频(我假设)是一个由短(2字节)整数组成的数组。当您将数组中的每个字节乘以增益因子时,您将2字节的采样值变成了胡言乱语(也称为噪声).我不是java程序员,但您的解决方案是将字节数组转换为2字节整数数组(无论您在java中如何操作),然后将每个2字节整数值乘以增益因子(然后,我猜,在播放之前,将其转换回字节数组)
更新:在C#中,如果我有一个音频数据的字节数组(例如,从实际格式为2字节整数的WAV文件中提取),我将使用位转换器和数组类应用增益,如下所示:
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);
}
浮动增益=0.5f;
对于(int i=0;i
这是相当笨拙的,我从来不会真正这么做。在C#世界中,我总是将音频作为16位或32位整数的数组,或者32位或64位浮点值来处理。我真的不知道java音频是如何工作的,但这应该是可能的(而且更容易)在某个地方,你的音频作为一个16位整数数组放在第一位-然后你就不必做任何奇怪的转换像这样应用增益或做任何其他你想做的事情
更新2:另外,我不确定您的原始音频源是否包含2字节整数样本值。它实际上可能是4字节整数或(更可能)4字节浮点样本值,在这种情况下,我的样本代码仍然会产生噪声。使用4字节浮点,正确的代码应该是:
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);
}
浮动增益=0.5f;
对于(int i=0;i
即使您的音频数据是字节数组的形式,但您的真实音频(我假设)是一个由短(2字节)整数组成的数组。当您将数组中的每个字节乘以增益因子时,您将2字节的采样值变成了乱码(也称为噪声).我不是java程序员,但您的解决方案是将字节数组转换为2字节整数数组(无论您在java中如何操作),然后将每个2字节整数值乘以增益因子(然后,我猜,在播放之前,将其转换回字节数组)
更新:在C#中,如果我有一个音频数据的字节数组(例如,从实际格式为2字节整数的WAV文件中提取),我将使用位转换器和数组类应用增益,如下所示:
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);
}
浮动增益=0.5f;
对于(int i=0;i
这是相当笨拙的,我从来不会真正这么做。在C#世界中,我总是将音频作为16位或32位整数的数组,或者32位或64位浮点值来处理。我真的不知道java音频是如何工作的,但这应该是可能的(而且更容易)在某个地方把你的音频作为一个16位整数的数组放在第一位,这样你就不必做任何像这样奇怪的转换来应用增益或做任何事情
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);
}
short sValue = (array[i] + array[i+1] <<8)
if(array[i] < 0)
array[i+1] += 1;
byte[] decodedBuffer = Base64.decode(message64, Base64.NO_WRAP);
// byte[] newdata;
for (int i=0; i<decodedBuffer.length; i++) {
Byte b = decodedBuffer[i];
if (b<=Byte.MIN_VALUE||b>=Byte.MAX_VALUE) decodedBuffer[i] = Byte.MIN_VALUE;
}
if (audioTrack != null)
audioTrack.write(decodedBuffer, 0, decodedBuffer.length);