禁用java中的其他声音

禁用java中的其他声音,java,raspberry-pi,javasound,audio,Java,Raspberry Pi,Javasound,Audio,我用Java编写了一个程序,使用pi4j库在单击(物理)按钮时发出声音。这个程序可以工作,但现在它可以交替播放所有声音。我希望当你点击2,3,4或更多的按钮时,你只听到一个声音 这是我希望你能帮助的代码 public class ButtonSoundsProject{ public static void main(String args[]) throws InterruptedException { System.out.println("Toy has been started!

我用Java编写了一个程序,使用pi4j库在单击(物理)按钮时发出声音。这个程序可以工作,但现在它可以交替播放所有声音。我希望当你点击2,3,4或更多的按钮时,你只听到一个声音

这是我希望你能帮助的代码

public class ButtonSoundsProject{
public static void main(String args[]) throws InterruptedException {
    System.out.println("Toy has been started!");

    // create gpio controller
    final GpioController gpio = GpioFactory.getInstance();

    // provision gpio pin #02 as an input pin with its internal pull down resistor enabled
    GpioPinDigitalInput[] pins = {
        gpio.provisionDigitalInputPin(RaspiPin.GPIO_00, PinPullResistance.PULL_DOWN),
        gpio.provisionDigitalInputPin(RaspiPin.GPIO_01, PinPullResistance.PULL_DOWN),
        gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN),
        gpio.provisionDigitalInputPin(RaspiPin.GPIO_03, PinPullResistance.PULL_DOWN),
        gpio.provisionDigitalInputPin(RaspiPin.GPIO_04, PinPullResistance.PULL_DOWN),
        gpio.provisionDigitalInputPin(RaspiPin.GPIO_05, PinPullResistance.PULL_DOWN),};

    final ArrayList<String> soundList = new ArrayList<String>();
    soundList.add("/home/pi/Sounds/Sound1.wav");
    soundList.add("/home/pi/Sounds/Sound2.wav");
    soundList.add("/home/pi/Sounds/Sound3.wav");
    soundList.add("/home/pi/Sounds/Sound4.wav");
    soundList.add("/home/pi/Sounds/Sound5.wav");
    soundList.add("/home/pi/Sounds/Sound6.wav");
    soundList.add("/home/pi/Sounds/Sound7.wav");
    soundList.add("/home/pi/Sounds/Sound8.wav");
    soundList.add("/home/pi/Sounds/Sound9.wav");
    soundList.add("/home/pi/Sounds/Sound10.wav");
    soundList.add("/home/pi/Sounds/Sound11.wav");
    soundList.add("/home/pi/Sounds/Sound12.wav");


    // create and register gpio pin listener
    GpioPinListenerDigital listener = new GpioPinListenerDigital() {
        @Override
        public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
            // display pin state on console

            final int randomNum = 0 + (int) (Math.random() * 12);
            System.out.println(randomNum);

            System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
            InputStream in;
            try {
                System.out.println(soundList.get(randomNum).toString());
                String filepath = soundList.get(randomNum).toString();
                in = new FileInputStream(new File(filepath));
                AudioStream as = new AudioStream(in);
                AudioPlayer.player.start(as);

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

    };

    gpio.addListener(listener, pins);


    for (;;) {
        Thread.sleep(500);
    }
}

}    
公共类按钮声音项目{
公共静态void main(字符串args[])引发InterruptedException{
System.out.println(“玩具已经启动了!”);
//创建gpio控制器
最终GpioController gpio=GpioFactory.getInstance();
//将gpio引脚#02作为输入引脚,并启用其内部下拉电阻器
GPIOPIIndigitalInput[]引脚={
gpio.ProvisioningDigitalInputPin(RaspiPin.gpio_00,PinPullResistance.PULL_DOWN),
gpio.ProvisioningDigitalInputPin(RaspiPin.gpio_01,PinPullResistance.PULL_DOWN),
gpio.ProvisioningDigitalInputPin(RaspiPin.gpio_02,PinPullResistance.PULL_DOWN),
gpio.ProvisioningDigitalInputPin(RaspiPin.gpio_03,PinPullResistance.PULL_DOWN),
gpio.provisionDigitalInputPin(RaspiPin.gpio_04,PinPullResistance.PULL_DOWN),
gpio.provisionDigitalInputPin(RaspiPin.gpio_05,PinPullResistance.PULL_DOWN),};
最终ArrayList声音列表=新ArrayList();
添加(“/home/pi/Sounds/Sound1.wav”);
添加(“/home/pi/Sounds/Sound2.wav”);
添加(“/home/pi/Sounds/Sound3.wav”);
添加(“/home/pi/Sounds/Sound4.wav”);
添加(“/home/pi/Sounds/Sound5.wav”);
添加(“/home/pi/Sounds/Sound6.wav”);
添加(“/home/pi/Sounds/Sound7.wav”);
添加(“/home/pi/Sounds/Sound8.wav”);
添加(“/home/pi/Sounds/Sound9.wav”);
添加(“/home/pi/Sounds/Sound10.wav”);
添加(“/home/pi/Sounds/Sound11.wav”);
添加(“/home/pi/Sounds/Sound12.wav”);
//创建并注册gpio引脚侦听器
GpioPinListenerDigital listener=新的GpioPinListenerDigital(){
@凌驾
public void handlePiopIndicatalStateChangeEvent(GPIOPiIndigitalStateChangeEvent){
//在控制台上显示pin状态
最终int randomNum=0+(int)(Math.random()*12);
System.out.println(randomNum);
System.out.println(“-->GPIO引脚状态更改:”+event.getPin()+“=”+event.getState());
输入流输入;
试一试{
System.out.println(soundList.get(randomNum.toString());
String filepath=soundList.get(randomNum.toString();
in=新文件输入流(新文件(文件路径));
AudioStream as=新的AudioStream(in);
AudioPlayer.player.start(as);
}捕获(例外情况除外){
例如printStackTrace();
}
}
};
addListener(监听器,pins);
对于(;;){
睡眠(500);
}
}
}    
如评论中所述,我无法就
AudioStream
AudioPlayer
类向您提供建议,因为我的JDK中似乎没有这些类。因为我的方法是相似的,我会给你我所拥有的,希望你能从那里得到

基本上,解决方案是停止和/或“静音”该音频剪辑。这就是我如何使用
javax.sound
包实现它的:

private Clip currentAudioClip; // Keep a reference to the current clip being played

public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {

    // Call this every time regardless.
    // If nothing is playing, this will do nothing.
    stopAudio();

    String filepath = soundList.get(randomNum)
    URL soundFileUrl = new File(filePath).toURI().toURL();

    AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFileUrl);

    Line.Info lineInfo = new Line.Info(Clip.class);
    Line line = AudioSystem.getLine(lineInfo);

    currentAudioClip = (Clip) line;
    currentAudioClip.open(audioInputStream);
    audioClip.start();

    // Alternative if you want to loop continuously. Comment out the `.start` line to use this.
    // audioClip.loop(Clip.LOOP_CONTINUOUSLY);
}

public void stopAudio(){
    if(audioClip != null){
        muteLine(); // A gotcha I discovered (see explanation below)
        audioClip.stop();

        // audioClip.loop(0); // if you chose to loop, use this instead of `.stop()`
        audioClip.flush();
        audioClip = null;
    }
}

public void muteLine(){
    BooleanControl muteControl = (BooleanControl) audioClip.getControl(BooleanControl.Type.MUTE);
    if(muteControl != null){
        muteControl.setValue(true); // True to mute the line, false to unmute
    }       
}
简言之,每次触发pin状态更改事件时,前一个音频剪辑将停止,并应播放新的音频剪辑。你不应该听到任何与此重叠的声音

还要注意,这是对我的原始代码的一个轻微修改,所以如果有任何问题,请告诉我

关于GOTCHA的注意事项

我写了一篇关于我遇到的一个奇怪问题的文章。问题是,我发现我的音频剪辑不会停止播放命令。它将继续播放一段看似任意的时间。奇怪的是,我只是在树莓上测试应用程序时才注意到这一点;它在我本地的机器上运行得非常好(甚至在其他几台机器上)

我的问题可能与剪辑的“循环”有关;如果是这样的话,你只是想让剪辑播放它的长度,而不是更远,你可能不会遇到这个问题,你可能可以省去我包含的“静音”代码。然而,如果你观察到同样的问题,至少你有一个解决方案


希望这有帮助,如果您有任何问题,请告诉我。

您使用的是什么库,其中包含
AudioStream
AudioPlayer
类?我在标准Java库中找到了这些方法。我似乎找不到任何Javadoc(尽管我认为它们似乎属于
sun.audio
包)。我知道如何解决你的问题,但我不能就这些课程向你提供建议,因为我不能和他们一起玩,看看他们的表现如何。我的方法与此类似,使用
javax.sound
包;这足够了吗?你用的是什么JDK版本(我的是7)?Paul我的JDK版本也是7。我希望我能给你一个惊喜,但我的声誉还不够高。我会尝试一下,并让你知道它是否有效。谢谢您的时间。@user3460769没问题。你现在应该可以了。让我知道它是如何工作的。我只需要让一切都是静态的,一开始我完全忘记了这一点,我想‘为什么我会有这么多红线’哈哈:)@user3460769哦,对了,因为你主要是这样做的,忘了这一点。我的是一个单独的类,我会实例化它。不管是谁,没关系。只是在处理实际实例等时,不要让一切都是静态的。:)@PaulRitcher我确实把所有东西都弄成了静态的这是个问题吗?