Raspberry Pi上的Java Audio Clip#getFramePosition()非常慢

时间:2018-11-07 11:56:48

标签: java audio raspberry-pi

此问题底部的代码段在我的台式机上运行良好,对clip.getFramePosition()的调用花费了1ms或更短的时间。在运行Raspbian Stretch和JDK 8u191的Pi 3 Model B +上,调用同一函数大约需要900毫秒。这似乎太慢了。

我实际上是在尝试通过JLayer播放MP3文件,但WAV文件也会出现此问题,并且由于不需要外部依赖项,因此使用WAV文件更容易重现,

CPU和内存

运行代码时,top报告的Pi的CPU和内存使用率永远不会超过10%。我还尝试将音频预加载到byte数组中,然后播放而不是流。它具有相同的问题,因此这似乎不是磁盘I / O瓶颈。

阻止

在运行时,clip对象是com.sun.media.sound.DirectAudioDevice.DirectDL的实例,其getLongFramePosition()方法具有一个同步块,该块调用了native方法:

synchronized(this.lockNative) {
    var1 = DirectAudioDevice.nGetBytePosition(this.id, this.isSournce, this.bytePosition);
}

因此,可能是某些原因阻止了我的通话。但是,我认为在播放Clip的过程中查询它的进度是合理的。

那会是什么? 有人能阐明这种缓慢吗?我是在滥用API,还是仅仅是Raspbian的Java Audio实现的问题?

更新#1:Ubuntu MATE + Liberica

我尝试使用Liberica JRE 11在Ubuntu MATE上运行代码,但速度仍然很慢。

更新#2:外部声卡

我将外部USB声卡插入pi并通过它播放了音频。我没想到它可以解决问题,但没有。

更新#3:直接使用JLayer

通过JLayer AdvancedPlayer类而不是通过Java Sound API播放MP3会更好。获取进度大约需要50毫秒,而不是900毫秒,但这仍然很慢。

更新#4:使用Pi 3模型B

我周围有一个Pi 3 Model B(不是B +)。运行最新的Raspbian时,它具有相同的问题。使用Raspbian Jessie(2016-03-18)时,速度稍快(〜700ms),但不多。


示例代码

import java.io.File;
import java.io.InputStream;
import java.util.Date;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

public class Main {

    public static void main(String[] args) throws Exception {
        File file = new File("/home/pi/beat.wav");
        AudioInputStream ais = AudioSystem.getAudioInputStream(file);
        AudioFormat format = ais.getFormat();

        Clip clip = AudioSystem.getClip();
        clip.open(ais);
        clip.start();

        for (int i = 0; i < 100; i++) {
            long start = new Date().getTime();
            long pos = clip.getFramePosition();
            long duration = new Date().getTime() - start;
            System.out.println("Pos: " + pos + ", duration: " + duration);
            Thread.sleep(10);
        }
    }
}

0 个答案:

没有答案