Воспроизведение звука в 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/
Добавить комментарий