Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我想在彼此之后播放声音,但要让它们等到第一个声音完成。我该怎么做?_Java_Audio_Beep - Fatal编程技术网

Java 我想在彼此之后播放声音,但要让它们等到第一个声音完成。我该怎么做?

Java 我想在彼此之后播放声音,但要让它们等到第一个声音完成。我该怎么做?,java,audio,beep,Java,Audio,Beep,我目前正在做一个简单的莫尔斯电码翻译,我希望我的代码在“-”上播放一个长的嘟嘟声,在“.”上播放一个短的嘟嘟声,当然这是一个接一个地完成的。但我的程序目前正在同时播放。我做错了什么 我尝试添加onCompletionListener,但Netbeans 8.1出现错误,无法解决问题 //Play the morse code public void playButton(ActionEvent event){ String morse = mcTextField.getText(

我目前正在做一个简单的莫尔斯电码翻译,我希望我的代码在“-”上播放一个长的嘟嘟声,在“.”上播放一个短的嘟嘟声,当然这是一个接一个地完成的。但我的程序目前正在同时播放。我做错了什么

我尝试添加onCompletionListener,但Netbeans 8.1出现错误,无法解决问题

    //Play the morse code
public void playButton(ActionEvent event){
    String morse = mcTextField.getText();
    char[] charArray = morse.toCharArray();
    for(int x = 0; x<charArray.length; x++){

        if(charArray[x] == '.'){
            playBeep(shortBeep);
        }
        else if(charArray[x] == '-'){
            playBeep(longBeep);
        }
        else{
            sleep(500);
        }
        sleep(1000);
    }
    }



private void playBeep(String name){
    String musicFile = name;   

    Media sound = new Media(new File(musicFile).toURI().toString());
    MediaPlayer mediaPlayer = new MediaPlayer(sound);
    mediaPlayer.play();

    sleep(1000);   

}

 private void sleep(int duration){
    try{
        Thread.sleep(duration);
    }catch(Exception e){
        System.out.println("Did not work."+e);
    }
}
//播放莫尔斯电码
公共无效播放按钮(ActionEvent事件){
字符串morse=mcTextField.getText();
char[]charArray=morse.toCharArray();
对于(int x=0;x这可以利用,但基本思想应该适用于大多数音频库,只要提供“播放结束”通知

这样做的目的是,将要播放的序列放入一个队列,它播放下一个音调,等待它完成并播放下一个音调,直到队列中不再有音调

因为
AudioClip
在它自己的线程中播放,所以它使用另一个
thread
来允许示例“等待”序列完全播放。如果您是从UI框架中执行此操作,那么您就可以避免额外的开销

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class Test {

    public static void main(String[] args) throws InterruptedException {
        try {
            new Test();
        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException ex) {
            ex.printStackTrace();
        }
    }

    public Test() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
        Sound longBeep = new Sound(new File(...));
        Sound shortBeep = new Sound(new File(...));

        List<Sound> message = new ArrayList<Sound>(9);
        message.add(shortBeep);
        message.add(shortBeep);
        message.add(shortBeep);
        message.add(longBeep);
        message.add(longBeep);
        message.add(longBeep);
        message.add(shortBeep);
        message.add(shortBeep);
        message.add(shortBeep);

        play(message);
    }

    public void play(List<Sound> message) {
        try {
            List<Sound> queue = new ArrayList<>(message);
            Transmit transmit = new Transmit(message);
            Thread thread = new Thread(transmit);
            thread.start();
            transmit.waitFor();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    public class Transmit implements Runnable {

        private List<Sound> queue;
        private ReentrantLock lock;
        private Condition playCondition;

        public Transmit(List<Sound> message) {
            this.queue = new ArrayList<>(message);

            lock = new ReentrantLock();
            playCondition = lock.newCondition();
        }

        @Override
        public void run() {
            playNext();
        }

        public void waitFor() throws InterruptedException {
            lock.lock();
            if (!queue.isEmpty()) {
                try {
                    playCondition.await();
                } finally {
                    lock.unlock();
                }
            } else {
                lock.unlock();
            }
        }

        protected void playNext() {
            if (queue.size() > 0) {
                lock.lock();
                try {
                    System.out.println("Play Next");
                    Sound sound = queue.remove(0);
                    sound.addLineListener(new LineListener() {
                        @Override
                        public void update(LineEvent event) {
                            if (event.getType().equals(LineEvent.Type.STOP)) {
                                sound.removeLineListener(this);
                                System.out.println("Audio Completed");
                                playNext();
                            }
                        }
                    });
                    sound.play();
                } finally {
                    lock.unlock();
                }
            } else {
                lock.lock();
                try {
                    playCondition.signalAll();
                } finally {
                    lock.unlock();
                }
            }
        }

    }

    public class Sound {

        private Clip audio;

        public Sound(AudioInputStream audioInputStream) throws LineUnavailableException, IOException {
            audio = AudioSystem.getClip();
            audio.open(audioInputStream);
        }

        public Sound(File file) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
            this(AudioSystem.getAudioInputStream(file));
        }

        public Sound(URL url) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
            this(AudioSystem.getAudioInputStream(url));
        }

        public Sound(InputStream stream) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
            this(AudioSystem.getAudioInputStream(stream));
        }

        public void close() {
            Objects.requireNonNull(audio, "Audio Clip has not been initalised");
            audio.close();
        }

        public void play() {
            Objects.requireNonNull(audio, "Audio Clip has not been initalised");
            audio.setFramePosition(0);
            audio.start();
        }

        public void addLineListener(LineListener listener) {
            Objects.requireNonNull(audio, "Audio Clip has not been initalised");
            audio.addLineListener(listener);
        }

        public void removeLineListener(LineListener listener) {
            Objects.requireNonNull(audio, "Audio Clip has not been initalised");
            audio.removeLineListener(listener);
        }
    }

}
导入java.io.File;
导入java.io.IOException;
导入java.io.InputStream;
导入java.net.URL;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Objects;
导入java.util.concurrent.locks.Condition;
导入java.util.concurrent.locks.ReentrantLock;
导入javax.sound.sampled.AudioInputStream;
导入javax.sound.sampled.AudioSystem;
导入javax.sound.sampled.Clip;
导入javax.sound.sampled.LineEvent;
导入javax.sound.sampled.LineListener;
导入javax.sound.sampled.LineUnavailableException;
导入javax.sound.sampled.unsupportDaudioFileException;
公开课考试{
公共静态void main(字符串[]args)引发InterruptedException{
试一试{
新测试();
}捕获(不支持DaudioFileException | IOException | LineUnavailableException ex){
例如printStackTrace();
}
}
public Test()引发不支持的DaudioFileException、IOException、LineUnavailableException{
Sound longBeep=新声音(新文件(…);
Sound shortBeep=新声音(新文件(…);
列表消息=新的ArrayList(9);
message.add(shortBeep);
message.add(shortBeep);
message.add(shortBeep);
message.add(longBeep);
message.add(longBeep);
message.add(longBeep);
message.add(shortBeep);
message.add(shortBeep);
message.add(shortBeep);
播放(信息);
}
公共无效播放(列表消息){
试一试{
列表队列=新的ArrayList(消息);
传输=新传输(消息);
螺纹=新螺纹(传输);
thread.start();
transmit.waitFor();
}捕获(中断异常例外){
例如printStackTrace();
}
}
公共类传输实现可运行{
私有列表队列;
私有重入锁;
私人条件;
公共传输(列表消息){
this.queue=newarraylist(消息);
锁=新的可重入锁();
playCondition=lock.newCondition();
}
@凌驾
公开募捐{
playNext();
}
public void waitFor()引发InterruptedException{
lock.lock();
如果(!queue.isEmpty()){
试一试{
游戏条件。等待();
}最后{
lock.unlock();
}
}否则{
lock.unlock();
}
}
受保护的void playNext(){
if(queue.size()>0){
lock.lock();
试一试{
System.out.println(“播放下一步”);
声音=队列。删除(0);
addLineListener(新的LineListener(){
@凌驾
公共作废更新(LineEvent事件){
if(event.getType().equals(LineEvent.Type.STOP)){
声音。移除侦听器(此);
System.out.println(“音频完成”);
playNext();
}
}
});
声音。播放();
}最后{
lock.unlock();
}
}否则{
lock.lock();
试一试{
playCondition.signalAll();
}最后{
lock.unlock();
}
}
}
}
公共级音响{
私人剪辑音频;
公共声音(AudioInputStream AudioInputStream)引发LineUnavailableException,IOException{
audio=AudioSystem.getClip();
打开(音频输入流);
}
公共声音(文件文件)引发不支持的DaudioFileException、IOException、LineUnavailableException{
这个(AudioSystem.getAudioInputStream(文件));
}
公共声音(URL)引发不支持的DaudioFileException、IOException、LineUnavailableException{
这个(AudioSystem.getAudioInputStream(url));
}
公共声音(InputStream流)引发不支持的DaudioFileException、IOException、LineUnavailableException{
这个(AudioSystem.getAudioInputStream(stream));
}
公众假期结束(){
对象.requirennull(音频,“音频剪辑尚未初始化”);
audio.close();
}
公共游戏{
对象.requirennull(音频,“音频剪辑尚未初始化”);
音频。设置帧位置(0);
audio.start();
}
公共图书馆