2014-04-23 117 views
2

我使用pi4j lib在Java中编写了一个程序,在单击(物理)按钮时发出声音。这个节目的作品,但它现在可以互换所有的声音。我希望当你点击2,3,4或更多的按钮时,你只能听到一个声音。禁用java中的其他声音

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

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); 
    } 
} 

}  
+0

你使用的是哪个库,包含'AudioStream'和'AudioPlayer'类? –

+0

我在标准的Java库中找到了这些方法。 – user3460769

+0

我似乎无法找到任何Javadocs(尽管它们似乎属于我认为的'sun.audio'软件包)。我知道如何解决你的问题,但我不能就这些课程给你提供建议,因为我不能和他们一起玩,看看他们的表现如何。我的方法类似,但使用'javax.sound'包;这足够吗? –

回答

0

正如评论所说,我不能给你建议有关AudioStreamAudioPlayer类,因为我似乎并不具备那些在我的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 
    }  
} 

总之,每一个引脚状态改变事件被触发时,前面的音频片段将被停止,一个新的应发挥。你不应该有任何重叠的声音。

另外请注意,这是我原来的代码稍加修改,所以让我知道,如果有任何问题,

注意有关GOTCHA

我在Raspberry PI Stackexchange在写a question约我遇到一个奇怪的问题。问题是,我发现我的音频剪辑不会停止播放命令。它会继续玩一个看似任意的时间。奇怪的是,我只是在测试树莓上的应用程序时才观察到这一点;它在我的本地机器上(甚至在其他几台机器上)工作得非常好。

这可能是我的问题与我的剪辑的“循环”有关;如果是这种情况,并且您只是希望剪辑能够长时间播放而没有进一步播放,那么您可能不会遇到该问题,并且您可能无需使用包含的“静音”代码。但是,如果你确实观察到同样的问题,至少你有一个解决方案。

希望这可以帮助,让我知道如果您有任何问题。

+0

我希望我能给你一个提醒,但我的声望还不够高。我会尝试一下,让它知道它是否有效。感谢您的时间。 – user3460769

+0

@ user3460769没问题。你应该能够现在。让我知道它是如何工作的。 –

+0

我不得不把所有东西都变成静态的,一开始我完全忘记了这一点,我就像'为什么我会得到这么多红线'哈哈:) – user3460769