循環リスト

ETCをやっと取り付けてきた。(取り付けたのは、ディーラーの人だけど)例の3月 中に付けると安くしますよに踊らされて、車屋さんまで駆け込んだけど、時既に遅し。 勢いで、その場で申し込んだけど、待てど暮らせど入荷せずで、今日までお預けを 食らっていたのだ。これで、森田知事陳情のアクアラインも気兼ねなく渡れそう。

ETCって、無線機だよなあ。そうすると中身は、ワンチップのICになってるのかな? そのIC製作が難しくて、不作になってしまい、思うように作れなかったのかな? ICにどんなマークが付いているか、見てみたいものだ。

Haskellの問題別解

Haskellのお題に対する、別解が 投稿されてた。

f(' ':xs) = " "  ++ (f xs)
f s = s

再帰します版だ。Lisp脳に共鳴しましたよ。

DSPによるフィルター

ディジタルフィルターには、2種類あるそうだ。IIR型とFIR型。そのうちの、IIR型は、 出力をフィードバックさせるので、旨く設計しないと、発散(発振)してしまうらしい。 FIR型にはその心配は無いけど、IIR型と同じ性能を出そうとすると、規模が大きく なってしまうとか。

FIR型は信号をdelayさせながら、フィルターの係数と積和演算を行う事で、実現される。 統計処理で、変化の激しいデータを、移動平均で滑らかにするのと原理は一緒だ。 (この場合は、変化の激しい部分が除去されるので、ローパスフィルターとなる) Cで書いた例が出ていた。

const int TAP 5;
contt float hm[TAP] = { 0.50211, 0.00778, -0.005602, 0.003984, -0.018306 };

int main(){

	float xn[TAP + 1];
	float in, out;

	for (int k=0; k <= TAP; k++)       // clear buffer
		xn[k] = 0.0;

	while(true) {
		cordec.Read( in );             // A/D
		xn[0] = in;
		out = 0.0;

		for (int k=0; k<=TAP; k++)
			out += hm[k] * xn[k];
		for (int K=TAP; k>0; k--)     // delete most old data
			xn[k] = xn[k-1]

		codec.Write( out )            // D/A
	}
}

係数が入る配列 hm と、信号が入る配列 xn との、積和演算を行い、結果が求まったら、 xnの内容をシフト(delay)させている。積和を高速で求める必要があるのは言う までもないけど、配列のシフトを効率よく行える事が、DSPの必須要件となっている。

結論を書いてしまうと、リングバッファーを支援するハードウェア機能がDSPには備わって いるのだ。

循環リストでリングバッファー

同じ事をSchemeでも書けるけど、どうせ書くならDSPにも対抗してみたいぞ。って訳で、 今まで、こんなもん利用価値があるんかいなと思っていた、 Schemeの循環リストに 行き着いた。

循環リストって読んで字のごとく、どこまで行っても切れ目が無い、メビウスの輪 みたいなものだ。循環リストをそのまま表示しようとすると、終わりが無いので、 いつまでも表示し続けてしまい、大変な事になる。(gaucheには、対策が施されて いるので、そんな事にはならないけど)

この循環リストを使えば、天然でリングバッファーになる。使い方は、こんな風に なるかな。

(use srfi-1)

(define hm '(0.50211 0.00778 -0.005602 0.003984 -0.018306))
(define xn (circular-list 0 0 0 0 0))

(define (cordec-write v)
  (format #t "Output: ~s\n" v))

(define (cordec-read)
  (display "Input: ")
  (flush)
  (read))

(define (fir)
  (let loop ([in  0.0])
    (set-car! xn in)
    (cordec-write (fold + 0.0 (map * xn hm)))
    (set! xn (cdr xn))
    (loop (cordec-read))))

A/D も D/A も、無いので、手動で我慢しました。(笑)

Windows に積んでいる codec は?

ちょいと悔しいので、WindowsXPマシンの codecを調べてみる。コンパネを開いて、 ドライバーを調べてみると、soundMAX integrated Digital Audio となっていて 製造元は Analog Devices なんて書いてある。

この情報を元に、ネットを探してみると、チップ名が AD1986Aなんてのが引っかかってきた。 果たして、このチップを搭載してるのだろうか? ばらして見ちゃうのが一番確実 だけど、組み立てた時に必ず、部品が余っちゃうんだよなぁ(苦笑)

ここは、もう少しスマートに、チップを調べる方法を考えてみる。で、思いついた のは、 FreeBSDを立ち上げて、dmesgを見るという方法。 最近のFreeBSDは、LiveCDのISOも提供されてるので、もしもの時用に1枚作って おくかな。

NotePCの中身を調べる

CD焼いて、そいつで起動。普通の FreeBSDのインストール画面が出てきたので、そこから Fix it を選び、CDを指定する。CUI画面が出てくるので、後は普通に操作すればいい。

例の方法で、サウンドドライバーをどばっと指定するも、一向に /dev/sndstatに 情報が現れない。dmesgの尻尾の方を確認してみたら、依存性があるので真面目に やれ(超意訳)もどきのメッセージが残っていたので、指示通りにロードして行ったら 無事に動いた。

codecの石は、Analog Devices AD1981B を使っていて、こいつをドライブしてるのが、Intel IO COntroller Hub 4(大容量PDFにつき注意) という事が判明。だからどうしたと言われると困るけど、ちょっぴり透視した 気分になれて、楽しいじゃん。