Usando javax.sound.sampled.Clip para reproduzir, fazer loop e parar vários sons em um jogo. Erros Inesperados

Estou tentando tocar dois sons wav ao mesmo tempo durante um jogo (música de fundo e um efeito). Eu construí primeiramente este pedaço de código usando outro manipulador de áudio em java que lidaria com a reprodução, a parada e o loop do som. Essa construção tocaria a música de fundo ou efeito, mas apenas um de cada vez. Eu olhei em torno da internet e foi-me dito para usar javax.sound.sampled.Clip para lidar com os sons de modo reutilizado a mesma construção (play, stop, loop), mas mudou para usar javax.sound.sampled.Clip. Agora estou completamente perdida. Pelo que tenho lido até agora eu fiz tudo correto e não obtenho nenhum erro no editor do eclipse, mas quando eu executo eu recebo um dos dois erros. No eclipse (rodando no Linux), um LineUnavailableException é lançado. No eclipse (executando no windows 7) eu recebo um java.lang.NullPointerException na seção loop () deste código. Se você pudesse me mostrar o que estou fazendo de errado ou me indicar alguma documentação relevante, agradeceria. Eu estou supondo que é algo com o meu código que lida com exceções, mas não tenho certeza. Se você vir algum outro erro de código hediondo, por favor me avise que eu estou me esforçando para ser o melhor programador que posso e realmente aprecio críticas construtivas. Obrigado pelo seu tempo.

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

Consegui fazer o código funcionar e agora tenho um melhor entendimento dos Clips. A página que mais me ajudou foi http://www3.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html que quebrou tudo e me ajudou a ver onde cometi erros. Aqui está o meu código final de trabalho. Como antes, se você ver quaisquer erros horríveis ou sobre mira na lógica ou no estilo, me avise.

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

Eu encontrei uma técnica útil para parar o som. Você pode copiar essas duas classs e testá-las por si mesmo. No entanto, o método clip.stop () é mais um método de pausa. Ele pára o som de tocar, sim, mas não limpa o som da linha. Como resultado, o som ainda está na fila para tocar e nenhum novo som pode ser reproduzido. Portanto, o uso do método clip.close () eliminará esses dados enfileirados e permitirá que um novo som seja reproduzido ou que outra ação ocorra. Observe também no código a seguir que um arquivo de som foi colocado na pasta do projeto chamado “predator.wav”, este som pode ser qualquer tipo de som que você queira usar ao invés do som que eu escolhi, mas tenha certeza que é um formato .wav e o som deve estar na camada mais alta da pasta do projeto.

 /* * 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; } } } } 
Intereting Posts