MultiThreading和声音问题

时间:2016-04-29 22:16:47

标签: java multithreading audio

在线查看之后,我发现了一个类的简单示例,它显示了三个左右的线程同时工作。但我似乎无法将其纳入我的计划。我正在制作一个声音板,利用数字键盘上的1-9键,按下时应该播放声音位,但仍然允许其他键发出按下的声音或识别它已被释放并停止播放。但即使(我认为)我有一个多线程系统设置,一个线程完全控制程序,播放一个音频文件完成。

这是程序的主要内容:一个实现Runnable的简单框架,在Launcher类中创建并启动。它有“圆”对象,在帧上数字键盘的位置显示红色圆圈,如果按下相应的数字,则变为蓝色。它还包含一个实现Runnable的SoundButton ArrayList。

框:

public class Frame extends JFrame implements Runnable{
private static final long serialVersionUID = 1L;
private Pane pane;
private ArrayList<Circle> c;
private ArrayList<SoundButton> SB;
private KeyManager keyManager;

public Frame(ArrayList<SoundButton> soundButton){

    keyManager = new KeyManager();
    this.addKeyListener(keyManager);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.getContentPane().setPreferredSize(new Dimension(400, 400));
    this.pack();
    this.setLocationRelativeTo(null);

    pane = new Pane();
    this.add(pane);

    c = new ArrayList<Circle>();
    SB = soundButton;

    c.add(new Circle(20, 140));
    c.add(new Circle(80, 140));
    c.add(new Circle(140, 140));
    c.add(new Circle(20, 80));
    c.add(new Circle(80, 80));
    c.add(new Circle(140, 80));
    c.add(new Circle(20, 20));
    c.add(new Circle(80, 20));
    c.add(new Circle(140, 20));

    this.setVisible(true);
}

public void init(){
    pane.draw(c);
}

public void update(){
    pane.draw(c);
    keyManager.update();
    if(keyManager.isNine()){
        c.get(8).press();
        SB.get(0).start();
    }
    else{
        c.get(8).release();
        SB.get(0).stop();
    }
    if(keyManager.isEight()){
        c.get(7).press();
        SB.get(1).start();
    }
    else{
        c.get(7).release();
        SB.get(1).stop();
    }
    if(keyManager.isSeven()){
        c.get(6).press();
    }
    else{
        c.get(6).release();
    }
    if(keyManager.isSix()){
        c.get(5).press();
    }
    else{
        c.get(5).release();
    }
    if(keyManager.isFive()){
        c.get(4).press();
    }
    else{
        c.get(4).release();
    }
    if(keyManager.isFour()){
        c.get(3).press();
    }
    else{
        c.get(3).release();
    }
    if(keyManager.isThree()){
        c.get(2).press();
    }
    else{
        c.get(2).release();
    }
    if(keyManager.isTwo()){
        c.get(1).press();
    }
    else{
        c.get(1).release();
    }
    if(keyManager.isOne()){
        c.get(0).press();
    }
    else{
        c.get(0).release();
    }
}


public void run() {

    init();

    int fps = 60;
    double timePerUpdate = 1000000000/fps;
    double delta = 0;
    long now;
    long lastTime= System.nanoTime();
    long timer = 0;
    int updates = 0;

    while(true){
        now = System.nanoTime();
        delta += (now - lastTime) / timePerUpdate;
        timer+= now - lastTime; 
        lastTime = now;

        if(delta >= 1){
            update();
            updates ++;
            delta--;
        }

        if(timer >= 1000000000){
            //System.out.println("Updates and Frames: "+ updates);
            updates = 0;
            timer = 0;
        }

    }
}

}

SoundButton:

public class SoundButton implements Runnable{

private AudioPlayer sound;
private boolean running = false;
private Thread thread;

public SoundButton(String path){
    sound = new AudioPlayer(path);
}
@Override
public void run() {

}

public synchronized void start(){
    if(running){
        return; 
    }
    else{
    running = true;
    thread = new Thread(this);
    thread.start();
    sound.play();
    }
}

public synchronized void stop(){
    if(!running)
        return; 
    running = false;
    sound.stop();
    try {
        thread.join();
    } catch (InterruptedException e) {

        e.printStackTrace();
    }


}

}

发射器:

public class Launcher {


public static void main(String[] args){
    ArrayList<SoundButton> SB = new ArrayList<SoundButton>();
    SB.add(new SoundButton("/sound/sound1.mp3"));
    SB.add(new SoundButton("/sound/sound2.mp3"));
    Frame f = new Frame(SB);
    Thread t = new Thread(f);
    t.start();

}

}

如果需要,我的AudioPlayer类:

public class AudioPlayer 

{
    私人剪辑片段;

public AudioPlayer(String s)
{
    try
    {
        AudioInputStream ais = AudioSystem.getAudioInputStream(
                                getClass().getResourceAsStream(s));

            AudioFormat baseFormat = ais.getFormat();
            AudioFormat decodeFormat = new AudioFormat(
                    AudioFormat.Encoding.PCM_SIGNED,
                    baseFormat.getSampleRate(),
                    16,
                    baseFormat.getChannels(),
                    baseFormat.getChannels() * 2,
                    baseFormat.getSampleRate(),
                    false
                    );

        AudioInputStream dais = AudioSystem.getAudioInputStream(
                                decodeFormat, ais);
        clip = AudioSystem.getClip();
        clip.open(dais);

    }
    catch(Exception e)
    {
        e.printStackTrace();
    }   
}

public void play()
{
    if (clip == null)
    {
        System.out.print("null");
        return;
    }
    stop();
    clip.setFramePosition(0);
    clip.start();
    System.out.println("Drain...");
    clip.drain();
    System.out.println("...Drained");
}
public void stop()
{
    if (clip.isRunning())
    {
        clip.stop();
    }
}
public void close()
{
    stop();
    clip.close();
}

}

1 个答案:

答案 0 :(得分:0)

这是一个简单的修复,将SoundButton中start方法中的sound.play()移动到run方法而不是start方法。