MaxからM4L経由でAbleton Liveの小節番号（アレンジメント位置）を制御する

# はじめに

小節や拍などで時間が厳格に管理された楽譜的なものが存在する作品を制作する際、Maxだけで時間管理をするのが大変面倒なケースがあります。

Maxだけで書く場合、例えば1小節1拍目でAというイベント、2小節3拍目でBというイベントを呼び出すときは下のような書き方ができます。また、[sel]オブジェクトなどを使って地道に書いていくという手もあります。しかしイベント数が多くなってきたり小節数の変更が出てきたりすると地獄のような書き換え作業をすることになり泣けます。

![f.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/217195/ec4f16bd-9390-9f7d-e057-58c6e3bab782.gif)

他にも、ある曲の10小節目から25小節目にかけて何某かのパラメータをゆっくり変化させたいなどというときは、これをMaxだけで書ききるのはけっこう嫌な作業になってきます。変化の仕方が線形ならまだ良いですが、変なカーブで変わるとかになるとかなり辛くなってきます。

そこでそういった、**時間にそって起こるパラメータ変化やイベント呼び出しはAbleton Live(+ MIDI)で管理してしまったほうが楽だよね**ということになります。



#具体的な話

##信号の流れ
<img width="946" alt="スクリーンショット 2018-08-14 15.11.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/217195/2eeeff0b-53d1-347a-098d-e7bbf88fdc3a.png">
以降では、他のMasterコンピューターから何曲目/小節/拍番号がudpなどで自分のコンピューターに送られてくるようなケースを考えます。
やるべきことは

- Abletonに諸々の情報を書き込んだMIDIクリップを用意
- 受け取った小節/拍番号とAbletonの再生位置が同期するようにする。
- 曲の切り替えにも対応したい。
- MIDIクリップの情報をoFなりMaxに返す。

注)上図では、はじめにMax7を介してAbletonに小節番号など送っていますが、Max for Liveで直接信号を受け取っても何ら問題ありません。



##Live上のMIDIデータ


さてまず、Ableton LiveにはイベントのタイミングでMIDI noteやらMIDI CCを飛ばすようなMIDIクリップを作って曲ごとに並べます。

例えば、C1でイベントAを呼び出すとか、D2でイベントBを呼び出すというようなことや、或いはMax/oFのパラメーターを時間に沿って毎回決まったように制御したい場合は、MIDI CCをつかって図右下のようにパラメーターの時系列を書き込んでやって、これをMaxやらoFで受け取るようにします。ただし、MIDI CCは基本的に0~127のintなので、場合によっては解像度荒くてだめな場合もあるかと思います。そういうときは代わりにPitch Bendを使います。

<img width="1146" alt="スクリーンショット 2018-08-14 12.49.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/217195/320b7cee-6ce6-4d7c-3a67-edc6c3400628.png">

このMIDIクリップからの情報は、LiveでMIDI出力先をto Max1などとしてやれば、Max側では[ctlin]や[notein]を使うことで受け取ることができます。oFなどに送るときは（僕は）一度MaxでMIDI CCとして受け取ったのちOSCに変換してoFに送るということをします。（もしかするとすごく遠回りをしているの可能性あり）
<img width="85" alt="スクリーンショット 2018-08-14 13.50.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/217195/a86b6415-fd37-6fde-af4e-c55e63cde6c9.png">


##MaxからAbleton Liveにアクセス
###1. Live API
さて、Ableton　Liveは大抵のパラメータはMIDIで制御できるのですが、不幸なことに小節数などにはMIDIメッセージをアサインできません。

<img width="1061" alt="スクリーンショット 2018-08-14 1.38.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/217195/4c74a014-cc64-9c07-fcfa-af4aafa82dfa.png">
[Fig: MIDIマップモードスイッチを押すとMIDIをアサインできる箇所は紫色で囲まれる。しかし小節番号（7.4.1と書かれている場所）は制御できない。]

そこで登場するのがLive APIです。
[Live API Overview](https://docs.cycling74.com/max6/dynamic/c74_docs.html#live_api_overview)
[Controlling Live using Max for Live (Tutorial)](https://help.ableton.com/hc/en-us/articles/209071389-Controlling-Live-with-Max-for-Live-Lesson-1)

Live APIとは
>Besides building new instruments and effects to be used in Live, Max For Live also allows to access Live itself, its tracks, clips, devices and hardware control surfaces. This chapter defines some basic terms used throughout the whole Live API and introduces the Max objects representing the Live API.

ということで、雑に言うとMax for LiveでAbleton Liveのもうちょっと深いところを制御するためのものです。

APIはLive Object Modelとして階層構造になっており、何が制御できて何ができないのかはこれを参考にすることでわかります。
[Live Object Model](https://docs.cycling74.com/max6/dynamic/c74_docs.html#live_object_model)

###2. 再生/停止　BPM変更　再生場所移動
今回使うのは[live.object]と[live.path]です。これに下の図のようにメッセージを送ってやるとAbleton Liveも追従します。横の[live.thisdevice]などは、M4Lに自分自身のidを教える的なものだと思っています（自信なし）。

<img width="633" alt="スクリーンショット 2018-08-14 11.29.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/217195/cb851001-6e7e-c021-e3b2-bf48b59e406a.png">
<pre><code>
----------begin_max5_patcher----------
695.3oc0WtsaiBCDF9ZxSAxZujFg4TH6qR0JjCYTpqBFjsIapp5695CjDuaK
A1D2tZiTPBiy7OyG+y.40EAnMsGAAJ76gOFFD75hf.yR5EBFNO.0PNVumHLa
Cw5a1.bTj8RcbP.LIQRaY5KiGVusWtGjxW5.arQnnPzFBaGJ7GCaQHeYu4pn
yAiHqehx1UwgZo82kjUtLNJbcr9Xt4Xh534fnxFJSojvUb2jxMVw45eeYwHw
ht0jMsad9Ab7kbhSZ.Ivq.FYiMgiuHtsNMpmnW7sEKzGhlILa.gfrCNIlDNZ
xUj.jgTQU2dxKJdD9MLZTtdS7Dmtxf00WGnIS.zoBlCQKQeHzv2.z9Zcf3zx
kkwpOo90FhWOCaX9+danDZ5Z8nCzkmCNmUk2kMbdQzAqq7nWD9oJhuCbODNN
unL4eIxJxcZyRVuL+Nf0TwxASE+u1xZqQe1rlmMcyZxWSu5HNt8zCvR4STwV
3.sFF08YvYj0EFcKlwz3B63Ky7qxr6BuSFLG9l8w1wTOOuqtmyUYZknUU1RZ
C3wYeCMeqLMe3rr6Zr2jAy0ah8Wu7XvSUuOEpsgUJL5KhMXPRRLFDasdyDax
f49nW7m9CILsrZpgt17Oy2aCZEXyTqTezhNdvbfVt+ZQuFyTWPmddsoLEasC
Ewdno7JAygVoi3vNk7jCv1JasVQjRNcSuz9e0BNCs.TUGvETgDX0vYCpk1mX
tQbE5X+4+zyPC85+9MBQaOu9DMGd48vKkvVPHoryO89wyUidOe3s54pypuHc
JlgN5Ql2sP4yrfv2oNYyPGrOJnST4S+VTxLzovC5fmysnU9Pn4PtbeHT7LDp
7cBYGRP55NnmmX2rQC0b4ma45SKiLmRY1SMuSKhqdeyS62tBgqFwJUSs541g
uGKru6FpocKvY8zg4TJkeawu.X8mIUL
-----------end_max5_patcher-----------
</code></pre>

messageの内容はそれぞれ

- set current_song_time $1: 再生ポジションを制御します（ただし拍でしか制御できない）
- set tempo $1: BPMをいじれます。
- set is_playing $1: Liveの再生/停止を制御します。0で停止、1で再生。

となっています。current_song_timeは残念ながら(小節　拍)のような値の受け取り方はできません。普通の4拍子の曲であれば

```math
（小節-1)*4 + 拍
```
でOKですが、変拍子になると要検討です。

###3. Track mute
<img width="507" alt="スクリーンショット 2018-08-14 14.47.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/217195/f79fc341-f699-19f9-60ea-1707d6ca21ec.png">

次は曲の切り替えをmuteを使って行います。これも同じく[live.object]と[live.path]を使います。割とややこしいパッチなので、下のコードをコピペしてみてください。

<pre><code>
----------begin_max5_patcher----------
940.3oc4Y1sjZCBEG+53SQFt15.AHF6csuF6zwIpzcy1XhCAstcm8cuAHYkZ
UIZHX6r2nSH34OmemCG9vWGE.VTtmUAB+b3CgAAuNJHP0jrgflmC.qS2uLOs
R0MPA6mkKdFLV+JAauP0bEKOD11Z4VQNSHdYCSaYvhzhGAiCAfvu0zkJwK4p
2BZ+QaREKeJq3w4b1Rg92ghRl.GGFQUegwpGfSfuakhsqyJpkRMzhZMDmUwJ
DohrxhqwXYqTimZu6SnHvAEzdiVBYiuMZj7iw8GXXWCrnjjISothX1slAxhQ
dAYQNGY0Nj6HlMiYBLnW.Fx4SJSfNbRoMiY.L5LGBrsqWv3fSL3juFcNjIwk
Ba2TcLTRj7qjYxOo3ygLzkQVLTOqjN8LFyDYIGFU7z0LAiOmUjtPOjgMu66k
EhpreoZiHiGthxqYUUoOx9q7xZD8TXd1N17JlHTvSW9ipKLy9.skizhZ+PYk
uvyRyC+ZY9Jv0DLHIH4bTBDohInndk.a2ZlgCJ3DHGcNjiFZji7Exopxh3Xp
SPtUqYh73+sPtuxxiHXGlka2ZlHm7wLKOB4xrb6VyD436Fxkfd8VAyeESfps
LPQJvDC6WsDaFy.xjgu58Y1GmHbQX9UrONGhYRhZaFSST6qEdi6YwpwLw70U
w1gaWVV3XhrDB3R6+y8nFmnx9HTpNW7xYzVPsUiYh5oWEpwCckZnmJgzvHL1
IKNZ2ZlHmb+qT6KLilQcWkZqFy.xX7GoJ0MjwMUpsZLSLO8tVot9ExgseykI
ZtLyI4xm0XlPN45xkacpzcrUy0HZdpPvyVTO0upA0MrN.LeCiWkUIXEKYuOU
PGj9OeQ0laVxMKpZ0XlArYeLWTsgQNZQU6VybQU3MWuWYt5jzhi+WPTdnr8+
LNTUtkurEfs26c3gQ0JVkHq38aR7gC2BgQmJ4qXb0MvcxfuaklbZoiFdoImQ
ZT+jF1EulNH.uSRiGDfCua.Wdu62bFtOjdPh0cRZBbHh0xas2pzGMCzUdcmj
FNHw5tH8QQEeBb4+I7ojF2Ooi6RZ1Tcm5mRTuoDoCJgm4Bkv9RIEXP1nWrKT
pSYDTWojMeRd9CYm5mRcI2Cm3Beh3qrbBzW4dJiXMN4BeBO0WYDsC2KqD1E9
D1W4dGsBgO2nT2jdP1nTmjlzgSgnOJV5lM6j2Ig9mqTs9vuOWp5dxX0iYE5G
UGuCvY6xZ6utkTd8gSE0mkbKWer08w5qcErtrV3hsYMDuV42F8a.mx47VA
-----------end_max5_patcher-----------
</code></pre>

まず、live.pathを使ってどのトラックをミュートするのか選択し、その後live.objectでmuteのon/offをするという流れです。

- path live_set tracks \$1: トラック番号(\$1+1)を指定
- set mute $1:  muteのオンオフ

下の動画のような挙動をします。

![画面収録.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/217195/7933102e-2f70-6a05-5cc0-c3d128046970.gif)


後は、各パラメータに[udpreceive]でもつけて、外からいじれるようにすれば終わりです。




*ちなみにM4Lの中にudpreceiveを書くときの注意点ですが、Live内で編集ボタンを押してパッチを編集するとパケットはLive内のM4Lではなく、編集のために立ち上がっているMaxの方に送られるため編集が終わったらMaxを一度落とす必要があります。

*逆にLiveの現在の再生ポジションをどこかしらに送るときは下のパッチが使えそう。

<img width="431" alt="スクリーンショット 2018-08-14 12.25.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/217195/b02a3848-d59d-7572-fb08-6e9cdcfa452b.png">

#終わりに

この記事で書いたような話、意外に日本語での情報が皆無だったので自分なりにまとめてみましたが、特にリファレンスがあるわけでもなく組んだ仕組みなので、もし「もっといいやり方あるよ」というかたはぜひご連絡くださいませ。