今回は音声ファイルの再生をします。まず手元にwavファイルを用意してください。ない場合は以下のサンプルをダウンロードして使ってください。なんの変哲もないサイン波です。
おそらく多くの音声ファイルはmp3で保存することが多いと思いますがJavaの基本のAPIでは再生することができません。mp3の再生についてはまた別の機会に書くようにします。
再生に必要な部品
基本的な流れとしては
- wavファイルの入力ストリームを開く
- 再生用の書き出しラインを取得する
- 入力ストリームから順次データを読んで再生用ラインに書き出して行く
- 入力がなくなったら終了
といった形です。
処理にはjavax.sound.sampledというパッケージを使います。最初に完成時のインポート部分を貼っておきます。おおよそ使うクラスがわかると思います。
import java.io.File; import java.io.IOException; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.UnsupportedAudioFileException;
このうちAudioSystemというクラスによって必要な入出力を取得するため重要になります。
まずFileのオブジェクトを引数にして読み込みのストリームを開きます。
AudioInputStream audio_input_stream = AudioSystem.getAudioInputStream(audio_file);
その後そのストリームから音声のフォーマットを取得します。このフォーマットを元に書き出しのLineオブジェクトを取得します。
AudioFormat audio_format = audio_input_stream.getFormat(); DataLine.Info info = new DataLine.Info(SourceDataLine.class, audio_format, AudioSystem.NOT_SPECIFIED); SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
ファイルのフォーマットに対応した出力ラインをAudioSystemに対して要求しています。
取得したラインを開きます。
line.open(audio_format, AudioSystem.NOT_SPECIFIED); line.start();
あとは書き出し処理です。
int buffer_size = 128000; int bytes_read = 0; byte[] ab_data = new byte[buffer_size]; while (bytes_read != -1) { bytes_read = audio_input_stream.read(ab_data, 0, ab_data.length); if (bytes_read >= 0) { line.write(ab_data, 0, bytes_read); } } line.drain(); line.close();
ラインの終了処理もしています。
では呼び出しの処理です。
playFile(new File("/Users/myaccount/files/sine_500.wav"));
ファイルのパスは適宜変えてください。
実行すると音がなります。
ソースコード
以下ソースコード全部を書いておきます。
import java.io.File; import java.io.IOException; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.UnsupportedAudioFileException; /** * * @author minaberger */ public class WavTest { public static void main(String[] args) throws Exception { playFile(new File("/Users/myaccount/files/sine_500.wav")); } public static void playFile(File audio_file) throws LineUnavailableException, UnsupportedAudioFileException, IOException { AudioInputStream audio_input_stream = AudioSystem.getAudioInputStream(audio_file); AudioFormat audio_format = audio_input_stream.getFormat(); DataLine.Info info = new DataLine.Info(SourceDataLine.class, audio_format, AudioSystem.NOT_SPECIFIED); SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info); line.open(audio_format, AudioSystem.NOT_SPECIFIED); line.start(); int buffer_size = 128000; int bytes_read = 0; byte[] ab_data = new byte[buffer_size]; while (bytes_read != -1) { bytes_read = audio_input_stream.read(ab_data, 0, ab_data.length); if (bytes_read >= 0) { line.write(ab_data, 0, bytes_read); } } line.drain(); line.close(); } }
コメント
Exception in thread “main” javax.sound.sampled.UnsupportedAudioFileException: File of unsupported format
at java.desktop/javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
at WavTest.playFile(WavTest.java:24)
at WavTest.main(WavTest.java:18)
とでますがどうすればいいですか。
コメントありがとうございます。
ここで失敗しているようですね。ファイルはこのページにあるリンクのものを使われましたか?
http://mocha-java.com/wp-content/uploads/2016/11/sine_500.wav
wav以外のものだとうまくいかないかもしれません。