「FIRディジタルフィルタの作成」でPython言語によるFIRディジタルフィルタの作成を作成しました。今回は、C#言語を使って、FIRディジタルフィルタを作成します。入力・出力ともwavファイルとします。
開発/実行環境
- Visual Studio2013 Express (C#)
- Windows 7 Professional
FIRディジタルフィルタソフトの作成
C#言語を使ってFIRディジタルフィルタスクリプトを作成します。「wavファイルの作成とwavファイル情報の表示」で作成したwavファイルを入力します。ただし、記録時間は30秒から3秒にしました。
- 32行目のSystem.IO.StreamReaderメソッドでフィルタ係数ファイル「constant」を読み込み、38行目でフィルタ係数を保存します。
- 48行目でFile.ReadAllBytesメソッドを使ってwavファイルをバイナリで読み込みます。
- 49行目のfor文で、「0x2c」バイト分オフセットをかけて、wavファイルのヘッダ部分をスキップします。wavファイルのヘッダ部分の構成については「C#によるWaveファイルの解析」を参照してください。
- FIRディジタルフィルタの処理にはQueue クラスを使用します。タップ数分キューに挿入しておき、64行目でそれぞれの入力データに対してフィルタ係数を乗算していきます。
- 67行目は、キューに挿入されているデータがタップ数に満たない場合の判断を行っています。
- 58行目の「32768.0」や73行目の「10000.0」は正規化もどきの為に使用しています。処理結果を見ながら増減させてください。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace FirFilter { class Program { static void Main(string[] args) { string line; string coeffFile = "constant"; string wavFile = "100-500-1000-8000hz.wav"; string wavFileOut = "100-500-1000-8000hzOut.wav"; const int taps = 10; double[] coefficients = new double[taps]; Queue<double> buffer = new Queue<double>(); int i = 0; double output = 0; double input = 0; byte[] data; byte[] sounddata = new byte[4]; int posoffset = 0x2c; StreamReader file = new System.IO.StreamReader(coeffFile); for (i = 0; i < taps; i++) { if ((line = file.ReadLine()) != null) { coefficients[i] = double.Parse(line); } else { Console.WriteLine("Could not read the coefficients from {0}", coeffFile); } } file.Close(); data = File.ReadAllBytes(wavFile); for (i = posoffset; i < data.Length; i += 2) { if (buffer.Count == taps) { buffer.Dequeue(); } input = (short)((data[i + 1] << 8) + data[i + 0]); buffer.Enqueue(input/32768.0); int k = buffer.Count - 1; // i = 0; output = 0; foreach (double value in buffer) { output += coefficients[k] * value; // Console.WriteLine("coefficients:{0} value:{1} ", coefficients[k], value); k--; if (k < 0) { break; } } // Console.WriteLine("****pixcel: {0} {1} /{2} ",i, input, output); output *= 10000.0; sounddata = BitConverter.GetBytes((int)output); data[i + 0] = sounddata[0]; data[i + 1] = sounddata[1]; } File.WriteAllBytes(wavFileOut, data); } } }
System.IO.StreamReaderメソッドで読み込まれるファイル「constant」の内容を次に示します。この係数により高周波成分が減衰し、波形も滑らかになります。
0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1
FIRディジタルフィルタソフトの実行
入力したwavファイル「100-500-1000-8000hz.wav」を次に示します。
FIRディジタルフィルタ後のwavファイル「100-500-1000-8000hzOut.wav」を次に示します。高周波成分が減衰したため高い音が小さくなり、低音が拡大されています。
audacityアプリを用いて、今回のC#言語によるFIRディジタルフィルタ後の波形「100-500-1000-8000hzOut.wav」(上側)と前回のPython言語によるFIRディジタルフィルタ後の波形「fir.wav」(下側)を比較します。
audacityアプリでFIRディジタルフィルタ後の波形をFFT処理すると、100、500、1000、8000hzのそれぞれが変わっていないことが確認できました。