有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

raspberry pi禁用java中的其他声音

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

}    

共 (1) 个答案

  1. # 1 楼答案

    如评论中所述,我无法就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
        }       
    }
    

    简而言之,每次触发pin状态更改事件时,前一个音频剪辑将停止,并播放新的音频剪辑。你不应该听到任何与此重叠的声音

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

    关于GOTCHA的注意事项

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

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

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