概要

AVRマイコンを使って1chipシンセサイザーを作ってみました。
図のような構成で、昔のアナログシンセサイザーの動きをエミュレーションします。


ごらんの通りごくオーソドックスなアナログシンセの構成です。
今回は全てのブロックが1chipのAVRマイコンのソフトウェア処理で実現されています。
図中ではVCO/VCF/VCAとなっていますが、もちろんVoltage Controledではありません。アナログシンセのイメージで説明するためにこれらの名称を用いています。

回路構成

fig.2にMIDIシンセサイザーの最小構成の回路図を示します。


マイコンにはいつも使っているAVRのMEGA8を使いました。
MEGA AVRには乗算命令があり、8x8の乗算をわずか2クロックで実行できるため、デジタルフィルタやVCAの音量調整が効率よく行えます。

外付け部品を最小にするため、音声出力はPWMを用いています。
PWM出力にCRの簡単なLPFをつけることで、アナログ出力を得ています。
本格的に使うには、OP ampを用いたフィルタを使った方がいいでしょう。
多ピンのAVRを使ってラダーネットワークのDACを使った方がさらにいいと思います。

fig.3に基板イメージを示します。


fig.3 MIDI synthesizer main board

MIDI入力はAVRのUART機能を用います。
通常のMIDI I/Fの場合はフォトカプラを使います。私はPCのCOMポートを用いたMIDIドライバでテストしたので、RS-232C I/Fを接続しています。
なお、通常のMIDI I/Fでは31.25Kbpsですが、RS-232CのMIDIドライバは38.4Kbpsを使っているので注意が必要です。

シンセサイザとしての動作は上記構成で可能ですが、その他にLCDパネルやSW類をつけました。
全回路図


fig.4 MIDI synthesizer picture

VCOブロック

VCOはDDSで実現しています。
DDSは演算量が少なく、正確な周波数を得やすいので楽器のVCOには向いています。

DDS方式でA=440Hzの正弦波を発振させた時の波形写真です。

fig.5 SIN wave by DDS
上の波形を出力するプログラム

今回は演算をサボって16bitのアキュムレータを使っているので若干ピッチのエラーが大きくなっています。
ただ、DDSでピッチ誤差が大きくなるのは低音部分です。今回は10KHzサンプリング/16bitアキュムレータで20Hz以下(!)の所で最大20centのピッチエラーがあります。
MIDIコマンドのピッチパラメータが8Hzぐらいから始まっていたので実装しただけなのですが、ま、そんな所はどうせピッチなんか分からないので構わないでしょう。
50Hz以上に限れば±1cent以下なので大変優秀です。
20bit以上のアキュムレータを使えば全域で±0.1cent以下になりますが、C言語では16bitの次は32bitになってしまうので演算量が増えるだけです。
出力波形は、正弦波/矩形波/三角波/鋸歯状波/PWM波が選べます。PWMのDutyは0〜255まで設定できます。

LFOブロック

LFOもVCOと同様DDSを用いています。
但し、LFOはVCOと別のタイマを用いて、100Hzのサンプリング周期にしています。
2種類のサンプリングレートを使い分ける事により、割り込みルーチンでの演算量を減らすことが出来ます。
LFOの波形は正弦波のみとしました。
LFOの出力をVCOのDDS演算に加算することで、ピッチの変調効果を得ています。

EGブロック

EGはEnvelope Generatorの略で、発音開始から終了までの音量変化を作るブロックです。
オーソドックスなAtack/Decay/Sustain/Releaseの4パラメータを制御できるようにしました。
LFOと共通の100Hz周期の割り込みで実現しています。

VCFブロック

VCFはアナログシンセの音色を決める大事なブロックです。
デジタルフィルタで実現するのですが、演算量を減らすため、以下のような簡単な構成になっています。
y[i] = y[i-1] + m * ( x[i] - y[i-1] )
これでLPFが実現できます。
将来的にはBPF特性を持たせて、レゾナンスをエミュレーションできるようなフィルタに変更したいと思います。

VCAブロック

VCAは音量調整を行うブロックです。
MIDI入力についているVelocityパラメータと、EGブロックからの入力で最終的な音量を制御します。

ユーザインターフェイス

アナログシンセには設定するパラメータがたくさん必要なので、2行のLCDパネルとロータリーエンコーダでメニューを選んで、パラメータを変更するようにしました。
SW1を押しながらロータリーエンコーダを回すとメニュー項目が変化します。
SW1を押さずにロータリーエンコーダを回すと選んだパラメータが変化します。
演奏中にパラメータを変更するのは大変なので、AVRマイコン内部のEEPROMにパラメータを記憶しておいて、後で呼び出せるようにしました。

オーディオアウト

PWM出力にCRのLPFをつけてアナログ出力としています。
PWMの分解能を8bitにしたので、PWMのキャリア周波数は 16MHz/256=62.5KHz になります。
DDSのサンプリングレートが20KHzなので、LPFのカットオフを10KHz程度にして、PWMのキャリアも取り除くようにします。

制御プログラム

プログラムはWinAVRを使ってC言語で開発しました。
サウンド合成に関わる部分はタイマ割り込みによる周期的なサンプリングで行っています。
当初は速度向上のためアセンブラで記述するつもりでしたが、C言語でもそれなりの性能が見込めそうだったので、全てをCで記述しています。
音声サンプリングに10KHz、LPF/EGの動作用に100Hzの2つのタイマー割り込みを使いました。そのほかにPWM出力用にタイマを使っています。
AVRマイコンはタイマが豊富にあるため重宝しました。

実行結果

準備中

まとめ

AVRマイコンの能力を生かして1chipでMIDI入力からアナログ出力まで可能なシンセサイザを実現しました。
かつて電子楽器がデジタル化の道を歩んだ時、それまで主流であったアナログシンセの発音方式は演算量の多さから廃れてしまいました。
時は流れ、今や我々アマチュアが数百円で手に入れられるマイコンで、当時は不可能であったデジタルフィルタのリアルタイム処理が実現可能になりました。
楽器としてはまだ未完成ですが、マイコンの応用例としては中々面白いものになったのではないかと思います。

今後の課題

今回は単音のみのシンセサイザを作りました。
MEGA8の処理能力ではせいぜい2音のポリフォニックがいいところではないかと思います。
AVRマイコン1個では実用的な発音数は望めないので、カスケードに接続することで発音数を増やすのが現実的です。今回のプログラムでもカスケード接続を意識して、発音していないMIDIコマンドは下位ユニットに渡すようになっています。

音色についてはVCFのプログラム改善で変化するでしょう。
しかし、思い切ってVCFの前でアナログ出力し、VCFにはアナログフィルタを使った方が音色に味が出たりするのではないかと思います。
有名なMoogのラダー型フィルタなんか使ってみるのも面白いでしょう。 少し昔のハイブリッドシンセサイザはそういう構成になっていたそうです。
戻る