- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个立体声 AudioInputStream
,我想将其分成两个单声道 AudioInputStream
,一个用于立体声流的左声道,一个用于右声道。我该怎么做?
注意:我已经测试了以下问题的答案,但没有任何效果(这就是我再次询问的原因)。
How to split a Wav file into channels in java?
这是我正在尝试的工作(主要来自上面的链接)。在下面的代码中,while 循环无限运行。 readsize
始终为 4(或者无论 sampleInBytes * 2
是什么),它永远不会变成 -1(这意味着它是流的结尾),因此它永远不会中断。
AudioInputStream originalAudioInputStream = null;
try {
originalAudioInputStream = AudioSystem.getAudioInputStream(audiofile);
} catch (UnsupportedAudioFileException e) {
//file not supported
} catch (IOException e) {
//error
}
//read file and convert it to PCM SIGNED big endian
AudioFormat destaf = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
originalAudioInputStream.getFormat().getSampleRate(),
originalAudioInputStream.getFormat().getSampleSizeInBits(),
originalAudioInputStream.getFormat().getChannels(),
originalAudioInputStream.getFormat().getSampleSizeInBits() / 8 * originalAudioInputStream.getFormat().getChannels(),
originalAudioInputStream.getFormat().getSampleRate(), true);
AudioInputStream signedBigEndianInputStream = AudioSystem.getAudioInputStream(destaf, originalAudioInputStream);
//split stereo AudioInputStream
ByteArrayOutputStream leftbaos = new ByteArrayOutputStream();
ByteArrayOutputStream rightbaos = new ByteArrayOutputStream();
byte[] bytes = new byte[(signedBigEndianInputStream.getFormat().getSampleSizeInBits()/8)*2];
while (true) {
int readsize = 0;
try {
readsize = signedBigEndianInputStream.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
if(readsize==-1){
break;
}
rightbaos.write(bytes,0,bytes.length/2);
leftbaos.write(bytes,bytes.length/2,bytes.length/2);
}
byte[] leftData = leftbaos.toByteArray();
byte[] rightData = rightbaos.toByteArray();
AudioFormat outFormat = new AudioFormat(signedBigEndianInputStream.getFormat().getEncoding(),signedBigEndianInputStream.getFormat().getSampleRate(),signedBigEndianInputStream.getFormat().getSampleSizeInBits(),1,signedBigEndianInputStream.getFormat().getFrameSize()/2, signedBigEndianInputStream.getFormat().getFrameRate(),signedBigEndianInputStream.getFormat().isBigEndian());
ByteArrayInputStream leftbais = new ByteArrayInputStream(leftData);
AudioInputStream leftoutputAIS = new AudioInputStream(leftbais, outFormat, leftData.length / outFormat.getFrameSize());
ByteArrayInputStream rightbais = new ByteArrayInputStream(rightData);
AudioInputStream rightoutputAIS = new AudioInputStream(rightbais, outFormat, rightData.length / outFormat.getFrameSize());
//close inputstreams
try {
rightoutputAIS.close();
leftoutputAIS.close();
rightbais.close();
leftbais.close();
rightbaos.close();
leftbaos.close();
signedBigEndianInputStream.close();
originalAudioInputStream.close();
} catch (IOException e) {
//error
}
谢谢!
最佳答案
您假设音频存储在两个 block 中:
相反,音频通常存储在 interleaved fashion 中.
即:
为了分离两个流,您必须执行以下操作:
// just to show which types are used
// i.e., initialization is not shown
AudioFormat destaf;
ByteArrayOutputStream leftbaos;
ByteArrayOutputStream rightbaos;
AudioInputStream signedBigEndianInputStream;
byte[] bytes;
[...]
final int bytesPerSample = destaf.getSampleSizeInBits() / 8;
final int channels = 2;
while (true) {
int readsize = 0;
try {
readsize = signedBigEndianInputStream.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
if (readsize==-1){
break;
}
for (int sample=0; sample<readsize/channels/bytesPerSample;sample++) {
final int offset = sample * bytesPerSample * channels;
leftbaos.write(bytes, offset, bytesPerSample);
rightbaos.write(bytes, offset + bytesPerSample, bytesPerSample);
}
}
[...]
关于java - 如何将PCM流拆分为每个 channel 的AudioInputStreams?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61549655/
我知道需要使用JMF来处理视频,但是JMF api非常困惑且难以理解。我看到类似this的东西但我想做的与我想的相反。 最佳答案 问题已解决。完成上述操作需要Xuggler。 JMF除了播放视频之外没
文件格式为“PCM_SIGNED 44100.0 Hz,16位,立体声,4字节/帧,小端”,我想在放大两个文件之一的同时将它们添加在一起。我计划读取两个 wav 将它们放入两个 audioinputs
我有一个 AudioInputStream 不支持 skip()。它由 jflac 支持。 因此,我正在使用 read ( byte[] ) 调用并转储数据,以在文件中向前跳转。 不幸的是,搜索 17
我仍在致力于我的小项目,用 JAVA 创建一个混音控制台,但我遇到了一个新的障碍。我正在尝试从 byteArray 创建一个 audioInputStream,然后读取它以听到声音。但我的代码有问题:
我需要从 AudioInputStream 获取值并将其存储在 byte[] 中。调用 read(byte[]) 返回 -1。如果我能够读取整数值,我可以将其转换为 byte[]。我该如何解决这两个问
我已使用 AudioInputStream 将背景音频插入到我的程序中。 当我按下 On 时,背景音频将播放,而 Off 将停止播放背景音频。 这是我的音频播放部分的代码: public void p
大家好。我有一个音频类,可以播放 .wav 文件。但我想永远循环它。 import javax.sound.sampled.AudioInputStream; import javax.sound.s
I am trying to skip a negative number of bytes with AudioInputStream skip(long bytes) method . 问题是试图
是否有一个很好的(纯Java)开源库来获取从 AudioInputStream 获取的样本的频谱? 最佳答案 有几个FFT库,例如Apache Commons Math包括 FFT。 但请记住,频谱估
如何声明/访问追加文件 AudioInputStream 数据以将其写入 for 循环之外的磁盘?当我将磁盘写入命令放入 for 循环中时,它几乎按预期工作,但外部无法识别附加文件。 import j
我的程序的一部分需要加载声音并在提示时播放它们。目前,我支持加载已作为资源“嵌入”到项目中的 .wav 文件。为此,我使用如下代码行: sounds[i+1] = AudioSystem.getAud
有随机访问AudioInputStream的例子吗?就像任何普通音频播放器一样 - 当您将小节带到任何您想要的地方并从任何地方播放时,我如何以这种方式访问音频流中的字节? 像这样简单的东西:rea
我想创建 2 个可以启动和停止背景音频的 JMenuItem。 这是我的代码: public class MainClass extends JFrame { private AudioInp
我正在创建一个应用程序来播放音频文件 (WAV)。播放效果非常好,我做了一个小功能,通过 audioInputStream 的 skip() 方法向前“跳跃”X(秒),这也完美地工作了。 我的问题是实
我试图在 Java 中获取音频文件的持续时间。 我编写了这段代码(在 stackoverflow 的帮助下): public static Duration getDuration(File file
我想获得 AudioInputStream 的持续时间(以微秒为单位)。我怎样才能轻松做到这一点?我找到了 how can I get duration of an audio file: ,但不能这
我在找出我使用 AudioInputStream 实际读取的内容时遇到了一些问题。下面的程序只是打印我得到的字节数组,但实际上我什至不知道这些字节是否实际上是样本,因此字节数组是音频wave。 Fil
所以在我的代码中,我创建了一个音频输入流: try{ File f = new File(main.getWavFileName(0, tab)); AudioInputStrea
我正在播放通过 AudioInputStream 接收的音频。音频数据存储在远程服务器上。 检索AudioInputStream通过AudioSystem.getAudioInputStream(ne
我尝试使用 javax.sound library. 更改 wav 文件的采样率 实现我想要的方法后,我尝试了一下,它成功了!但创建的 .wav 文件只有几个字节大。确切地说,它只有 2.090 字节
我是一名优秀的程序员,十分优秀!