Вступление
В этом уроке мы узнаем, как создавать ритмы с помощью класса Rhythm , как использовать встроенный RhythmKit JFugue для удобного создания ритма и как применять к нашей песне различные ритмические инструменты. Мы также расскажем, как сохранить нашу музыку в файл MIDI с помощью JFugue и как читать музыку из файла MIDI с помощью библиотеки JFugue.
Это третья и последняя часть серии руководств из трех частей, в которой мы пытаемся воссоздать вступление джазовой версии Sunday Morning by Maroon 5 . Но шаги, описанные в статьях, легко применимы и к любому другому процессу создания песни.
В первой части серии мы рассмотрели основы библиотеки JFugue, научились использовать ноты, октавы, длительность, темп, инструменты и паттерны. В конце первой статьи мы создали вступительный вокал без каких-либо аккордов. К концу этого урока в нашей песне будут готовые аккорды, которые будут играть вместе с вокалом.
В предыдущей части серии мы узнали, как использовать аккорды и
последовательности аккордов в библиотеке JFugue. Мы также рассмотрели,
как использовать setKey()
, distribute()
и allChordsAs()
ChordProgression
, как одновременно воспроизводить разные паттерны с
помощью голосов и как применять свойства атаки / затухания к нотам и /
или аккордам.
Вот ссылки на предыдущие части нашей серии руководств по JFugue:
- Руководство для начинающих по JFugue, часть I: Примечания, продолжительность, шаблоны
- Руководство для начинающих по JFugue, часть II: аккорды и последовательности аккордов
- Руководство для начинающих по JFugue, часть III: ритмы, чтение и запись в MIDI (здесь)
Ритмы в JFugue
JFugue позволяет нам использовать ритмы со встроенным классом Rhythm
Этот класс обеспечивает интуитивно понятный способ взаимодействия с
токенами ритма для создания желаемого ритма. Как упоминалось ранее, V9 -
это предопределенный голосовой канал для всех перкуссии. Таким образом,
любой объект, который мы создаем из этого класса, будет добавлен в V9 по
умолчанию.
Чтобы использовать Rhythm
, мы должны сначала импортировать его:
import org.jfugue.rhythm.Rhythm;
Затем мы создаем его, чтобы добавить слои:
Rhythm rhythm = new Rhythm()
.addLayer("O..oO...O..oOO..")
.addLayer("..S...S...S...S.")
.addLayer("````````````````")
.addLayer("...............+");
player.play(rhythm.getPattern().repeat(2));
Запустите код, чтобы проиграть этот крутой бит, который также доступен на официальном сайте JFugue.
Строка, которую Rhythm
, на первый взгляд может показаться немного
другой, но учтите, что она преобразует их все обратно в стаккато на
оборотной стороне. А с помощью getPattern()
мы можем превратить их в
Pattern
и использовать методы, специфичные для шаблона, такие как
repeat()
. Метод addLayer()
работает аналогично Voices. Вы можете
думать о каждом слое как о эквиваленте голоса , за исключением того,
что мы уже находимся в голосе (V9), мы не можем добавить его, но вместо
этого мы добавляем до 16 слоев.
Чтобы уточнить, каждый из символов, которые передаются в класс, представляет инструмент или Остальное из RhythmKit по умолчанию JFugue . Здесь вы можете изучить каждый инструмент, соответствующий символам в приведенном выше примере:
Продолжительность Персонаж
. Ri O (прописные) [BASS_DRUM] я о (нижний регистр) [BASS_DRUM] с. S (прописные) [ACOUSTIC_SNARE] я s (нижний регистр) [ACOUSTIC_SNARE] рупий ^ (каретка) [PEDAL_HI_HAT] я `(обратная кавычка) [PEDAL_HI_HAT] s рупий * (звездочка) [CRASH_CYMBAL_1] я + (плюс) [CRASH_CYMBAL_1] с рупий X (прописные) [HAND_CLAP] я x (нижний регистр) [HAND_CLAP] рупий
Такой способ создания ритмов может выглядеть забавно и аккуратно, но с его помощью сложно составить джазовый ритм. Во-первых, он намного менее читабелен, а также продолжительность фиксирована, если вы не используете шаблоны для управления им (как мы сделали с Chord Progressions).
К счастью, JFugue также позволяет нам использовать токены ритма со
старыми добрыми Pattern
! Здесь мы добавим ритмы в паттерн с помощью
струны стаккато:
Pattern introRhythm = new Pattern("T180 V9 [CLOSED_HI_HAT]x Rx [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt");
Это очень похоже на то, что мы делали раньше, за исключением того, что
на этот раз мы не используем I
перед каждым инструментом, мы просто
передаем имя ударного инструмента. После названия каждого инструмента
идет x
который, как вы, возможно, помните, является маркером
длительности Sixty-fourth
длины полной ноты. Остальное должно
показаться довольно знакомым.
Давайте поиграем с нашими предыдущими паттернами аккордов и вступлений:
Pattern mainChords = new Pattern("T180 V0 D4Min9hqit Ri G3Maj13hqi Ri C4Maj9wh Rh");
mainChords.add("D4Minhqit Ri G4Majhqi Ri C4Majwh Rht");
Pattern pianoTouch = new Pattern("T180 V1 Rw | Rw | Rhi | G4qi G3s A3is CMajis ri");
pianoTouch.add("Rw | Rw | Rhi | G4s C5wa100d0");
Pattern introOnce = new Pattern(mainChords, pianoTouch);
player.play(introOnce, introRhythm.repeat(8));
Это первая часть вступления, теперь мы добавим немного BASS_DRUM
чтобы
создать наш основной ритм, который должен воспроизводиться на протяжении
всей песни (по крайней мере, по большей части). Добавьте это после
воспроизведения первого вступления:
Pattern mainRhythm = new Pattern("T180 V9 [BASS_DRUM]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rtt [BASS_DRUM]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt [BASS_DRUM]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rtt [BASS_DRUM]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt "
);
Звучит лучше, чем кажется. Давайте попробуем:
Pattern introSecondPart = new Pattern(mainChords, mainRhythm.repeat(2));
player.play(introSecondPart);
Посетите наш репозиторий GitHub, чтобы увидеть полный список ударных инструментов.
Давайте также добавим бас-гитару, чтобы завершить нашу музыку:
Pattern bassGuitar = new Pattern("T180 V3 I[SLAP_BASS_1] D3is D3s Rhq G3is G3s Rqis B2qi | C3is C3s Rhq D3is D3s Rq E3is E3s Rq | D3is D3s Rhq G2is G2s Rqis B2qi | C3is C3s Rhq G3is G3s Rq A3s Ri G3s E3q ");
bassGuitar.add("D3is D3s Rhq G2is G2s Rqis B2qi | C3is C3s Rhq D3is D3s Rq E3is E3s Rq D3is D3s Rhq G2is G2s Rqis B2qi C3is C3s Rhq G3i Ri A3q G3is F3s E3q ");
player.play(bassGuitar);
Прежде чем добавлять бас-гитару в какие-либо паттерны, нам нужно решить,
когда мы хотим, чтобы она играла. Мы не хотим, чтобы он начал
воспроизводиться сразу, вместо этого было бы намного лучше, если бы он
начинался с introSecondPart
.
Что ж, мы не можем использовать тот же трюк, что и с pianoTouch
, по
крайней мере, не совсем так. Мы можем добавить образец тишины,
достаточно продолжительный, чтобы он introFirstPart
и добавить к нему
басовую линию, например:
Pattern bassGuitarSilence = new Pattern("T180 V3 Rw Rw Rw Rw | Rw Rw Rw Rw | Ri");
bassGuitarSilence.add(bassGuitar);
player.play(bassGuitarSilence.repeat(2), introSecondPart.repeat(8));
Но тогда мы не сможем играть ее на повторении, потому что это приведет к
тому, что каждый раз, когда мы играем на нашей бас-гитаре, будет
проходить одинаковое количество тишины. Вместо этого мы передадим
bassGuitarSilence
и bassGuitar
отдельности, без использования
add()
, но все же оставив их в одном голосовом канале.
Таким образом, одному придется подождать, пока другой закончит игру:
player.play(bassGuitarSilence, bassGuitar.repeat(4), introSecondPart.repeat(8));
Вот об этом. Теперь осталось только объединить вокал и аккорды, которые мы создали в предыдущих частях нашей серии руководств, с нашими ритмами, чтобы завершить вступление нашей песни.
Я также немного отрегулировал время от времени, чтобы синхронизировать музыку с ритмом, так что вот окончательная версия:
import org.jfugue.player.Player;
import org.jfugue.pattern.Pattern;
public class MyMusic {
public static void main(String[] args) {
Player player = new Player();
Pattern mainChords = new Pattern("T180 V0 D4Min9hqit Ri G3Majhqi Ri C4Maj9wh Rht ");
mainChords.add(" D4Minhqit Ri G4Majhqi Ri C4Majwh Rht ");
Pattern pianoTouch = new Pattern("T180 V1 Rw | Rw | Rhi | G4qi G3s A3is CMajis ri");
pianoTouch.add(" Rw | Rw | Rhi | G4s C5wa100d0 Rw ");
Pattern introOnce = new Pattern(mainChords, pianoTouch);
Pattern introRhythm = new Pattern(
"T180 V9 [CLOSED_HI_HAT]x Rx [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt ");
Pattern introFirstPart = new Pattern(introOnce, introRhythm.repeat(8));
Pattern mainRhythm = new Pattern(
"T180 V9 [BASS_DRUM]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rtt [BASS_DRUM]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt [BASS_DRUM]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rtt [BASS_DRUM]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [ELECTRIC_SNARE]x [CLOSED_HI_HAT]x [MARACAS]x Rss [BASS_DRUM]x [MARACAS]x Rtt [CLOSED_HI_HAT]x [MARACAS]x Rss [CLOSED_HI_HAT]x [MARACAS]x Rtt ");
Pattern vocalsSilence = new Pattern("T180 V4 Rw Rw Rw Rw | Rw Rw Rw Rw | Rq ");
Pattern vocals = new Pattern("T180 V04 ");
vocals.add("I[TROMBONE] Rh G5is E5i Ri | G5s Ris E5q Rs | G5q E5i Rs D5q rs C5h Rs");
vocals.add("I[ALTO_SAX] C4i A5q G5isa50d0 Rs A5s E5i D5is Rs C5qis");
vocals.add("I[TROMBONE] Rqi A4s G5i E5i Rs | G5is Rs E5q | D5is C5i Rs C5q G4q Ri");
vocals.add("I[TRUMPET] G3is A3s C4is D4s C4is D4s G4is A4s G4is A4s | E4q rs F4h");
vocals.add("I[TROMBONE] G5is E5i Ri | G5s Ris E5q Rs | G5q E5i Rs A5is rs G5q A5s E5i D5i ri C5h Rit");
vocals.add("I[TROMBONE] C5s A3q C5i Rs | D5i Rs Eb5qs Rs | D5q Eb5i Rs D5is Eb5s D4q Rs | C5i A4q C5h Rw Rhi");
Pattern introSecondPart = new Pattern(mainChords, mainRhythm.repeat(2));
Pattern bassGuitarSilence = new Pattern("T180 V3 Rw Rw Rw Rw | Rw Rw Rw Rw | Rq ");
Pattern bassGuitar = new Pattern(
"T180 V3 I[SLAP_BASS_1] D3is D3s Rhq G3is G3s Rqis B2qi | C3is C3s Rhq D3is D3s Rq E3is E3s Rq | D3is D3s Rhq G2is G2s Rqis B2qi | C3is C3s Rhq G3is G3s Rq A3s Ri G3s E3q ");
bassGuitar.add(
"D3is D3s Rhq G2is G2s Rqis B2qi | C3is C3s Rhq D3is D3s Rq E3is E3s Rq D3is D3s Rhq G2is G2s Rqis B2qi C3is C3s Rhq G3i Ri A3q G3is F3s E3q ");
Pattern introThirdPart = new Pattern(introFirstPart, bassGuitarSilence, bassGuitar.repeat(2), vocalsSilence,
vocals.repeat(2), introSecondPart.repeat(4));
player.play(introThirdPart);
}
}
Не стесняйтесь улучшать его или продолжать сочинять всю песню, так как теперь вы знаете почти все, что вам нужно знать!
Сохранение музыки в MIDI-файл с помощью JFugue
Потратив необходимое количество времени и усилий, вы можете создавать
отличные MIDI-песни с JFugue. Отличная музыка становится еще лучше, если
делиться ею с друзьями и близкими. Чтобы поделиться нашей музыкальной
композицией, мы будем использовать метод JFugue savePatternToMidi()
для преобразования наших паттернов в файл MIDI.
Чтобы сохранить нашу музыку в MIDI, сначала нам нужно импортировать
MidiFileManager
а затем передать путь к файлу вместе с нашим шаблоном
(ами):
import org.jfugue.player.Player;
import org.jfugue.pattern.Pattern;
public class MyMusic {
public static void main(String[] args) {
// Our patterns…
try {
File filePath = new File("path/to/your/midi");
MidiFileManager.savePatternToMidi(introThirdPart, filePath);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Проверьте путь к файлу, чтобы убедиться, что ваш MIDI готов к использованию.
Чтение музыки из MIDI-файла с помощью JFugue
Точно так же мы также можем прочитать MIDI-файл и преобразовать его в
паттерны. Мы будем использовать метод loadPatternFromMidi()
для
передачи пути к файлу MIDI и чтения содержимого.
Обратите внимание, что нам также потребуется обработать исключение ввода-вывода:
import org.jfugue.midi.MidiFileManager;
public class MyMusic {
public static void main(String[] args) throws IOException {
Pattern loadedFile = new Pattern();
try {
File filePath = new File("C:\\Users\\Ruslan\\Desktop\\MySundayMorning.midi");
loadedFile = MidiFileManager.loadPatternFromMidi(filePath);
} catch (InvalidMidiDataException e) {
e.printStackTrace();
}
System.out.println(loadedFile);
}
}
На этом мы завершаем нашу серию учебных пособий по библиотеке JFugue, состоящую из трех частей.
Заключение
В этом руководстве мы рассмотрели, как создавать и использовать ритмы в
JFugue с помощью Rhythm
и как использовать встроенный RhythmKit
JFugue для удобного создания ритмов. Мы также узнали, как создавать
ритмы, используя Pattern
со струнами стаккато , и как применять к
нашей песне различные ритмические инструменты. Наконец, мы рассмотрели,
как сохранить нашу музыку в файл MIDI с помощью JFugue и как читать
музыку из файла MIDI с помощью JFugue.
Вы можете ознакомиться с предыдущей статьей, чтобы узнать об аккордах и последовательностях аккордов, а также узнать больше о голосах, характеристиках атаки и затухания: Руководство для начинающих JFugue, часть II: Аккорды и последовательности аккордов .
Или, если вам нужны более подробные сведения об основах JFugue, таких как ноты, октавы, длительность и шаблоны, вы можете ознакомиться с первой статьей: Руководство для начинающих по JFugue, часть I: Примечания, длительности, шаблоны.