Techブログ

Tech blog

Pythonの話

pythonに作曲してもらう

カテゴリ:Pythonの話

2020.07.21

このエントリーをはてなブックマークに追加

こんにちは。inglowの開発担当です。
今回は、近年超キテる「python」を使って、作曲ができないかと思い試してみました。
musicXMLなる形式があると知って思いついたものを実験してみたものです。

開発環境は下記です。

  • バージョン:python3.8.3
  • ライブラリ:music21、markovify
  • エディタ:notepad++、MuseScore3(musicXMLの表示用)

今回作るもの

今回は、「マルコフ連鎖」というアルゴリズムを使用して、pythonに作曲をしてもらいます。
本当は、理論化されていて、伴奏等もできそうではあるのですが…。
今回は、既存のメロディを学習させて、その学習データをもとに作曲をしてもらうことにしました。
今回使用するメロディは、自分が敬愛する、とあるサウンドクリエイターの曲のサビ部分を学習させることにしました。

music21の下準備

music21を便利に使うために少し下準備が必要です。
musicXMLを読み取り・生成ができますが、XMLの形式のままだと、どんなメロディなのか想像がしづらいため、musicXMLから楽譜の形式で表示できるソフトウェアが必要になります。
今回は、以前利用したことがあり、操作方法も何となくわかる「MuseScore3」というソフトを利用することにしました。

ライブラリをインストールして最初に動かす際に、「MuseScore3」の実行ファイルにパスを通す(musicXMLを生成したらこのソフトで表示してね!という設定)必要があります。

この設定をあとから変更する場合は、下記のようなプログラムになります。

楽譜データを読み取る

まずは、musicXMLを作成していきますが、テキストファイルでがしがしつくるのは大変すぎるので、先ほどの工程でインストールした「MuseScore3」で1メロディ=1ファイルになるようにデータを作成していきました。
作成したmusicXMLのファイルを、pythonに読み取らせて、music21によってオブジェクトに変換させます。
また、今回は、複数のファイルがあるため、フォルダの中の「musicXML」ファイルをすべて読み取るような動きにしました。

変数の「piece」が楽譜データのオブジェクトとなります。

楽譜データを学習モデルに変換する

楽譜データのオブジェクトが準備できたら、次は、「markovify」ライブラリで学習モデルが作成できるように、音符のデータをテキストに変換します。
markovifyで文章を作成する際には、文章を、単語ごとにスペースで区切った形に変換するので、今回は、1音毎にスペースで区切っていきます。

ここまででモデル作成のためのテキストデータができました。このデータを、markovifyで学習データに変換してもらいます。

これで、学習モデルが出来上がりました。

生成された作曲データを楽譜に出力する

先ほど生成した学習モデルから、メロディのテキストを生成してもらいます。

これでメロディを作成してもらいましたが、学習モデルと同じ形式のテキストなので、「E_0.5 E_0.5 D_0.5 C#_0.5….」というようなテキストになっています。これを、MuseScore3で表示できるように、musicXMLに変換します。
変換の手順は、先ほどmusicXMLからテキストにした時の逆の手順で行っていきます。

MuseScore3で生成された楽譜が表示されました!
今回のソースの全文は下記のような感じになります。

作成した曲を聞いてみる

表示された楽譜は、MuseScore3の再生機能でそのまま聞くことができます。いろいろなパターンで生成を試してみたので、生成した結果を一部紹介します。

パターン1:読み取ったキー(調)のまま学習モデルにする

調がバラバラなため、次に行く音のデータが少ないのか、結構な確率で生成されないことがありました。

パターン2:読み取った後、主音(キーになる音)を合わせて学習モデルにする

楽譜をそのまま読み取ると、調が合わず、そのまま学習させた時みたいにあちこちしてしまいます。
メロディーが返ってくるべき音(通常、最後になる音)を合わせることで、そのまま学習させるよりも統一感が出てきます。

一番それっぽい感じにできるのではないかなと思っています。主音を合わせることで、次に行く音のバリエーションが増えたのか、生成されないことがありませんでした。

パターン3:読み取った後、調合(楽譜の左にあるシャープとかフラット)を合わせて学習モデルにする

返ってくるべき音が違うものの、楽譜にした時に、左につけておく調号を合わせることでも統一感を出すことができます。
(気になる方は、「五度圏」や、「平行調」というワードを調べていただければと思います。)

主音は違うものの、使っている音はほぼ同じなはずなのですが、全体的に短くしか生成されませんでした。バリエーションが少なすぎるのでしょうか…。

パターン4:全部のメロディを12通りのキーにして学習させる

返ってくるべき音をド~シまでのすべてのパターンに変換したものを学習させました。
カラオケで言うと、キー変更の-6~+6までのパターンを学習させた感じです。

学習データが増えたはずなのですが、増えたからと言ってそれっぽいものがつくれるかとはまた違うみたいですね…。

ここまで総合すると、パターン2の主音を合わせるのが一番メロディ制作がしやすいのかなという感じになりました。
さらに実験で、モデル作成のstate_sizeを触ってみます。
ここまでは、3を設定して生成していたので、1と2も試してみます。

state_size=1

学習したメロディの片鱗はほぼなくなりましたが、生成されたメロディの長さが短いか長いかの二極化してしまいました。

state_size=2

少し元のメロディの片鱗は残っているものの、わりとそれらしくはなりました。

さいごに

せっかくpythonちゃんがメロディを作ってくれたので、一番それっぽかったメロデイに伴奏をつけてあげました。

データが少ないためか、めちゃくちゃだったりメロディアスでなかったりする時もありますが、それなりにそれっぽい感じで生成できたのではないかなと思います。
音楽はやはり、人の気持ちが乗ってこそとも思いますが、人が作るとついつい自分が演奏しやすいように作ってしまうといったこともあるかと思いますので、こういった形で作曲するのもまた新鮮かもしれません。
また、どういった感じになれば人が聞いて気持ちいメロディになるのか等、音楽の研究に使うのも面白いかなと思いました。
人の手が必要になりますが、「○○ぽいメロディだけ」といった風に学習させていけば、悲しい曲、盛り上がる曲といった感じでの作曲もさせられるのかなと思いました。
今度は別のアルゴリズムでも試してみたいです。

一覧へ戻る

記事をカテゴリから探す