[okiadpcm] どうも DMA 使うには intio_dmac.c (sys/arch/x68k/dev/intio_dmac.c) にある関数を使うようだ。 同じ DMA を使っているドライバとして x68k の fd ドライバ (sys/arch/x68k/dev/fd.c) を真似して DMA の設定あたりを 書いてみる。 けど DMA 転送完了の割り込みが1回上がるだけで そっから先に進まない...。
[okiadpcm] eso ドライバや aria ドライバのソースを見ていて、 割り込み処理の方法が分かったので (注:理解したのではない、 両者に共通の処理を発見したというだけ) 真似して書いてみた。 すると割り込みはちゃんと回りはじめた。 が、数秒すると panic した。まあよくあることだ(笑)。
再起動後、自動 fsck がこけてシングルモードになった。 手動で fsck して無事起動。
[okiadpcm] 何回目かの割り込みで変なアドレス触りに行って落ちるらしいのだが、 それだけじゃ何にも分からない。試しにもう一度落してみることにする。 audioplay(1) コマンドを走らせてデバッグメッセージがずらずらーっと 出て例によって panic。やっぱり分からん(笑)。
で、再起動時にけったいなエラーでシングルユーザモードになった。 /sbin/mount がなくなっていた。panic 恐るべし。 mount_ffs で /usr/src になっているディスクをマウントして /usr/src/sbin/mount/mount を /sbin にコピーして事なきを得る。 この他 /usr/bin の cmp, diff, eject, error なんかも ダメージを受けて fsck に削除されていた。
make world した跡残しておいてよかったー。 実は X をコンパイルする領域を確保するために make world の 跡を全部消そうと思ってたんだけど X のコンパイルの 準備に手間取っていて作業できなかったのが幸いした。 誰か NetBSD/x68k 1.5 のリリース形式の tarball 作ってー(マジ)。
その後も面白い現象続出の一日だった。 デバイスファイル /dev/sd2f とかが消えたせいで mount に 失敗したり、ファイルの所有者やグループが 234859187 みたいな 数字になるなんてのは朝飯前、 /dev/stdin のパーミッションが brw-r-S--T になったり(笑)、 /usr/lib/libstdc++.so.1.0 がメジャー番号400番という 存在しないブロックデバイスになってみたり、 そのファイルを消し忘れたまま libstdc++ のソースディレクトリから 上書きインストールしようとして make install ってやったら 存在しないデバイスファイルをオープンすることになって 再び panic したり、fsck を何度かけても clean にならなかったり、 かなりのライブラリが消滅してたので1つのライブラリを 復旧させてマルチユーザモードで起動しても まだ login コマンドが動作できなくて、 リセットボタン押す羽目になるからまた次の起動の fsck でこけたり、 そりゃあもうありとあらゆることが起きた。
結局13時頃に panic して、次に自分のユーザ ID でログインできたのは 18時だったりする。 延べ20回くらいは fsck したような気がする。 おまけにかなりのファイルが消滅した。 まあホームディレクトリなんかは別ディスクになっているので 被害は最小限に抑えることができている。 ディスクはでかけりゃいいってもんじゃないのよ。 1GB のディスクに比べて 120MB のディスクの fsck の速いこと速いこと。 それに今回のケースのように分かれてないといけない事態だってあるのよ。
[Human68k/SLIP] SLIP.SYS 常駐成功。って PPP.SYS まる写しだから当たり前なんだけど(笑)。 ユーザランドからデバイスドライバのバージョンを取得できた。 なんとなく雰囲気は掴めた感じ。
[動機不純(笑)] FreeBSD の ports/converters/mmencode を pkgsrc にする。 簡単な ports だったのですぐに変換できて pkglint も通った。 でも使いかた分からないので動作未確認(笑)。 続いて ports/news/bgrab を pkgsrc にする。 わりとすぐに出来たが、動作せず。
[etc] 会社の先輩からお古の FMV (Pentium/120MHz) を頂いて FreeBSD 4.2-RELEASE を入れた。 自宅が X68000(Human68k) + ppp で大学経由のインターネットに 接続できるようになってから3年、 やっと自宅でまともにウェブが見れるようになった。 ホームページもやっと自宅から満足に書き換えられる。 ああ、長かった。
全然 NetBSD とも NetBSD/x68k とも関係なさそうに見えるけど、 実はこのマシンはそのうち NetBSD/i386 に変わる予定。 おまけに Human68k で作成中の SLIP の対向になる予定。 現在自宅の DNS、Samba、Web のサーバとして稼働中。
[okiadpcm] bus_dma まわりがあまりにも意味不明なので DMAC を直接叩く古典的な手法をとることにする。 それと NetBSD/x68k 1.2 では音が出ていたのかもしれない 旧 okiadpcm ドライバのソースを参考にする。 割と簡単に割り込みが回るところまでは出来たし、 なんと今度は何かしらの音が出た。万歳。 でもいつもと同じ場所で同じように panic した。 毎回 40 回目の割り込みでお亡くなりになるって lowat を割り込んだとかリングバッファの端まできて 戻る処理してなかったって時の症状なんだけどねえ。 でもどこで落ちてるのか分からない...。
[okiadpcm] と思ってたんだけど、今まで1つの .au ファイルでしか 実験したことなかったので、何気なく他の .au ファイルを探してきて 鳴らしてみると panic しなかった。 スピーカ壊れそうなくらいめちゃくちゃな音が出るけど。
ということは割り込みが悪いんじゃなくて、 このファイル(buddy_holly.au :-)) が悪いのね。 やはり、最初からソフトウェアで変換したのを鳴らそうと するのは無理がある。ということでネイティブである ADPCM を鳴らすための実装をする。 といっても query_encoding に case 1つ追加するだけだけどね。 ああ、MD/MI 分離って美しい(笑)。
[fd] で、Human68k のハードディスクにおいてある ADPCM ファイルを もってこなければならない。 しかし、なぜか NetBSD/x68k が fd をマウントしてくれない。 おまけに Human68k は家庭内 LAN から取り残されているので まったくもって陸の孤島ならぬ、室内の孤島。 はてさてどうしたものか。わらをもすがる思いでマウントしてみる。
ハイライトのエラーがずらずら出てきた...。 もう一度、今度は fd0a だ。# mount -t human /dev/fd0c /fd
ハイライトのエラーが1つ出たけどマウントできた。あらら...。 fd0c じゃなかっただけなのね...。おかしいなあ。 以前もめっちゃ試したはずなのに。# mount -t human /dev/fd0a /fd
[okiadpcm] 紆余曲折を経て(?)、無事隣においてある Human68k から ADPCM ファイルを入手してきて、再生してみる。 おおーっ、ちゃんと音が出る!! okiadpcm0 ドライバ完成。
[okiadpcm] ADPCM は再生できて、.au ファイル3つともかろうじて音はでるが なんか変、うち1つに至っては途中で panic する。 どうみても sw_code に書いた関数がおかしい。 Human68k ではちゃんと変換できてたわけだから たぶんとなりのディスプレイ見ながら書き写した時に 間違えたに違いない。そう思って見比べてみた。 案の定、ポインタ初期化するの忘れてる箇所を発見。 あっさり修正できた、かに思えたんだけど、 mulaw は 8bit/sampling、ADPCM は 4bit/sampling なので sw_code で mulaw を ADPCM に変換した後のデータ長は半分になるんだけど、 現在の NetBSD の audio ドライバは sw_code で データ長が縮むことに対応してないみたい。 恐る恐る /sys/dev/audio.c と audio_if.h にも 手を加えて、なんとなく .au ファイルも再生できるように なったけどまだ半分くらいはノイズになる。 まあこの辺はそんなに重要でもないかなあ。 面白さという意味では早く完成度を高めたほうがいい。 とりあえず他のフォーマットを鳴らすことは 後まわしにして ADPCM の録音とかサンプリングレートの 切替えを先にやることにする。
旧 okiadpcm ドライバの中のコードをそっくり頂いてきて サンプリングレートの変換はわりとあっさり実装できた。 でもこのアルゴリズムってかなり手抜きなので、 この ADPCM 用のネイティブファイル以外を再生する時の レート変換には使えない。 要考察。とりあえずのものはこれでいいや。
[i386] i386系マシンで1台めっちゃいいやつを組み立てようと 前々から思っていたが、私の性分からしていつも思っているだけ になるので期限を勝手に4月末に定めてぼちぼち重い腰を上げることにする。
会社帰りに漠然と CPU かマザーボードか何かしらを買おうと ソフマップ広島店に立ち寄る(といっても駅とは反対方向なんだけど)。 PentiumIII/1GHz を買えば、Z80 3.579545MHz、MC68000/10MHz、 Pentium/120MHz と合わせてクロック4桁制覇になるなーと 馬鹿なことを考えるがさすがに 933MHz に比べて値段が一段高い。 が、3月末までなら 1GHz 版に限ってルピーポイントが多いという キャッチコピーに惹かれ思わず衝動買いする。
[etc] 地震(震度5強)にもめげず、自宅の損壊にもめげず、 西に対応していないデバイスがあればドライバを書き、、、(笑)。 買ってきてそのままそこら辺に放置してた PentiumIII の上に 14型テレビが落下する。箱の隅がちょっとへこんだ程度なので 中身は大丈夫だろうと思って確認せずに安全な箇所に避難させる。
[okiadpcm] ADPCM ネイティブで録音処理を書いて いざ録音のテストをしようとして audiorecord(1) の マニュアルを読んでて分かったんだけど、 どうも録音は mulaw とかじゃないとできないらしい。 つーか最初にマニュアル読めよ(笑)。 ということで、ADPCM → mulaw のソフトウェア変換ルーチンが できるまで録音はお預けだね。 それ以前に mulaw → ADPCM の変換(再生側)もうまく動作してないんだけど。 途中まできれいに鳴っているのと、DMAC に渡すバイト数を 半分にすると早送りで再生されることから DMAC の問題ではなくてやっぱり変換ルーチンの問題みたいなんだけど、 やっぱりカーネルの中で処理したのを一旦外部に 吐き出させて検証するしかないのかなあ。
[okiadpcm] 地震のときに自分の家以外の場所にこのソースが流出していないことに 気付いて恐くなったので、早めに公開することにした。 まだまだ不完全なんだけどね。
[etc] そういえば先週末に audiorecord(1) のマニュアル読んでたときに 見つけた typo を今日になって send-pr した。 send-pr した後風呂に入って出てきてメールを読むと もう commit されていた。さすがだ...。