Arduino+FM音源で遊ぶ(ライブラリの使い方解説)

今回はYM2151ライブラリの使い方についてメモします。ライブラリというよりはMDXシーケンサの実装に伴ない必要な物をまとめただけといった感もありますが、レジスタ裸の状態ですと音を出すまで結構大変なので理解の助けになればと思います。リファレンスはこのページにまとめています。

YM2151Library

まずは基本のお約束、HelloOpmWorld!

Arduinoの各ライブラリの例に漏れず、YM2151.cpp/YM2151.h/Common.hの3点を使いたいスケッチのディレクトリにコピーした後YM2151.hをインクルードするだけです、内容はサンプル3点で同一です。Common.hはマクロを2点定義しているだけなのでお好きなように再定義してください。最低限音を出すのに必要なコードをまとめたのがこちらです。

uint8_t	channel = 0;
YM2151.begin();
YM2151.loadTimbre(channel,(uint16_t)SampleTimbre01);
YM2151.setVolume(channel,0xf,0);
YM2151.setPanpot(channel,0x3);
YM2151.setTone(channel,0x20,0);	// 音階=0x20
YM2151.noteOn(channel);

まずbegin()メソッドを呼び初期化する必要があります、やや時間がかかる処理ですのでsetup()の中で1度だけ呼ぶのがベターだと思います。以降チャンネルごとに設定していきますが、ご存知の通りYM2151は8音同時に出力が可能なので0~7まで同じように設定していきます。

  • loadTimbre(uint8_t,uint16_t)で音色パラメータをセットします、この関数はMDXフォーマット形式で定義されたPROGMEM prog_uchar配列のアドレスを渡します。パラメータについてはさらに分りやすい方法を用意しましたので後述します。
  • setVolume(uint8_t,uint8_t,uint16_t)でボリュームを設定します、範囲は0~15で15が音量最大です。ハードの制約上音色の組み方によりボリュームを下げると破綻する場合があります。
  • setPanpot(uint8_t,uint8_t);でパンポットを設定し、左右どちらに発音するか設定します。ハードの制約上、デジタルな鳴り分けしかできません。
  • setTone(uint8_t,uint8_t,int16_t)で音程を設定します、オクターブ0のD#を0として音階を設定します。3番目のkfは音階の微調整です、6bitで設定しますが、音階と合成しているので連続変化音を作りたい場合はこちらのみで大丈夫です。
  • noteOn(uint8_t)で発音します。

setVolume、setPanpotは一見不要に見えますが、関連レジスタの設定も行っているので音色の再設定を行った後は必ず呼んでください。特にリセット直後はレジスタ初期値0なので呼ばないと全く鳴りません、noteOff(uint8_t)で発音を止めます。

お手軽音色設定関数について

まだFM音源が現役だった頃から難易度が高かったのが音色設定です。倍音を多重合成して音を出しているのでほんの僅かなパラメータの違いにより大きく出力が変わる上、数も多いので当時から沢山の音色設定ツールが作られた程です。そこで、VAL-SOUNDさんが、

FM-Sound Library

にかなり大量の音色を公開していらっしゃるので、そのままロードできるよう関数を追加しました。記述としては、

PROGMEM prog_uchar	AnalogBass[]={
6, 7,  31, 0, 0,12, 1,18, 1, 1, 0,0,
31, 0, 1,12, 1, 4, 1, 2, 0,0,
31, 0, 0, 9, 0, 3, 0, 1, 7,0,
31, 0, 0, 9, 0, 3, 0, 1, 3,0
};
YM2151.loadSeparationTimbre(channel,(uint16_t)AnalogBass);

このような感じです、但しOPN/OPNAもサポートする音色な為、パラメータが若干増えているYM2151は微妙に使いきれない状態となります。

以上全体的に説明をやや端折ってしまいましたので、分かりにくい点がありましたらコメントやメールで遠慮無くお願いします。

いろいろ更新しました

転送ツール他を29日に更新し、若干機能強化を行いました。サポートページにまとめてあります。

YM2151シールドサポートページ

Arduino+FM音源で遊ぶ(MTM05ご来場ありがとうございました)

おかげ様で(ほぼ)完売しました

特にYM2151/YM3012の仕入れにかなりの額を投入したので「売れ残ったらどうしよう・・」と嫌な汗をかいていたのですが、YM2151/YM3012無しが1セット残り、YM2151/YM3012付きは完売となりました。ただ初日は若干トラブルが有りMIDIとWiiヌンチャクのデモが動作しておらずご迷惑おかけしました。原因はWiiヌンチャクのピンヘッダの接続を間違えていて、Wireライブラリが通信に失敗した所でHALT状態になっていたというオチでした。その場で原因を調べようにもUSBポートの数が足りなく、色々ともう少し余裕を持たないとダメだという教訓ですね。そう、ここでWireライブラリの仕様を責めたらプログラマ失格なのです!

MTM05バージョンについて

MTM05バージョンで出したキット内容についてざっくり解説します、まずハード周りの変更点です。

MTM04版のRev1.1でMIDI入力にフォトカプラのTLP521を使用していましたが、実際に信号を流すと取りこぼしが多く、オシロで見ると案の定波形がメタメタだったのでデジタル出力のPC900Vに変更しています。結果としてarduino.ccで公開されいるMIDI Library2.5がそのまま利用できることを確認しています。また、Rev1.1でカットしたYM2151の割込み出力をAnalog04に入力可能なようにジャンパパターンを追加しました。基板の方は電子回路初心者の方でも安定して組み上げられるよう、少々値は張りましたが製造をP板.COMさんに委託しました。キットの外観はこんな感じで。

組み上げるとこのように、緑基板で地味地味ですが、緑以外だと+2万円という見積もりだったので断念。

ソフト面では前回MDX再生スケッチの再現度が完璧でなく、ソフトLFOの一部のモードが動作していなかったのを修正したのでおおよそ100%の実装度に到達したと思います。あとArduinoのCPUパワーに余力があるのが分かったので、やや効率は落ちていますがYM2151のレジスタを叩いている部分を極力分離し、Arduino標準のお作法に習う形でYM2151.cpp/.hにライブラリとしてまとめています。音色設定配列はブラックボックス気味ですが発音制御と音程、ボリューム、パンポット制御辺りまではお手軽にできるようになっています。

ライブラリの詳しいドキュメントは後日公開します。

各コードについてはbrogからのリンクですと色々不便ですので「YM2151シールドサポートページ」として以下のGoogleSitesにまとめています。

YM2151シールドサポートページ

キットに同梱した組立説明書も近々PDF変換してこのページに上げておきますので、組んだ後は捨ててしまって問題無いと思います。私自身が余分な紙資料キライ!でScanSnapで何でも電子化な人ですので。Wordで書いている都合上やや解像度は下がってしまいますが。

今後の展開について

まずほぼやります!なToDoについては、ライブラリの使い方解説、エラー処理がユルいMDX転送ツールの手直し、MTM05版紹介動画の作成、辺りです。

後はどうでしょうかね、YM2151の詳細解説とかですかね?現状ネット上に存在しないので、英語の勉強も兼ねて日/英版でテキスト化とか、また恥ずかしい物を晒すことになりそうですが。

キットの追加ロットについてはやはり肝心要のYM2151/YM3012の入手が不安定なのと、石自体がかなり高価な部類で個人で回すには在庫リスクが高いので、反響が予想外に大きかったらやりますといった感じでお願いします、申し訳ない。

Arduino+FM音源で遊ぶ(MTM05に出展しキット販売を行います!)

準備完了

細かい部品の手配も完了し、基板の新リビジョン版も完成したので、後は説明書を書いて部品を小分けするだけといった状態です。

小型オシレータも大量にあると迫力です、ちなみにYM2151/YM3012は古い石ということもあるので、このようにゼロプレッシャーをムリヤリ取り付けて全数チェックを行います。

最終的な原価計算がまだなので価格未定です。

というわけで実はかなり前に受理されていますがMTM05に出展しキットを販売を行います。

Make: Tokyo Meeting 05

あと直前で申し訳ないですが5月9日の「はんだづけカフェ」さんのオープニングイベントにおじゃまして最新リビジョンのお披露目をするかもしれません。

はんだづけカフェ

キット販売とか何気に小売初体験なので色々ドキドキです。ではMTM05でお待ちしております。

Arduino+FM音源で遊ぶ(石の入手に成功しました)

入手できました

いくつかの半導体商社さんに問い合わせ、無事入手できました。レールは汚いですが全て新品の正規品です。

数は正直悩んだのですが、MTMの時に同じ島だったいえなが氏から30ほど出しましたという話をお聞きしましたので、同じ数量にしてみました。補修用に5セット追加して計35セットです。

あとは基板を手直して量産。他の雑多な部品をDigikeyや秋月に注文してパッキング、説明書を作ってMDXシーケンサの仕上げを行い、ライブラリを整備、といった所ですかね?やる事多いです。

私事ですが

えー、思いっきり私事で申し訳ないですが昨年12月末で退職し現在まったりと仕事を探しています。超多忙期明けなのでまだスローペースですが、色々趣味コードを書いてみたいと思います。

Arduino+FM音源で遊ぶ(デモ動画作りました)

動画作りました
素材撮りから作るのは初めての経験だったので、えらく遠回りをしてしまいましたができました。

こっそりとYouTubeに乗り換えです。

8日夜現在ではSD解像度になっていますが、処理が終われば多少綺麗になると思います。しかしHD動画の編集は重いですね、i7とか欲しくなってしまいます。

Arduino+FM音源で遊ぶ(MTM04無事終了しました)

来場ありがとうございました!

こんなヤッツケの出展物で特に開場直前はものすごく不安だったのですが、中々どうしてで沢山の方に楽しんで頂けたようで正直ホッとしました。ただ説明はハッキリ言ってすごくヘタで要領を得ず大変ご迷惑おかけしました、初日はフライヤーも用意できていませんでしたし。

またキット化についてはそれはそれは沢山の方に御質問頂いたので、遅くとも次のMTMまでには何らかの形で出したいと思います。ただ肝心要のYM2151+YM3012の入手が不確定なので手元に数が揃うまでは安心できませんが。

解説動画作ります
ちょっと真面目に解説動画を作ろうと考えています、カメラの手配から開始なので少し間が空きますが少々お待ちください。

Arduino+FM音源で遊ぶ(MTM04に出展しますよ編)

Googleの絶版書籍データベース化は日本語除外されてしまいましたねー、残念。未来永劫個人ベースで電子化する方向しかないのでしょうか?

Rev1.1基板が到着

前回省略してしまいましたが、Rev1.1基板の狙いとしてはまずRev1.0基板ではUSBからのノイズ混入が酷かったのでLPFを入れるというのと、限界まで小さく仕上げるという2点です。表面実装部品を使えば大幅に小型化できますが、まだそんなスキルは無いのでリード付き部品で限界近くまで詰めてみました。S/Hとバッファアンプは4回路入り単一電源、レイルtoレイルのOPアンプを使用してDCV01を省略。部品点数を減らしています。

というわけでかっちり指定納期でPCBCARTから送られてきました、えらいぞPCBCART。

Arduino風になるのを狙ってメッシュベタにしたのですが、ラインが細くてなんだか違う雰囲気になってしまいました。めげずに実装してみます。

バックアップを含めて3台仕上げてみました、今のところ不良率0。石がなぜ3台分あるかというと、万が一の為にチップワンストップ他で手配していた分が届いたからです。しかしDACのYM3012はチップワンストップでも見つからず、海外のあやしい業者から購入した物ですがマーキングが何だか変でコピー品のような感じがします。普通に鳴りますけどね。

MTM04に出展します

というわけで唐突ですがオライリーさん主催のMakeTokyoMeetingに出展します。

MAKE: Japan : Make: Tokyo Meeting 04

グループ名は’ISH’で登録してあります。実はMake誌は英語版の01から読んでいる結構なファンだったりするのですが、仕事で見に行く時間が作れなくずっと悔しい思いをしていたので、少々無理していきなり出展でデビューしてみました。しょぼい出展ですが時間があれば是非見にきてください。ついでに「アレどうなったの?アレ」といったぶっちゃけた話もオッケーです(本当にスイマセンスイマセン・・・)

Arduino+FM音源で遊ぶ(ソフトウェア編)

データシートの入手

ハードウェアの準備は整ったので今度は鳴らしてみます。しかし英語版の電気的仕様のデータシートはネットで入手可能ですが、レジスタレベルの詳細ドキュメントは見つかりません。そこで有名なX68000解説本であるInsideX68000に当たってみることにしました。実はX68000実機共々昔所有していたのですが、とっくの昔に捨ててしまった為再度探す羽目になってしまいました。しかしAmazonマーケットプレイスに10,000円!で出ている他はヤフオクにもBookOffにも見当たらないようです。

というわけで欲しいのはサウンド周りのセクションだけですので、図書館でコピーサービスを利用するという作戦に出ることにしました。最初は国会図書館行きか?メンドクサイナーと思っていたのですが今は蔵書を横断検索できるサイトがあり、東京都立図書館であればOutsideX68000もセットで置いてあるようなのでコピーを貰ってきました。全部で400円程度だったと思います。なぜOutsideも?と思われるかもしれませんが、この時点ではまだハード設計をしていたため、リファレンスとしてX68000の回路図も欲しかったのです。

しかし一連の資料探しで絶版本にしか存在しない情報へのアクセスは随分と考えさせられました。欲しいのは紙に書かれている情報なわけで、図書館ならあると言われても休日半分潰す覚悟で望まないといけないわけですから。しかもこれが海外からだとほぼ絶望的です、丁度Googleが絶版本をネット公開するという話が出ていた頃だったので、利用者的にはうまく版権者と話を付けてほしいと願って止みません。

ちなみにOutside~は今現在都内全検索しても数冊しか存在しません。最後の砦、国会図書館という手がありますが平日しか使えないですしね。

鳴ったっ!のでMDX

データシートも手に入ったことですし実装が済んでから早速レジスタを叩いて鳴らしてみました。何分初めて外注した基板ですので、かなり不安でしたが無事動作しているようです。

もちろんこの時点でプロジェクト終了!とするつもりは最初からありませんで、当時いろんなプロアマ含めた先人達がこのYM2151を必死に叩いて腕を競いあっていたので、何とかしてそれを再現してみたい、といわけで思いついたのが草の根BBS等で流通していたMDXというシーケンスデータフォーマットです。これの再生ドライバをArduino上で書いてしまえ、という訳で次のステップに進みます。

転送ソフトMDXImageTransferを起こす

MDXはX68000上で動作するMXDRVというシーケンサ用のデータです。Winにも移植されていますのでご存じの方は多いと思いますが、最も初期のフォーマットである故、YM2151の仕様ベッタリ、機能的にも最小限度、その代りデータサイズも非常に小さい、というArduinoに移植するにはまさしくうってつけの物件です。しかしMDXは小さいと言っても大きいデータは10kを超えてしまいますのでRAMには当然入りません。プログラム用のフラッシュメモリはDuemilanoveなら32Kありますので当然こっちにという話になりますが、プログラムに埋め込んでしまうとMDXを変えるたびにコードをリコンパイル&転送というあまり現実的でない話になってしまうので、最初からPCより別個に転送する仕様を考えます。

まず最初にトライしたのがArduino<->PCで適当なプロトコルをでっちあげて転送されたデータをプログラムフラッシュに書き込むという方法です。ところがシリアル転送は上手くいったもののフラッシュの書き込みになぜか失敗してしまいます。ちなみにフラッシュの書き込みはブートローダーのコードを参考にしました。

ATmega328Pのデータシートをよくよく見たところ、モード毎にプログラムフラッシュの書き込み許可設定を変えられるらしく、なんとArduinoではデフォルトではユーザモードからは禁止という設定になっているではないですか。うわーーー時間ムダに・・・、AVRのライタで設定をいじって許可してしまおうかとも考えたのですが、それってArduino?という話になってしまうので別の手段を考えます。

先の方法でフラッシュの書き込み手順を調べる為に読んでいたブートローダーですが、ユーザエリアからダメならこれと直接通信してしまえという訳でさらっと書いてしまいました。何分クライアントの挙動はソースで読めるので簡単です。つまりArduinoIDEがプログラムを転送するのと同じプロトコルでMDXを転送してしまうという手段です。但し、コードの書き込みだけ標準のArduinoIDEでやるのも2度手間になってしまうので、コード用のIntelHEXデータを読み込んで転送する機能もつけてみました。結果こんな感じのUI付きプログラムになりました。

ちなみにC#です、この手の小物を作るには良い環境ですよね。あとこの方法をマネしたいという方に注意ですが、ブートローダーのフラッシュ書き込みシーケンスではユーザエリアはもとよりブートローダーエリアも書き込み許可されていますので、アドレス設定をミスるとブートローダーを飛ばしてしまいますので十分注意してコーディングしてください。私は一回やってしまってAVRのISPを購入する羽目になってしまいました。秋月なら4000円で売っています。店頭でも言うと出してくれます。

MDXドライバを書く

これも苦労しました、、と言いたい所ですが今現在100%実装ではなく中途半端に鳴らせている状態ですのでまた今後のエントリーに書きたいと思います。80%位ですかねぇ、細かい挙動はオリジナルのドライバソースを参照しないとダメなので大変です。

そしてRev1.1基板へ・・

ここまで完成すると欲が出てきまして、MDX再生だけじゃつまんない!というわけで、バス制御線や割り込みをざっくり省略してAnalogINを開けた上に、MIDI入力を追加したRev1.1基板を設計&発注しまして今現在納品待ちです。

ちょっと詰め過ぎ感じですが基板設計も大分慣れてきました。

長くなりましたが以上をもってようやく現在の状況に追い付きました。brogねたは溜めこんじゃダメという結論で。

Arduino+FM音源で遊ぶ(基板発注+チップ入手編)

うーむ、ブログが亀ペースで制作のスピードに全然追いついていません。気を取り直していきましょう。

初めての基板発注

ボード設計もほぼ完了という訳で、最終的なガーバーデータをチェックする為あちこちのサイトを巡回していたのですが、色々な所で目にしたのがこちらの中国にある PCBCART – Professional China Prototype PCB Manufacturer という業者です。地理的に近いこともあって最終的な納期がかなり早くなるというのが決め手となりPCBCARTへ鞍替えすることにしました。それとOLIMEXはユーロ決済になってからというもの、激安というほどでもなくなりアマチュア基板外注界ではあまりメジャーな選択ではなくなっているようです。

PCBCARTの実際の使い勝手等は日本語で詳しくまとめていらっしゃる方がたくさんいますので省略しますが納期的にはこんな感じでした。ちなみに遅い方の12日コースです。

  • 9月14日(日)発注、データアップロード
  • 9月15日(月)パッドなしランドの処理方法やら割り付けやらの質問が来る、即日回答
  • 9月16日(火)OrderConfimationステータスになる
  • 9月23日(木)発送したよメールが来る
  • 9月26日(土)基板到着

対応がなかなかすばやく料金も国内の業者と比べると半額以下ですので概ね満足です。仕上がりは云々できるほど目が肥えていないのですがこんな感じで届きました。

一緒に割り付けされているのは次期トランポの自作セキュリティに使おうと設計していた12V->5V DC/DCコンバータ基板です。最初この基板に使うDC/DCを探していたところBurrBrownのDCV01に行きつき、「これって音響用OPアンプの電源が1チップ?」→「Arduinoで音モノ!」→「YM2151でしょ」の3段構成で今に至った訳です。

YM2151入手の旅

基板発注後はYM2151の入手に取りかかりました、もちろんとっくの昔に製造停止となっている石ですので、RSやDigiKeyに発注して終わりという訳には行きません。最初に一番リーズナブルな選択肢として不人気なアーケード基板から取り外すという手段を試してみました。

カプコンのクイズ殿様の野望です、2000円也。許せッ・・・!という訳でバラして半田を吸い取り、外ししてみたのですが・・・

YM2151は成功したもののYM3012は失敗・・、スマン本当にスマン殿様の野望よ。気を取り直してBプランです。アーケード基板は荒い使われ方を想定して基板が厚めでICの足ががっちり曲げてあり難しいということが分かったので、今度はジャンクでケースとボードのみでヤフオクに出ていたX68000Proにしてみました、偶然にも同じく2000円。

写真はバラし途中の物です。古いPCは恐ろしくコストがかかっているのでネジや子基板が多く分解は手間でした。そして今回は危なげなく取り外しに成功です。

実装してみる

上がってきた基板を実装してみたのがこちらです、

実装密度が低いのでスカスカな印象ですね。シールドといいつつかなりはみ出ています。次はこの基板でYM2151を鳴らす所まで書きたいと思います。

Arduino+FM音源で遊ぶ(設計編)

FakeTiltShiftねたは・・・

雨で順延しているうちに仕事の方がマスター直前になってしまい、現在週末全く休めていません!撮影に行けるようなまとまった時間とか無し!というわけで細切れ時間を利用してArduinoで遊んでみました。

Arduino+FM音源

前回のインターバルタイマがあまりにあっけなかったので少し噛みごたえのあるネタというわけで、次はこいつをArduinoに繋げて遊んでみることにしました。

FM音源のYM2151です。80年代末~90年代ごろのアーケードゲームやSHARPのパソコンX1/X68000などかなり広く使われたFM音源で、OPMと呼ばれたりもします。5V駆動でDIPなのでArduinoとの相性も良いですが、基本的にZ80等の8bitバスのCPUで制御することを前提にしているため若干複雑になっています。また独自に4Mhz程度のクロックを入力する必要があり、前回のようにユニバーサル基板のシールドにジュンフロン線で手ハンダでは安定しそうにありません。

はじめての基板外注

なので以前から気になっていたOLIMEXなどの激安基板製作会社に発注をかけてみることにしました。私はPCBE等でいきなりパターンを描いて感光基板で焼く経験しかありませんでしたのでドキドキです。

EAGLEで設計

データシートは英語版がネットに転がっているので問題はありませんが、OLIMEX発注ですとドリルサイズやパターン、シルクに至るまでかなり制限がありますので部品ライブラリから起こす必要があります。今までいきなりパターンを描いていたので、最初は苦行のように感じましたが何とか乗り切りました。回路図はこのように。

20年前のビンテージ物の石とはいえ結構な配線量で手配線とか絶対無理!って感じです。そしてパターン図はこのように。オートルーターがこんなに便利な物だとは知りませんでした。ミスも教えてくれるしもう手描きパターンには戻れませんね。

実はこのシールドを作るきっかけになったのがDACのYM3012の上にあるBurrBrownのDCV01というレギュレターでして、ワンチップしかも外付け部品無しで+5VからDACとバッファアンプに必要な+-12V電源を生成してくれます。これをDigiKeyで見つけて作ってみようと思い立ったわけです。

続きは・・

実はこのシールド完成して動作しています、かなり紆余曲折あったのでぼちぼち経緯を書いていこうかと思います