0

私は、サウンド再生メソッドといくつかのカスタムコードに基づいて自分で石畳にしたクラスを使用しています。唯一の問題は、playSoundFile()メソッドの出力ストリームにコピーするwhileループがどのように機能するかを100%確信していないことです。簡単な説明と、ループに設定する方法の提案(できれば、サウンドファイルの長さで繰り返し呼び出すタイマーを設定せずに)をいただければ幸いです。

「私の」コード:

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

3 に答える 3

2

単純な(短い)サウンドをループする場合は、より複雑なjavax.soundクラスをすべて避け、Clipを使用します。Clipを使用したサンプルコード

于 2011-01-24T22:31:47.737 に答える
1

前に終了した後、音楽の再生を再開する必要があります。音楽の再生がいつ停止するかをどのように定義できますか?

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

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

最も簡単な方法は、そのブロックをsmtのように配置して再起動することplaySoundFile(file)です。

しかし、このコードはにおいがします。リファクタリングについて考える必要があります;)

また、このブロックを不定詞ループに入れてみることができると思います

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

しかし、それも最善の解決策ではありません。

于 2011-01-24T20:35:52.430 に答える
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
       }
    }
  }
}
于 2013-08-02T13:36:54.177 に答える