PCM Wave 文件 - 立体声到单声道
我有一个立体声音频文件。将其转换为单声道只是跳过每隔一个字节(在标头之后)的情况吗?它以 16 位签名 PCM 格式编码。我有 javax.sound.sampled
可用。
以下是我尝试过但不起作用的代码:
WaveFileWriter wfw = new WaveFileWriter();
AudioFormat format = new AudioFormat(Encoding.PCM_SIGNED, 44100, 16, 2, 2, 44100, false);
AudioFormat monoFormat = new AudioFormat(Encoding.PCM_SIGNED, 44100, 16, 1, 2, 44100, false);
byte[] audioData = dataout.toByteArray();
int length = audioData.length;
ByteArrayInputStream bais = new ByteArrayInputStream(audioData);
AudioInputStream stereoStream = new AudioInputStream(bais,format,length);
AudioInputStream monoStream = new AudioInputStream(stereoStream,format,length/2);
wfw.write(monoStream, Type.WAVE, new File(Environment.
getExternalStorageDirectory().getAbsolutePath()+"/stegDroid/un-ogged.wav"));
此代码在使用 Jorbis 读取 .ogg
文件后使用,将其转换为 PCM 数据。唯一的问题是结果是立体声,而我需要它是单声道,所以如果有其他解决方案,我很高兴听到它!
I have an audio file which is stereo. Is converting it to mono just a case of skipping every other byte (after the header)? It's encoded in 16bit signed PCM format. I've got javax.sound.sampled
available.
Here's code I tried that didn't work:
WaveFileWriter wfw = new WaveFileWriter();
AudioFormat format = new AudioFormat(Encoding.PCM_SIGNED, 44100, 16, 2, 2, 44100, false);
AudioFormat monoFormat = new AudioFormat(Encoding.PCM_SIGNED, 44100, 16, 1, 2, 44100, false);
byte[] audioData = dataout.toByteArray();
int length = audioData.length;
ByteArrayInputStream bais = new ByteArrayInputStream(audioData);
AudioInputStream stereoStream = new AudioInputStream(bais,format,length);
AudioInputStream monoStream = new AudioInputStream(stereoStream,format,length/2);
wfw.write(monoStream, Type.WAVE, new File(Environment.
getExternalStorageDirectory().getAbsolutePath()+"/stegDroid/un-ogged.wav"));
This code is used after reading a .ogg
file using Jorbis to convert it to PCM data. The only problem is the result is stereo and I need it to be mono, so if there's another solution I'm happy to hear it!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
几乎 - 你想跳过所有其他样本,而不是字节。在您的情况下,每个样本的大小似乎为 16 位 = 2 字节。因此,您可能想要获取 2 个字节、跳过 2 个字节、获取 2 个字节等等。
看起来您只是写出了文件的前半部分,而不是写出了所有其他示例。此外,您还必须修复 WAV 标头,以指定单个通道(请参阅您的
monoFormat
)。Almost - you want to skip every other sample, not byte. In your case it looks like each sample is of size 16 bits = 2 bytes. So you would want to take 2 bytes, skip 2 bytes, take 2 bytes and so on.
This looks like you just write out the first half of the file instead of writing out every other sample. Also you have to fix the WAV header, to specify a single channel (see your
monoFormat
).看看这段代码。当我需要弄乱 wav 文件中的字节时,它对我很有帮助。
Take a look at this code. It helped me when I needed to mess with the bytes in a wav file.
2018年回答这个问题。我也有类似的情况,并意识到自己犯了一个明显的错误。构造函数参数中的“格式”参数不正确。
第五个参数(在您的情况下,第二个“2”)表示帧大小。帧大小 = 样本大小 * 通道数。因为您的位深度是 16,所以您的样本大小是 2 个字节。
样本大小 = 2
通道 = 2
帧大小 = 样本大小 * 通道 = 4
因此,您的代码行应该为:
另外,您是否尝试过使用 FormatConversionProvider?
https://docs.oracle.com/javase/tutorial/sound/converters。 html
本教程对我有很大帮助,但我相信它假设您已经导入了上述类。
我没有看到此线程上发布的这些解决方案,但也许您已经弄清楚了。无论如何,希望这有帮助!
Answering this in 2018. I have a similar situation and realized a glaring mistake I made. Your "format" parameters in the argument of the constructor aren't correct.
The fifth parameter (in your case, the second "2") represents the frame size. Frame size = Sample size * Channels. Because your bit depth is 16, your sample size is 2 bytes.
Sample size = 2
Channels = 2
Frame size = Sample Size * Channels = 4
So, your line of code should read
Also, have you tried using the FormatConversionProvider?
https://docs.oracle.com/javase/tutorial/sound/converters.html
This tutorial helped me a bunch, but I believe it assumes you've already imported the aforementioned class.
I didn't see these solutions posted on this thread, but perhaps you already figured it out. At any rate, hope this helps!