概要

NXPセミコンダクターズから発売されたLPC800シリーズのMCUのテストを兼ねて,4オペレータ8和音のFM音源を実装してみました.

 

動機

まあ言わずもがなという感じではありますが,きっかけはLPC800の発表&発売であります.

LPC800はCortex-M0+をベースにしたARM MCUですが,なんといっても8ピンDIPパッケージが用意されていることが大きな目玉です.

これはAVRやPICを潰しにきたな…と思いながら数ヶ月ワクワクしていた頃,秋月に8ピンDIPパッケージのLPC810が入荷したとの情報を入手しました.

それも1個80円という超お手頃価格で.(今や75円@秋月ですが)

32bit MCUが80円で買えるとは良い世の中だということで嬉々として秋月へ大人買いしに行ったわけです.

だがしかし世の中はうまくいかない

買ってきてさあ使おう,とも思ったのですが少し立ち止まって先達のレビューを見てみると,

使いにくい,メモリがすぐなくなる

などなどの評価が目立ちます.うーん,ADCもないし落ち着いて考えると結構用途限られるなあ…と考えていたのですが,落ち着いて逆に考えてみると,LPC810の取り柄は,

  • (8bitじゃ収まらない)計算が8bit MCUより速い!(そりゃそうだ)
  • 安い・小さい(DIP8ピンに32bitの性能は確かにすごいよね!)

というあたりに集約されるんじゃないかなと考えました.

なんとかの一つ覚え

ここまで来たらじゃあアレ作るしかないか,ということでまたしてもFM音源を作ったわけです.

お前「ARMで作るVA音源」はどうした!とか言わないでください(そっちも検討中です…)

高校時代にAVRでこんなものを作っているので「なんとかの一つ覚え」感はありますが,一応理由はあるのです.

まず一つ目が処理速度の要求がそこそこ高いということです.

FM音源に限らず,ミュージックシンセサイザは数千~数万サンプル/秒の出力を行う必要があります.

ローエンドのMCUは高々数十MHzで動くのが限界ですから,1サンプルにつき数百~数千クロックしか使えません.

従って,動作周波数が(ローエンドのMCUの中では)高い,あるいは1クロックにできる計算がより高度である方が凝った音源を作る上では有利になります.

割と凝った話をすると,FM音源に限らず,信号処理っぽい処理が入るプログラムでは,データに対してある係数を掛けていくということをよく行います.

この時の係数は実数だったりすることが多いわけですが,チープなMCUはFPUのようなハイソなものは搭載していないわけで,固定小数点演算を実装していくことになります.

固定小数点演算では,加減算は単純な整数の加減算と変わらないわけですが,乗算において桁あわせ動作が必要になります.桁あわせ動作は右シフトになるのですが,AVRでは1命令で1ビットシフトしかできません.

ARMであれば(と,いうかモダンな32ビットMCUなら?)1命令で多ビットシフトができます.(バレルシフタがALUにあるってことですね.)かなりの回数の固定小数点演算を行うアプリケーションでは,ここが処理速度に効いてくると思います.

この他にも当たり前ですが,多バイト長のデータの演算・ロード・ストアが速いというメリットもあります.

次に,先ほどの取り柄として取り上げましたが,安くて小さいのも重要であります.

先ほど述べたAVRによるFM音源の実装では発音用MCUとしてATMega328Pを使用していました.このMCUは1個250円@秋月です.

4和音の実装としていたので発音用MCUだけで1000円になってしまいます.一方LPC810を使えば倍の8和音にしても1個80円*8=640円です.英世でお釣りが来ます.素晴らしい.

さらにATMega328Pは28ピンDIPですがLPC810は8ピンDIPです.ATMega328P1つのスペースにLPC810を3つは実装できます.

まあ,本当に実装密度を上げたければもっと別の方法を検討するべきではありますが.

とりあえず,以上のような2つの理由から,LPC810でFM音源を実装したら面白いかなと考え,実装してみました.

実装

今回実装するFM音源は以下の様な仕様としました.

  • 4オペレータ8和音(アルゴリズム8種類)
  • LPC810を8個搭載し1個につき1音の発音を担当する
  • MIDI受信とUIはLPC1343を利用(たまたまあったのでこれを使った)
  • LPC810が処理するのは固定長の独自コマンド
  • コマンドはLPC1343からSPIバスで送信される
  • 各オペレータの発振波形は正弦波のみ
  • LPC810の動作周波数は30MHz(上限)
  • サンプリング周波数は31250Hz
  • 出力は8ビットPWM DAC(PWM周波数は93750Hz)
  • ADSRエンベロープジェネレーターを実装(サスティーンの状態で減衰も可能)
  • ピッチベンド用パラメータの実装

4オペレータなのはAVR版が4オペレータだったのでそれを維持した状態でどのくらいの性能が出せるか確かめたかったからからです.

8和音なのは4和音のAVR版で同時発音数の不足を感じたのと,手持ちのLPC810の消費を兼ねていっそ倍にしてやるか!という適当な動機からです.

MIDIを固定長の独自コマンドに変換して発音MCUに送信するというアーキテクチャはAVR版と基本的に変わっていませんが,

AVR版はUARTにマルチプレクサを組み合わせて送信先制御を行っていたのを,ARM版ではSPIバスでCSピンを使って送信先制御を行っています.

但し,ブロードキャストが可能なようにマスターであるLPC1343からの一方向通信となっています.

発振波形が正弦波のみなのはAVR版に比べてグレードダウンした点です.これは単純にメモリが足りなかったために泣く泣く省略したという感じです.

正弦波のテーブルを持つのも辛いため,π/2[rad]だけテーブルを持ち,後はsin関数の対称性を利用して表引きをしています.

メモリ容量の割に計算能力があるからこそ使えるアプローチだと思います.

PWM周波数はサンプリング周波数の整数倍になるようにしてみました.EGについてはAVR版とほぼ同じ実装です.

ピッチベンド用パラメータの実装についてはAVR版になかった機能です.

結果(?)

結果といっても動画にあるとおりです,としか言いようが無いと思います…

一応見た感じだと,処理をだいぶ余裕を持ってできているようです.

AVRでは1サンプルの生成がサンプリング周期ギリギリだったのですが(と言うかアセンブリレベルでガリガリチューンして収めた),

ARMでは2サンプル位は1サンプリング周期に生成できそうです.動作周波数はAVR版の1.5倍なので,動作周波数の向上以上の性能向上が実現できています.

4オペレータでも音作りが結構大変なので,あまりモチベーションはないですが,おそらく6オペレータ程度であれば簡単に実現できるでしょう.

裏テーマ:富豪的ハードウェア

「富豪的プログラミング」というのは有名だと思いますが,同じような発想でマイコン工作してみよう,というのが裏のテーマだったりします.

大げさに言えばマルチプロセッサシステムの実験,であるのですが,一般的にデジタルミュージックシンセサイザの特徴として

  • 各々のノート(音)に関して相互依存性が(ほぼ)ない
  • 入出力データ量に対して計算量が大きい(おおかたの処理はO(n)ですが係数が大きいです)

という特徴があげられると思います.要は並列化しやすいアプリケーションだというわけです.

そんなわけで,高校時代に製作したAVR版FM音源で並列構成を取ったわけです.しかし,AVR版ではDACも外付けなのでトータルコストは結構かかってしまっています.

しかし,今回はMCU本体は80円(75円),DACはPWMなのでフィルタのRC代数十円で済むわけです.

これだけのリソースを安く手に入れることができるわけですから,わざわざ苦労して1つのMCUで何音も計算させたりせずに,

すっきりと1音分の処理を書くことに専念して,最低限のマルチプロセッサ制御部を書くほうが楽にできるのでは?という提案です.

しかも今回のような構成では100円出してMCUと周辺のRC部品を買ってくれば,簡単に1音同時発音数を増やすことができます.

逆に,1音分だけ切り出して使うことも容易です.(既存の自作システムにサウンド機能を追加する場合などに良いでしょう)

…と,ここまでぐだぐだ書いてきましたが,ミュージックシンセサイザにおいて,同時発音数であったりパート数を稼ぐ目的で,同じモジュールをたくさん積むというのはよくやられている手法であります^^;

(同時発音数ではOberheimのSEM/1-Voice/4-Voice/8-Voiceが,パート数ではヤマハのTX116~816が有名ですかね)

旧来からやられている手法ではありますが,安くて速いMCUの使い道としても有効なのではないか,と思っています.

8ピンMCUなので小ささを武器にしたすごく小さいサイズの電子工作をする方が多いと思いますが,こんな使い方もあるよ,という例でした.

回路図

まだ描いてないです…

ソース

ちょっと待って…