1
@shoichi316

ReaperとTouchDesignerでアルゴリズム作曲がしたい

やりたいこと

アルゴリズム作曲といえばMax/MspやPure Dataなどを思い浮かべる人が多いと思いますが、基本的にこれらのツールはリアルタイムで音楽を生成することに長けているかわりにタイムライン的に音を配置していくような作曲は少々やりずらく感じます。
そこでRaeperというDAWを使って、より一般的なDAWっぽい操作感でアルゴリズム作曲をしたいと考えました。

Reaperについて

ReaperはオープンソースのDAWであり、無料でも使えるため、DTM初心者がとりあえず手を出すDAWソフト、という印象を持っている方も多いと思います。ですが実際は非常に多機能かつ拡張性のあるソフトなんです!
quiita.png
中でもReascriptという機能はlua, eel, python用に用意されているAPIを用いることで書き出しの自動化やマクロの作成、エフェクトの作成などができるようになります。
このReascriptをPythonで使って簡単なアルゴリズム作曲をしてみます。

CSVファイルの準備

今回はアルゴリズム作曲というか現代音楽でよくありがちなデータマッピングで音楽を作る手法をやってみます。音楽におけるデータマッピングについては松本昭彦さんのこのページ http://akihikomatsumoto.com/maxmsp/guido.html が非常にわかりやすいと思います。
今回は芸術的な云々ということはおいておき、CSVファイルの情報からMIDIノートを生成してみます。
今回使わせていただいたデータは http://www2.obirin.ac.jp/tsubota/eq/menu3.html ここで公開されている地震発生時刻と震源の深さ、発生地点の移動経度などがまとめられているのデータです。
スクリーンショット 2021-05-08 192615.png
まずはこのデータをTouchDesignerを使って扱いやすくしていきます。
今回はなるべくシンプルにするために発生時刻、発生地点の緯度、震源の深さの3つデータを発音タイミング、ピッチ、ベロシティにマッピングすることにします。
まず、TouchDesignerに先ほどのCSVを読み込みます。
TouchDesigner 2021.12380_ C__Users_akkir_Documents_Touchdesigner_csv_for_reaper.toe_ 2021_05_08 20_30_40.png
TouchDesignerでは難しいことはやらない(というか使わなくてもいいけど視覚的にデータ処理がしやすいから使う)ので細かい説明は省きます。
発生時間の時間単位を掻けたり足したりしてhourにまとめて一年間を一列の時単位にまとめます。
TouchDesigner 2021.12380_ C__Users_akkir_Documents_Touchdesigner_csv_for_reaper.toe_ 2021_05_08 20_38_00.png
発生時間と緯度と震源の深さをそれぞれ発音タイミング、ピッチ、ベロシティに最適な値となるようにレンジを調節し、ピッチ、ベロシティに関しては0-127の整数にしておきます(MIDI規格の範囲)。発音タイミングに関しては今回書くプログラムでは秒指定になるので、そのつもりでレンジを調節します。
TouchDesigner 2021.12380_ C__Users_akkir_Documents_Touchdesigner_csv_for_reaper.toe_ 2021_05_08 20_44_50.png
fileout datでCSVファイルとして書き出します。
スクリーンショット 2021-05-08 205216.png
3列目(深度のデータ)は計測されていない部分もあるので欠けていますが問題ありません。

Reaperの準備

Reaperで準備することはトラックを一つ作って任意の名前を付け、media item(MIDIノートを入力できるボックス)を一つ作っておくだけです。media itemはトラック上でctrlを押しながらドラックすると作成できます。これらもReascriptで自動化することはできますが今回はMIDIノートの生成だけのプログラムを書きます。
[unsaved project] - REAPER v6.28 - EVALUATION LICENSE 2021_05_08 21_07_50.png

Reascript

Reascriptでpythonを使う場合は設定が必要になります。
Options > Preferenecs > ReaScriptのpythonの有効化にチェック入れ、python.dllのパスと名前を入れることでpythonでreascriptが使えるようになります。
スクリーンショット 2021-05-08 211845.png
tomoさんのnoteにわかりやすくのっています。
https://note.com/suntomo/n/nac439dbafb66

次にメニューバーのActionsからShow action listをクリック→開いたウィンドウの右下のNew actionをクリック→New reascriptを選択し.pyで任意の名前で保存します。
スクリーンショット 2021-05-08 212806.png
するとこのようなウィンドウが出るので
[unsaved project] - REAPER v6.28 - EVALUATION LICENSE 2021_05_08 21_31_43.png
以下のコードを貼り付け、トラック名とcsvのパスを入れます。

csv_for_reaper.py
from csv import reader

search = "自分でつけたトラック名"
notelength = 3 

ppq = 960

with open(r'csvデータのパス', 'r') as csv_file:
    csv_reader = reader(csv_file, delimiter = '\t')
    notelist = list(csv_reader)

notenum = len(notelist)

tracknum = RPR_CountTracks(0)
for index in range(tracknum):
    track = RPR_GetTrack(0,index)
    name = RPR_GetSetMediaTrackInfo_String(track, "P_NAME","", False)[3]
    if name == search:
        trackindex = index

item = RPR_GetMediaItem(0, trackindex)
take = RPR_GetMediaItemTake(item, 0)
for addnote in range(notenum):
    startsec = float(notelist[addnote][0])*ppq
    endsec = startsec + (notelength*ppq)
    pitch = int(notelist[addnote][1])
    velocity = int(notelist[addnote][2])
    RPR_MIDI_InsertNote(take, True, False, startsec, endsec, 0, pitch, velocity, False)

保存すると同時に実行されるはずなので、うまくいけばこのようにmidiノートが生成されます。
[unsaved project] - REAPER v6.28 - EVALUATION LICENSE 2021_05_08 21_44_35.png
うまくいかなかった場合は
・csvライブラリが入ってない
・トラック名が間違ってる
・csvのパスが間違ってる
などが考えられると思います。
エラーメッセージも出るのでそれを読んでみてください。

pythonプログラムについて軽く説明すると

csv_for_reaper.py
with open(r'csvデータのパス', 'r') as csv_file:
    csv_reader = reader(csv_file, delimiter = '\t')
    notelist = list(csv_reader)

notenum = len(notelist)

ここでcsvを読み込んでリスト化し、リストの数を取得しています。

csv_for_reaper.py
tracknum = RPR_CountTracks(0)
for index in range(tracknum):
    track = RPR_GetTrack(0,index)
    name = RPR_GetSetMediaTrackInfo_String(track, "P_NAME","", False)[3]
    if name == search:
        trackindex = index

ここで任意の名前のトラックを探し、

csv_for_reaper.py
item = RPR_GetMediaItem(0, trackindex)
take = RPR_GetMediaItemTake(item, 0)
for addnote in range(notenum):
    startsec = float(notelist[addnote][0])*ppq
    endsec = startsec + (notelength*ppq)
    pitch = int(notelist[addnote][1])
    velocity = int(notelist[addnote][2])
    RPR_MIDI_InsertNote(take, True, False, startsec, endsec, 0, pitch, velocity, False)

ここでリスト化したcsvのデータを取り出してstartsec(発音タイミング),pitch,velocityに代入するのをリストの数ぶんforでくりかえしています。
あたまにRPRがついているのはreaperのAPI functionなので詳しくは
https://www.reaper.fm/sdk/reascript/reascripthelp.html
こちらを参照してください。

基本は以上です!
かなりいろんなことができそうなので、これからもちょくちょくやっていこうと思ってます!
私はコードベースのプログラミングが得意ではないのでおかしい部分などもあると思いますが、もしよかったら教えていただけると幸いです。

1
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
shoichi316
Touchdesignerやゲームエンジン、メディアサーバを連携させた映像システムを組む仕事をしています。

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
フロントエンド強化月間 - 開発する上で知っておくべき知見を共有しよう
~
Azure AIを活用した機械学習に関する記事を投稿しよう!
~