2011-01-24 2 views
0

J'utilise une classe que j'ai bricolé en me basant sur une méthode de jeu de sons et ensuite du code personnalisé. Le seul problème est que je ne suis pas sûr à 100% comment la boucle while qui copie dans le flux de sortie dans la méthode playSoundFile() fonctionne. Je serais extrêmement reconnaissant pour une explication rapide de cela, ainsi que des suggestions sur la façon de le configurer en boucle (de préférence sans mettre en place une minuterie pour l'appeler à la longueur du fichier sonore)Looping sound Java

'Mon 'Code:

import java.io.File; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.SourceDataLine; 

// Plays sounds passed to it. Loop stop etc to be supported later, maybe... 
public class SoundPlayer { 

    File filSound; 
    boolean isFileThere; 

    public void loop() { 
     throw new UnsupportedOperationException("Create something first... DUH");//http://stackoverflow.com/questions/2205565/java-clean-way-to-automatically-throw-unsupportedoperationexception-when-calling 
    } 

    public void play() { 
     if (isFileThere) { 
      playSoundFile(filSound); 
     } 
    } 

    public void play(File file) { 

     playSoundFile(file); 

    } 
    public static void playSoundFile(String sFile) { 
     playSoundFile(new File(sFile)); 
    } 

    public static void playSoundFile(final File file) {//http://java.ittoolbox.com/groups/technical-functional/java-l/sound-in-an-application-90681 
     new Thread(//http://stackoverflow.com/questions/4708254/how-to-play-audio-in-java-application 
       new Runnable() { 

      public void run() { 

       try { 
//get an AudioInputStream 
        AudioInputStream ais = AudioSystem.getAudioInputStream(file); 
//get the AudioFormat for the AudioInputStream 
        AudioFormat audioformat = ais.getFormat(); 

//ULAW format to PCM format conversion 
        if ((audioformat.getEncoding() == AudioFormat.Encoding.ULAW) 
          || (audioformat.getEncoding() == AudioFormat.Encoding.ALAW)) { 
         AudioFormat newformat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
           audioformat.getSampleRate(), 
           audioformat.getSampleSizeInBits() * 2, 
           audioformat.getChannels(), 
           audioformat.getFrameSize() * 2, 
           audioformat.getFrameRate(), true); 
         ais = AudioSystem.getAudioInputStream(newformat, ais); 
         audioformat = newformat; 
        } 

//checking for a supported output line 
        DataLine.Info datalineinfo = new DataLine.Info(SourceDataLine.class, audioformat); 
        if (!AudioSystem.isLineSupported(datalineinfo)) { 
         //System.out.println("Line matching " + datalineinfo + " is not supported."); 
        } else { 
         //System.out.println("Line matching " + datalineinfo + " is supported."); 
//opening the sound output line 
         SourceDataLine sourcedataline = (SourceDataLine) AudioSystem.getLine(datalineinfo); 
         sourcedataline.open(audioformat); 
         sourcedataline.start(); 
//Copy data from the input stream to the output data line 
         int framesizeinbytes = audioformat.getFrameSize(); 
         int bufferlengthinframes = sourcedataline.getBufferSize()/8; 
         int bufferlengthinbytes = bufferlengthinframes * framesizeinbytes; 
         byte[] sounddata = new byte[bufferlengthinbytes]; 
         int numberofbytesread = 0; 
         while ((numberofbytesread = ais.read(sounddata)) != -1) { 
          int numberofbytesremaining = numberofbytesread; 
          System.out.println(numberofbytesread); 
          sourcedataline.write(sounddata, 0, numberofbytesread); 
         } 
        } 

       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 
    } 

    public void stop() { 
     throw new UnsupportedOperationException("Create something first... DUH");//http://stackoverflow.com/questions/2205565/java-clean-way-to-automatically-throw-unsupportedoperationexception-when-calling 

    } 

    public void setSoundFile(File file) { 
     isFileThere = true; 
     filSound = file; 
    } 
    public void setSoundFile(String sFile) { 
     isFileThere = true; 
     filSound = new File(sFile); 
    } 
} 

Répondre

1

Vous devez redémarrer la lecture de la musique après la fin des étapes précédentes. Comment pouvez-vous définir quand la musique arrête de jouer?

//... 
         System.out.println(numberofbytesread); 
         sourcedataline.write(sounddata, 0, numberofbytesread); 
        } 
       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } finally { //added 
       /*here it stops*/ 
      }    //added 

La façon esyest sera reprise en mettant dans ce smt bloc comme playSoundFile(file).

Mais ce code sent. Vous devriez penser à refactoring;)

, je pense aussi, vous pouvez mettre ce bloc en boucle infinitif

while(true){ 
        SourceDataLine sourcedataline = (SourceDataLine) AudioSystem.getLine(datalineinfo); 
        sourcedataline.open(audioformat); 
     /... 
         sourcedataline.write(sounddata, 0, numberofbytesread); 
        } 
} 

Mais, il est pas trop meilleure solution.

2

Pour boucler des sons simples (courts), j'éviterais toutes les classes javax.sound plus complexes et j'utiliserais Clip. Certains sample code using Clip.

0

Le problème est la taille du tampon.

donc vous devez laisser « terminer » le fil de jeu avant « reseting il » vous auriez autrement overlaping son avec audio vraiment petit (exactement ou plus petite que la taille du tampon par exemple 00:01)

donc dans votre jeu fil

class SomeLoopPlayer implements Runnable 
{ 
    private boolean loop=true; 

    public void play() 
    { 
    new Thread(this).start(); 
    } 

    public void run() 
    { 
    try 
    { 
     while(true) 
     { 
     try //eos catch 
     { 
      //init sourcedataline or aif if null 
      //read or drain the source buffer in cycle 
     } 
     catch(IOException e) 
     { /* stream ended or other exception -> ignore for now */ } 
     finally 
     { 
     if(loop) 
      play(); 
     return;// terminate current thread 
     } 
    } 
    } 
}