How to: UNIT-SYNTHで超簡単に電子楽器を作ろ!
みんな、こんにちは!マイコンを使って色んな音色で音を出したいことってあるよね?ボクはアヒルちゃん型音楽ガジェットを作った時に、最初はM5Capsuleに内蔵されたブザーで音を出してみたけど、これはイマイチで、その後にUNIT-SYNTHというユニットが発売されたことで、ブザーを使うよりも簡単に色んな音を出せるようになったよ。UNIT-SYNTHはシンセサイザーといって電子的に音を合成して色んな音色を出力するための装置だよ。今回はM5StackとUNIT-SYNTHを使って簡単に色んな音を出す方法についてまとめていくよ。
UNIT-SYNTHなら色んな音を簡単に音を出せる!
アヒルちゃん型音楽ガジェットの詳細はこちら👇
作りたいもの
M5Stack AtomLiteとUNIT-SYNTHを接続して、AtomLiteのボタンAを押したときにドレミと鳴らすものを作ってみるよ。あと、AtomLiteのボタンAを長押しすると楽器を変更できるようにするよ。
対象読者
- UNIT-SYNTHの使い方を知りたい
- M5Stackを使って簡単に楽器を作りたい
環境
ハードウェア
- M5Stack AtomLite
- UNIT-SYNTH
ここではAtomLiteを使っているけど、お手元にあるM5Stackシリーズなら何でもOKだよ。
ソフトウェア
- Arduino IDE / Platform IO
- M5Unified
- M5UnitSynthライブラリ
ここではUNIT-SYNTHの制御にM5Stackさんが提供してくれているM5UnitSynthライブラリを使用するから事前にArduinoのライブラリで追加をしておいてね。M5UnitSynthと検索すると出てくるよ。
UNIT-SYNTH
UNIT-SYNTHはM5Stackさんが2024年4月に発売したシンセサイザーユニットだよ。M5Stackシリーズのマイコンモジュールに接続して色んな音を出すことができるよ!
シンセサイザーは最初にも少し説明したけど、電子的に音を合成して出力する装置のことだよ。ピアノとかギターとか色んな楽器を音色として選択することができるよ。MIDIって頭についているけど、MIDIというのは Musical Instruments Digital Interface の略で、コンピュータ同士で音楽の情報をやり取りするためのインタフェース規格だよ。ということは、このUNIT-SYNTHはMIDIというインタフェース規格で制御するシンセサイザーってことだね!
どんなことができる?
UNIT-SYNTHでできることを簡単にまとめると:
- 同時に64個の音を出せる(エフェクトなしの場合)
- 128種類の音色を選択できる
- イコライザー、リバーブのようなエフェクトをかけられる
UNIT-SYNTHにはフランスのdreamさんのGM音源チップSAM2695が使われていて、この音源チップで色んな音を合成してUNIT-SYNTH内蔵のスピーカーから音を出力しているよ。SAM2695はエフェクトをかけない場合、64個の音を同時に出すことができるよ。あと、ピアノ、ドラム、弦楽器、木管楽器のような音色が128種類用意されていて色々な音も出すことができるよ。
そういえば、かんぷれに搭載されている音源もSAM2695だね。SAM2695はとても使いやすくてコスパが良いMIDI音源チップみたいで、結構色々なところで使われているみたいだよ!
音を出すために最低限必要な知識
MIDIの詳細はここでは解説しない(ボクもよく分かっていないから)けど、SYNTH-UNITで音を出すために最低限必要な知識をざっくりと説明しておくよ。
楽器を制御するための情報って何があるのかな?ボクはあんまり音楽に詳しくはないけど、次の3つぐらいの情報があれば楽器を制御できそうじゃない?音の強さはなくても音は出せそうだけど、MIDIの規格では音を出すときに音の強さも指定する必要があるから入れているよ。
- 音を出す/止める
- 音の高さ(ドレミ・・)
- 音の強さ(弱い音〜強い音)
MIDIでは機器から機器に送る制御信号のことをメッセージと呼んでいるよ。例えば、音を出すっていうNote Onというメッセージがあって、Note Onメッセージには音の高さと音の強さの値を含めることになっているよ。
チャネル
MIDIにはチャネルという値があって、メッセージを送信する際にはチャネルも指定することになっているよ。1つのチャネルに1つの音色を設定できるようになっていて、例えばチャネル1=ピアノ、チャネル2=ギターって感じに設定できるよ。MIDIで使えるチャネルは0〜15の合計16チャネルだよ。
あれ?SAM2695は64個の音を出せるんじゃ?16チャネルしかないと16個の音しか出せないんじゃないの?という疑問があるよね。どうやって64個の音が出るのかというと、Note Onのメッセージは1つのチャネルで同時に複数送ることができて(正確に言うと待ち時間なしで複数のNote Onを連続して送る)、ドミソというNote Onメッセージを同じチャネルに同時に送ると、ドとミとソの音を1つのチャネルで同時に鳴らすことができるよ。
MIDIメッセージの構造
ここまで説明した内容をちょっとまとめると、Note Onというメッセージを送信する場合、以下のような組み合わせでメッセージを送信しているよ。MIDIの機器(例えばシンセサイザー)がこのメッセージを受け取ると、チャネル番号に設定された音色で指定された音の高さ、強さで音を出すことができるよ。
チャネル番号+コマンド(Note On)+音の高さ+音の強さ
今回使用するコマンド、音の高さ、音の強さで指定する値の詳細は次の項目で説明していくよ。
音を出す/止める (Note On / Note Off)
MIDIで音を出すコマンド、音を止めるコマンドはそれぞれNote OnとNote Offというコマンドだよ。どちらのコマンドも音の高さと音の強さを指定するよ。
- 音を出す:Note On
- 音を止める:Note Off
今回はM5Stackさんが用意してくれているM5UnitSynthライブラリを使用するから、ライブラリでNote On / Note Offを送る方法をここでは説明するね。
M5UnitSynth::setNoteOn(uint8_t channel, uint8_t pitch, uint8_t velocity)
setNoteOnを使用するとUNIT-SYNTHから音を出すことができるよ。setNoteOnで指定する引数はさっきも説明したけど、以下の3つだよ。
- channel: チャネル番号
- pitch: 音の高さ
- velocity: 音の強さ
音の高さと音の強さで指定する値についてはこの後に詳しく説明するよ。チャネル番号は例えばチャネル1をピアノに設定して、ピアノの音を出したいときは1を指定するよ。channelで指定した楽器の音を鳴らすことができるよ。
NoteOnのメッセージをUNIT-SYNTHに送ると、音を止めるメッセージを送るまではずっと音がなっているよ。音を止めるには次で説明するNote OffのメッセージをUNIT-SYNTHに送るよ。
M5UnitSynth::setNoteOff(uint8_t channel, uint8_t pitch, uint8_t velocity)
setNoteOffを使用するとUNIT-SYNTHで鳴っている音を止めることができるよ。setNoteOffで指定する引数はsetNoteOnと同じだよ。ポイントは音を止めたいチャネル番号と音の高さをsetNoteOnで指定した値と一致させることだよ。
例えば、setNoteOn(0,21,127)で鳴らした音はsetNoteOff(0,21,127)という感じでメッセージを送ると音が止まるよ。音の強さの値は、ここではあんまり気にしなくていいよ。
音の高さ(ノート)
Note On / Note Offで音を出したり止めたりできることは分かったけど、Note On / Note Offのメッセージで指定する音の高さは何を指定すればいいのかな?ここでは音の高さについて説明するよ。
音の高さはドレミファソラシド…のようにドはドの音、レはレの音というのがあるよね。音の高さは空気が振動する時の周波数によって決まっているよ。ドならドの音が鳴る周波数があるってこと。音楽では一般的にドレミ…ではなくて英語表記のCDEFGABがよく使用されているよ。ド=C、レ=D…シ=Bのように対応しているよ。MIDIでもCDEFGABと文字の後に付くオクターブの数字で音程を表しているよ。中央のドはC4という感じ。
MIDIでは音を出すためのNote Onというコマンドがあるのはすでに説明して、Note Onを送るときには音の高さを指定する必要があったよね。この音の高さを表す値をノート番号と言うんだけど、これはA0からC8までの音が21番から108番に割り当てられているよ。MIDIで指定できる全てのノート番号は以下の通りだよ👇
ノート番号 | 音程 | 備考 |
---|---|---|
21 | A0 | ピアノの最低音 |
22 | A#0 / Bb0 | |
23 | B0 | |
24 | C1 | |
25 | C#1 / Db1 | |
26 | D1 | |
27 | D#1 / Eb1 | |
28 | E1 | |
29 | F1 | |
30 | F#1 / Gb1 | |
31 | G1 | |
32 | G#1 / Ab1 | |
33 | A1 | |
34 | A#1 / Bb1 | |
35 | B1 | |
36 | C2 | |
37 | C#2 / Db2 | |
38 | D2 | |
39 | D#2 / Eb2 | |
40 | E2 | |
41 | F2 | |
42 | F#2 / Gb2 | |
43 | G2 | |
44 | G#2 / Ab2 | |
45 | A2 | |
46 | A#2 / Bb2 | |
47 | B2 | |
48 | C3 | |
49 | C#3 / Db3 | |
50 | D3 | |
51 | D#3 / Eb3 | |
52 | E3 | |
53 | F3 | |
54 | F#3 / Gb3 | |
55 | G3 | |
56 | G#3 / Ab3 | |
57 | A3 | |
58 | A#3 / Bb3 | |
59 | B3 | |
60 | C4 | 中央のド (Middle C) |
61 | C#4 / Db4 | |
62 | D4 | |
63 | D#4 / Eb4 | |
64 | E4 | |
65 | F4 | |
66 | F#4 / Gb4 | |
67 | G4 | |
68 | G#4 / Ab4 | |
69 | A4 | 基準音 (440Hz) |
70 | A#4 / Bb4 | |
71 | B4 | |
72 | C5 | |
73 | C#5 / Db5 | |
74 | D5 | |
75 | D#5 / Eb5 | |
76 | E5 | |
77 | F5 | |
78 | F#5 / Gb5 | |
79 | G5 | |
80 | G#5 / Ab5 | |
81 | A5 | |
82 | A#5 / Bb5 | |
83 | B5 | |
84 | C6 | |
85 | C#6 / Db6 | |
86 | D6 | |
87 | D#6 / Eb6 | |
88 | E6 | |
89 | F6 | |
90 | F#6 / Gb6 | |
91 | G6 | |
92 | G#6 / Ab6 | |
93 | A6 | |
94 | A#6 / Bb6 | |
95 | B6 | |
96 | C7 | |
97 | C#7 / Db7 | |
98 | D7 | |
99 | D#7 / Eb7 | |
100 | E7 | |
101 | F7 | |
102 | F#7 / Gb7 | |
103 | G7 | |
104 | G#7 / Ab7 | |
105 | A7 | |
106 | A#7 / Bb7 | |
107 | B7 | |
108 | C8 | ピアノの最高音 |
M5UnitSynthライブラリのsetNoteOnやsetNoteOffでノート番号を指定するときは、上の表のノート番号を直接指定してもいいし、NOTE_C4のようなマクロでの指定もできるよ。マクロの定義は以下を参照してみてね。
音の強さ (ベロシティ)
次はNote Onと一緒に送る音の強さの情報を説明するよ。ベロシティは速さって意味だけど、鍵盤を叩く速さを表しているみたいだよ。ピアノの鍵盤を叩く速さが速いほど音が強くなるし、遅いと音は弱くなるよね。ベロシティで指定できる値は0〜127で値が大きいほど音が強くなるよ。
音の種類 (program change)
ここまででUNIT-SYNTHで音を出す、音を止める方法について説明してきたけど、UNIT-SYNTHでは色々な楽器を音色として設定できるから、音色を設定する方法についても説明するよ。M5UnitSynthライブラリではsetInstrumentを使用することで簡単に音色を設定することができるよ。
M5UnitSynth::setInstrument(uint8_t bank, uint8_t channel, uint8_t value)
- bank: 音色テーブルの切り替え
- channel: チャネル番号
- value: 音色の番号
bankはSAM2695にある2つの音色テーブルを切り替えるために使用するんだけど、説明するとややこしくなるから、ここでは常に0を指定しておくよ。
channelはsetNoteOnやsetNoteOffで使用するチャネル番号と同じで、どのチャネルの音色を変更したいかを指定するよ。0〜15まで指定できるよ。ただし、チャネル10はドラム用のチャネルになっていて、ドラム以外の音は割り当てられないようになっているよ。
valueは音色の番号を指定するよ。M5UnitSynthライブラリでは、unit_synth_instrument_tに音色の名前が設定されているから、これを使うと便利だよ。例えばグランドピアノはGrandPiano_1と定義されているよ。ノート番号と同じくM5UnitSynthDef.hで定義されているから参照してみてね。
ドラムはちょっと特殊
チャネル10はドラム専用のチャネルなんだけど、SAM2695では4種類のドラムセットを選択することができるよ。setInstrumentのチャネル番号に10を指定して、valueでドラムセットの番号を設定することでドラムセットを設定することができるよ。どんなドラムセットがあるかはSAM2695のデータシートを見てね。
dream社SAM2695データシート P.32より
音を出してみよ!
ちょっと説明が長かったかもしれないけど、これでUNIT-SYNTHで音を鳴らす方法が分かってきたかな?ここからはいよいよUNIT-SYNTHで音を出していくよ。
接続方法
まずはM5StackとUNIT-SYNTHを接続するよ。UNIT-SYNTHのGrove端子とAtomLiteのGrove端子をケーブルで接続してね。
AtomLiteの場合、GPIOの32と26がGrove端子に割り当てられているよ。UNIT-SYNTHとの通信はUARTで32が受信、26が送信になっているよ。これはAtomLiteの場合で、他のM5Stackを使用している場合はGPIOの番号が異なるから、使用しているM5Stackに合わせてね。
UNIT-SYNTHの初期化
UNIT-SYNTHの初期化は簡単で、M5UnitSynthクラスのオブジェクトからbeginを呼び出すだけだよ。
M5UnitSynth::begin(HardwareSerial serial, int baud, uint8_t RX, uint8_t TX)
synth.begin(&Serial2, UNIT_SYNTH_BAUD, 32, 26);
1つ目のserialにはUNIT-SYNTHと通信するシリアル通信のためのオブジェクトを指定しているよ。ESP32ではハードウェアシリアルが3つあって、使用していないシリアル通信のオブジェクトを指定しているよ。たぶんSerial1も使えるのかな?
UNIT_SYNTH_BAUDはこれをそのまま指定してね。
最後の2つはUNIT-SYNTHとシリアル通信するための受信と送信のGPIOを指定しているよ。AtomLiteではそれぞれ32と26だね。
これでUNIT-SYNTHを使用する準備が完了したよ!
サンプルコード
今回作りたいAtoLiteのボタンAを押すとドレミと鳴らすためのサンプルコードだよ。コードの説明はコメントとして直接記載しているよ。
#include <Arduino.h>
#include <M5Unified.h>
#include <M5UnitSynth.h>
M5UnitSynth synth;
uint32_t prog = 1;
void setup() {
// Initialize M5Unified
// M5Unifiedを初期化しているよ。
M5.begin();
// Initialize UNIT-SYNTH
// M5UnitSynthを初期化しているよ。
synth.begin(&Serial2, UNIT_SYNTH_BAUD, 32, 26);
// チャネル0の音色をグランドピアノに設定しているよ。
synth.setInstrument(0, 0, GrandPiano_1); // synth piano 1
// UNIT-SYNTHのマスター音量を200に設定しているよ。
synth.setMasterVolume(200);
// UNIT-SYNTHのチャネル0の音量を200に設定しているよ。
synth.setVolume(0, 200);
}
void loop() {
M5.update();
if(M5.BtnA.wasPressed()){
// ボタンAが押されたときにドレミと鳴らしているよ。
// ド
synth.setNoteOn(0, NOTE_C4, 127);
delay(500);
synth.setNoteOff(0, NOTE_C4, 0);
// レ
synth.setNoteOn(0, NOTE_D4, 127);
delay(500);
synth.setNoteOff(0, NOTE_D4, 0);
// ミ
synth.setNoteOn(0, NOTE_E4, 127);
delay(500);
synth.setNoteOff(0, NOTE_E4, 0);
}
if(M5.BtnA.wasHold()){
// ボタンAが長押しされたときに次の音色を選択するよ。
prog++;
synth.setInstrument(0, 0, prog%128);
}
}
実際に実行するとAtomLiteのボタンを1回押すとUNIT-SYNTHからドレミと聞こえて、ボタンを長押しすると楽器が変わることを確認できたかな?
まとめ
今回はUNIT-SYNTHを動作させるためのコード自体は簡単だったけど、MIDIを使用して音を鳴らすために必要な知識の説明に少し時間がかかったよね。それだけ音楽やMIDIが奥深いってことだね。今回は簡単にドレミと鳴らしてみただけだけど、ボタンを沢山用意したり、色々な演奏方法を考えることで自分だけの楽器を作れそうだよね?ボクもアヒルちゃん型の音楽ガジェットを作ろうとしているけど、みんなも自分で考えた楽器を作ってみてね!作ったものは教えてくれると嬉しいな!
じゃあ、今日はここまで、またね!
Discussion