JavaでWAVファイルをリピート再生する


Posted on 2021/12/04 at 4:30


短い警告音をリピートして鳴らしたい場面がありました。Clipオブジェクトのloop()を使えば簡単に実装できますが、 今回は警告音を鳴らす間隔をあけたいという希望があったため、検索するもネット上にいいサンプルが見つからず、自分で実装することにしました。

サンプルコード

再生させる音声はWindows10に標準に入っている音声を指定しているため、Windows10環境であればサンプルコードそのままで動作すると思います。

再生する音声ファイル、ボリューム(0~1)、リピートする回数、リピートの間隔(ms)を指定します。別スレッドで動作するため、swingから実行させることも可能です。

今回のサンプルでは「Ring06.wav」という音声ファイルを80%の音量、1秒間隔で3回再生します。

  
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class SoundPlay {

	private static ExecutorService es = Executors.newSingleThreadExecutor();
	
	private boolean isRunning = false;
	
	public static void main(String[] args) {
		SoundPlay player = new SoundPlay();
		player.play("c:/Windows/Media/Ring06.wav",0.8f, 3, 1000l);
	}
	
	public void play(String soundFilePath, Float volume, int loop, long waitTime) {
		es = Executors.newSingleThreadExecutor();
		es.execute(new Runnable() {
			@Override
			public void run() {
				AudioInputStream stream = null;
				AudioFormat format = null;
				Clip clip = null;
				try {
					stream = AudioSystem.getAudioInputStream(new File(soundFilePath));
					format = stream.getFormat();
					DataLine.Info cInfo = new DataLine.Info(Clip.class, format);
					if (!AudioSystem.isLineSupported(cInfo))
						return;
					clip = (Clip) AudioSystem.getLine(cInfo);
					clip.open(stream);
					if (volume != null) {
						FloatControl ctrl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
						ctrl.setValue((float)Math.log10(volume) * 20);
					}
					clip.addLineListener(new LineListener() {
						@Override
						public void update(LineEvent event) {
							LineEvent.Type type = event.getType();
							if (type == LineEvent.Type.STOP) {
								System.out.println("STOP");
								isRunning = false;
							} else if (type == LineEvent.Type.START) {
								System.out.println("START");
								isRunning = true;
							}
						}
					});
					for (int i=1; i<=loop; i++) {
						clip.setFramePosition(0);
						clip.start();
						clip.flush();
						while (!isRunning) {
							System.out.println("Not running...");
							Thread.sleep(100);
						}
						while (clip.isActive() || clip.isRunning()) {
							System.out.println("Running...");
							Thread.sleep(100);
						}
						clip.stop();
						while (isRunning) {
							System.out.println("Running...");
							Thread.sleep(100);
						}
						if (i == loop)
							break;
						System.out.printf("Sleep %d ms...\n", waitTime);
						Thread.sleep(waitTime);
					}
				} catch (UnsupportedAudioFileException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (LineUnavailableException e) {
					e.printStackTrace();
				} catch (InterruptedException e) {
				} finally {
					try {
						if (clip != null && clip.isOpen())
							clip.close();
					} finally {
						try {
							if(stream != null)
								stream.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		});
		es.shutdown();
	}
}
  
関連記事

JavaでWAV再生、シンプルメディアプレーヤーの作成

Java(Swing)で音声(WAV)ファイルを再生、停止するだけの、シンプルメディアプレーヤーを作成してみました。