2012-08-12 18 views
6

Sto provando a suonare due suoni wav contemporaneamente durante una partita (musica di sottofondo e un effetto). Per prima cosa ho costruito questo pezzo di codice usando un altro gestore audio in java che gestiva la riproduzione, l'arresto e il looping del suono. Questo costrutto riprodurrebbe la musica di sottofondo o l'effetto, ma solo uno alla volta. Ho guardato in Internet e mi è stato detto di usare javax.sound.sampled.Clip per gestire i suoni in modo tale che riutilizzassero lo stesso costrutto (play, stop, loop) ma lo ho cambiato per usare javax.sound.sampled.Clip. Ora sono completamente perso. Da quanto ho letto finora ho fatto tutto correttamente e non ho riscontrato errori nell'editor di eclipse, ma quando lo eseguo ho uno o due errori. In eclipse (in esecuzione su Linux) viene generata un'eccezione LineUnavailableException. In eclipse (in esecuzione su Windows 7) ottengo una java.lang.NullPointerException nella sezione loop() di questo codice. Se tu potessi mostrarmi cosa sto facendo male o indicarmi qualche documentazione pertinente, lo apprezzerei. Sto assumendo il suo qualcosa con il mio codice che gestisce le eccezioni ma non ne sono sicuro. Se vedi qualche altro codice orribile, per favore fammi sapere che mi sto impegnando per diventare il miglior programmatore che posso e apprezzo davvero le critiche costruttive. Grazie per il tuo tempo.Uso di javax.sound.sampled.Clip per riprodurre, eseguire il loop e interrompere i suoni multipli in un gioco. Errori imprevisti

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

risposta

12

Sono riuscito a far funzionare il codice e ora ho una migliore comprensione delle clip. La pagina che mi ha aiutato di più è stata http://www3.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html che rompe tutto e mi ha aiutato a vedere dove ho commesso degli errori. Ecco il mio codice finale di lavoro. Come prima, se vedi errori orribili o visioni in logica o stile fammelo sapere.

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

Ho trovato una tecnica utile per interrompere il suono. Puoi copiare queste due classi e provarla tu stesso. Tuttavia, il metodo clip.stop() è più un metodo di pausa. Interrompe la riproduzione del suono, sì, ma non cancella il suono dalla linea. Di conseguenza, il suono è ancora in coda per la riproduzione e non è possibile riprodurre alcun nuovo suono. Pertanto, utilizzando il metodo clip.close() si cancellano questi dati in coda e si consente di riprodurre un nuovo suono o di eseguire un'altra azione. Si noti inoltre che nel seguente codice è stato inserito un file audio nella cartella del progetto denominata "predator.wav", questo suono può essere qualsiasi tipo di suono che si desidera utilizzare al posto del suono che ho scelto, ma assicurarsi che sia un formato .wav e il suono deve trovarsi nel livello più alto della cartella del progetto.

/* 
* 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; 
      } 
     } 
    } 
} 
Problemi correlati