LoginSignup
3
2

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-11-23

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

今回作るもの

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

こちらが実際のデモ動画です。(今回はもう少し簡単なものを作ります。)

システム構成

以下の構成で作ります。
IoTLT vol.54 @IIJ (1).png

事前準備

Node.jsなどその他のライブラリのインストール・APIへのサインアップは本資料を参考にしてください。

ハンズオンの流れ

  1. MIDI/MQTTでリモート演奏できる仕組みを作る
  2. enebularとつないでみる
  3. Twitterで自動作曲してみる

MIDI/MQTTでリモート演奏できる仕組みをつくる

まずは、構成の中でMIDI/MQTT部を作りましょう。

先程の構成でいうと次の図の赤線部です。
IoTLT vol.54 @IIJ (2).png

この図を更に詳しく説明すると次の通りです。
MQTTブローカーと呼ばれる仲介サーバーを通して、シンセとenebularを接続してリモートで演奏できるようにします。
enebular

シンセ

今回は環境構築手順を簡単にするため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

PocketMidi

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

midi2mqtt

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

$ 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の場合

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

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

$ 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 midi2mqtt 1.1.0 starting
2019-04-21 18:14:21.463 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 Available MIDI inputs: [ 'loopMIDI Port 0' ]
2019-04-21 18:14:21.552 Available MIDI outputs: [ 'Microsoft GS Wavetable Synth 0', 'loopMIDI Port 1' ]
2019-04-21 18:14:21.917 mqtt connected mqtt://cmxwoqlw:XXXXXX@m16.cloudmqtt.com:16282
2019-04-21 18:14:21.918 mqtt subscribe pco2699/midi/in/+/+/+
```

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

補足説明: MQTTとは

Hoge

enebularとつないでみる

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

お手本flowをDiscoverで取り込んでみよう

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

プロジェクトの作成

Hoge
Project名 -> midibular (その他適当な名前でOK)

Discoverで取り込み

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

クリックしたら次の画像の通り、自分のプロジェクトに取り込みましょう。


MQTTブローカーのユーザ名やMQTTトピック情報を設定する

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

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

まずはMQTTブローカーのユーザ名・パスワードを設定します。
以下をダブルクリックしましょう。
enebular Flow Editor - Google Chrome 2019-11-18 21.33.15.png

右にメニューが出てくるので鉛筆マークを次の通りクリック

セキュリティタブをクリック

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

MQTTのトピック名の変更

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

そのため、トピック名を自分のものに合わせて設定します。
先程と同じノードをクリックします。
enebular Flow Editor - Google Chrome 2019-11-18 21.33.15.png

トピックと書いてある箇所にpco2699/midiと記載されているので、自分がmidi2mqttで設定したものに書き換えましょう。

他にもトピック名がいろいろな所に書かれているので、次のコメントが記載されているノードをすべて書き換えましょう。
enebular Flow Editor - Google Chrome 2019-11-18 21.42.52.png

すべてのトピック名の変更が終わったら次のinjectを教えてみてください。
音が鳴ったらここまではOKです。
enebular Flow Editor - Google Chrome 2019-11-18 21.44.29.png

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

音を鳴らすシンプルなflowをつくる

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

プロジェクトを一から作成する

Assets -> flowを選択して+マーク

flow名は適当な名前でOKです。

flowが表示されたらEditをおしましょう。

こんな感じで、enebularのflowエディターが立ち上がればOKです。

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

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

入力 -> mqttを選択してドラッグ

mqttノードをダブルクリックして編集画面を立ち上げ

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

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


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

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

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


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

PocketMidiを押して、↓のような形でメッセージが出れば連携ができてます!

MQTT/injectノードを使って、enebularから音を出してみる

今度は逆にenebularから音を出せるようにしてみましょう

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

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

出力側にmqttを設定します

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

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

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



delayの分だけ音が持続します!

ノードを接続して↓のようにしてみてください。

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

つくったものを解説します

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

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

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

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

enebular Flow Editor - Google Chrome 2019-11-18 22.06.56.png

右のメニューの鉛筆マークをクリック
enebular Flow Editor - Google Chrome 2019-11-18 22.09.09.png

Twitter ID: 自分のTwitter ID
その他は、説明欄に従って設定しましょう。
enebular Flow Editor - Google Chrome 2019-11-18 22.16.13.png

取得ツイートの検索設定

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

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

enebular Flow Editor - Google Chrome 2019-11-18 22.21.29.png

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

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

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

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

Twitterノードでツイートを収集する

まずは、Twitterノードを追加します。

enebular Flow Editor - Google Chrome 2019-11-19 21.10.10.png

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

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

enebular Flow Editor - Google Chrome 2019-11-19 21.26.48.png

右のメニューからデバッグを開いて、ツイートが流れてくればOKです。
enebular Flow Editor - Google Chrome 2019-11-19 21.25.59.png

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

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

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

enebular Flow Editor - Google Chrome 2019-11-19 21.31.34.png

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

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

enebular Flow Editor - Google Chrome 2019-11-19 21.42.32.png

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

enebular Flow Editor - Google Chrome 2019-11-19 21.51.42.png

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

enebular Flow Editor - Google Chrome 2019-11-19 21.57.54.png

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

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

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

enebular Flow Editor - Google Chrome 2019-11-19 22.04.29.png

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

enebular Flow Editor - Google Chrome 2019-11-19 22.06.07.png

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

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

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

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

enebular Flow Editor - Google Chrome 2019-11-19 22.10.26.png

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

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

次の通り設定しましょう。
enebular Flow Editor - Google Chrome 2019-11-19 22.23.09.png

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

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

もし、興味がある方は、以下の資料を参考にスケールを調べてみて自分の好きなスケールを設定してみてください。
音階 - Wikipedia
MIDIノート番号と音名、周波数の対応表 - asahi-net.or.jp

ここまでで次の通りつなぎます。
enebular Flow Editor - Google Chrome 2019-11-19 22.27.55.png

changeノード(ふたたび)で設定したスケールから一音選ぶ

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

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

enebular Flow Editor - Google Chrome 2019-11-19 22.32.24.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

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

enebular Flow Editor - Google Chrome 2019-11-19 22.40.52.png

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

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

enebular Flow Editor - Google Chrome 2019-11-19 22.45.46.png

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

ここまででこのようにつないでください。
enebular Flow Editor - Google Chrome 2019-11-19 22.46.14.png

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

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

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

enebular Flow Editor - Google Chrome 2019-11-19 22.50.11.png

ここまでのflowはこんな感じです。
enebular Flow Editor - Google Chrome 2019-11-19 22.54.12.png

音をOFFにするflowもつくる

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

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

enebular Flow Editor - Google Chrome 2019-11-19 22.55.17.png

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

enebular Flow Editor - Google Chrome 2019-11-19 22.57.18.png

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

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

enebular Flow Editor - Google Chrome 2019-11-19 22.58.50.png

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

そして、コピーしたtemplateを書き換えてnoteoffの情報を送信できるようにします。
enebular Flow Editor - Google Chrome 2019-11-19 23.02.06.png

enebular Flow Editor - Google Chrome 2019-11-23 14.46.13.png

最後につなぎ合わせてflowが完成します!
enebular Flow Editor - Google Chrome 2019-11-19 23.03.33.png

動作確認してみよう

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

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

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2