До перейти к делу , расскажу немного о компьютерном звуке.
Существует два основных формата воспроизведения звуков на компьютере: цифровые (формат WAV) и синтезированные ( МИДИ ).
Цифровое аудио сегодня является основным стандартом компьютерного звука.
Это оцифрованный звук, который вы слышите при воспроизведении песен в формате mp3 или прослушивании компакт-дисков, просмотре фильма или игре в компьютерные игры.
Оцифрованный звук представляет собой набор битов, последовательно описывающий значение уровня амплитуды звуковой волны в каждый момент времени звука.
При его воспроизведении звуковая карта лишь преобразует «цифровой» звук в привычную нам «аналоговую» форму.
Но есть еще один тип компьютерного звука – синтезированный (MIDI).
Звуковая карта может выполнять функцию музыкального синтезатора, способного воспроизводить звуки до 128 различных музыкальных инструментов.
Качество и принцип симуляции инструментов зависит от вашей звуковой карты.
Можно попытаться смоделировать звук инструмента с помощью комбинации нескольких ЧМ (частотных) генераторов простых частот, для каждого из которых заданы амплитуда, частота, фаза и куча других параметров.
Но чаще она обращается к хранящимся в ней «банкам данных» семплов звуков инструментов.
В настоящее время существует множество звуковых карт, которые могут работать с Звуковой шрифт .
Это всего лишь wav-сэмплы, которые можно загрузить в звуковую карту и управлять звуком этих инструментов в MIDI-секвенсоре.
SoundFonts обычно имеют расширение .
sf2 и также могут называться патчами или программами.
Несколько SoundFont объединяются в банки SoundFont, которые могут содержать до 128 инструментов и одну ударную установку.
В Интернете вы легко найдете профессиональные библиотеки банков инструментов в формате SF2. Чтобы синтезатор воспроизвел нужный звук, нужно отправить ему специальную команду.
Набор таких команд описан стандартом MIDI. MIDI — это аббревиатура от «Цифровой интерфейс музыкальных инструментов», что буквально переводится как цифровой интерфейс для музыкальных инструментов.
Используя эти команды, мы можем «сообщить» синтезатору звуковой платы, на каком инструменте мы хотим, чтобы он сыграл ту или иную ноту.
Например, фа-диез на фортепиано или любом другом из 128 инструментов.
Допустим, вам для какой-то цели нужно научиться играть ноты с помощью Java. И вы решили узнать, как заставить синтезатор вашей звуковой карты делать это.
Погрузившись своей поисковой системой в информационное море Интернета, вы вдруг поймете, что найти толковую информацию по этому вопросу непросто.
Скажу, что библиотек для работы с миди достаточно.
И все они обещают, что с их помощью процесс программирования музыки станет проще.
Я наткнулся на два таких: jfugue и jMusic. На YouTube есть визуальные руководства по их использованию.
Каждая из этих библиотек имела свои методы и правила.
Чем экзотичнее библиотека, тем меньше информации и примеров.
Вам также придется довериться правильности и точности их работы.
По многим причинам я считаю, что лучше сначала начать изучать и научиться пользоваться стандартной библиотекой: Javax/звук/миди Тем, кто впервые сталкивается с этой темой, моя статья призвана помочь сделать первые шаги.
Я научу вас самым базовым навыкам работы со звуком MIDI. И тогда вы сами сможете расширить их использование и при необходимости легко дополнить информацию из описания библиотеки и примеров из Интернета.
Итак, все, что вам нужно для начала, — это научиться играть по нотам.
Ваше пожелание включает в себя некоторую дополнительную информацию – название ноты (номер) и продолжительность звука.
А также инструмент, на котором вы хотите играть.
Желание формулируется довольно просто и ясно: «Я хочу, чтобы звучала такая-то нота, в определенное время и на выбранном инструменте».
Однако вам будет сложно сразу найти соответствующую информацию о том, как это сделать.
Именно поэтому и написана эта статья – чтобы вы не теряли время и сразу получили то, что вам нужно.
И они начали этим пользоваться.
Определить номера купюр можно с помощью этой таблицы:
Вы можете увидеть номера инструментов Здесь
Прежде чем программировать воспроизведение, потребуется некоторая подготовка.
А именно, вам нужно будет получить объект синтезатора ( Синтезатор ) и откройте его.
Затем получите доступ к его каналам.
Возможно, это звучит не совсем понятно, но на практике все просто:
Канал можно представить как универсального музыканта, умеющего играть на любом из 128 инструментов.Synthesizer synth = MidiSystem.getSynthesizer(); synth.open(); MidiChannel[] channels = synth.getChannels();
У вас 16 таких каналов.
Вот, собственно, и вся подготовка.
Далее вам нужно научиться подавать команды музыкантам.
Допустим, вы хотите, чтобы звучала нота Фа первой октавы.
Для этого, просмотрев таблицу с номерами нот, вы узнаете, что ее номер 65. Выбираем одного из 16 музыкантов.
Скажем под номером 0( каналы[0] ).
Воспроизведение происходит по команде ПримечаниеВкл.
.
Он принимает 2 параметра: номер MIDI-ноты (от 0 до 127) и громкость звука (также до 127).
Это будет выглядеть так: channels[0].
noteOn(65, 80);
По этой команде музыкант номер «ноль» начнет играть ноту Фа первой октавы.
80 это громкость.
Можно представить, что музыкант нажал клавишу синтезатора и звук льётся.
Думаю, вы догадались, что для прекращения звука вам также нужно будет дать команду.
Те.
чтобы именно этот музыкант отпустил нажатую клавишу - выполняем команду ПримечаниеВыкл.
.
Таким образом: channels[0].
noteOff(65);
Между этими командами следует делать паузу, от которой будет зависеть продолжительность звука.
Вот и все, собственно.
И никакие сторонние библиотеки не нужны.
Теперь вы можете написать все необходимое в удобной для себя форме.
Осталось открыть вам последний секрет – научить волшебным словам, которые заставят «музыкантов» взяться за другую музыку.
инструмент. Напомню, что вы можете выбрать инструмент Здесь .
Вы можете назначить один из 128 инструментов на любой из 16 каналов.
По умолчанию почти все каналы используют фортепиано.
Вот как инструмент «скрипка» назначается на «нулевой» канал: channels[0].
programChange(41);
Вам потребуется импортировать следующие стандартные пакеты: import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Synthesizer;
Итак, код, воспроизводящий звук, будет выглядеть так: try {
Synthesizer synth = MidiSystem.getSynthesizer();
synth.open();
MidiChannel[] channels = synth.getChannels();
channels[0].
programChange(41); channels[0].
noteOn(65, 80); Thread.sleep(1000); // in milliseconds channels[0].
noteOff(65);
synth.close();
} catch (Exception e) {
e.printStackTrace();
}
Далее, как уже говорилось, возможности программирования извлечения звука ограничены только вашей фантазией.
Для примитивной демонстрации создадим собственный метод воспроизведения звуков, который будет выполняться нажатием, паузой и отпусканием одной командой.
Для этих целей выделим отдельный класс, структура и функционал которого не нуждаются в пояснении: package music.player;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Synthesizer;
public class Player {
private MidiChannel[] channels = null;
private Synthesizer synth = null;
public Player() {
try {
synth = MidiSystem.getSynthesizer();
synth.open();
channels = synth.getChannels();
channels[0].
programChange(41); } catch (MidiUnavailableException ex) { Logger.getLogger(Player.class.getName()).
log(Level.SEVERE, null, ex); } } public void close() { synth.close(); } public void playSound(int channel, int duration, int volume, int. notes) { for (int note : notes) { channels[channel].
noteOn(note, volume); } try { Thread.sleep(duration); } catch (InterruptedException ex) { Logger.getLogger(Player.class.getName()).
log(Level.SEVERE, null, ex); } for (int note : notes) { channels[channel].
noteOff(note);
}
}
}
В конструкторе класса создается и открывается синтезатор.
Получаем массив каналов и присваиваем первому (нулю) инструмент «скрипка».
Метод playSound получает на вход номер канала, продолжительность звука, громкость и последовательность нот, которые будут звучать одновременно.
Реализация предельно проста — проигрываются все входящие ноты, выдерживается интервал длительности и затем все выключаются.
Вот пример использования этого класса — играются четыре аккорда: Player player = new Player();
player.playSound(0, 1000, 80, 69, 72, 76);
player.playSound(0, 1000, 80, 69, 74, 77);
player.playSound(0, 1000, 80, 67, 71, 74);
player.playSound(0, 1000, 80, 67, 72, 76);
player.close();
Ну и в заключение запрограммируем для эксперимента какую-нибудь известную красивую мелодию.
Просто скопируйте код, и при его запуске вы услышите «Jasper Forks — River Flows In You»: int notes[][] = {{470, 81}, {230, 80}, {470, 81}, {250, -1}, {230, 80}, {470, 81}, {230, 69}, {230, 76}, {470, 81}, {230, 69}, {470, 74}, {470, 73}, {470, 74}, {470, 76}, {470, 73}, {470, 71}, {970, -1}, {230, 69}, {230, 68}, {470, 69}, {730, -1}, {230, 64}, {230, 69}, {230, 71}, {470, 73}, {970, -1}, {230, 73}, {230, 74}, {470, 76}, {730, -1}, {230, 69}, {230, 74}, {230, 73}, {470, 71}, {1450, -1}, {470, 81}, {230, 80}, {470, 81}, {250, -1}, {230, 80}, {470, 81}, {230, 69}, {230, 76}, {470, 81}, {230, 69}, {470, 74}, {470, 73}, {470, 74}, {470, 76}, {470, 73}, {470, 71}, {970, -1}, {230, 69}, {230, 68}, {470, 69}, {730, -1}, {230, 64}, {230, 69}, {230, 71}, {470, 73}, {970, -1}, {230, 73}, {230, 74}, {470, 76}, {730, -1}, {230, 69}, {230, 74}, {230, 73}, {470, 71}, {250, -1}};
Player player = new Player();
for (int[] note : notes) {
if (note[1] != -1) {
player.playSound(0, note[0], 80, note[1]);
} else {
try {
Thread.sleep(note[0]);
} catch (InterruptedException ex) {
Logger.getLogger(Music.class.getName()).
log(Level.SEVERE, null, ex);
}
}
}
player.close();
В массиве пары чисел содержат длительность звука и номер ноты.
Для различия запишем паузу как «минус один».
Оставим канал и громкость одинаковыми для всех нот — 0 и 80 соответственно.
Что ж, я думаю, у вас не возникнет трудностей с пониманием изложенного материала.
Буду рад, если эта статья сэкономит вам время и силы, позволив легко приступить к программированию воспроизведения MIDI-звука в JAVA. Теги: #java #Звук #midi #java
-
Трансляция Wwdc На Macspoon.ru
19 Oct, 24 -
Магия Vim — Визуальный Режим
19 Oct, 24 -
Новые Технологии Для Моторных Масел Лукойл
19 Oct, 24