Java 如何为循环中的每次迭代播放声音?

Posted

技术标签:

【中文标题】Java 如何为循环中的每次迭代播放声音?【英文标题】:Java How would I play a sound for every iteration in a loop? 【发布时间】:2012-03-31 15:59:11 【问题描述】:

例子:

For(int i=0; i<4; i++)
playSound("Sound.wav");

我有以下课程:

主要

import java.io.IOException;
import java.util.*;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class MainClass 

    public static void main (String [] args) 
    throws UnsupportedAudioFileException, IOException, LineUnavailableException, InterruptedException
    

        Thread main = new Thread();
        Thread sound = new Thread();
        main.start();

        Scanner in = new Scanner (System.in);

        Encode MorseCode = new Encode();


        System.out.print("Enter a Phrase: ");
        String input = in.next();

        String selected = "";
        String converted = "";
        String morse = "";


        for (int i = 0; i < input.length(); i++) 
        
            //for every character instantiate a new sound object
            playSound ps = new playSound();

            //Select the next character
            selected = input.charAt(i) +"";

            // Convert the character
            converted = MorseCode.getEncode(selected);

            //Trying to  pause the main thread until the sound clip finishes
            if(converted == ".")
            
                //set main thread to sleep for duration of sound clip
                //main.sleep(ps.getWait()*1000);
                main.yield();

                //start other thread to complete the task of playing the soudn
                sound.start();
                ps.playBlip();
               
            main.join();
            morse = morse +" "+converted;
            converted = "";
        

        System.out.print("Morse Code: "+morse);

    

编码器

public class Encode

    public Encode()

    public String getEncode(String toEncode)
    
        String morse = toEncode;

        if (toEncode.equalsIgnoreCase("a"))
            morse = ".-";
        if (toEncode.equalsIgnoreCase("b"))
            morse = "-...";
        if (toEncode.equalsIgnoreCase("c"))
            morse = "-.-.";
        if (toEncode.equalsIgnoreCase("d"))
            morse = "-..";
        if (toEncode.equalsIgnoreCase("e"))
            morse = ".";
        if (toEncode.equalsIgnoreCase("f"))
            morse = "..-.";
        if (toEncode.equalsIgnoreCase("g"))
            morse = "--.";
        if (toEncode.equalsIgnoreCase("h"))
            morse = "....";
        if (toEncode.equalsIgnoreCase("i"))
            morse = "..";
        if (toEncode.equalsIgnoreCase("j"))
            morse = ".---";
        if (toEncode.equalsIgnoreCase("k"))
            morse = "-.-";
        if (toEncode.equalsIgnoreCase("l"))
            morse = ".-..";
        if (toEncode.equalsIgnoreCase("m"))
            morse = "--";
        if (toEncode.equalsIgnoreCase("n"))
            morse = "-.";
        if (toEncode.equalsIgnoreCase("o"))
            morse = "---";
        if (toEncode.equalsIgnoreCase("p"))
            morse = ".--.";
        if (toEncode.equalsIgnoreCase("q"))
            morse = "--.-";
        if (toEncode.equalsIgnoreCase("r"))
            morse = ".-.";
        if (toEncode.equalsIgnoreCase("s"))
            morse = "...";
        if (toEncode.equalsIgnoreCase("t"))
            morse = "-";
        if (toEncode.equalsIgnoreCase("u"))
            morse = "..-";
        if (toEncode.equalsIgnoreCase("v"))
            morse = "...-";
        if (toEncode.equalsIgnoreCase("w"))
            morse = ".--";
        if (toEncode.equalsIgnoreCase("x"))
            morse = "-..-";
        if (toEncode.equalsIgnoreCase("y"))
            morse = "-.--";
        if (toEncode.equalsIgnoreCase("z"))
            morse = "--..";
        if (toEncode.equalsIgnoreCase("0"))
            morse = "-----";
        if (toEncode.equalsIgnoreCase("1"))
            morse = ".----";
        if (toEncode.equalsIgnoreCase("2"))
            morse = "..---";
        if (toEncode.equalsIgnoreCase("3"))
            morse = "...--";
        if (toEncode.equalsIgnoreCase("4"))
            morse = "....-";
        if (toEncode.equalsIgnoreCase("5"))
            morse = ".....";
        if (toEncode.equalsIgnoreCase("6"))
            morse = "-....";
        if (toEncode.equalsIgnoreCase("7"))
            morse = "--...";
        if (toEncode.equalsIgnoreCase("8"))
            morse = "---..";
        if (toEncode.equalsIgnoreCase("9"))
            morse = "----.";
        if (toEncode.equalsIgnoreCase("."))
            morse = ".-.-";
        if (toEncode.equalsIgnoreCase(","))
            morse = "--..--";
        if (toEncode.equalsIgnoreCase("?"))
            morse = "..--..";

        return morse;
    

播放声音

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.Audiosystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;


public class playSound 


    public playSound()

    public void playBlip() throws UnsupportedAudioFileException, IOException, LineUnavailableException
    

        File soundFile = new File("blip.wav");
        AudioInputStream sound = AudioSystem.getAudioInputStream(soundFile);

        DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
        Clip clip = (Clip) AudioSystem.getLine(info);
        clip.open(sound);

        clip.addLineListener( new LineListener() 
        
            public void update(LineEvent event) 
            
                if (event.getType() == LineEvent.Type.STOP) 
                
                    event.getLine().close();
                    System.exit(0);
                
            
        );

        clip.start();
        clip.drain();
        clip.close();
    
    public int getSoundDurationForThreadWait() throws UnsupportedAudioFileException, IOException, LineUnavailableException
    
        File soundFile = new File("blip.wav");
        AudioInputStream sound = AudioSystem.getAudioInputStream(soundFile);

        DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
        Clip clip = (Clip) AudioSystem.getLine(info);
        clip.open(sound);

        //making this method return milliseconds since threads waits are in this unit
        return (int) (clip.getMicrosecondLength()/1000);

    
        

问题 程序只播放一次声音。我怀疑存在线程阻塞问题。

期望的结果:

输入短语:你好

按照摩尔斯电码的预期播放音频

【问题讨论】:

@Osw 它只播放一次。我认为theres线程问题。主线程应该等到每个音频播放,但它存在于第一次播放之后。 我看不到您实际在等待音频播放的任何地方,因此它不会全部播放。 @Lattyware 你能提供答案来帮助我吗?非常感谢 “按照摩尔斯电码的方式播放音频” 对于瞬时声波发生器,请参阅Beeper。将字母转换为开/关时间代码是另一回事,但我可能会使用 javax.swing.Timerjava.util.Timer 【参考方案1】:

具体的问题是你的playBlip()方法被设计成在整个程序到达声音片段的结尾时终止:

        clip.addLineListener( new LineListener() 
        
            public void update(LineEvent event) 
            
                if (event.getType() == LineEvent.Type.STOP) 
                
                    event.getLine().close();
                    System.exit(0); // <------------ terminate the JVM
                
            
        );

但总的来说,我认为您应该更仔细地检查您的方法;除了混淆之外,您有很多似乎没有任何用途的代码。例如,您有两个Thread 实例mainsound,它们的设计目的是完全不做任何事情:调用main.start() 将启动一个立即退出的新线程。

【讨论】:

好的,所以我删除了 System.exit(0)。应该如何处理线程来处理播放声音? @***:你为什么要这样做? drain 是同步的;这似乎正是你想要的。您想等到声音播放完毕,不是吗? Ruakh 是的,这正是我想要的,我只是不确定 api 处理的是什么。

以上是关于Java 如何为循环中的每次迭代播放声音?的主要内容,如果未能解决你的问题,请参考以下文章

Java:多次播放声音

使用 javax.sound.sampled.Clip 在游戏中播放、循环和停止多个声音。意外错误

windows phone 7中的循环声音

在Dreamweaver里如何为按钮的点击添加声音?

如何延迟 For 循环直到声音在 Swift 中播放完毕

暂停 Web Audio API 声音播放