2012年12月9日日曜日

USB接続が可能な音源デバイスの自作

前置き

そういえば前回書き忘れましたが、今回の記事と前回の記事は、Web Music Developers JP Advent Calendar 2012に向けて書かれました。

デバイス自作のための準備

インタフェースの検討

全然ウェブとは関係ないですが、今回はちょっとテーマを広げて音源デバイスの自作について書きます。自作デバイスで全てを完結させることは困難ですので、どうしても外部から制御するためのインタフェースを載せる必要が出てきます。ハード工作的にはMIDIの口を作ることは簡単なのですが、やり取りできる情報は基本MIDI準拠の情報に限定されますので、MIDI⇔デバイスの間でプロトコル変換してあげる必要があり、それはそれで(デバッグが)面倒です。そこで今更ですがUSBの登場です。USBは利用する分には便利なのですが、いざ自作しようとすると仕様も大きく躊躇してしまいがちですが、簡単な制御だけなら比較的簡単に実装できます。また、USBを自作した時に問題になるのがドライバですが、将来的にはUSB APIを使ってブラウザから制御できるようになるんじゃないかなぁ・・・なんて楽観的に考えてます。ちなみにUSB APIはドライバを書く時と同じようなレイヤーのAPIになっています。(注:私もまだUSB APIは試してみた事がありません。gdkさんともお話をした事はなく、あくまで個人的かつ客観的な希望です。)

USBインタフェースの選択

電子工作レベルでUSBインタフェースを作ろうと思うと、だいたい選択肢は2つです。1つは今回このあと紹介するデバイスでも利用しているPIC18F2550を利用する方法。もう1つはAVRを利用する方法です。
PIC18F2550は秋月で350円で入手可能、かつ下の方に貼ったように書籍もでていますので、比較的敷居は低いのではないかと思います。また筆者さんがウェブでも参考記事を書いています。ただ、普通に開発しようとするとベンダー提供のUSBフレームワークを使う必要があり、標準開発環境MPLABが必須になります。MPLABはWindows版しかなく・・・と書こうと思ったんですが、MPLAB XになってWindows/Mac/Linuxが網羅されてるようです。この辺に日本語で記事が書かれてますが、普通にPIC18F2550の開発ができるようです。自分が試した頃は無償だと制限が多くWindows縛りもあったため、SDCCというオープンソースのCコンパイラ向けに、スクラッチでUSB関連のレジスタを叩くコードを書きました。あまり意味がなくなってしまったかもしれませんが、あとでこの辺も軽く紹介します。
AVRを使う方法がちょっとトリッキーで、V-USBというソフトウェアベースのUSBインタフェースを使います。これはUSBのD+/D-の信号をマイコンで直接読み書きしてくれるライブラリです。物理層の信号をマイコンが作るため1.5Mbpsの速度で汎用I/Oを0/1でパタパタさせます。マイコンのクロックが12MHz程度である事を考えると、ほぼ常時0/1の制御をしている事になります。よって、自作デバイスの制御にある程度CPUパワーが必要な場合には向きません。あるいはマイコン1つUSBインタフェースに専念させて、別のマイコンとシリアル接続、なんて使い方になります。こちらの方法については以前サンプル付きで詳しく書きましたので、そちらを参照して下さい。100円で手に入るTINY2313が使えるのが魅力です。また開発環境もgccなので安心・・・な人にとっては安心。人によっては不安の種になるかもしれませんが。
ちなみにPICの場合はハードウェアがUSBの信号をハンドルしてくれるので、ソフトウェアはデバイス設定やプロトコルの送受信をデバイスのレジスタ経由で指示するだけですみます。またUSB 2.0に完全対応しています。一方でAVRを使う場合にはUSB 1.1互換でかつlow-speedモードのみ利用できます。USB規格はlow-speedモードでのバルク転送、アイソクロナス転送を認めていないため、それらを使いたい場合には利用できません。

音源デバイス

音源デバイスを自作したい場合、大きく分けて2つのモチベーションがあるかと思います。1つは既存のデバイスをPCに繋げるようにしたい、というケース、もう1つ完全オリジナルの音源をスクラッチから開発するとうケースです。
私の場合は前者のケース。PSGやFM音源など往年の音源チップを入手し、PCから操作できるようにする、という物です。類似ケースとして、MIDI対応以前のビンテージシンセの接続なんかも考えられるでしょうか(そういっやシンセの場合、名器と呼ばれるものなら必ずMIDI化改造が出まわってますけどね)。
後者の場合はマイコンで簡易音源を自作したり、FPGAで本格的な音源を自作したりと言った感じですね。以前AVRで実験してた事がありますが、20MHzあればC言語で書いてもPSGくらいはエミュレーションできますし、アセンブラで書けばPSG+SCCやFM音源も十分にいけます。FPGAで自作する場合にはUSB回路自体をFPGAに入れてしまうのも手でしょうか。OpenCoresに使えるIPが幾つかあります。

製作例

PSG音源

秋月でも入手できる、いわゆるPSG音源互換のチップとしてYMZ294があります。コイツを使って作ったデバイスがこれ。作りが適当なのはご愛嬌。
写真左側のボードがUSB部、右側のボードがPSG音源部になります。

USB部の拡大写真です。右下の端子が汎用I/Oに接続され、別ボードの音源と繋げるようになってます。あと、テスト時に抜き差しで端子が弱ると嫌なので、電源スイッチをつけてます。それ以外はだいたいデータシートに載ってるリファレンス回路のまま。1000円もかからずに作れます。
こちらがPSG音源部。音源についてる4MHzクロックを使えば楽なのですが、ここでは敢えて家庭ゲーム機やMSXなどで使われていた3.58MHzを入力しています。またYMZ294の右側にPIC12F629が乗っているのですが、これは何か仕事をしているわけではなく、単にクロックを発振させるためだけに使っています。昔ながらのやり方だったら水晶の周りに発振回路を組むわけですが、面倒ですし。最近のマイコンだったらたいてい内部に色々な発振回路を持っていて、適切にfuse設定を書き込んでやれば発振後のクロックを出力してくれます。部品点数を減らして価格を抑えるって意味では海外のマイコンは非常に便利にできています。

SID音源

USB部はPSG音源と共通になっていますのでSID音源部のみの紹介です。
左の写真がSID音源部のボードになります。ところで、みなさんSID音源ってご存知でしょうか? Commodore 64に搭載されていた音源チップで、同時期の音源の中ではずば抜けて多機能な音源です。MOS Technologyの6581と呼ばれる物が初期の音源で、後期には機能追加された8580と呼ばれる物が流通しています。日本ではなかなか入手できず、海外のオークションで売られているものも故障品が多く、良品入手には非常に苦労しました。S.F.Pageさんのサイトに調度良い記事があったので気になる人は読んでみて下さい。一言で言えばワンチップ・ぷちアナログシンセ。萌える。
PSGと比べてそんなに差がないように見えるかもしれませんが、背面の配線は倍以上あります。なので下に見えるのは74374でラッチ。PICとの間のインタフェースのピン数の都合上、アドレスとデータを別サイクルに分けて転送してます。
さらに右の写真でアップした部分はSID音源ならではの苦労部分、MAX662による変圧回路。あと、ちょろっと見えてる黄色いコンデンサ。上の写真では6581とラッチの間に見える2つの黄色い部品です。実はこれらがSIDがアナログシンセたる所以です。実は6581は2つの電源を必要とします。デジタル部は5Vなので特に苦労はないのですが、アナログ部に使う電圧が12Vとちょっと、というかかなり高めなのです。さらに先ほど述べたコンデンサはアナログフィルタの特性を決める素子になっており、このコンデンサ如何により音色が変わってしまいます。って事で、部品調達にもちょっと手間とお金がかかりました。あと、もう1つ致命的なのが消費電力。実は6581はPMOSです。CMOSじゃないんです。なので消費電力は高めで、電源を入れるとあっという間に驚くほど熱くなります。ほんと最新のCPUバリの発熱。0.6〜1.0Wの消費電力となっており、実は変圧器の変換効率を考えると、2枚のボード合わせてUSBバスパワーの2.5Wを守っているのか怪しい・・・。

資料など

USB-PSG

地味ですが動画など。最初に一瞬出てくるコンソールはUSBモジュールのデバッグ用シリアル出力です。説明しませんでしたがUSBモジュールについてる右上の4本ピンがシリアルになってます。Windowsから思ってもいない初期化シーケンスが飛んできたりして、初期は結構はまりました。2つ目に出てくるコンソールはUSB接続先のLinuxマシンで、拙作のksgplayをUSB-PSG向けに修正したものを使い楽曲データを流し込んでます。KSGってのはMSX用の楽曲ログフォーマットで、PSGやOPLLの実装をチェックするために昔仕事で作った簡易プレイヤーがksgplayです。まぁ、実体は簡易MSXエミュレータです。YMZ294の横にあった2本品が出力になっていて、画面に見えてる小さい丸いスピーカーに繋いで音を出してます。
本当に動いてるの?って聞かれると、レジスタアクセスランプのLEDが光ってるでしょ、くらいしか証拠がない。

USB-SID


こちらはsidplay2という、本来は音源をエミュレーションして再生するオープンソースのプレイヤーを改造して実機対応にしています。最初の2つのチップは壊れていて、これは3つ目に入手したチップだったのですが、どうもch.1の音量が小さくて・・・やはりチップが完全な状態じゃないらしい。もちろん自分の回路がおかしくてチップを壊している可能性も否定できないわけですが。
こちらはアクセスランプすらないので、すでに実機を映すことすら諦めました。

PIC18F2550 USB制御コード

SDCC向けに書いたUSB制御コード。完全とは程遠いかもしれませんが、基本的な部分は問題なく動いてます。同じような事をしたい人の参考になるかもしれないので、一応Google Codeに当時のコードをアップしておきました。なんかもう、ファイル名がtest.cですよ。少なくともWindows Vistaと当時のLinuxのUSB初期化シーケンスには耐えてました。WindowsのUSBスタックも、だんだん厳しく仕様準拠を要求してきてるらしくて、もしかしたら7や8では動かない可能性もなきにしもあらず。その時は足りない部分をきちんと実装してあげて下さい。

参考書籍

改訂版が出ているらしいので、そちらをリンク。ちなみに自分は改定前の古い方を持ってます。MPLABからMPLAB Xになって色々と変わってるかもしれないので、使うツールに合わせて本を選んだほうが良いかも。

2 件のコメント:

匿名 さんのコメント...

趣旨は違うかもしれませんが、NSX39をMSXで制御できたりしないかな。
http://otonanokagaku.net/nsx39/

とよしま さんのコメント...

NSX39はUSB MIDIなので直接の制御は難しいかもですね。
ほかのPC経由でMSX -> MIDI -> PC -> USB MIDI -> NSX39 とかなら意味があるかは別として繋がりはしますね。

あとは、eVY1シールドと繋ぐROMカートリッジを作るってのは手頃な電子工作としてありかもしれませんね。