今日の一言
2010/06/03(Thu) グフォ [長年日記] 0:00現在曇 20℃
_ [Linux][C++]DF-Designを活用したローパスフィルタプログラム
DF-Designは、こちら(http://momiji.i.ishikawa-nct.ac.jp/dfdesign/)で公開されているFIRおよびIIRディジタルフィルタの設計/解析プログラム集。
以前に作ったプログラムが出てきたので、上げておく。
/***************************************** 実行: ./a.out data.csv filter_coefficient.csv (引数: データファイル フィルタ係数ファイル) ******************************************/ #include <iostream> #include <fstream> // ファイルストリームのヘッダ #include <vector> #include <stdlib.h> #include <cmath> using namespace std; /* 引数が足りているかを確認 */ bool operand_check(int argc) { if(argc != 3) { printf("missing file operand\n operand = data,filter\n"); return false; } return true; } /* データファイルの読み込み */ bool load_signal_data(const string &filename, vector<double> &org_data) { string tmp_c; ifstream fs (filename.c_str()); if (!fs) { cerr << "file not found: " << filename << endl; return false; } while(!fs.eof()) { getline(fs, tmp_c, '\n'); if(tmp_c[0]!='#' && tmp_c.size()!=0) { org_data.push_back(atof(tmp_c.c_str()));; } } fs.close(); return true; } /* フィルタ係数ファイルの読み込み */ bool load_filter_data(const string &filename, vector< double > &fk, vector< vector<double> > &fa, vector< vector<double> > &fb, vector<int> &anum, vector<int> &bnum) { string tmp_c; vector<double> a_tmp; //フィルタの各階ごとの係数aを一次配列に保存 vector<double> b_tmp; //フィルタの各階ごとの係数bを一次配列に保存 int index; int amax(0),bmax(0); //フィルタの各階ごとのΣの回数Nを保存 ifstream fs (filename.c_str()); if(!fs) { cerr << "file not found: " << filename << endl; return false; } getline(fs, tmp_c, '='); index=tmp_c.find_first_of('\n'); if(index!=-1) { tmp_c.erase(0,index+1); //改行を詰める } while(!fs.eof()) { if(tmp_c[0]=='S') { getline(fs, tmp_c, '\n'); while(!fs.eof()) { getline(fs, tmp_c, '='); index=tmp_c.find_first_of('\n'); if(index!=-1) { tmp_c.erase(0,index+1); //改行を詰める } if(tmp_c[0]=='S'){ break; }else if(tmp_c[0]=='k') { getline(fs, tmp_c, '\n'); fk.push_back( atof(tmp_c.c_str()) ); }else if(tmp_c[0]=='a') { getline(fs, tmp_c, '\n'); a_tmp.push_back( atof(tmp_c.c_str()) ); amax++; }else if(tmp_c[0]=='b') { getline(fs, tmp_c, '\n'); b_tmp.push_back( atof(tmp_c.c_str()) ); bmax++; } else { getline(fs, tmp_c, '\n'); //先頭文字がどれでもない場合、何もせず次の行へ } } } fa.push_back(a_tmp); fb.push_back(b_tmp); anum.push_back(amax); bnum.push_back(bmax); a_tmp.clear(); b_tmp.clear(); amax=0; bmax=0; } fs.close(); return true; } /* フィルタの適用 */ bool to_filter( const vector<double> &org_data, vector<double> &fix_data, const vector< double > &fk, const vector< vector<double> > &fa, const vector< vector<double> > &fb, const vector<int> &anum,const vector<int> &bnum) { double a_sigma(0.0); //aにかかる部分の和 double b_sigma(0.0); //bにかかる部分の和 int num(0); //データ番号 int aloop(0); //aにかかるΣのループのカウント int bloop(0); //aにかかるΣのループのカウント int sec(0); //フィルタの階数のカウント vector< double > mid; //中間値 for(num=0;num<org_data.size();num++) { fix_data.push_back(org_data[num]); mid.push_back(0.0); if(num >= anum[0]) { for(sec=0; sec<fa.size(); sec++) { for(bloop=1;bloop<bnum[sec];bloop++) { b_sigma = b_sigma+ fb[sec][bloop] * mid[num-bloop]; } mid[num] = fk[sec]*fix_data[num]-b_sigma; for(aloop=0;aloop<anum[sec];aloop++) { a_sigma = a_sigma + fa[sec][aloop] * mid[num-aloop]; } fix_data[num] = a_sigma; a_sigma=0.0; b_sigma=0.0; } } } return true; } /* メイン関数 */ int main(int argc, char**argv) { if( operand_check(argc) == false )return 0; //引数があっていなければ終了 vector< double > org_data; //フィルタ適用前のデータ vector<int> anum; //aに対するΣの数 vector<int> bnum; //bに対するΣの数 vector< double > fk; //フィルタ係数k vector< vector<double> > fa; //フィルタ係数a vector< vector<double> > fb; //フィルタ係数b vector< double > fix_data; //フィルタ適用後のデータ /* データの読み込み */ if( load_signal_data(argv[1], org_data) == false )return 0; //ファイルが読めなかったら終了 /* フィルタの読み込み */ if( load_filter_data(argv[2], fk, fa, fb, anum, bnum) == false )return 0; //ファイルが読めなかったら終了 /* フィルタの適用 */ to_filter( org_data, fix_data, fk, fa, fb, anum, bnum); /* データの書き出し */ ofstream fsw ("akihiro-i_signal.csv"); //決め打ち for(int datanum=0; datanum<org_data.size();datanum++) { fsw << fix_data[datanum] << endl; } fsw.close(); return 0; }
読み込むデータファイル(data.csv)はこんな感じ。
0 0.1 0.5 0.1 -0.4 -0.1 ・・・
フィルタの設定ファイル(filter_coefficient.csv)はこんな感じ。
Sec =1 k =5.35179369357953406e-06 b0 =0 b1 =-1.98687072069134119e+00 b2 =9.86956349390438525e-01 a0 =1.85630617396982241e+05 a1 =-3.71261234793964482e+05 a2 =1.85630617396982241e+05 Sec =2 ・・・
おそらく大きな間違いはないはず。
まあ、DF-Designがなくなったらどうしようもないけどな!
(コマンドライン版は一般公開されていない?)
_ [OpenCV][Linux][Ubuntu][Debian][FC][研究関係][雑記] OpenCV + IEEE1394カメラ + ffmpeg インストールまとめ( + mplayer)後日談
ここ(http://robotics.naist.jp/~akihiro-i/dialy/?date=20100520#p01)で、ffmpegは手動で入れろとか、コーデックが競合するからaptは使うなとか書いたが、一つ邪道な方法を思いついた。
1. apt-getでffmpegを入れる
→動画プレイヤーでコーデックが読み込めるようにセッティングされる。
2. OpenCVで録画する際にエラーが出るようになる
→aptでインストールされたライブラリを、ffmpegのソースからコンパイルしたものに置き換える。
うまくやれば両方動く。
ただ、前以上に危険なことをしているので、問題がないなら、前のやり方の方がおすすめ。
_ [OpenAL][Linux][Ubuntu][Debian][FC][Windows][研究関係][雑記] OpenALで録音する(途中)
このあたりをみれば分かりそう?
http://www.blitzbasic.com/Community/posts.php?topic=72909
http://ja.pastebin.ca/1646632
http://old.nabble.com/how-to-capture-data-%2B-possible-bug-in-documentation-td7931474.html
*録音まではたどり着けそうだが、録音したデータをどうやって扱えばいいかがよく分からなかったので、ここで断念。
時間が出来たらリベンジする。
_ [OpenAL][Linux][Ubuntu][Debian][FC][Windows][研究関係][雑記] テキストデータからwavファイルを作る(txt2wav.c) & wavファイルの中身をテキストデータで吐き出す(dumpwave.c)
テキストデータからwavファイルを作る
こちら(http://www.kk.iij4u.or.jp/~kondo/wave/index.html)のページでWAV ファイルのフォーマットの詳細が紹介されているので、それを参考にさせてもらって、ファイルIOを行うプログラムを作る。
また、ASCII テキストデータを WAVE 形式に変換する「txt2wav.c」というプログラムも公開されているので、それをみればより実践的な使い方が分かると思う。
特別なライブラリ等は使われてないので、そのまま
$ gcc txt2wav.c
とすればコンパイルできる。
*出来上がった実行ファイルを引数無しで実行すれば、プログラムの使い方を表示してくれる。
wavファイルの中身をテキストデータで吐き出す
こちら(http://oku.edu.mie-u.ac.jp/~okumura/wavefmt.html)の「dumpwave.c」を参考にすればいいと思われ。