javax.sound.sampled-尝试反复启动音频采样不会';行不通

javax.sound.sampled-尝试反复启动音频采样不会';行不通,java,audio,javasound,javax.sound.sampled,Java,Audio,Javasound,Javax.sound.sampled,我正在编程一个小型鼓序列器,一个罗兰tr808仿制品,有16个步骤/测量和16个仪器(=鼓样本)。用户有一个gui,可以在其中创建16x16模式 但是,如果一个样本连续快速播放多次,它通常只播放一次。比如说,我在第1、5、9和13步得到了一个低音鼓和tempo的130 bpm,它有时只在第1和9步播放bd,有时也在第5和/或13步播放bd。如果样本很短或节奏很慢,则模式中的每一步都正确弹奏的可能性更高。因此,我假设音频线不喜欢它,当我尝试再次播放尚未完成的示例时 但实际上我认为我在代码中已经考虑

我正在编程一个小型鼓序列器,一个罗兰tr808仿制品,有16个步骤/测量和16个仪器(=鼓样本)。用户有一个gui,可以在其中创建16x16模式

但是,如果一个样本连续快速播放多次,它通常只播放一次。比如说,我在第1、5、9和13步得到了一个低音鼓和tempo的130 bpm,它有时只在第1和9步播放bd,有时也在第5和/或13步播放bd。如果样本很短或节奏很慢,则模式中的每一步都正确弹奏的可能性更高。因此,我假设音频线不喜欢它,当我尝试再次播放尚未完成的示例时

但实际上我认为我在代码中已经考虑到了这一点。如果有人告诉我我的代码出了什么问题,我会非常感激

这是我的完整代码,由Andrew Thompson建议,经过修改,从互联网上获取了一些示例。不过,加载它们需要一些时间。导致问题的部分可能是Instrument类中的play()方法:

package testbox;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.sound.sampled.*;


public class boomboxtest {
    public static void main(String[] args) {

        Sequencer seq = new Sequencer();
        //bassdrum
        seq.toggleInstrument(0,0);
        seq.toggleInstrument(0,4);
        seq.toggleInstrument(0,8);
        seq.toggleInstrument(0,12);

        //snare
        seq.toggleInstrument(1,4);
        seq.toggleInstrument(1,12);

        //Hihat
        seq.toggleInstrument(2, 2);
        seq.toggleInstrument(2, 6);
        seq.toggleInstrument(2, 10);

        //Bongo
        seq.toggleInstrument(3, 6);
        seq.toggleInstrument(3, 10);

        seq.setTempo(130);
        seq.play();

    }
}


class Sequencer {
    private Mixer mixer;
    private List<SequencerListener> listeners = new ArrayList<SequencerListener>();
    public static final int INSTR_COUNT = 4;
    private int tempo_bpm = 120;
    private ExecutorService executor;
    private int current_step = 0;
    private int current_max_step = 16;
    private boolean[][] pattern = new boolean[32][INSTR_COUNT];
    private ArrayList<Instrument> instruments;
    Line[] lines = new Line[16];
    private SequencerEngine seq;

    private String[] filenames = {"http://www.canadianmusicartists.com/sample/kick_02.wav", "http://www.canadianmusicartists.com/sample/snare01.wav", "http://www.canadianmusicartists.com/sample/H_closedhat_01.wav", "http://www.canadianmusicartists.com/sample/bongo01.wav"};
    public Sequencer() {
        seq = new SequencerEngine();
        try{ 
            Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
            mixer = AudioSystem.getMixer(mixerInfo[0]);
        } catch (Exception e) {e.printStackTrace();}


        instruments = new ArrayList<Instrument>(INSTR_COUNT);
        for (int i = 0; i < INSTR_COUNT; i++) {
            System.out.println("Loading instrument " + i);
            Instrument instr = new Instrument(filenames[i], mixer);
            instruments.add(instr);
            lines[i] = instr.getLine();
        }
        syncMixer();

        executor = Executors.newCachedThreadPool();
        executor.submit(seq);
    }




    public void syncMixer() {
        if (mixer.isSynchronizationSupported(lines, false)) {
            mixer.synchronize(lines, false);
        } else {
            System.out.println("No hay synchronisado");
        }
    }

    public boolean isPlaying() {
        return seq.getRunning();
    }

    public boolean toggleInstrument (int instrument, int beat) {
        pattern[beat][instrument] = !pattern[beat][instrument];
        return pattern[beat][instrument];
    }

    public void play() {
        seq.toggleRun(true);
    }

    public void pause() {
        seq.toggleRun(false);
    }

    public void stop() {
        pause();
        setCurrent_step(0);
    }

    public int getTempo() {
        return tempo_bpm;
    }

    public void setTempo(int tempo) {
        if (tempo < 30) {
            tempo = 30;
        } else if (tempo > 200) {
            tempo = 200;
        } else {
            this.tempo_bpm = tempo;
        }
    }

    public int getCurrent_step() {
        return current_step;
    }

    public void setCurrent_step(int current_step) {
        this.current_step = current_step;
    }

    public boolean[][] getPattern() {
        return pattern;
    }

    public void kill() {
        seq.kill();
        executor.shutdownNow();
    }

    public void addListener(SequencerListener toAdd) {
        listeners.add(toAdd);
    }

    public class SequencerEngine implements Runnable{
        private boolean running;
        private boolean alive = true;

        public void run() {
            while( getAlive()) {
                while (getRunning()) {
                    if (current_step >= current_max_step) {
                        current_step = 0;
                    }



                    for (; current_step < current_max_step ; current_step++) {
                        stepListen();                       
                        if(!getRunning()) {
                            break;
                        }
                        long time = System.currentTimeMillis();
                        long steptime = 60000/(4*tempo_bpm);


                        for (int k = 0; k < INSTR_COUNT; k++) {
                            if (pattern[current_step][k]) {
                                instruments.get(k).play();  
                            }
                        }

                        while((System.currentTimeMillis()-time) < steptime) {}
                    }
                }

            }
        }


        public void stepListen() {
            for (SequencerListener sl : listeners) {
                sl.stepEvent(current_step);
            }
        }

        public boolean getRunning() {
            return running;
        }

        public boolean getAlive() {
            return alive;
        }

        public void toggleRun(boolean toggle) {
            running = toggle;
        }

        public void kill() {
            alive = false;
        }
    }
}

class Instrument {
    private String name;
    private File soundFile;
    private AudioInputStream stream;
    private AudioFormat format;
    private DataLine.Info info;
    private Clip clip;
    private Mixer mixer;

    public Instrument(String filename, Mixer mixer ) {
        this.name = filename;
        try {
            //soundFile = new File("sounds/" + filename);

            URL url = new URL(filename);

            this.mixer = mixer;

            //stream = AudioSystem.getAudioInputStream(soundFile);
            stream = AudioSystem.getAudioInputStream(url);
            format = stream.getFormat();
            info = new DataLine.Info(Clip.class, format);
            clip = (Clip) mixer.getLine(info);
            clip.open(stream);

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



    public void play() {
        clip.stop();
        clip.setFramePosition(0);
        clip.start();
    }

    public Line getLine() {
        return clip;
    }
}

interface SequencerListener {
    void stepEvent(int current_step);
}
封装测试盒;
导入java.io.File;
导入java.net.URL;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入javax.sound.sampled.*;
公共类测试{
公共静态void main(字符串[]args){
Sequencer seq=新的Sequencer();
//低音鼓
顺序切换仪表(0,0);
顺序切换仪表(0,4);
顺序切换仪表(0,8);
顺序切换仪表(0,12);
//圈套
顺序切换仪表(1,4);
顺序切换仪表(1,12);
//Hihat
顺序切换仪表(2,2);
顺序切换仪表(2,6);
顺序切换仪表(2,10);
//邦戈
顺序切换仪表(3,6);
顺序切换仪表(3,10);
seq.setTempo(130);
seq.play();
}
}
类序列器{
专用混音器;
私有列表侦听器=新的ArrayList();
公共静态最终仪表计数=4;
私人节奏=120;
私人遗嘱执行人;
专用int电流_步长=0;
专用int电流_最大_步长=16;
私有布尔[][]模式=新布尔[32][INSTR_COUNT];
私人ArrayList文书;
第[]行=新行[16];
私有序列工程顺序;
私有字符串[]文件名={”http://www.canadianmusicartists.com/sample/kick_02.wav", "http://www.canadianmusicartists.com/sample/snare01.wav", "http://www.canadianmusicartists.com/sample/H_closedhat_01.wav", "http://www.canadianmusicartists.com/sample/bongo01.wav"};
公共音序器(){
seq=新序列工程();
试试{
Mixer.Info[]mixerInfo=AudioSystem.getMixerInfo();
mixer=AudioSystem.getMixer(mixerInfo[0]);
}catch(异常e){e.printStackTrace();}
仪器=新阵列列表(仪器计数);
对于(int i=0;i200){
节奏=200;
}否则{
this.tempo_bpm=节奏;
}
}
public int getCurrent_步骤(){
返回电流步进;
}
公共无效设置当前步骤(int当前步骤){
此.current\u step=current\u step;
}
公共布尔值[][]getPattern(){
回报模式;
}
公共空杀(){
seq.kill();
执行者。关机现在();
}
public void addListener(SequencerListener to添加){
添加(toAdd);
}
公共类SequencerEngine实现Runnable{
私有布尔运行;
private boolean alive=true;
公开募捐{
while(getAlive()){
while(getRunning()){
如果(当前步数>=当前最大步数){
当前步进=0;
}
对于(;当前步长<当前最大步长;当前步长++){
stepListen();
如果(!getRunning()){
打破
}
长时间=System.currentTimeMillis();
长步长=60000/(4*tempo_bpm);
对于(int k=0;k