Воспроизведение звука в Java

от автора

Воспроизведение звука в Java

Введение

Нормальной русскоязычной информации по теме просто нет. Java-tutorials тоже оставляют желать лучшего. А архитектура javax.sound.sampled хоть и проста, но далеко не тривиальна (я бы вообще сказал, что этот пакет писали извращенцы). Поэтому свой первый пост на Хабре я решил посвятить именно этой теме. Приступим:

Воспроизведение звука

Тут всё более-менее просто. Импортируем javax.sound.sampled и поехали:

try { 	File soundFile = new File("snd.wav"); //Звуковой файл 	 	//Получаем AudioInputStream 	//Вот тут могут полететь IOException и UnsupportedAudioFileException 	AudioInputStream ais = AudioSystem.getAudioInputStream(soundFile); 	 	//Получаем реализацию интерфейса Clip 	//Может выкинуть LineUnavailableException 	Clip clip = AudioSystem.getClip(); 	 	//Загружаем наш звуковой поток в Clip 	//Может выкинуть IOException и LineUnavailableException 	clip.open(ais); 	 	clip.setFramePosition(0); //устанавливаем указатель на старт 	clip.start(); //Поехали!!!  	//Если не запущено других потоков, то стоит подождать, пока клип не закончится         //В GUI-приложениях следующие 3 строчки не понадобятся 	Thread.sleep(clip.getMicrosecondLength()/1000); 	clip.stop(); //Останавливаем 	clip.close(); //Закрываем } catch(IOException | UnsupportedAudioFileException | LineUnavailableException exc) { 	exc.printStackTrace(); } catch (InterruptedException exc) {} 
Регулятор громкости

Поигравшись со звуками вы наверняка захотите иметь возможность программно изменять громкость звука. Java Sound API предоставляет такую возможность с фирменной кривотой.

//Получаем контроллер громкости FloatControl vc = (FloatControl)clip.getControl(FloatControl.Type.MASTER_GAIN); //Устанавливаем значение //Оно должно быть в пределах от vc.getMinimum() до vc.getMaximum() vc.setValue(5); //Громче обычного 

Этот код нужно поместить между строчками clip.open(ais) и clip.setFramePosition(0).

Упрощаем процесс

Ну и наконец, чтобы вы не мучились, выкладываю класс для проигрывания звуков

import java.io.File; import java.io.IOException;  import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; 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 Sound { 	private boolean released = false; 	private Clip clip = null; 	private FloatControl volumeC = null; 	private boolean playing = false; 	 	public Sound(File f) { 		try { 			AudioInputStream stream = AudioSystem.getAudioInputStream(f); 			clip = AudioSystem.getClip(); 			clip.open(stream); 			clip.addLineListener(new Listener()); 			volumeC = (FloatControl)clip.getControl(FloatControl.Type.MASTER_GAIN); 			released = true; 		} catch(IOException | UnsupportedAudioFileException | LineUnavailableException exc) { 			exc.printStackTrace(); 			released = false; 		} 	}  	//true если звук успешно загружен, false если произошла ошибка 	public boolean isReleased() { 		return released; 	} 	 	//проигрывается ли звук в данный момент 	public boolean isPlaying() { 		return playing; 	}  	//Запуск 	/* 	  breakOld определяет поведение, если звук уже играется 	  Если reakOld==true, о звук будет прерван и запущен заново 	  Иначе ничего не произойдёт 	*/ 	public void play(boolean breakOld) { 		if (released) { 			if (breakOld) { 				clip.stop(); 				clip.setFramePosition(0); 				clip.start(); 				playing = true; 			} else if (!isPlaying()) { 				clip.setFramePosition(0); 				clip.start(); 				playing = true; 			} 		} 	} 	 	//То же самое, что и play(true) 	public void play() { 		play(true); 	} 	 	//Останавливает воспроизведение 	public void stop() { 		if (playing) { 			clip.stop(); 		} 	}  	//Установка громкости 	/* 	  x долже быть в пределах от 0 до 1 (от самого тихого к самому громкому) 	*/ 	public void setVolume(float x) { 		if (x<0) x = 0; 		if (x>1) x = 1; 		float min = volumeC.getMinimum(); 		float max = volumeC.getMaximum(); 		volumeC.setValue((max-min)*x+min); 	} 	 	//Возвращает текущую громкость (число от 0 до 1) 	public float getVolume() { 		float v = volumeC.getValue(); 		float min = volumeC.getMinimum(); 		float max = volumeC.getMaximum(); 		return (v-min)/(max-min); 	}  	//Дожидается окончания проигрывания звука 	public void join() { 		if (!released) return; 		synchronized(clip) { 			try { 				while (playing) clip.wait(); 			} catch (InterruptedException exc) {} 		} 	} 	 	//Статический метод, для удобства 	public static Sound playSound(String s) { 		File f = new File(s); 		Sound snd = new Sound(f); 		snd.play(); 		return snd; 	}  	private class Listener implements LineListener { 		public void update(LineEvent ev) { 			if (ev.getType() == LineEvent.Type.STOP) { 				playing = false; 				synchronized(clip) { 					clip.notify(); 				} 			} 		} 	} } 

Пользоваться очень просто, например:

Sound.playSound("sounds/hello.wav").join(); 
Форматы

Пару слов о поддержке форматов звуковых файлов: забудьте про mp3 и вспомните wav. Также поддерживаются au и aif.

ссылка на оригинал статьи http://habrahabr.ru/post/191422/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *