Utilisation de javax.son.échantillonner.Clip pour jouer, boucle, et arrêter mutiple sons dans un jeu. Des Erreurs Inattendues


J'essaie de jouer deux sons wav à la fois pendant un jeu (musique de fond et un effet). J'ai d'abord construit ce morceau de code en utilisant un autre gestionnaire audio en java qui gérerait la lecture, l'arrêt et la boucle du son. Cette construction jouerait la musique de fond ou l'effet, mais un seul à la fois. J'ai regardé autour d'Internet et on m'a dit d'utiliser javax.son.échantillonner.Clip pour gérer les sons donc réutilisé la même construction (play, stop, loop) mais commuté pour utiliser javax.son.échantillonner.Clip. Maintenant, je suis complètement perdu. D'après ce que j'ai lu jusqu'à présent, j'ai tout fait correctement et je n'obtiens aucune erreur dans l'éditeur eclipse, mais lorsque je l'exécute, j'obtiens l'une des deux erreurs. Dans eclipse (fonctionnant sous Linux), une exception LineUnavailableException est levée. Dans eclipse (fonctionnant sous Windows 7), j'obtiens un java.lang.NullPointerException dans la section loop () de ce code. Si vous pouviez me montrer ce que je fais mal ou me diriger vers une documentation pertinente, je l'apprécierais. Je suis en supposant que son quelque chose avec mon code qui gère les exceptions mais je ne suis pas sûr. Si vous voyez d'autres erreurs de code hideuses, faites-le moi savoir que je m'efforce d'être le meilleur programmeur possible et que j'apprécie vraiment les critiques constructives. Je vous remercie pour votre temps.

    import java.io.File;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import javax.sound.sampled.AudioInputStream;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.Clip;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.UnsupportedAudioFileException;

    /**
     * Handles play, pause, and looping of sounds for the game.
     * @author Tyler Thomas
     *
     */
    public class Sound {
        private Clip myClip;
        public Sound(String fileName) {
                try {
                    File file = new File(fileName);
                    if (file.exists()) {
                        Clip myClip = AudioSystem.getClip();
                        AudioInputStream ais = AudioSystem.getAudioInputStream(file.toURI().toURL());
                        myClip.open(ais);
                    }
                    else {
                        throw new RuntimeException("Sound: file not found: " + fileName);
                    }
                }
                catch (MalformedURLException e) {
                    throw new RuntimeException("Sound: Malformed URL: " + e);
                }
                catch (UnsupportedAudioFileException e) {
                    throw new RuntimeException("Sound: Unsupported Audio File: " + e);
                }
                catch (IOException e) {
                    throw new RuntimeException("Sound: Input/Output Error: " + e);
                }
                catch (LineUnavailableException e) {
                    throw new RuntimeException("Sound: Line Unavailable: " + e);
                }
        }
        public void play(){
            myClip.setFramePosition(0);  // Must always rewind!
            myClip.loop(0);
            myClip.start();
        }
        public void loop(){
            myClip.loop(Clip.LOOP_CONTINUOUSLY);
        }
        public void stop(){
            myClip.stop();
        }
    }
Author: T. Thomas, 2012-08-12

2 answers

J'ai pu faire fonctionner le code et maintenant avoir une meilleure compréhension des Clips. La page qui m'a le plus aidé était http://www3.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html il décompose tout et m'a aidé à voir où j'ai fait des erreurs. Voici mon code de travail final. Comme avant, si vous voyez des erreurs horribles ou des vues dans la logique ou le style, faites-le moi savoir.

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
 * Handles playing, stoping, and looping of sounds for the game.
 * @author Tyler Thomas
 *
 */
public class Sound {
    private Clip clip;
    public Sound(String fileName) {
        // specify the sound to play
        // (assuming the sound can be played by the audio system)
        // from a wave File
        try {
            File file = new File(fileName);
            if (file.exists()) {
                AudioInputStream sound = AudioSystem.getAudioInputStream(file);
             // load the sound into memory (a Clip)
                clip = AudioSystem.getClip();
                clip.open(sound);
            }
            else {
                throw new RuntimeException("Sound: file not found: " + fileName);
            }
        }
        catch (MalformedURLException e) {
            e.printStackTrace();
            throw new RuntimeException("Sound: Malformed URL: " + e);
        }
        catch (UnsupportedAudioFileException e) {
            e.printStackTrace();
            throw new RuntimeException("Sound: Unsupported Audio File: " + e);
        }
        catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Sound: Input/Output Error: " + e);
        }
        catch (LineUnavailableException e) {
            e.printStackTrace();
            throw new RuntimeException("Sound: Line Unavailable Exception Error: " + e);
        }

    // play, stop, loop the sound clip
    }
    public void play(){
        clip.setFramePosition(0);  // Must always rewind!
        clip.start();
    }
    public void loop(){
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    }
    public void stop(){
            clip.stop();
        }
    }
 12
Author: T. Thomas, 2012-08-16 03:28:15

J'ai trouvé une technique utile pour arrêter le son. Vous pouvez copier ces deux classes et tester vous-même. Néanmoins, le clip.méthode stop() est plus une méthode pause. Il empêche le son de jouer, oui, mais il n'efface pas le son de la ligne. En conséquence, le son est toujours en file d'attente pour jouer et aucun nouveau son ne peut être joué. Donc, en utilisant le clip.la méthode close () effacera ces données en file d'attente et permettra à un nouveau son d'être joué ou à une autre action d'avoir lieu. Notez également dans le suivant le code, un fichier son a été placé dans le dossier du projet appelé "predator.wav" ce son peut être n'importe quel type de son que vous voulez utiliser à la place du son que j'ai choisi, mais être sûr que c'est une .le format wav et le son doivent être dans le niveau le plus élevé du dossier du projet.

/*
 * File: KeyMap.java
 * Author: Andrew Peturis Chaselyn Langley; UAB EE Students
 * Assignment:  SoundBox - EE333 Fall 2015
 * Vers: 1.0.0 10/20/2015 agp - initial coding
 *
 * Credits: Dr. Green, UAB EE Engineering Professor
 */

import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class KeyMap {

    private char keyCode;
    private String song;
    private Clip clip;

    // Don't allow default constructor
    private KeyMap() {
    }

    public KeyMap(char keyCode, String song) throws LineUnavailableException {
        this.keyCode = keyCode;
        this.song = song;

        // Create an audiostream from the inputstream
        clip = AudioSystem.getClip();
    }

    public boolean match(char key) {
        return key == keyCode;
    }

    // Play a sound using javax.sound and Clip interface
    public String play() {
        try {
            // Open a sound file stored in the project folder
            clip.open(AudioSystem.getAudioInputStream(new File(song + ".wav")));

            // Play the audio clip with the audioplayer class
            clip.start();

            // Create a sleep time of 2 seconds to prevent any action from occuring for the first
            // 2 seconds of the sound playing
            Thread.sleep(2000);

        } catch (LineUnavailableException | UnsupportedAudioFileException | IOException | InterruptedException e) {
            System.out.println("Things did not go well");
            System.exit(-1);
        }
        return song;
    }

    // Stop a sound from playing and clear out the line to play another sound if need be.
    public void stop() {
        // clip.stop() will only pause the sound and still leave the sound in the line
        // waiting to be continued. It does not actually clear the line so a new action could be performed.
        clip.stop();

        // clip.close(); will clear out the line and allow a new sound to play. clip.flush() was not 
        // used because it can only flush out a line of data already performed.
        clip.close();
    }
}

/*
 * File: SoundBox.java
 * Author: Andrew Peturis, Chaselyn Langley; UAB EE Students
 * Assignment:  GUI SoundBox - EE333 Fall 2015
 * Vers: 1.0.0 09/08/2015 agp - initial coding
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;
import javax.sound.sampled.LineUnavailableException;

/**
 *
 * @author Andrew Peturis, Chaselyn Langley
 *
 */
public class SoundBox {

    static Scanner scanner = new Scanner(System.in);   //Scanner object to read user input
    InputStream input;

    /**
     * @param args the command line arguments
     * @throws java.io.IOException
     */
    public static void main(String[] args) throws IOException, LineUnavailableException {

        String line;
        Character firstChar;
        String predator = "predator";
        String explosion = "explosion";

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        KeyMap[] keyedSongs = {
            new KeyMap('a', predator),};

        while (true) {
            line = br.readLine();
            firstChar = line.charAt(0);

            for (int i = 0; i < keyedSongs.length; i++) {
                if (keyedSongs[i].match(firstChar)) {

                    // Notice now by running the code, after the first second of sleep time the sound can
                    // and another sound can be played in its place
                    keyedSongs[i].stop();
                    System.out.println("Played the sound: " + keyedSongs[i].play());
                    break;
                }
            }

            if (firstChar == 'q') {
                break;
            }
        }
    }
}
 2
Author: Andrew Peturis, 2015-12-09 17:33:12