Scratch 3 MIDI Extension（機能拡張）

MIT のプログラミング環境である[Scratch](https://Scratch.mit.edu)の入力、出力としてMIDI機器を使えるように、拡張機能（Extension) を[Web MIDI API](https://www.w3.org/TR/webmidi/)を使って作製しています。電子楽器の鍵盤や、MIDIコントローラをScratchの入力として使うことも可能ですし、電子楽器を音が出るScratchの出力装置として使うこともできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/067d912e-9fb6-17e1-7c1f-94b574e10df1.png)


Rolandの[GO:KEYS](https://rolandcom.github.io/gokeys-scratch-extension/) もScratchから制御でます。私の作製した機能拡張は、MIDIで通信できれば、どんな楽器でも使うことができます。特定の楽器に限っているわけではありません。

ちょっと前に作ったビデオです。キーボードを弾くと、その鍵盤の音程に応じてロケットが左右へ移動し、鍵盤を押す力で、ロケットの飛ぶ高さが変わります。（見づらくてすいません。）
https://youtu.be/iWIwDGgzD1Y

【注意】なを、Web MIDI API は<b>Chromeブラウザ</b> でのみ対応しています（2020年、Edgeでも動作するようになりました。）ので、MIDI ExtensionもChromeブラウザでのみ利用可能です。

## Extension
以前のWeb版のScratch 2.0は、Flashアプリとして記述されていました。Extensionはjavascriptで開発ができました。動作は通常版では無く、Extensionを動作させるには、特別な[ScratchX](http://scratchx.org/)を使わなければなりませんでした。ただ、Flashは2020年末にて終了とのことですので、こちらはクローズだろうなと思っています。

このほかに、ローカルＰＣでオフラインで動作するScratch 2.0では、HTTP Extensionsを開発することができました。今確認してみると、ローカルで動作する[Scratchデスクトップ](https://scratch.mit.edu/download)は3.0がベースになっています。こちらのExtensionについては未調査です。

Scratch 3.0の正式版は2019年1月2日リリースされ、HTML、CSS、JavaScriptのセットであるHTML5で記述されています。また、ソースコードがGithubに公開されています。この公開されているソースコードに自前の機能拡張を追加する仕組みを持っています。HTML5で記載されていますので、Extenshinの制作は敷居が低くなりました。

## アプリケーション

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/8af6b09f-9926-f103-d0b3-2d8b24fb938b.png)

MIDI が使えるScratch 3.0 をgithub に置きましたので、アクセスしてみて下さい。
https://uchiwafuujinn.github.io/scratch3webmidi/
作り方は別途な記事にて記載したいと思います。ここでは使い方を書いておきます。


## MIDI Extension の使い方

### 準備
- MIDI 機器をコンピュータに接続してください。ブラウザが立ち上がる時にMIDI機器を認識していると思われます。（ブラウザを立ち上げてからMIDI機器をつないでも認識できないことがあります。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/75676675-d3d9-c6aa-ea28-85b6aca4fe37.png)

- Chrome ブラウザを立ち上げます
- [アプリケーション](https://uchiwafuujinn.github.io/scratch3webmidi/)を開きます
- ブロックパレットの左の一番下に機能拡張を追加するボタンがあります。これをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/31d229dd-f250-25d3-dc49-ef37b934b6e1.png)

- 選択できる機能拡張が表示されます。MIDI Extensionのボタンをおします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/d30431db-54eb-a0b9-a212-9b9def2b3452.png)

- MIDI が使える、というコーションが表示されます。OK を押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/96acab98-f090-ef65-584b-a8d108547e1a.png)

- Web MIDIのブロックが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/d6ce6dbb-f0ff-4f9b-3c17-2a3a53363641.png)

### ブロックの使い方

ブロックは整理されていない感（冗長）たっぷりかと思います。必要かな？と想像して作っていたらこんなことになってしまいました。使ってみていただき、整理をお手伝いしていただける方、ありましたらお声がけ下さい。

#### レポーターブロック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/d7e54261-c834-6188-58dd-ea2af500f568.png)

- NoteNum 直近でノートONになったノートの番号
- Velocity 直近でノートONになったノートのベロシティ
- PB ピッチベンドの値
- PC 直近で受け取ったプログラムチェンジの番号
- Ticks 内臓しているビートカウンターの値、一拍を480として、一小節で折り返す
- CC (NN) 表示されている番号(NN)のコントロールチェンジの値 

#### ハットブロック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/d99d8159-a8c0-72d4-e08d-82a569aa9a2d.png)

- MIDI EVENT いずれかのチャンネルメッセージを受け取ったことを示します
- Key ON キーON イベント
- Key OFF キーOFF イベント
- P.Bend ピッチベンドイベント
- PrgChg プログラムチェンジイベント
- Ctrl Chg コントロールチェンジイベント
- KEY ON (NN) 表示されている番号(NN)のキーON イベント

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/c29a8272-8f5b-f3a9-dc0b-e320ceb197f0.png)

- BEAT (NN) ビートを刻むハットブロックです。(NN)はテンポです。
このExtension が読み込まれると、ビートは常に刻まれています。ON/OFF/Resetはいまのところ付けていません。

#### Boolean レポーターブロック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/f0b72dac-575d-5c97-e6ba-8c7fd6d34264.png)

最後に受け取ったイベントの種類を判定します。イベントが、カッコ内の文字で示されたイベントをイコールであれば,trueが返ります。

- 'key on' --- キーON イベント
- 'key off' --- キーOFF イベント
- 'cc-chg' --- コントロールチェンジ イベント
- 'p-bend' --- ピッチベンド イベント
- 'pg-chg' --- プログラムチェンジ イベント

#### メッセージブロック

ここまでのブロックはMIDI 機器からのMIDIイベントを、Scratchが受けるためのものでした。メッセージブロックは、Scratchから、MIDI機器に対してイベントを送るときに使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/9a77e24f-514c-5c54-f90b-336e83e4677b.png)

- NOTE ON (D1)(D2)(D3) ノートON メッセージを送ります。D1->チャンネル番号、D2-> ノート番号、D3-> ベロシティです。
- NOTE ON (D1)(D2)(D3)(D4) ノートON メッセージを送ります。D1->チャンネル番号、D2-> ノート番号、D3-> ベロシティです。D4->デュレーション（音符の長さ）
- NOTE OFF (D1)(D2)(D3) ノートOFF メッセージを送ります。D1->チャンネル番号、D2-> ノート番号、D3-> ベロシティです。
- Rest (NN) tickes 時間調整です。NN tickes 待ちます。

### 例
#### 一小節

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/aa94bfd5-2989-c221-1c46-0738b0aa4037.png)

この音符をプログラムしてみると、次のように書けます。NOTE ON の４番目の数字、ここでは460が音符の長さを示しています。Rest 48 tickes は次の音までの時間を表しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/5c71f343-b366-7e32-8e24-d4c9ddabb16d.png)

また、次のように書いても同じ挙動になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58417/834de858-4c18-25e2-8891-218624a6a033.png)

## Extension の作り方
Extension の作り方を、私は、Scratch Japan Wiki  [Scratch_3.0の拡張機能を作ってみよう](http://bit.ly/2kljIKW) を参考にさせてうただきました。次の機会に記載してみたいと思います。