Java 将PCM字节数组转换为环绕声道
据我所知,我使用的音频字节数组(PCM立体声16位)是每个样本4字节。我注意到,当您将字节值反转(即-128到128和128到-128)时,它不会将声音放入环绕声道。听起来是一样的(前音频)。我尝试过每隔一个字节(每2个字节)而不是所有的字节反转一次,得到了类似环绕声的效果,但它非常脏而且不稳定。如何准确地操作常规PCM 16位立体声WAV文件(以字节数组形式),以便将音频置于环绕声道中 我的代码:Java 将PCM字节数组转换为环绕声道,java,arrays,audio,byte,surround,Java,Arrays,Audio,Byte,Surround,据我所知,我使用的音频字节数组(PCM立体声16位)是每个样本4字节。我注意到,当您将字节值反转(即-128到128和128到-128)时,它不会将声音放入环绕声道。听起来是一样的(前音频)。我尝试过每隔一个字节(每2个字节)而不是所有的字节反转一次,得到了类似环绕声的效果,但它非常脏而且不稳定。如何准确地操作常规PCM 16位立体声WAV文件(以字节数组形式),以便将音频置于环绕声道中 我的代码: public byte[] putInSurround(byte[] audio) {
public byte[] putInSurround(byte[] audio) {
for (int i = 0; i < audio.length; i += 4) {
int i0 = audio[i + 0];
int i1 = audio[i + 1];
int i2 = audio[i + 2];
int i3 = audio[i + 3];
if (0 > audio[i + 0]) {
i0 = Math.abs(audio[i + 0]);
}
if (0 < audio[i + 0]) {
i0 = 0 - audio[i + 0];
}
if (0 > audio[i + 1]) {
i1 = Math.abs(audio[i + 1]);
}
if (0 < audio[i + 1]) {
i1 = 0 - audio[i + 1];
}
if (0 > audio[i + 2]) {
i2 = Math.abs(audio[i + 2]);
}
if (0 < audio[i + 2]) {
i2 = 0 - audio[i + 2];
}
if (0 > audio[i + 3]) {
i3 = Math.abs(audio[i + 3]);
}
if (0 < audio[i + 3]) {
i3 = 0 - audio[i + 3];
}
audio[i + 0] = (byte) i0;
//audio[i + 1] = (byte) i1; <-- Commented Out For Every Other Byte.
//audio[i + 2] = (byte) i2; <-- Commented Out For Every Other Byte.
audio[i + 3] = (byte) i3;
}
return audio;
}
public byte[]putsournd(byte[]audio){
对于(int i=0;i音频[i+0]){
i0=Math.abs(音频[i+0]);
}
if(0<音频[i+0]){
i0=0-音频[i+0];
}
如果(0>音频[i+1]){
i1=Math.abs(音频[i+1]);
}
如果(0<音频[i+1]){
i1=0-音频[i+1];
}
如果(0>音频[i+2]){
i2=Math.abs(音频[i+2]);
}
如果(0<音频[i+2]){
i2=0-音频[i+2];
}
如果(0>音频[i+3]){
i3=Math.abs(音频[i+3]);
}
如果(0<音频[i+3]){
i3=0-音频[i+3];
}
音频[i+0]=(字节)i0;
//音频[i+1]=(字节)i1;我在任何方面都不是DSP专家,但我有一些可能有用的观察结果:
- 您以4字节的增量解析数组,这与单个16位立体声采样正确对应:
2个通道*16位=32位=4字节
现在,我可能不明白您想做什么,但在现代环绕音频中,环绕声道通常是相互独立的。这意味着每个环绕音频采样需要超过4个字节。例如,如果您有5个声道,则每个采样需要10个字节,这可能意味着您需要单独的输入和输出代码中的ut数组
有一些方法,如和,其中环绕声道被矩阵编码到两个立体声声道中,但所涉及的DSP数学远比代码中的复杂。更不用说需要特殊解码器以及这些方法所隐含的质量损失了
- 反转2字节样本的每个字节毫无意义:1000d的样本值将变为-744d。这样的按位操作在DSP中很少使用,如果有的话
- 通常音频样本存储为带符号2的补码二进制数。这使得按字节处理它们非常复杂,特别是在没有无符号数和指针转换的语言中,如Java。最好将字节数组转换为
short
或int
-数组,或使用不同的prOcGLIME语言,如C+++< /P>
- 反转-128生成+128,这不能存储在有符号字节中,正如Java所使用的那样
- 当“相互反转字节”时,存储的是
i+0
和i+3
的倒数,而不是i+0
和i+2
或i+1
和i+3
- 相互反转字节的结果,尽管仍然没有任何意义,但会产生不同的效果,这取决于音频表示是否正确。请使用小端字节顺序
反转字节0和2会改变样本的LSB,这只会在音频剪辑的动态范围受到限制时增加高振幅的噪声和彻底的失真
反转字节1和3将近似于在高振幅下反转整个样本,并在动态范围有限的剪辑中增加大量失真
- 反转整个样本,而不是单个字节,是一个180度相移的近似值。我不确定你在哪里可以使用它,尽管
如果您需要更多的帮助,您需要告诉我们您到底想做什么。您至少应该提到您的预期输出以及您正在使用的DSP算法。如果您有NetBeans的副本,我有我所指程序的代码。在Editor.java中,第847行和第1行调用了环绕过程205和程序本身是在1309。这是一个循环的音频程序,我正在写,它必须能够放置一个前扬声器方向的wav到后扬声器。由于4字节/样本,它可能是一个(信号样)3D问题,而不是(通道样)8字节/样本问题。