갈루아의 반서재

 

Magenta로 음악만들기

Magenta 는 회화 및 음악을 생성해주는 파이썬 라이브러리이다. 아래에서는 note_seq 라이브러리를 활용하여 주피터랩을 통해 브라우저가 연주하는 것을 구현해보자.

 

Magent 및 관련 패키지 설치

Magenta 를 사용할려면 당연히 Magenta 부터 설치해야 한다. 먼저 패키지 인덱스 정보를 업데이트한다.

(pluto) fossa@fossa:~$ sudo apt-get update

이제 Magenta 관련 패키지를 설치한다. 하지만 시작부터 다음과 같은 에러가 발생했다.

E: Package 'libfluidsynth1' has no installation candidate 

 

현재 실습환경은 Ubuntu 20.04 인데 원문의 코드는 Ubuntu 18.04 기반이기 때문에 생기는 에러다.

(pluto) fossa@fossa:~$ sudo apt-get install libfluidsynth1
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package libfluidsynth1 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'libfluidsynth1' has no installation candidate

따라서 여기에 나와있듯이 Ubuntu 20.04 와 호환되는 패키지를 설치하여 진행하면 된다.  즉, libfluidsynth1 이 아니라 libfluidsynth2 패키지를 설치해야하는 것이다.

libgfortran3 -> libgfortran5
gudev-1.0 -> gir1.2-gudev-1.0
libusb-1.0.0-dev -> libusb-1.0-0-dev
libfluidsynth1 -> libfluidsynth2
libnettle6 -> libnettle7
libopenexr22 -> libopenexr24

아래 스크린샷에서 보듯이 Ubuntu 20.04 의 경우 libfluidsynth2 패키지를 설치해야 한다.

(pluto) fossa@fossa:~$ sudo apt-get install libfluidsynth2

계속해서 추가적으로 필요한 패키지를 다음과 같이 설치한다. 물론 아래와 같이 하나씩 설치할 필요는 없다. 

(pluto) fossa@fossa:~$ sudo apt-get install fluid-soundfont-gm
(pluto) fossa@fossa:~$ sudo apt-get install build-essential
(pluto) fossa@fossa:~$ sudo apt-get install libasound2-dev
(pluto) fossa@fossa:~$ sudo apt-get install libjack-dev
(pluto) fossa@fossa:~$ pip install -qU pyfluidsynth pretty_midi

 

마지막으로 magenta 를 설치한다. 하지만 다음에서 보듯이 버전이 맞지 않는 에러가 발생했다. 

(pluto) fossa@fossa:~$ pip install -qU magenta
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
tensorflow-cpu 2.2.1 requires numpy<1.19.0,>=1.16.0, but you have numpy 1.19.2 which is incompatible.
tensorflow-cpu 2.2.1 requires tensorboard<2.3.0,>=2.2.0, but you have tensorboard 2.4.0 which is incompatible.
tensorflow-cpu 2.2.1 requires tensorflow-estimator<2.3.0,>=2.2.0, but you have tensorflow-estimator 2.4.0 which is incompatible.

아래 3개의 라이브러리를 버전을 지정하여 재설치해야한다. 각각의 릴리스 정보를 확인하여 해당 범위에 맞게 재설치한다.

 

numpy<1.19.0,>=1.16.0 (현재 1.19.2 설치되어 있음) : 1.19.0 직전 버전은 1.18.5 이다.
tensorboard<2.3.0,>=2.2.0 (현재 2.4.0 설치되어 있음) : 2.3.0 직전 버전은 2.2.2 이다.
tensorflow-estimator<2.3.0,>=2.2.0, (현재 2.4.0 설치되어 있음) : 2.3.0 직전 버전은 2.2.0 이다.

(pluto) fossa@fossa:~$ pip install numpy==1.18.5
(pluto) fossa@fossa:~$ pip install tensorboard==2.2.2
(pluto) fossa@fossa:~$ pip install tensorflow-estimator==2.2.0

magenta 설치가 끝났다.

(pluto) fossa@fossa:~$ pip install -qU magenta

설치된 버전을 확인해보자.

import magenta
import note_seq
import tensorflow

print('🎉 Done!')
print(magenta.__version__)
print(tensorflow.__version__)

🎉 Done!

2.1.3

2.2.0

 

 

NoteSequences로 사운드 생성하기

Magenta 라이브러리는 NoteSequences를 중심으로 전개된다.

 

magenta/note-seq

A serializable note sequence representation and utilities. - magenta/note-seq

github.com

이는 일련의 음표의 추상적 표현으로 각각은 서로 다른 피치, 악기 그리고 타건강도로 이루어진다. 예를 들어, 아래는 "반짝 반짝 작은별"을 표현하는 NoteSequence 로 피치를 바꿈으로써 소리가 어떻게 달라지는지 직접 확인해볼 수 있다.

from note_seq.protobuf import music_pb2

twinkle_twinkle = music_pb2.NoteSequence()

# Add the notes to the sequence.
twinkle_twinkle.notes.add(pitch=60, start_time=0.0, end_time=0.5, velocity=80)
twinkle_twinkle.notes.add(pitch=60, start_time=0.5, end_time=1.0, velocity=80)
twinkle_twinkle.notes.add(pitch=67, start_time=1.0, end_time=1.5, velocity=80)
twinkle_twinkle.notes.add(pitch=67, start_time=1.5, end_time=2.0, velocity=80)
twinkle_twinkle.notes.add(pitch=69, start_time=2.0, end_time=2.5, velocity=80)
twinkle_twinkle.notes.add(pitch=69, start_time=2.5, end_time=3.0, velocity=80)
twinkle_twinkle.notes.add(pitch=67, start_time=3.0, end_time=4.0, velocity=80)
twinkle_twinkle.notes.add(pitch=65, start_time=4.0, end_time=4.5, velocity=80)
twinkle_twinkle.notes.add(pitch=65, start_time=4.5, end_time=5.0, velocity=80)
twinkle_twinkle.notes.add(pitch=64, start_time=5.0, end_time=5.5, velocity=80)
twinkle_twinkle.notes.add(pitch=64, start_time=5.5, end_time=6.0, velocity=80)
twinkle_twinkle.notes.add(pitch=62, start_time=6.0, end_time=6.5, velocity=80)
twinkle_twinkle.notes.add(pitch=62, start_time=6.5, end_time=7.0, velocity=80)
twinkle_twinkle.notes.add(pitch=60, start_time=7.0, end_time=8.0, velocity=80) 
twinkle_twinkle.total_time = 8

twinkle_twinkle.tempos.add(qpm=60);

# This is a colab utility method that visualizes a NoteSequence.
note_seq.plot_sequence(twinkle_twinkle)

# This is a colab utility method that plays a NoteSequence.
note_seq.play_sequence(twinkle_twinkle,synth=note_seq.fluidsynth)

# Here's another NoteSequence!
teapot = music_pb2.NoteSequence()
teapot.notes.add(pitch=69, start_time=0, end_time=0.5, velocity=80)
teapot.notes.add(pitch=71, start_time=0.5, end_time=1, velocity=80)
teapot.notes.add(pitch=73, start_time=1, end_time=1.5, velocity=80)
teapot.notes.add(pitch=74, start_time=1.5, end_time=2, velocity=80)
teapot.notes.add(pitch=76, start_time=2, end_time=2.5, velocity=80)
teapot.notes.add(pitch=81, start_time=3, end_time=4, velocity=80)
teapot.notes.add(pitch=78, start_time=4, end_time=5, velocity=80)
teapot.notes.add(pitch=81, start_time=5, end_time=6, velocity=80)
teapot.notes.add(pitch=76, start_time=6, end_time=8, velocity=80)
teapot.total_time = 8

teapot.tempos.add(qpm=60);

note_seq.plot_sequence(teapot)
note_seq.play_sequence(teapot,synth=note_seq.synthesize)

다른 악기의 경우 해당 시퀀스가 어떻게 연주되는지도 확인할 수 있다. 다음과 같이 is_drum=True 를 추가함으로써 드럼 솔로의 경우 어떻게 재생되는지 확인할 수 있다.

 

drums = music_pb2.NoteSequence()

drums.notes.add(pitch=36, start_time=0, end_time=0.125, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=38, start_time=0, end_time=0.125, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=42, start_time=0, end_time=0.125, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=46, start_time=0, end_time=0.125, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=42, start_time=0.25, end_time=0.375, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=42, start_time=0.375, end_time=0.5, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=42, start_time=0.5, end_time=0.625, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=50, start_time=0.5, end_time=0.625, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=36, start_time=0.75, end_time=0.875, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=38, start_time=0.75, end_time=0.875, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=42, start_time=0.75, end_time=0.875, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=45, start_time=0.75, end_time=0.875, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=36, start_time=1, end_time=1.125, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=42, start_time=1, end_time=1.125, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=46, start_time=1, end_time=1.125, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=42, start_time=1.25, end_time=1.375, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=48, start_time=1.25, end_time=1.375, is_drum=True, instrument=10, velocity=80)
drums.notes.add(pitch=50, start_time=1.25, end_time=1.375, is_drum=True, instrument=10, velocity=80)
drums.total_time = 1.375

drums.tempos.add(qpm=60)

# This is a colab utility method that visualizes a NoteSequence.
note_seq.plot_sequence(drums)

# This is a colab utility method that plays a NoteSequence.
note_seq.play_sequence(drums,synth=note_seq.fluidsynth)

 

이어지는 포스팅에서 추가적인 내용을 살펴본다. 

 

관련링크

colab.research.google.com/github/cpmpercussion/creative-prediction/blob/master/notebooks/3-zeldic-musical-RNN.ipynb#scrollTo=0l9YYFrooSKf

www.analyticsvidhya.com/blog/2020/01/how-to-perform-automatic-music-generation/

colab.research.google.com/notebooks/magenta/hello_magenta/hello_magenta.ipynb