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