跳过指定字节数的SourceDataLine(JavaSound)

跳过指定字节数的SourceDataLine(JavaSound),java,audio,javasound,Java,Audio,Javasound,出于某些原因,我需要使用SourceDataLine而不是Clip来播放程序中的音频。分配我想跳到剪辑的帧位置很容易,但是SourceDataLine没有这个方便的API 我想使用AudioInputStream.skipn,其中n是请求跳过的字节数。但是如果我想跳过1.25秒,我不知道如何正确设置n。我该怎么做 我的代码来自于此。 请检查in.skip in函数流 每个AudioInputStream都有一个AudioFormat对象,您可以通过该方法获取该对象。要确定1.25秒的字节数,需要

出于某些原因,我需要使用SourceDataLine而不是Clip来播放程序中的音频。分配我想跳到剪辑的帧位置很容易,但是SourceDataLine没有这个方便的API

我想使用AudioInputStream.skipn,其中n是请求跳过的字节数。但是如果我想跳过1.25秒,我不知道如何正确设置n。我该怎么做

我的代码来自于此。 请检查in.skip in函数流

每个AudioInputStream都有一个AudioFormat对象,您可以通过该方法获取该对象。要确定1.25秒的字节数,需要计算1.25秒的帧数和帧大小:

AudioFormat format = audioInputStream.format();
float b = format.getFrameSize() * format.getFrameRate() * 1.25f;
// round to nearest full frame
long n = (b/format.getFrameSize())*format.getFrameSize();
long skipped = audioInputStream.skip(b);
// you might want to check skipped to see whether the
// requested number of bytes was indeed skipped.
解释:

帧是所有通道的一个完整采样。所以如果你有一个立体声信号,一帧是两个样本,左和右。 FrameSize是用于帧的字节数。对于CD质量,这将是每个通道2字节,即立体声情况下每帧4字节。 FrameRate是每秒的帧数。 由于不应分割帧,因此必须将其四舍五入到整个帧。
注意,上面的代码假定您有PCM编码的音频。如果您还有其他功能,请首先使用pcmStream=AudioSystem.getAudioInputStreamAudioFormat.Encoding.PCM\u签名,audioInputStream转换到PCM。

谢谢,我已经试过了,frameSize4*framerate44100*1.25。但是它跳过了太多的字节,我的音频是3秒长,而且它跳过了所有的字节。我在我的帖子中添加了详细信息,请查看。这可能是mp3spi的错误。为了进行测试,请将mp3文件转换为wave并尝试使用它;没有。只需将in.skipn替换为in.readnew字节[n]。它应该有同样的效果,只要丢弃你读到的内容。在任何一种情况下,都必须检查返回值,以确保实际跳过/读取了请求的字节数。由于某些原因。。什么原因?请看,有一个问题我再也懒得去解决了。@andrewhompson原始文件是MP3,剪辑无法打开。这很奇怪。。剪辑和AudioInputStream可以打开完全相同的音频类型。如果编解码器位于运行时类路径上,则两者都支持MP3。使用剪辑打开MP3的唯一问题是,剪辑的最大大小非常小。我写了BigClip来解决这些问题。也许它可以解决这个问题。@AndrewThompson,当我试图用Clip打开它时,我得到了一条错误行,格式为MPEG1L3 44100.0 Hz,每个采样未知位,立体声,未知帧大小,38.28125帧/秒,不受支持。。SourceDataLine只是很好地播放文件,我只需要找出如何跳过指定的字节。
AudioFormat format = audioInputStream.format();
float b = format.getFrameSize() * format.getFrameRate() * 1.25f;
// round to nearest full frame
long n = (b/format.getFrameSize())*format.getFrameSize();
long skipped = audioInputStream.skip(b);
// you might want to check skipped to see whether the
// requested number of bytes was indeed skipped.