java - 我的线程恰好循环了 43 次然后抛出异常

标签 java audio

我想不通。我的代码完美运行了 43 次,然后我得到一个 LineUnsupportedExceptionClip对象尝试重新打开该行。它是一个节拍器,所以精确的计时很重要,我已经把代码设计成一个主要的功能点。我创建了一个 Clip[]Clip对象,一个小节中有多少节拍,我在我的while循环中循环,每个小节关闭并刷新剪辑并定义一个新的Clip[] Clip 对象,如果我不时不时关闭线路并重置音频将停止播放的所有内容,我不确定剪辑 isActive() 方法是否返回 false 或发生了什么,但该解决方案似乎已修复问题,直到我开始得到这个异常,任何想法可能导致它?

这是我从最后一个工作循环到异常的输出......

0

打钩...

计数::42

循环完成时间:6

节拍持续时间应为:499

剩余 sleep 时间:493

1

打钩...

数::43

无法获得线路

java:/build/buildd/openjdk-6-6b24-1.11.5/build/../pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c:720:Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1cork:断言“流”失败。

以及当前参与该线程的两个类...

股票代码.java

package com.timer;

import java.io.IOException;

 import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class Ticker extends Thread {

private App app;

private String[] soundFiles;

private Ticker() {
}

public Ticker(App app) {
    this.app = app;
    soundFiles = new String[app.getBeatsPerMeasure()];
}

private AudioInputStream stream;

private Clip[] ticks;
AudioFormat format;
DataLine.Info dataLineInfo;

public String setFileNames() {
    for (int i = 0; i < app.getBeatsPerMeasure(); i++) {
        soundFiles[i] = "firstBeatCut.au";
    }
    return "";
}

public String loadArray(int... iArray) {
    if (iArray.length != app.getBeatsPerMeasure()) {
        return "Sorry there was an error.";
    }
    for (int i = 0; i < iArray.length; i++) {
        iArray[i] = i;
        System.out.println(iArray[i]);
    }
    return "";
}

public void tick() {
    long difference, timeTaken, timeAllowedToSleep, before, after;
    long idealTime;

    int i = 0;
    int count = 0;

    ticks = new Clip[app.getBeatsPerMeasure()];

    while (app.isTicking()) {
        System.out.println("Tick...");

        before = System.nanoTime();

        try {

            stream = AudioSystem.getAudioInputStream(this.getClass()
                    .getResource("./firstBeatCut.au"));

        } catch (UnsupportedAudioFileException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (ticks[i] != null && ticks[i].isRunning()) {
            ticks[i].stop();
            if (ticks[i].isActive()) {
                ticks[i].close();
            }
        }

        count++;
        System.out.println("COUNT:: " + count);
        try {
            ticks[i] = (Clip) AudioSystem.getClip();
            if (!ticks[i].isOpen()) {
                ticks[i].open(stream);
            }
        } catch (LineUnavailableException e) {
            System.out.println(e.getMessage());

        } catch (IOException e) {
            e.printStackTrace();
        }
        ticks[i].setMicrosecondPosition(0);

        if (ticks[i].isOpen()) {
            ticks[i].setMicrosecondPosition(0L);
            ticks[i].start();
        } else {
            try {
                ticks[i].open(stream);
            } catch (LineUnavailableException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            ticks[i].setMicrosecondPosition(0);
            ticks[i].start();
        }

        idealTime = app.calculateSleep(app.getBPM())
                - ticks[i].getMicrosecondLength();

        after = System.nanoTime();

        timeTaken = (after - before);
        difference = (idealTime - timeTaken);
        System.out.println("Loop completed in: " + (timeTaken / 1000000L)
                + "\nBeat Duration should be: " + (idealTime / 1000000L)
                + "\nTime left to sleep: " + (difference / 1000000L));

        timeAllowedToSleep = difference;

        if (timeAllowedToSleep > 0) {
            try {
                Thread.currentThread().sleep(timeAllowedToSleep / 1000000L);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println(i);

        stopTick(ticks[i], ++i);
        if (i == app.getBeatsPerMeasure()) {
            i = 0;
        }
    }
}

public void closeTick(Clip tick) {
    tick.close();
}

public void stopTick(Clip tick, int index) {
    tick.stop();
    if (index == 4) {
        closeTick(tick);

        try {
            tick = AudioSystem.getClip();
        } catch (LineUnavailableException e) {
            e.printStackTrace();
        }
    }
}

public void play(Clip tick) {
    tick.setMicrosecondPosition(0L);
    tick.start();
}

public long calculateTimeAllowedToSleep(long sTime, long time) {
    long diff = time - sTime;
    long timeToSleep;
    long ssTime = 60000 / 120;
    timeToSleep = ssTime - diff;
    return timeToSleep;

}

}

ActionHandler.java
package com.timer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ActionHandler implements ActionListener, ChangeListener {

private App app;
Ticker ticker;
Thread t1;
private int beatsInMeasure;
private boolean ticking;

public ActionHandler(final App app) {
    this.app = app;
    this.ticker = new Ticker(app);
    beatsInMeasure = app.getTimeSignature()[0];
    ticking = app.isTicking();
    ticker.loadArray(0,1,2,3);
}

private Runnable doTick = new Runnable() {
    public void run() {
        while (app.isTicking()) {

            ticker.tick();

        }
    }
};

public void actionPerformed(ActionEvent e) {
    JButton b = (JButton) e.getSource();
    if (b == app.getBtnStart()) {
        if (b.getText().equalsIgnoreCase("Start")) {
            app.setStartText("Stop");
            app.resetEnabled(false);
            ticker.setFileNames();
            app.setTicking(true);
            t1 = new Thread(doTick);
            t1.start();
        } else {
            app.setStartText("Start");
            app.resetEnabled(true);
            app.setTicking(false);
            app.setTicking(false);
            try {
                t1.join();
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    } else if (b == app.getBtnReset()) {
        app.reset();
    }
}

@Override
public void stateChanged(ChangeEvent e) {
    JSpinner sp = (JSpinner) e.getSource();
    SpinnerNumberModel model = app.getModel();
    if (sp.getValue() != null) {
        app.calculateSleep(Integer.parseInt(String.valueOf(
                sp.getModel().getValue()).toString()));
    }
}
}

最佳答案

如果您打开一条线,请在每次完成后立即关闭它。我从 Ticker 的 stop 方法中删除了 if 语句,它运行良好。我要 sleep 了,感谢所有评论的人。

关于java - 我的线程恰好循环了 43 次然后抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14135685/

相关文章:

android - 如何通过Android中的耳机发送音频输出?

audio - ffmpeg - 重新混合具有多个音频流的 TS 文件

python - 在python中自动同步两个录音

java - Android ShowcaseView 用法 - 无法将其导入到我的项目中

java - 无法删除 Firebase 中的子节点

java - Firebase 依赖项导致 Gradle 构建错误 - 程序类型已存在

audio - 安装YAAFE后未创建Python_packages,MATLAB和yaafe_extensions目录

java - 将某些字符/键的输入重新映射到 JTextComponent 的最佳方法?

java - JFileChooser 的替代品

ios - MPMoviePlayerController 黑色窗口,不加载音频文件