PSoC3/5LPで使えるUSBMIDIに挑戦してみました.以下ではCQのPSoC5LP基板で実験していますので,おそらくPSoC3でも同様だろうとは思いますが,未検証です.
マニュアルはありますが,USBFSの一部として書かれていて,これだけ読んですんなりプログラムが書けた人はあまりいないんじゃないかと思います.いろいろ試して,たぶんこういうことだろうというのが,左のテキストです.MIDIシーケンサーソフトなどから発せられたMIDIメッセージを受け取るための骨格はたったこれだけです.あとは必要なデータだけを選別して処理すればいいわけです.
コールバック関数のごく単純な例です.Note on/off しか処理していないという大手抜き版.
簡単なMIDIプレーヤーを作ってみました.手持ちのPSGを使ってもいいですが,どうせならたくさん音が欲しいので,音源を含めて作ってみることにします.
音源は方形波でいいとして,まずはPWMモジュールを使うことを考えました.CQの基板では9個までPWMモジュールを取ることができるみたいでしたが,きりがいいので8個にしました.
それぞれのPWMモジュールの出力をいったんステータスレジスタに受けて,それぞれのチャンネルのボリューム分だけ加えて足し合わせるという作戦です.
これでうまくいったので喜んでいたのですが,実際にいろいろなMIDIの音楽データを再生してみると,音数がまるで足りません.それにPSoC5LPというCPUの性能からいえば,音が8個しか使えないというのはいかにも情けない気がします.さてどうしたものか…
一晩悩んで,結局完成版はこうなりました.32bitのタイマーが1個,ずっと動いています.
この値を,鳴らしたい周波数の1/2周期に相当するカウント値で割り算します.その答えが奇数ならH,偶数ならLとでも決めてやれば,PWMでやっていたのと同じデータが得られる…
これで一気に音数をふやすことができました.32音で作ってみましたがまったく問題なく動きます.
ピン配置の表です.DACの出力をP3[7]に出して,CQのPSB基板のAOUT0,1につないでいます.
[20140521追記] クロックの設定はこんな感じです.CQのPSoC5LP基板は水晶つきですので,それを使っています.
配線はP3[7]とAOUT0,1の間だけなのでとてもシンプルです.
こんな感じでMIDIシーケンサーにつないで演奏させます.わたしはDomino1.43を使っています.
作ったプログラムをここに置きます.Creator 3.0 SP1 で作っています.
</object>
YouTube: Simple MIDI player with PSoC5LP & USBMIDI module
実際のプログラミングでは,ずっとOLEDの表示遅延に悩みました.工夫してもなかなか再生遅れが改善されません.さんざ苦しんだあげく,結局,DACに値をセットする割り込みを40kHzから20kHzに変更したらあっさり解決…そんな高いレートいらんかったんや…その辺の苦心はソースコードからお察しください.