2011-01-24 3 views
0

Я использую класс, который я объединил в себе, основываясь на методе звуковой игры, а затем на каком-то специальном коде. Единственная проблема заключается в том, что я не уверен на 100%, как работает цикл while, который копирует выходной поток в методе playSoundFile(). Я был бы чрезвычайно благодарен за его быстрое объяснение, а также за любые предложения о том, как настроить его на цикл (желательно, не настраивая таймер для повторного вызова его по длине звукового файла)Looping sound Java

«Мой 'Код:

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

ответ

1

Необходимо перезапустить воспроизведение музыки после предыдущих целей. Как вы можете определить, когда музыка перестает играть?

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

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

esyest путь будет перезапустить его, поставив в этом блоке смт как playSoundFile(file).

Но этот код пахнет. Вы должны думать о рефакторинге;)

Кроме того, я думаю, вы можете попробовать поставить этот блок в неопределенной петле

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

Но, это не лучшее решение тоже.

2

Для зацикливания простых (коротких) звуков я бы избегал всех более сложных классов javax.sound и использовал Clip. Некоторые sample code using Clip.

0

Проблема в размере буфера.

так что вам нужно, чтобы «закончить» воспроизводимый нить перед тем «переустановку его» в противном случае вы бы перекрывающихся звук с очень небольшой аудио (точно или меньше, чем размер буфера, например, 0:01)

так в вашей игре нить

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 
     } 
    } 
    } 
}