Руководство для начинающих по JFugue, часть III: ритмы, чтение и запись в MIDI

Введение В этом руководстве мы узнаем, как создавать ритмы с помощью класса Rhythm, как использовать встроенный RhythmKit JFugue для удобного создания ритма и как применять к нашей песне различные ритмические инструменты. Мы также расскажем, как сохранить нашу музыку в файл MIDI с помощью JFugue и как читать музыку из файла MIDI с помощью библиотеки JFugue. Это третья и последняя часть серии руководств из трех частей, в которой мы пытаемся воссоздать вступление джазовой версии Sund.

Вступление

В этом уроке мы узнаем, как создавать ритмы с помощью класса Rhythm , как использовать встроенный RhythmKit JFugue для удобного создания ритма и как применять к нашей песне различные ритмические инструменты. Мы также расскажем, как сохранить нашу музыку в файл MIDI с помощью JFugue и как читать музыку из файла MIDI с помощью библиотеки JFugue.

Это третья и последняя часть серии руководств из трех частей, в которой мы пытаемся воссоздать вступление джазовой версии Sunday Morning by Maroon 5 . Но шаги, описанные в статьях, легко применимы и к любому другому процессу создания песни.

В первой части серии мы рассмотрели основы библиотеки JFugue, научились использовать ноты, октавы, длительность, темп, инструменты и паттерны. В конце первой статьи мы создали вступительный вокал без каких-либо аккордов. К концу этого урока в нашей песне будут готовые аккорды, которые будут играть вместе с вокалом.

В предыдущей части серии мы узнали, как использовать аккорды и последовательности аккордов в библиотеке JFugue. Мы также рассмотрели, как использовать setKey() , distribute() и allChordsAs() ChordProgression , как одновременно воспроизводить разные паттерны с помощью голосов и как применять свойства атаки / затухания к нотам и / или аккордам.

Вот ссылки на предыдущие части нашей серии руководств по JFugue:

Ритмы в 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: Примечания, длительности, шаблоны.

comments powered by Disqus