据我所知,我使用的音频字节数组(PCM Stereo 16bit)每个样本4个字节。我注意到当你反转字节值(即-128到128和128到-128)时,它不会将声音置于环绕声道中。听起来一样(前置音频)。我尝试反转每隔一个字节(每2个字节)而不是所有字节,并得到类似环绕声的东西,但它非常脏和不连贯。我究竟如何操作常规PCM 16位立体声WAV文件(以字节数组形式)以便将音频放置在环绕声道中?
我的代码:
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;
}
答案 0 :(得分:0)
我不是以任何方式,塑造或组建DSP专家,但我有一些可能有用的观察结果:
您以4个字节的增量解析数组,这正确对应于单个16位立体声声音样本:2 channels * 16 bits = 32 bits = 4 bytes
。
现在,我可能不明白你想要做什么,但在现代环绕音频中,环绕声通道通常彼此独立。这意味着每个环绕音频采样需要超过4个字节。例如,如果您有5个通道,则需要10个字节/样本,这可能意味着您的代码中需要单独的输入和输出数组。
有Dolby Surround和Dolby Pro Logic等方法,其中环绕声道被矩阵编码到两个立体声声道中,但所涉及的DSP数学远比你的代码中的数学复杂得多。 。更不用说需要特殊的解码器和这些方法所暗示的质量损失。
反转 2字节样本的每个字节是没有意义的:样本值1000d将变为-744d。像这样的按位运算很少在DSP中使用,如果有的话。
通常,音频样本存储为带符号的2的补码二进制数。这使得在字节方面处理它们非常复杂,特别是在没有无符号数字且没有指针转换(如Java)的语言中。最好将字节数组转换为short
或int
数组,或使用不同的编程语言(如C ++)。
反转-128产生+128,无法存储在Java使用的带符号字节中。
当“反转彼此字节”时,存储i + 0
和i + 3
的倒数,而不是i + 0
和i + 2
或i + 1
和i + 3
。
根据您的音频表示是否为little-endian or big-endian,反转每个字节的结果虽然仍然没有任何意义,但会产生不同的效果。 RIFF WAV files使用little-endian字节顺序。
反转字节0和2会改变采样的LSB,当音频剪辑的动态范围有限时,这只会增加高振幅和完全失真的噪声。
反转字节1和3将近似反转高幅度的整个样本,并在动态范围有限的剪辑中添加批次失真。
反转整个样本,而不是单个字节,是180度相移的近似。我不知道你可以在哪里使用它,但是......
如果你需要更多的帮助,你需要告诉我们你究竟想做什么。您至少应该提到您的预期输出和您正在使用的DSP算法。