Java音频剪辑#getFramePosition()在Raspberry Pi上非常慢

Java音频剪辑#getFramePosition()在Raspberry Pi上非常慢,java,audio,raspberry-pi,Java,Audio,Raspberry Pi,这个问题底部的代码片段在我的台式电脑上运行良好,调用clip.getFramePosition()需要1毫秒或更短的时间。在运行Raspbian Stretch和JDK 8u191的Pi 3 Model B+上,调用相同的函数大约需要900毫秒。这似乎太慢了 实际上,我正试图通过JLayer播放MP3文件,但WAV文件也会出现问题,使用WAV文件更容易复制,因为不需要外部依赖项 CPU和内存 运行代码时,top报告的Pi的CPU和内存使用率从不超过10%。我还尝试将音频预加载到字节数组中,并播放

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

实际上,我正试图通过JLayer播放MP3文件,但WAV文件也会出现问题,使用WAV文件更容易复制,因为不需要外部依赖项

CPU和内存

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

阻塞

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

synchronized(this.lockNative) {
    var1 = DirectAudioDevice.nGetBytePosition(this.id, this.isSournce, this.bytePosition);
}
所以可能有什么东西挡住了我的电话。然而,我认为在播放
剪辑时查询其进度是合理的

可能是什么? 有人能解释一下这种缓慢吗?我是否误用了API,或者这只是Raspbian的Java音频实现的一个问题

更新#1:ubuntumate+Liberica

我试着用Liberica JRE 11对UbuntuMate运行代码,但速度仍然很慢

更新#2:外部声卡

我将一个外部USB声卡插入我的pi,并通过它播放音频。我没想到它能解决这个问题,它也没有

更新#3:直接使用JLayer

通过JLayer
AdvancedPlayer
类而不是通过Java Sound API播放MP3会更好一些。获得进度需要50毫秒而不是900毫秒,但仍然非常缓慢

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

我有一个PI3模型B(不是B+)在周围。当运行最新的Raspbian时,它也有同样的问题。Raspbian Jessie(2016-03-18)的速度稍快(约700毫秒),但不多


示例代码

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);
        }
    }
}
导入java.io.File;
导入java.io.InputStream;
导入java.util.Date;
导入javax.sound.sampled.AudioFormat;
导入javax.sound.sampled.AudioInputStream;
导入javax.sound.sampled.AudioSystem;
导入javax.sound.sampled.Clip;
公共班机{
公共静态void main(字符串[]args)引发异常{
File File=新文件(“/home/pi/beat.wav”);
AudioInputStream ais=AudioSystem.getAudioInputStream(文件);
AudioFormat=ais.getFormat();
Clip Clip=AudioSystem.getClip();
夹子。打开(ais);
clip.start();
对于(int i=0;i<100;i++){
长启动=新日期().getTime();
long pos=clip.getFramePosition();
长持续时间=新日期().getTime()-开始;
系统输出打印项次(“Pos:+Pos+”,持续时间:+duration);
睡眠(10);
}
}
}

new Date().getTime()
相当于
System.currentTimeMillis()
。无法保证系统时钟实际具有毫秒精度。@greg-449这只是一个重现问题的片段。我从来没有找到解决这个问题的办法,所以我减少了损失,买了一台二手的MacMini来运行我的软件。仍然有兴趣找出为什么它在Pi上如此缓慢!