質問

バイト配列として (vb に) 保存されているサンプルの周波数を見つける必要があります。サンプルは正弦波で周波数は既知なので確認できますが、数値が少し奇妙で、私の数学力は弱いです。値の全範囲は 0 ~ 255 です。数値の 99% は 235 ~ 245 の範囲内にありますが、残りの 1% には 0 と 1、および最大 255 までの外れ値がいくつかあります。これを正規化して外れ値を除去するにはどうすればよいでしょうか (サンプルが異なると変化する可能性があるため、235 ~ 245 の間隔を計算します)。また、ゼロクロッシングを計算して周波数を取得するにはどうすればよいですか?この説明がゴミだったらごめんなさい!

役に立ちましたか?

解決

おそらく FFT が最良の答えですが、本当に自分の方法で実行したい場合は、これを試してください。

正規化するには、まずヒストグラムを作成して、0 から 255 までの各値の出現回数を数えます。次に、次のようにして、両端の値の X パーセントを捨てます。

for (i=lower=0;i< N*(X/100); lower++)
  i+=count[lower];
//repeat in other direction for upper

ここで正規化します

A[i] = 255*(A[i]-lower)/(upper-lower)-128

-128..127 の範囲外の結果は破棄してください。

これで、ゼロクロスをカウントできるようになりました。ノイズに騙されないように、最後の数ポイントの勾配を追跡し、平均勾配が正しい方向に進んでいる場合にのみ交差点をカウントするとよいでしょう。

他のヒント

この問題に対処する標準的な方法は、1 つのデータ ブロックを考慮し、できれば実際の頻度の少なくとも 2 倍 (より多くのデータを取得することは悪いことではないため、少し過大評価するのが良いでしょう) を考慮してから、 FFT そして、その周波数が結果として得られる FFT スペクトルの最大の数値に対応すると推測します。

ちなみに、非常によく似た問題が以前にここで質問されています。それらの答えを検索することもできます。

フーリエ変換を使用します。ゼロクロッシングを数えるよりもはるかにノイズに影響されません。

編集:@aaaaaaaaaaaaaaaaa

FFT を実行するための F# ライブラリを見つけました。 ここから

結局のところ、これまでF#ユーザーに私が見つけた最高の無料実装は、まだ素晴らしいFFTWライブラリです。彼らのサイトには、事前にコンパイルされたWindows DLLがあります。Guruと単純なインターフェイスの両方を使用して、F#からFFTWへのスレッドセーフアクセスを可能にする最小限のバインディングを書きました。パフォーマンスは優れており、32ビットWindows XP Proは64ビットLinuxよりも最大35%遅いです。

これで、VB.net、C# などから F# lib を呼び出すことができると確信しています。これはドキュメントに記載されているはずです。

あなたの説明からよく理解できたなら、あなたが持っているのは、サイン、定数、およびいくつかのランダムなグリッチの組み合わせである信号です。言って、好き

x[n] = A*sin(f*n + phi) + B + N[n]

ここで、N[n] は除去したい「グリッチ」ノイズです。

グリッチが 1 サンプルの長さである場合は、グリッチの長さよりも大きくなければならないメディアン フィルターを使用してグリッチを除去できます。グリッチの両側にあります。長さ 1 のグリッチは、長さの中央値 3 サンプルで十分であることを意味します。

y[n] = median3(x[n])

中央値は次のように計算されます。フィルタリングしたい x のサンプル (x[n-1],x[n],x[n+1]) を取得して並べ替えると、出力は中央のものになります。

ノイズ信号がなくなったので、一定の信号を取り除きます。バッファーの長さは限られており、既知であるため、バッファー全体の平均を計算するだけでよいことは理解しています。それを差し引きます。

これで、単一の洞信号が得られました。ゼロクロスをカウントすることで基本周波数を計算できるようになりました。前のサンプルが 0 未満であった、0 を超えるサンプルの量を数えます。周期はバッファのサンプルの総量をこれで割ったもので、周波数は周期の逆 (1/x) です。

私は大多数の意見に同意し、必要なのは fft ソリューションであるようです (fft アルゴリズムは非常に高速です) と言いますが、何らかの理由で fft が答えではない場合は、次を使用してデータに正弦曲線を当てはめてみることをお勧めします。フィッティングプログラムと、フィッティングされた周波数の読み取り。

使用する フィティク, 、データをロードして、 a*sin(b*x-c) どこ 2*pi/b フィッティング後の周波数をお知らせします。

Fityk は、GUI やスクリプト作成用のコマンドラインから使用でき、C++ API を備えているため、プログラムに直接組み込むことができます。

「ベーシックFFT」でググってみました。 ビジュアルベーシックFFT あなたの質問は FFT を叫んでいますが、DSP について少しでも理解せずに FFT を使用すると、理解できない、またはどこから来たのかわからない結果が生じる可能性があることに注意してください。

周波数アナライザーを入手するには http://www.relisoft.com/Freeware/index.htm それを実行してコードを見てください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top