夏休みの自由研究 - MIDI 楽器を作ろう (プログラミングと音楽と) - 前編

2020-07-02
How to be a Developer

Author : 清水 崇之

こんにちは、ソリューションアーキテクト/AWS 芸人しみず(@shimy_net)です。この記事では AWS の話は 1 ミリも出てきませんので期待していた方はごめんなさい。先日、またまた編集長から「普段やっていることを書いて」と無茶振りされまして筆を取ったわけですが書くことがなくて頭をかかえました。いま作っている物は AWS と全く関係がないですし、皆さんに説法できるような大層なアーキテクチャ論も持ち合わせておりません。

いろいろと考えた末、エンジニアとしてのモチベーションをポエムにしながら、編集長から言われたとおり「普段やっていること」とやらをそのまま書いてみることにしました。マインドセットの参考にでもなれば幸いです。

みなさんのプログラミングを始めたキッカケは何ですか ?

昔話です。私の実家は「街の電気屋さん」でして、部品や工具が転がっている環境で育ちました。3 歳のころにはカナヅチでクギを打っていたそうです。そんなしみず少年とプログラミングの出会いについてお話します。 

当時、CASIO / ワードプロセッサ HW100 (1985 年発売) が家にありました。パーソナル向けとしては画期的なワープロだったと思います。発売年から推定すると私は未就学児ですから文字が読めませんので、外字機能で絵文字を作って印刷して遊んでいました。いわゆるドット絵ですね。遊びすぎると親から小言をいわれるので、早起きして隠れてやっていました。この機種のおかげでキーボードやプリンタの使い方を覚えました。

その後、小学 1 ~ 2 年のころに BASIC に触れました。カセットテープに入った S-BASIC  をロードしてコンピュータを起動して四則演算で遊んでいました。SHARP / MZ シリーズのどれかの機種 (おそらく MZ-700 / 1982 年発売) だと思います。新しいもの好きの伯父が父に売りつけた中古品です。残念ながらこの機種は父が誰かに譲渡してしまい直ぐに手元からなくなりました。そのため記憶がほとんどないのですが、この機種のおかげでコンピュータの処理系を理解したと思います。ちなみに父は未だにコンピュータを使えません。

注)写真はMZ-80Bです。
引用:https://corporate.jp.sharp/info/history/h_company/

ありがたいことに伯父が父に中古品を売りつけるという謎行動は続きます。伯父は新しい機種にどんどん買い替えていたのでしょう。そのおかげで小学 3 年のころに NEC / PC9801CV (1988 年発売) の中古品を手に入れました。この機種はモニタ一体型のコンパクト筐体で見た目もキュートで大変お気に入りでした。この機種のおかげでプログラミングの基礎を学んだといっても過言ではありません。小学生になって文字を学んだことで本やマニュアルを読めるようになったことがブレークスルーだったと思います。文字を読むことは本当に大事です。

遊び半分で本や雑誌のサンプルプログラムを写経しながら N-88 BASIC のプログラミングを覚えていったのですが、もっとも興味深かったのが FM 音源でした。ガラケーの着メロを作る機能を覚えていますか ? あれと同じような機能が遥か昔にあったのです

PC-9801CV には同時発音数 3 音の FM 音源が搭載されていて、プログラミングすると音楽を奏でることができました。というわけで、しみず少年は音楽にも出会いました。

いろんな音色がでる FM 音源に魅了されて、プログラムだけでなく楽譜も写経しました。音楽の教科書に載っている曲をどんどん N-88 BASIC プログラムに置き換えていきました。「グリーングリーン」や「ドナドナ」ですね。

MML というマクロランゲージで音程や長さを記述しなければなりませんし、同時発音数も 3 音しかないので大抵の曲はそのままプログラムに置き換えることは困難でした。ベース音とメロディ音に加えてあと 1 音をうまく選択して配置するなど工夫が必要でした。楽しい作業ではありますが苦労もありました。

以下の例では、楽譜にある「ドレミファソラシド」「ドソ」を演奏するプログラムを示します。各パートの音色 (@13 : ピアノ)、音量 (@V100)、テンポ (T 120) を指定して、オクターブ (O4) や音符の音程と長さや休符を記述します。たとえば 4 分音符のドであれば C4、2 分休符であれば R2、途中でオクターブを上げるのであれば > と記述します。実行環境もマニュアルも手元にないため数十年ぶりに思い出しながら書いているので不正確かもしれません。

PLAY ALLOC 255,255,255
PLAY "MB@13@V100", "MB@13@V100", "MB@13@V100",
PLAY #0, “T120O4C4D4E4F4G8A8B8>C8R2”, “O3C1G2R2”, “R1R1”

そんなある日、伯父から「MS-DOS で MIDI プレイヤーを動かしてみたら ?」という話を聞きました。そこで伯父からフロッピーディスクをもらって、どこかの誰かが作った MIDI プレイヤーを動かしてみると軽快な音楽がスピーカーから流れてきました。

「おれのプログラムより軽い」それが最初の感想でした。私が作った BASIC のプログラムは小節の切り替えタイミングでもたつくのですが、その MIDI プレイヤーは一切もたつきませんでした。漠然とした悔しさと憧れを感じました。この記憶が IT エンジニアをやるモチベーションの起点かなぁ、と当時を振り返ります。

ちなみに、この MIDI プレイヤーは MIMPI という有名ソフトウェアで、1992 年のフリーソフトウェア大賞音楽部門を受賞されています。そりゃ敵うわけもなく・・・とほほの。

MIDI 楽器を作ろう

というわけで、私のなかではプログラミングと音楽は仲良しでして、最近は MIDI 楽器を作りたくなりました。今回の記事は MIDI 楽器の作り方についてお話します。まだ作っている途中なのでこの記事は「前編」になりそうです。

そもそも MIDI ってなに ?

MIDI はシンセサイザーやドラムマシンなどの電子楽器の演奏データを相互にやりとりするための規格です。MIDI に対応した鍵盤で演奏すると、その音程やタイミングといった演奏データを他のデバイスに送信することができます。受信側のデバイスが先ほど紹介した FM 音源のようなものであれば、たとえばバイオリンの音色で演奏データを発音させることができます。また SMF (スタンダード MIDI ファイル) などに演奏データを保存・編集したり、保存したデータを再生したりできます。MIDI 規格は 1981 年に公開されてから長らく音楽制作の現場で利用されています。ちなみに AWS DeepComposer キーボードも MIDI に対応していますよ。

AWS DeepComposer の記事はこちら »

Arduino で MIDI をプログラミングする

Arduino はオープンソースハードウェアのマイコンの一種で、入出力ポートを備えているのでセンサーやモーターを接続してさまざまな装置を作ることができます。また Arduino IDE とよばれるプログラムを作成するための開発環境が提供されており、作成したプログラムを Arduino ボードに転送して装置を思い通りに動作させることができます。さらに Arduino ボードに接続して使用するための様々なシールドが発売されており、欲しい機能を簡単に追加することができます。

今回は MIDI を扱うために Arduino Uno Rev3SparkFun MIDI Shield を利用します。こちらの写真は入手したシールドを組み立てて Arduino に接続したところです。このシールドには MIDI イン/アウト端子だけでなくボリュームノブなども搭載しているので MIDI フィジカルコントローラーのようなものを作るときにも便利です。

MIDI は非同期シリアル通信なので、Arduino プログラムにて Serial.write() などで送信すれば原理的には動作します。しかし、MIDI メッセージを規格どおりに生成するプログラムをゼロから開発するのは非常に大変です。そこで活躍するのが Arduino MIDI Library です。#inclide <MIDI> と記述してヘッダーファイルを読み込めば利用できます。MIDI による演奏データのひとつにノートオン (鍵盤を押した) というメッセージがありますが、以下の例では打鍵した音程によって処理を切り替えるプログラムです。

#include <MIDI.h>
MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI);
 〜
void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);
}
 〜
void loop() {
    if (MIDI.read()) { 
        switch(MIDI.getType()) {
            case midi::NoteOn:
                switch(MIDI.getData1()) {
                    case 60:
						// ドのメッセージを受信したときの処理
                        break;
                    case 62:
                        // レのメッセージを受信したときの処理
                        break;
                    case 64:
                        // ミのメッセージを受信したときの処理
                        break;
 〜

ソレノイドコイルで生楽器を演奏する

ソレノイドコイルは電流を流すとコイルに磁力が発生して鉄心が直進運動 (プッシュ / プル) する電子パーツです。

こちらの写真は、電池を使ってソレノイドを動作させた様子です。電流を流すと鉄心 (太い方) が本体に引き込まれ、本体の後ろからは引き込まれた分の鉄心 (細い方) が飛び出すのがわかります。

この鉄心で打楽器を叩けば簡易的に音を鳴らすことができるはずです。そこで玩具のシロフォン (鉄琴) を直接的にソレノイドコイルで叩いてみました。

動画をみると直接的にシロフォン (鉄琴) を叩くのは難しそうだと分かります。そこでソレノイドを使って玉を発射できる機構を作って、発射された玉で間接的にシロフォン (鉄琴) を叩くようにするのはどうでしょうか。作りながら構造を考えて行こうと思いますので、詳細は「後編」でお届けいたします。

兎にも角にも、Arduino IO ピンとソレノイドコイルを接続してプログラムからソレノイドの ON/OFF を制御できるようにしなくてはなりません。複数のソレノイドを IO ピンに直接接続するとArduino の電力が不安定になりますので、N-MOSFET を使った次のようなスイッチング回路を介して接続します。

今回は 1 オクターブ分の幹音 (ドレミファソラシド) に対応する 8 個のソレノイドコイルを制御したいので、上記の回路を基板上に 8 個分おなじように実装してそれぞれの回路と Arduino IO ピン 2〜9 を接続します。

先述の Arduino プログラムを以下のように修正します。ノートオンの MIDI メッセージを受信すると、打鍵された音程に対応するソレノイドコイルを動作させるために接続先の IO ピンに digitalWrite() で信号を送ります。

#include <MIDI.h>
#define PIN_C 2
#define PIN_D 3
#define PIN_E 4
…
MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI);
 〜
void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);
  pinMode(PIN_C, OUTPUT);
  pinMode(PIN_D, OUTPUT);
  pinMode(PIN_E, OUTPUT);
}
 〜
void loop() {
    if (MIDI.read()) { 
        switch(MIDI.getType()) {
            case midi::NoteOn:
                switch(MIDI.getData1()) {
                    case 60:
			 	 		 // ドのメッセージを受信したときの処理
                        digitalWrite(PIN_C, HIGH);
                        delay(100);
                        digitalWrite(PIN_C, LOW);
                        break;
                    case 62:
                        // レのメッセージを受信したときの処理
                        digitalWrite(PIN_D, HIGH);
                        delay(100);
                        digitalWrite(PIN_D, LOW);
                        break;
                    case 64:
                        // ミのメッセージを受信したときの処理
                        digitalWrite(PIN_E, HIGH);
                        delay(100);
                        digitalWrite(PIN_E, LOW);
                        break;
 〜

今回「前編」で作ったもの

ここまで作ったものを動作確認してみましょう。MIDI キーワード→ (MIDI ケーブル) → MIDI Shield & Arduino →スイッチング回路→ソレノイドのように接続します。 

MIDI キーボードを演奏すると送信された MIDI メッセージにしたがって Arduino で対応する音程のソレノイドコイルを制御できました。動画を見ていただくと 8 個のソレノイドコイルがドレミファソラシドに対応して独立して動くのが分かります。

ソレノイドによるシロフォンの演奏 (玉の発射機構) は次回「後編」でお届けします。どんな作りになることやら・・・。


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

筆者プロフィール

清水 崇之 (しみず たかゆき) (@shimy_net)
アマゾン ウェブ サービス ジャパン合同会社
技術統括本部 西日本ソリューション部 ソリューションアーキテクト / 部長

最先端技術を追いながら世界を爆笑の渦に巻き込みたい、そんな AWS 芸人になりたいと思って AWS に入社して早 6 年。今年からは AWS DJ として頑張ります。

過去のプレゼンテーションはこちら »

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する