首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >播放采样声音javax.sound.sampled延时过大

播放采样声音javax.sound.sampled延时过大
EN

Stack Overflow用户
提问于 2013-06-05 13:42:45
回答 1查看 262关注 0票数 0

我有一个工作的软合成器,它输出和播放样本正确,但我有一个巨大的延迟,大约一秒钟。我的代码基于这里的一篇文章:http://www.drdobbs.com/jvm/creating-music-components-in-java/229700113?pgno=2

我是不是忽略了什么?样本的生成不是问题,它发生得很快,而且很简单。

我尝试将缓冲区大小更改为几个不同的值,但都没有成功。我目前正在OSX机器上测试,这会是问题所在吗?

仅供参考,done永远不会出错。当是静默的时候,我只是简单地将0的样本提供给缓冲区。

代码语言:javascript
复制
public class Player extends Thread {
    public static final int SAMPLE_RATE = 44100;
    public static final int BUFFER_SIZE = 2200;
    public static final int SAMPLES_PER_BUFFER = BUFFER_SIZE / 2;
    private static final int SAMPLE_SIZE = 16; // Don't change
    private static final int CHANNELS = 1;
    private static final boolean SIGNED = true;
    private static final boolean BIG_ENDIAN = true;
    private AudioFormat format;
    private DataLine.Info info;
    private SourceDataLine audioLine;
    private boolean done;
    private byte[] sampleData = new byte[BUFFER_SIZE];
    private Oscillator osc;

    public Player(Oscillator osc) {
        format = new AudioFormat(SAMPLE_RATE, SAMPLE_SIZE, CHANNELS, SIGNED, BIG_ENDIAN);
        info = new DataLine.Info(SourceDataLine.class, format);
        this.osc = osc;
    }

    public void run() {
        done = false;
        int bytesRead = 0;

        try {
            audioLine = (SourceDataLine) AudioSystem.getLine(info);
            audioLine.open(format);
            audioLine.start();

            while ((bytesRead != -1) && !done) {
                bytesRead = osc.getSamples(sampleData);

                if (bytesRead > 0) {
                    audioLine.write(sampleData, 0, bytesRead);
                }
            }
        } catch (LineUnavailableException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } finally {
            audioLine.drain();
            audioLine.close();
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2013-06-05 16:31:31

您似乎没有设置音频系统使用的音频缓冲区大小-相反,您正在使用SAMPLES_PER_BUFFER来控制一次生成的采样数量。

这不是一回事-操作系统将请求呈现它使用的任何缓冲区大小(在MacOSX上,样本是通过回调提取的)。

这段代码:

代码语言:javascript
复制
        while ((bytesRead != -1) && !done) {
            bytesRead = osc.getSamples(sampleData);

            if (bytesRead > 0) {
                audioLine.write(sampleData, 0, bytesRead);

将简单地填充until的缓冲区,直到它阻塞。然后将到达一个呈现请求,该请求清空缓冲区,然后再次解除阻塞。这将以音频缓冲区大小的速率发生。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16932347

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档