Soundがcaptureできれば... WaitOne()は、正しかった
1.トリガーをかけるには?
私は、今まで、オシロスコープの、お世話になりながら、
観測波形が、どうして静止するか? あまり考えたことは、ありませんでした....ええ加減な、やっちゃ (^_^;;
今回は、必要に迫られて、調べてみました。
テクトロの「オシロスコープの全て」と言う、PDFを、webにて発見。
Tektronix社に、御礼申し上げます。
このPDFの、この部分で、ピーンと、きました。
「 デジタル・オシロスコープは、トリガがかかるかどうかにかか
わらず常に入力信号を処理しているので、このようなプリトリガ
観測が可能なわけです。データが常にオシロスコープの中を流れ
ていて、トリガは単にそのデータをメモリに保存するタイミング
を指定しているだけです。 」
トリガーをかける点を、ゼロボルトにすると、都合が、いいです。
ただ、0Vを通る時、負から正へ、又は、正から負への2通りが、ありますので
どちらかを指定しなければ、なりませぬ。
プログラム的には
captureするbufferを、100 ポイントほど、大目にしておいて
仮のbuffer temp2に、いったん、データを取り込み
j番目のデータが負の時で、尚且つ、j+1 番目のデータが正になる j を、記憶して
この、j 番目のデータから、取り込む事にすれば、静止して、見えるでしょう....
100ポイントを過ぎても、この、j 番目が見つからなければ、あきらめて、 最初の位置から取り込みます。
2.サウンドカードの、本当の性能は??
単位インパルスが、全ての周波数を均等に持つ性質を利用して、
impulse.wavなるものを作り、このwavファイルを再生して、
LINE出力に、LINE入力を直結して、調べました。
96KHzサンプリング 16bit
素晴らしい、性能ですね...Prodigy7.1XT 正解!
下の図は、LINE入力では、なくて、プログラムで、単位インパルスを作って、そのspectrumを、調べたものです。
同、96KHZサンプリング 16bit
同じことを、48KHzサンプリング 16bitで、調べてみました。
48KHz サンプリング 16bit
同じ結果が出ます、素晴らしい....
しかしーー、ですね。
LINE入力に、外部発信器(AD9851DDS)を接続し、1、2,3,4,5KHZ 各周波数を、入力するとですねー、 えー
振幅が、合わんのですわ.....
AD9851DDS発信器の出力が、この周波数帯では、一定である事は、
TR4171スペアナ(去年、校正したが、古いので、保証は1ヶ月ほどだった...)で、確認済みです。
もう一台 DDS発信器があるので、これをLINE入力に接続しても、同じ結果でした。
DFTでは、
「信号の長さが信号の周期の整数倍に一致しない場合と、一致する場合では、spectrumの結果が違ってくる」事は
承知しておりますが、
単位インパルス入力では、この差が、どうして、観測されないのでしょうか?
これこそ、「信号の長さが信号の周期の整数倍に一致しない場合」なんだと、思うのです...
2,3dB位の差が、出てきますね、残念。
こうなったら、1Hz毎の、校正表なんかが、必要かも...
測定器って、難しいことを、実感しましたわ (@_@;;
3.DirectXが、落ちるのを防ぐには
データをcaptureする時、私は、このタイミングを、WaitThread()の中に、入れません。
Invalidate();で呼び出される、overrideした OnPaint()に書いています。
理由は、Debug時、troubleに、悩まされたからです。
このプログラムを起動しておいて、別のプログラムを起動したりすると、しょっちゅう、troubleが起こります。
この場合、データをcaptureする、captureBuffer.Read(...)は、mainプログラムとは、別のThread (WaitThread) で、動いています。
ところが、overrideされたOnPaint(..)の中で、captureBuffer.Read(...)すると、troubleが、結構、解消されるのです。
OnPaint(...)は、勿論、WaitTHread()とは、別のThreadに、あります。mainのThreadに、あるのかも....
タスクマネージャー(topmost window)なんかを、起動すると、落ちたりする事があります。
これは、「DirectXのdeviceの消失」の中に、記述が、ありました。
それ以外は、解消されました、よかった、ホッ。
4.NotificationEvent.WaitOne()は、正しかった!
frame per secondの改善の為に、WaitOne()ではなくて、Thread.Sleep()を使いましたが
考えてみると、
これは、正しかったのか?
48KHzサンプリングだと、16384個のデータを収集するのに、
( 1/48000)*16384 = 0.3413 sec
ざっと、340ms掛かるのに、
ThreadSleep(30)を使い、30ms毎に、データを収集したのは、果たして正しかったのか....否
30msは、表示の更新を30ms毎に行うと、言う具合にすべきだったのか....
16384個のデータを、n分割し、この分割毎に、captureデータに、追加して行くべきなのか....
96KHzサンプリングだと、半分の時間で、同数のデータを、収集できるので、98KHzサンプリングに、しようかなー。
それと、引換えに
96KHzサンプリングだと、周波数分解能は、48KHzサンプリングの半分になってしまうし....
48000/16384 = 2.93Hz/point 96000/16384 = 5.86Hz/point
まあ、使い方に拠る、ちゅうことですよね....
H18.9.9