TwitterとMIDI/MQTTを組み合わせて自動作曲してみようハンズオン

本資料は2019/11/22 株式会社ウフルにて開催された「TwitterとMIDI/MQTTを組み合わせて自動作曲してみようハンズオン」の資料です。
https://enebular.connpass.com/event/144948/

## 今回作るもの

Twitterの特定のハッシュタグを取得して、内容をもとにメロディを自動で作曲してくれる装置を作ってみましょう！

こちらが実際のデモ動画です。(今回はもう少し簡単なものを作ります。)
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">明日の <a href="https://twitter.com/hashtag/IoTLT?src=hash&amp;ref_src=twsrc%5Etfw">#IoTLT</a> で発表予定のハッシュタグのツイートの勢いで自動で作曲する機械の動画です。ご査収ください。 <a href="https://t.co/ZCHaG7tYMD">pic.twitter.com/ZCHaG7tYMD</a></p>&mdash; takayama.k (@pco2699) <a href="https://twitter.com/pco2699/status/1165990908673658884?ref_src=twsrc%5Etfw">August 26, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## システム構成

以下の構成で作ります。
![IoTLT vol.54 @IIJ (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/c74f0533-8835-f994-9eb5-eaf5006dd3f0.png)


## 事前準備
Node.jsなどその他のライブラリのインストール・APIへのサインアップは[本資料](https://scrapbox.io/prepared/%E4%BA%8B%E5%89%8D%E6%BA%96%E5%82%99)を参考にしてください。


## ハンズオンの流れ
1. MIDI/MQTTでリモート演奏できる仕組みを作る
1. enebularとつないでみる
1. Twitterで自動作曲してみる

## MIDI/MQTTでリモート演奏できる仕組みをつくる
まずは、構成の中でMIDI/MQTT部を作りましょう。

先程の構成でいうと次の図の赤線部です。
![IoTLT vol.54 @IIJ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/97d8a202-1950-ad58-055d-6ef9e0c5d961.png)

この図を更に詳しく説明すると次の通りです。
MQTTブローカーと呼ばれる仲介サーバーを通して、シンセとenebularを接続してリモートで演奏できるようにします。
![enebular](https://i.gyazo.com/4a9df358e47b4f12387f491121023e43.png)

### シンセ
今回は環境構築手順を簡単にするためWeb上のシンセを使います。
Chromeで↓のページを開いてください。
https://webaudiodemos.appspot.com/midi-synth/index.html


### 動作確認しよう
106.jsとLoopMidi(Windowsのみ)とPocketMIDIを立ち上げて
必要な設定を行います。

![Web Audio MIDI Synthesizer - Google Chrome 2019-11-23 14.36.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/c9df998f-d858-b5e1-0823-3c58540f4738.png)


#### PocketMidi
PocketMidi
PocketMidi -> OutputPort -> LoopMidi Port or 先程設定したポート名
Pocket MIDI上の鍵盤を叩いて音が鳴ればOKです！

#### midi2mqtt
事前にインストールしたmidi2mqttに必要な引数を与えて、実際に立ち上げてみましょう

```cmd
$ midi2mqtt -i "loopMIDI Port 0" -o "loopMIDI Port 1" -u "mqtt://cmxwoqlw:XXXXXX@m16.cloudmqtt.com:16282" -t "pco2699/midi"
```
(XXXXXXはパスワードのため隠してあります。)
-i -> インプット用のMIDIポート
-o -> アウトプット用のMIDIポート
-u -> MQTTサーバの情報
-t -> (任意の名前(Twitterのアカウント名とか))/midi  にしてください

Macの場合

```cmd
midi2mqtt -i "IACDriver 1" -o "IACDriver 2"  -u "mqtt://cmxwoqlw:Mm3nZNSYHcpp@m16.cloudmqtt.com:16282" -t "pco2699/midi"
```

以下のコマンドでMIDIインプット/アウトプットポートを確認することができます。
外部のシンセを利用する場合は、このコマンドで、オプション `-i`、オプション `-o`をそれぞれ適宜自分のインプットポート、アウトプットポートに書き換えましょう。

```cmd
$ midi2mqtt
2019-11-23 14:24:51.399 <info>  midi2mqtt 1.1.0 starting
2019-11-23 14:24:51.405 <info>  mqtt trying to connect to mqtt://127.0.0.1
2019-11-23 14:24:51.488 <info>  Available MIDI inputs:  [ 'loopMIDI Port 0' ] -> MIDIインプットポート
2019-11-23 14:24:51.493 <info>  Available MIDI outputs:  [ 'Microsoft GS Wavetable Synth 0', 'loopMIDI Port 1' ] -> MIDIアウトプットポート
```cmd

以下の形でコマンドが出力されれば問題なく動いています。

```
 λ midi2mqtt -i "loopMIDI Port 0" -o "loopMIDI Port 1" -u "mqtt://cmxwoqlw:XXXXXX@m16.cloudmqtt.com:16282" -t "pco2699/midi"
 2019-04-21 18:14:21.456 <info>  midi2mqtt 1.1.0 starting
 2019-04-21 18:14:21.463 <info>  mqtt trying to connect to mqtt://cmxwoqlw:XXXXXX@m16.cloudmqtt.com:16282
 
 RtMidiIn::cancelCallback: no callback function was set!
 
 2019-04-21 18:14:21.550 <info>  Available MIDI inputs:  [ 'loopMIDI Port 0' ]
 2019-04-21 18:14:21.552 <info>  Available MIDI outputs:  [ 'Microsoft GS Wavetable Synth 0', 'loopMIDI Port 1' ]
 2019-04-21 18:14:21.917 <info>  mqtt connected mqtt://cmxwoqlw:XXXXXX@m16.cloudmqtt.com:16282
 2019-04-21 18:14:21.918 <info>  mqtt subscribe pco2699/midi/in/+/+/+
```

これでPocketMIDIのキーボードを叩いて、前のmother32から音が鳴ればリモートでの演奏環境が完成です。
-t の後の文字列（トピック名と言います。）はあとで使うのでメモっておいてください。

### 補足説明: MQTTとは
![Hoge](https://i.gyazo.com/c8d7d9c6cb9380643c8285311ac23f13.png)

## enebularとつないでみる
さきほどのMIDI/MQTTをenebularとつないでみましょう
https://enebular.com/

### お手本flowをDiscoverで取り込んでみよう
今回つくるものを事前に私がDiscover機能という機能で公開してあります。
それを、取り込んでみて、音が鳴るか確認してみましょう。

#### プロジェクトの作成
![Hoge](https://i.gyazo.com/f559a44d6fd7d2ccc3ba8eb59c72c444.png)
Project名 -> midibular (その他適当な名前でOK)

#### Discoverで取り込み
Projectが出来たら、以下のリンクをクリックしましょう。
https://enebular.com/discover/flow/be605e0c-c316-4c72-a7ab-07bb34bf7a4d

クリックしたら次の画像の通り、自分のプロジェクトに取り込みましょう。
![](https://i.gyazo.com/693e2ba6330b6046afc0047410e27031.png)
![](https://i.gyazo.com/2b1068dbb5a06a105f659b28d9fd2a92.png)
![](https://i.gyazo.com/6028bf7c156bf211b9af979c606f5abb.png)

#### MQTTブローカーのユーザ名やMQTTトピック情報を設定する
flowを取り込んだだけだと、現状は動きません。
MQTTブローカーのユーザ名などの情報が消えてしまっているためです。
そのため、ユーザ名を設定しましょう。
（変更すべき箇所はすべてflowにコメントしてあるので、それを参考にしても問題ありません。）

##### MQTTブローカーのユーザ名・パスワードの設定

まずはMQTTブローカーのユーザ名・パスワードを設定します。
以下をダブルクリックしましょう。
![enebular Flow Editor - Google Chrome 2019-11-18 21.33.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/bd579213-7c9b-1e3a-8b82-92354a240b99.png)

右にメニューが出てくるので鉛筆マークを次の通りクリック
![](https://i.gyazo.com/6395cc2bf4fbff093c0aae25510092de.png)

セキュリティタブをクリック
![](https://i.gyazo.com/8630ca234ee47c6893074fcef077a512.png)

ユーザ名・パスワードの以下の通り設定して「更新」をクリック。
ID: cmxwoqlw
PW: ハンズオン当日にお知らせします

![](https://i.gyazo.com/f05d597e62377310afbfa864ba87237e.png)

##### MQTTのトピック名の変更

取り込んだフローだとMQTTのトピック名がすべて `pco2699/midi`に設定されています。
これだと、私のローカルに設定されているシンセが鳴ってしまいます。

そのため、トピック名を自分のものに合わせて設定します。
先程と同じノードをクリックします。
![enebular Flow Editor - Google Chrome 2019-11-18 21.33.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/bd579213-7c9b-1e3a-8b82-92354a240b99.png)

トピックと書いてある箇所に`pco2699/midi`と記載されているので、自分が`midi2mqtt`で設定したものに書き換えましょう。
![](https://i.gyazo.com/0a9912d1ced1b4750f7b2ee3f0a3248b.png)

他にもトピック名がいろいろな所に書かれているので、次のコメントが記載されているノードをすべて書き換えましょう。
![enebular Flow Editor - Google Chrome 2019-11-18 21.42.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/85acdfc2-f477-e2eb-0b5d-b658a168edc8.png)


すべてのトピック名の変更が終わったら次のinjectを教えてみてください。
音が鳴ったらここまではOKです。
![enebular Flow Editor - Google Chrome 2019-11-18 21.44.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/962b4da3-6d7c-475b-b846-99b2a2373550.png)

flowの一番下にある「Twitterのツイートから自動作曲するフロー」は後で動かします。

### 音を鳴らすシンプルなflowをつくる
音を鳴らすシンプルなenebularのflowを作って、今回の仕組みの基本を理解しましょう。

#### プロジェクトを一から作成する
Assets -> flowを選択して+マーク
![](https://i.gyazo.com/bf788539ef7dde71f8472bee732b4bb5.png)

flow名は適当な名前でOKです。
![](https://i.gyazo.com/bd140d9aa8736015ee9b3b4569487b51.png)

flowが表示されたらEditをおしましょう。
![](https://i.gyazo.com/873aede9985432c585604e66929907a0.png)

こんな感じで、enebularのflowエディターが立ち上がればOKです。
![](https://i.gyazo.com/626ddc02c2831382a8d0bfad4387e495.png)

#### MQTT/debugノードを使って、ローカルから送出したMIDI情報を見れるようにする
まずは、MQTTノードとdebugノードを使ってローカルから送出したMIDI情報を見れるようにしましょう。

入力 -> mqttを選択してドラッグ
![](https://i.gyazo.com/b5e89bd157051756f1abc69de1cc508a.png)

mqttノードをダブルクリックして編集画面を立ち上げ
![](https://i.gyazo.com/dcc330f1d88adc9f0dd982429f06dab8.png)

mqtt -brokerを追加のよこのペンマークを押す

情報は以下の通り入力
サーバ: m16.cloudmqtt.com
ポート:  16282

![](https://i.gyazo.com/4aee8784abfd6d75accde3b1bad6174a.png)
![](https://i.gyazo.com/d98432c86eb5f2d5e3e50acc0ddc0f08.png)

ID: cmxwoqlw
PW: 当日に教えます

![](https://i.gyazo.com/0ccfcc484d519e6175d3a712a8001431.png)

トピック名: {設定したユーザ名}/midi/out/+/+/+

設定が完了したら、出力 -> debugとつないでみましょう

![](https://i.gyazo.com/1c7685798b9482248ac3d2441e34473b.png)
![](https://i.gyazo.com/f7b2d854ad39ba231d2d32efdb72cccc.png)

これで右上をデプロイを押して動作確認しましょう

PocketMidiを押して、↓のような形でメッセージが出れば連携ができてます！
![](https://i.gyazo.com/89c33bde5a915a1e4ec875b59d8b1929.png)


#### MQTT/injectノードを使って、enebularから音を出してみる
今度は逆にenebularから音を出せるようにしてみましょう
![](https://i.gyazo.com/7f2131cfe1f3a62939becb6eb26df983.png)

入力側はinjectノードを利用します。

ペイロードはとりあえず0-127までの数字を入れてください。
（数字じゃないと音がでない）

![](https://i.gyazo.com/40b2f10a385914f0ed11193ad17d0c14.png)

![](https://i.gyazo.com/1b0d4a4822a23ff968af7513a25d8157.png)

出力側にmqttを設定します

![](https://i.gyazo.com/e1cdf653772c8f1724e4abd44dbc8877.png)

サーバ: さきほど設定したMQTTサーバ
トピック: {ユーザ名}/midi/in/0/noteon/60

noteonで音がなり始めます、これだと音がなり続けてしまうのでnoteoffも用意します。
MQTTノードをCtrl+C Ctrl+Vでコピーできるので、コピーしてください。
トピックは↓
トピック: {ユーザ名}/midi/in/0/noteoff/60

同じメッセージを時間差で送るためにdelayノードを用意します。

![](https://i.gyazo.com/51aead515ff9d3003988786a40e85ee3.png)
![](https://i.gyazo.com/e83a793a64bafefb8bcd384b083ac986.png)
delayの分だけ音が持続します！

ノードを接続して↓のようにしてみてください。
![](https://i.gyazo.com/415921548c43e6db3cb9e086f0efa40b.png)

これでデプロイしてみて、injectノードをクリックして音が鳴ればOKです！

つくったものを解説します
![](https://i.gyazo.com/0c42397e02b7868052792e4cd49e3a82.png)

```
topic: {midi2mqttの起動時に設定したtopic}/in/{midiチャンネル}/{noteon|noteoff}/{音の高さ}
```

![](https://i.gyazo.com/16455930213f6083e112ac371f3fe8bc.png)

msg.topic -> 音の高さ
msg.payload -> 音のベロシティ
を設定してるイメージです！

## Twitterで自動作曲してみる

enebularとMIDI/MQTTを使って音を鳴らすことができました。
次はいよいよTwitterと連携させて自動作曲してみましょう。

### Discover機能で取り込んだお手本flowを動かす
先程、取り込んだお手本flowのTwitterで自動作曲するflowをまだ動かしていませんでした。
まずはこちらを動かしてみましょう。

#### TwitterのAPIキーの設定
事前準備を実施していればTwitter APIの「Consumer API Keys」、「アクセストークン情報」が準備できているはずです。

https://developer.twitter.com/en/apps
[Details] -> [Keys and Token]

![Twitter Developers - Google Chrome 2019-11-18 22.04.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/035151b9-72d4-0186-9bf0-38f6e16a6223.png)

このAPIキーをお手本flowに設定しましょう。
お手本flowを再び、開いてください。

次の通り、Twitterのノードをダブルクリックしてください。

![enebular Flow Editor - Google Chrome 2019-11-18 22.06.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/433320fd-2568-2daa-89c5-c9d8fef049ba.png)

右のメニューの鉛筆マークをクリック
![enebular Flow Editor - Google Chrome 2019-11-18 22.09.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/8b454c03-ac71-6132-4d21-51ee99d72855.png)

Twitter ID: 自分のTwitter ID
その他は、説明欄に従って設定しましょう。
![enebular Flow Editor - Google Chrome 2019-11-18 22.16.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/73678cbf-6112-920e-3202-a2d62c766ea7.png)

#### 取得ツイートの検索設定
Twitterの取得ツイートの検索設定をしましょう。「フォローしているすべてのユーザ」や「公開されているすべてのツイート」などを選べます。自分の好きなものを設定しましょう。

ただ、ツイート数が多いと動作確認しづらいので、最初は自分のアカウントのツイートだけを検索対象にすることをおすすめします。

![enebular Flow Editor - Google Chrome 2019-11-18 22.21.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/7c197043-94ed-bba8-2274-d431eac360bc.png)

その他、トピック名の変更をしていない方はトピック名の変更もしておきましょう。

これで、ツイートして自分の手元で音が鳴ったら成功です！

### 一からTwitterの自動作曲flowを自作する

それでは、一からTwitterの自動作曲flowを自作してみましょう。
さきほど、簡単な音を鳴らすflowに追加します。元の簡単な音を鳴らすflowを開きましょう。


#### Twitterノードでツイートを収集する
まずは、Twitterノードを追加します。

![enebular Flow Editor - Google Chrome 2019-11-19 21.10.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/3c7201fe-7907-a3bd-5682-202de3963cb5.png)

APIキーの設定は先程と同様の方法で設定しましょう。

APIキーの設定ができたら、次の通り繋いで、ツイートが流れるか確認しましょう。

![enebular Flow Editor - Google Chrome 2019-11-19 21.26.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/dc578c9c-ac6f-6991-160f-c58221ce50d6.png)

右のメニューからデバッグを開いて、ツイートが流れてくればOKです。
![enebular Flow Editor - Google Chrome 2019-11-19 21.25.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/b8f1c578-7d61-aeaf-10f6-e45779dba72e.png)


#### splitノードでツイートを文字単位で分割する

取得できたツイートを元に、つぶやかれた一文字一文字を音にマッピングします。
そのためにまず、一つのメッセージにまとまっているツイートを複数のメッセージに分割します。

メッセージの分割には **splitノード**を利用します。

![enebular Flow Editor - Google Chrome 2019-11-19 21.31.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/3b33b851-6089-869e-6ed9-e2e21dfc2bb2.png)

splitノードをドラッグして配置しましょう。
そして、splitノードを次の通り、設定します。

文字列/バッファ 分割: 固定長, 1
メッセージをストリームに分割: on

![enebular Flow Editor - Google Chrome 2019-11-19 21.42.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/5e52b03b-e0dd-4adb-f617-cc36dbf01d68.png)

設定できたら、次の通りつないでみましょう。

![enebular Flow Editor - Google Chrome 2019-11-19 21.51.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/f0ea54d0-4080-47db-9198-3bf185f823b8.png)

デバッグを開くと一文字ずつ文字が分割されているのが確認できるはずです。

![enebular Flow Editor - Google Chrome 2019-11-19 21.57.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/a1569e56-3f5b-add1-1099-77410d85e522.png)

#### delayノードで分割したメッセージをちょっとづつ送信する

今のままだと、メッセージが一気に音になってしまうので、メロディになりません。
そのため、メッセージをちょっとづつ送ることで、メロディが鳴るようにしましょう。

メッセージをちょっとづつ送るには **delayノード** を利用します。

![enebular Flow Editor - Google Chrome 2019-11-19 22.04.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/5da066ae-7599-a580-716e-c03e4a021eb3.png)

delayノードをドラッグして配置しましょう。
delayノードを次の通り、設定します。

![enebular Flow Editor - Google Chrome 2019-11-19 22.06.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/e5eecbed-b7c6-080f-ed18-e077aeaac2ed.png)

さきほどと同様にdebugノードをつないで、動作確認してみましょう。メッセージがちょっとづつ送られるようになっていたらOKです。

#### functionノードで文字を数字に変換する

ツイートの文字を数字に変換します。数字に変換できれば、MIDIの音の高さにマッピングすることができます。
ツイートの文字を数字に変換するには、 **functionノード** を利用します。

functionノードは、JavaScriptを記述できるノードです。
ここの中に少しだけJavaScriptのコードを書きます。

![enebular Flow Editor - Google Chrome 2019-11-19 22.10.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/5040a3b9-c2ae-e15c-5561-9eda99921fcc.png)

functionノードの中身は次のように書きます。

```javascript:functionノードの中身
var p = msg.payload;
msg.value = p.charCodeAt(0) % 6
return msg;
```

やっていることはシンプルで、ツイートの文字を `charCodeAt(0)`で文字コードとして取得、それを12で割った余りを `msg.value` に設定しています。
これで `msg.value` には 0~5の間の数字が文字に応じて設定されるようになります。

この `msg.value` はのちほど利用します。

#### changeノードでスケールを設定する
さきほど、functionノードで文字を数字に設定しました。
こちらをそのままMIDIとして鳴らしてしまっても良いのですが、鳴らすと奇怪な旋律になってしまいそれっぽく聞こえません。

そのため、スケールと呼ばれる決められた音の高さの集まりを設定しておいて、それを先程のfunctionノードで計算された数字で選ぶ形にすると
旋律っぽく聞こえるようになります。

まず、このスケールを **changeノード** で設定しましょう。

**changeノード**はメッセージに任意の値を設定するのに使います。

![enebular Flow Editor - Google Chrome 2019-11-19 22.22.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/8e31cafa-12cf-d495-5fa9-71564146c791.png)

次の通り設定しましょう。
![enebular Flow Editor - Google Chrome 2019-11-19 22.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/0c8e505f-11b1-cd83-f195-b4ee42b5d960.png)

対象の値という入力欄でスケールの配列を設定しています。
ちなみに今回は、**Cマイナーペンタトニック・スケール** というスケールを設定します。

これでスケールの配列が`msg.payload`に設定されました。

もし、興味がある方は、以下の資料を参考にスケールを調べてみて自分の好きなスケールを設定してみてください。
[音階 - Wikipedia](https://ja.wikipedia.org/wiki/%E9%9F%B3%E9%9A%8E)
[MIDIノート番号と音名、周波数の対応表 - asahi-net.or.jp](http://www.asahi-net.or.jp/~HB9T-KTD/music/Japan/Research/DTM/freq_map.html)

ここまでで次の通りつなぎます。
![enebular Flow Editor - Google Chrome 2019-11-19 22.27.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/ed032353-99c6-64fa-e9fd-f0bc61b99e04.png)

#### changeノード（ふたたび）で設定したスケールから一音選ぶ
changeノードをまた利用して、functionノードで計算した数字でスケールの中から一音選びましょう。
changeノードは、任意の値を設定するだけでなく、配列から値を取得するのにも使えます。

同じようにchangeノードをドラッグしてきて次のように設定しましょう。

![enebular Flow Editor - Google Chrome 2019-11-19 22.32.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/8d1c9abd-4ae5-8809-ab9c-0849104188e6.png)
 
対象の値のところをクリックして「expression」を選ぶのを忘れないでください。

`payload[$$.value]`は`msg.payload`にあるスケールの配列を`msg.value`に設定されている数字をindexとして選択する、という式です。
これでfunctionノードで計算された数字を元に、スケールの中から一音を選ぶことができます。

#### templateノードで、音の高さをトピックに設定する

さきほどの音を簡単に鳴らすflowで説明しましたが、音の高さを設定するには、音の高さの数字だけでなく`pco2699/midi`のようなトピック名を`msg.topic`に設定する必要があります。`msg.topic`に音の高さの情報と`pco2699/midi`というトピック名をまとめて設定しましょう。

`msg`中に設定されている情報を何か固定の文字列に当て込みたい場合には、**template**ノードを利用します。

![enebular Flow Editor - Google Chrome 2019-11-23 14.42.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/4462a739-a1f0-2f82-f9fe-c0bfd874c053.png)


templateは次の通り設定します。
テンプレートの文字列の最初の部分は、自分自身のトピック名にするのを忘れないでください。

![enebular Flow Editor - Google Chrome 2019-11-19 22.40.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/b14df016-ff9d-a2c8-906c-07e5527329f1.png)

#### changeノードで音のベロシティを設定する

msg.payloadに音のベロシティ(強さ)を設定しましょう。

![enebular Flow Editor - Google Chrome 2019-11-19 22.45.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/da2861f5-aeba-5396-cd3d-96542ad1f2f0.png)

数字は0-127の間であればなんでも大丈夫です。数字が大きければ音が強く、少なければ音が弱く鳴ります。

ここまででこのようにつないでください。
![enebular Flow Editor - Google Chrome 2019-11-19 22.46.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/cc9919f4-f2df-d2ce-d5ea-8bbee3e371d2.png)

#### MQTTノードでMQTTに情報を流す

ここまでで必要な情報がメッセージ中に含まれているので、これをMQTTに流して、ローカルで音が鳴るようにしましょう。
MQTTに流すには、先程も利用したMQTTノードを利用します。

先程の音を簡単に鳴らすflowでは「トピック」に値を設定していましたが、今回はそこは空にします。
`msg.topic`にすでにトピックの値が設定されているからです。

![enebular Flow Editor - Google Chrome 2019-11-19 22.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/a02946e8-1292-e770-6ba7-c0c926e29666.png)

ここまでのflowはこんな感じです。
![enebular Flow Editor - Google Chrome 2019-11-19 22.54.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/7c3c7e32-03b4-d534-c4ad-5dbaa6624106.png)


#### 音をOFFにするflowもつくる

ここまでで完成...!と言いたいところですが、このflowだと、音をONする情報だけ(noteon)で、音をOFFにする情報が含まれていません。
これだと、ツイートするとずっと音が鳴りっぱなしになってしまいます。そのため、音をOFFにする(noteoff)flowも追加します。

といっても、ほとんどコピペでできます。
まず、いままで作ったflowの次の部分を選択してコピーペーストします。

![enebular Flow Editor - Google Chrome 2019-11-19 22.55.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/c817205e-df3e-004c-f441-29976d883149.png)

そして、delayノードを配置します。次のような形です。

![enebular Flow Editor - Google Chrome 2019-11-19 22.57.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/7e1bac94-bba7-ef7a-089a-73a332375e73.png)

delayノードを配置する理由は、noteonの情報の後に少し待ってからnoteoffの情報を送らないと、音がそもそも聞こえなくなってしまうからです。

delayノードの設定は次の通りです。

![enebular Flow Editor - Google Chrome 2019-11-19 22.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/d25f16ad-d8be-5ff7-777d-ec571f942733.png)

このdelayノードの時間を長く設定すればするほど、音が長く鳴るようになります。

そして、コピーしたtemplateを書き換えてnoteoffの情報を送信できるようにします。
![enebular Flow Editor - Google Chrome 2019-11-19 23.02.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/1dd54eb8-d0a4-5c7f-f812-c1732ce250e1.png)

![enebular Flow Editor - Google Chrome 2019-11-23 14.46.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/4aebd594-3231-78bb-f348-6810ddbc26b8.png)

最後につなぎ合わせてflowが完成します！
![enebular Flow Editor - Google Chrome 2019-11-19 23.03.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125528/99ae22f0-3533-78f4-a15c-2f3bc2a50816.png)

#### 動作確認してみよう

自分のアカウントのツイートだけを検索対象にしている場合は、実際に自分のアカウントでツイートしてみて、自分の手元で音が流れるか確認してみましょう。
音が流れない場合は、お手本のflowとノードを一つづつ比較してみて、ノードの設定に間違いがないか確認してみましょう！

以上で、ハンズオンは終わりです。
お疲れさまでした。