Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Воспроизведение MIDI звуков на языке JAVA

Anna | 2.06.2014 | нет комментариев
Прежде, чем перейти к сути, я немножко расскажу вам о компьютерном звуке.

Существует два основных формата воспроизведения звуков компьютером:
цифровой (WAV-формат) и синтезированный (MIDI).

Цифровой звук является основным эталоном компьютерного звука сегодня. Именно оцифрованный звук вы слышите, проигрывая композиции в mp3 формате либо прослушивая компакт-диски, просматривая фильм либо играя в комьютерные игры.

Оцифрованный звук представляет собой комплект битов, тот, что ступенчато описывает значение яруса амплитуды звуковой волны в всякий момент времени звучания. При его воспроизведении звуковая карта лишь переводит «цифровой» звук в привычную нам «аналоговую» форму.

Но существует и иной вид компьютерного звука — синтезированный (MIDI)

Звуковая карта может служить музыкальным синтезатором, способном воспроизводить звучания до 128-ми разных музыкальных инструментов. Качество и правило имитации инструментов зависит от вашей звуковой карты. Она может пытаться смоделировать звучание инструмента общностью нескольких FM (частотных) генераторов примитивных частот, для всякой из которых задана амплитуда, частота, фаза и куча других параметров. Но Почаще она обращается к хранящимся в ней «банкам данных» примеров звучания настоящих инструментов. (Допустимо комбинирование этих 2-х методов)

Дабы синтезатор воспроизвел необходимый звук, нужно передать ему особую команду. Общность таких команд описана эталоном MIDI.
MIDI это акроним от Musical Instruments Digital Interface, что в буквальном переводе — цифровой интерфейс музыкальных инструментов.

При помощи этих команд мы можем «сказать» синтезатору звуковой платы каким инструментом ту либо другую ноту мы хотим, что бы он воспроизвел. Скажем Фа-диез на рояле либо любом ином из 128-ми инструментов.

Возможен для каких-то целей вам потребовалось из java обучиться воспроизводить ноты. И вы решили узнать, как принудить синтезатор вашей звуковой платы это делать. Окунувшись поисковиком в информационное море интернета, вы невзначай осознаете, что толковой информации по этому вопросу обнаружить сложно.

Скажу, что существует довольное число библиотек для работы с midi. И все они обещают, что с их поддержкой процес программирования музыки будет проще. Я столкнулся с двумя такими: jfugue и jMusic. В Ютубе есть наглядные начальства о их использовании. В всякой из сходственных библиотек были выдуманы свои методы и правила. Чем больше экзотическая библиотека, тем поменьше информации и примеров. Так же придется довериться правильности и точности их работы.
Из многих соображений предполагаю, что отменнее начать постижение и обучиться использовать в начале стандартную библиотеку: javax/sound/midi

Тем, кто впервой сталкивается с этой темой, моя статья призвана подмогнуть сделать первые шаги. Я обучу вас самым базовым навыкам работы с midi звуком. А дальше вы теснее сами сумеете расширить их использование и, если понадобится, легко дополните информацию из изложения библиотеки и примерами из интернета.

Выходит, все что вам для начала необходимо — обучиться воспроизводить ноты.
Ваше желание включает некоторую дополнительную информацию — наименование ноты (номер) и продолжительность звучания. А так же инструмент, тот, что вы хотите Дабы её сыграл.
Желание абсолютно легко и ясно сформулировано: «Хочу, Дабы прозвучала такая-то нота, определенное время и выбранным инструментом.» Впрочем сходу обнаружить соответствующую информацию, как это сделать, вам будет трудно. Вот по этому эта статья и написана — Дабы вы не тратили свое время а сразу получили то, что необходимо. И начали использовать.

Номера нот вы можете определить по данной таблице:

А номера инструментов дозволено посмотреть тут

Перед непосредственным программированием воспроизведения понадобится некоторая подготовка. А именно, вам потребуется получить объект синтезатора (Synthesizer) и отрыть его. После этого получить доступ его каналам.
Звучит, допустимо, не совсем ясно, но на практике всё легко:

     Synthesizer synth = MidiSystem.getSynthesizer();
     synth.open();
     MidiChannel[] channels = synth.getChannels();

Канал дозволено представить как универсального музыканта, тот, что горазд играть на любом из 128-ми инструментов. Вы располагаете 16-тью такими каналами.
Вот в тезисе и каждая подготовка. Дальше нужно обучиться давать команды музыкантам.
Возможен вы хотите, чтоб звучала нота Фа первой октавы. Для этого, посмотрев таблицу с номерами нот, выясняете, что её номер 65. Выбираем одного из 16-ти музыкантов. Возможен под номером 0 (channels[0]). Воспроизведение происходит по команде noteOn.
Она принимает 2 параметра: MIDI номер ноты (от 0 до 127) и громкость звучания (так же до 127)
Выглядеть это будет так:

     channels[0].noteOn(65, 80);

По этой команде музыкант под номером «нуль» начнет воспроизведение ноты Фа первой октавы. 80 — это громкость. Это дозволено представить, что музыкант нажал клавишу синтезатора и льется звук.
Думаю, вы додумались, что для прекращения звучания так же понадобится дать команду. Т.е. Дабы реально данный музыкант отпустил нажатую клавишу. Это выполняется командой noteOff.
Таким образом:

     channels[0].noteOff(65);

Между этими командами понадобится сделать паузу, от которой и будет зависеть продолжительность звучания.
Вот, собственно, и всё. И не необходимы никакие сторонние библиотеки. Всё нужное сейчас вы сумеете комфортным методом написать под себя сами. Осталось открыть вам конечный секрет — обучить волшебным словам, которые принудят «музыкантов» взять иной муз. инструмент.
Напомню, что предпочесть инструмент дозволено тут. Любому из 16-ти каналов вы можете назначить один из 128-ми инструментов. По умолчанию примерно все каналы применяют фортепиано.
Так производится предназначение «нулевому» каналу инструмент «скрипка»:

    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);
        }
    }
}

В конструкторе класса создается и открывается синтезатор. Получаем массив каналов и первому (нулевому) назначаем инструмент «скрипка».

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB