いくつかの新しいサンプルが入ってくるたびに信号全体(または少なくとも巨大なビット)をフィルタリングする必要があるか、またはフィルタリングされた新しい部分を効率的に決定できる方法(スライディングDFTなど)があるか信号?
デジタルフィルターはそのようには機能しません。基本的に、従来のFIRまたはIIRはすべての新しいサンプルで機能します。これらのフィルターとは何か、そして人々がそれらをどのようにモデル化するかを実際に読んでください。
バターワースフィルターを使用したい
まあ、そこにはたくさんの実装があります。
私は現在scipyのバターとlfilterを使用しています
あなたはすでにそれを知っています!
さて、バターワースフィルターは再帰的なものであるため、サンプリングされた信号の次の部分を計算するには、最後の状態が必要になります。これは、「フィルター遅延状態zi」でlfilter
あり、zi
パラメーターとして次の呼び出しで戻ります。
しかし、それを使用して一定の信号を取得する方法がわかりません。
「継続的なフィルタリングを実現する」という意味だと思います。
さて、言われているように、重要なのは、独自のストリーミングアーキテクチャを作成するための準備をしているということです。私はそれをしません。既存のフレームワークを使用します。たとえば、Pythonで信号処理フローグラフを定義できるGNUラジオがあり、本質的にマルチスレッド化され、高度に最適化されたアルゴリズム実装を使用し、多くの入出力機能を備え、信号処理ブロックの巨大なライブラリが付属しています必要に応じて、PythonまたはC ++で記述できます。
たとえば、サウンドカードからサンプルを取り込み、バターワースフィルター処理してファイルに書き込むフローグラフは次のとおりです。
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
##################################################
# GNU Radio Python Flow Graph
# Title: Butterworth Test
# Generated: Mon Feb 8 16:17:18 2016
##################################################
from gnuradio import audio
from gnuradio import blocks
from gnuradio import eng_notation
from gnuradio import filter
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
class butterworth_test(gr.top_block):
def __init__(self):
gr.top_block.__init__(self, "Butterworth Test")
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = 48000
##################################################
# Blocks
##################################################
# taps from scipy.butter!
self.iir_filter_xxx_0 = filter.iir_filter_ffd(([1.0952627450621233e-05, 0.00013143152940745496, 0.0007228734117410033, 0.0024095780391366808, 0.005421550588057537, 0.008674480940892064, 0.010120227764374086, 0.008674480940892081, 0.005421550588057554, 0.0024095780391366955, 0.0007228734117410089, 0.00013143152940745594, 1.0952627450621367e-05]), ([1.0, -4.4363862740719835, 10.215121830052535, -15.374408118154847, 16.57333784740102, -13.325056987818655, 8.133543488903097, -3.77641064765334, 1.3181452681671835, -0.3361758629961047, 0.05930166356243964, -0.0064815521348275, 0.00033130678123743994]), False)
self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_float*1, "", False)
self.blocks_file_sink_0.set_unbuffered(False)
self.audio_source_0 = audio.source(samp_rate, "", True)
##################################################
# Connections
##################################################
self.connect((self.audio_source_0, 0), (self.iir_filter_xxx_0, 0))
self.connect((self.iir_filter_xxx_0, 0), (self.blocks_file_sink_0, 0))
def main(top_block_cls=butterworth_test, options=None):
tb = top_block_cls()
tb.start()
try:
raw_input('Press Enter to quit: ')
except EOFError:
pass
tb.stop()
tb.wait()
if __name__ == '__main__':
main()
このコードは、gnuradio-companion
プログラムを使用して一緒にクリックしたグラフィカルフローグラフから自動生成されたことに注意してください。
Pythonで信号処理フローグラフを実装する方法について詳しく知りたい場合は、GNU Radio Guided Tutorialsにアクセスし てください。
編集:私は@ Fat32の答えがかなり好きでした!彼がダブルバッファリングアーキテクチャとして説明していることは、GNU Radioが行うこととかなり似ています。
上流ブロックは、任意のサイズのサンプルチャンクでサンプルを生成し、それらを出力リングバッファー(上の図では矢印で表されています)に書き込み、新しいデータがあることを下流ブロックに通知します。
ダウンストリームブロックは通知を受け、入力リングバッファー(アップストリームブロックの出力バッファーと同じ)にあるサンプルを処理するのに十分なスペースが出力バッファーにあるかどうかを確認し、これらを処理します。完了すると、入力リングバッファーを使い果たしたことをアップストリームブロックに通知し(アップストリームブロックは出力として再利用できます)、ダウンストリームブロックは新しいサンプルが利用可能であることを通知します。
現在、GNU Radioはマルチスレッド化されており、上流のブロックはすでにサンプルを再び生成している可能性があります。通常のGNUラジオアプリケーションでは、ほぼすべてのブロックが同時に「アクティブ」になり、マルチCPUマシン上でかなり拡張できます。
したがって、GNU Radioの主な仕事は、このバッファインフラストラクチャ、通知とスレッドのハウスキーピング、明確な信号処理ブロックAPI、およびすべての接続方法を定義するものを提供することです。そのため、Fat32で記述されている内容を自分で書く必要はありません。自分を投稿してください!サンプルストリームのマーシャリングを行うのは適切に行うのは簡単ではないことに注意してください。GNURadioはその硬度を取り除き、やりたいことに集中できます:DSP。