トップ «前の日記(2010/06/02(Wed)) 最新 次の日記(2010/06/04(Fri))»
【ソース+水=麦茶色の何か】

半期 四半期 全カテゴリ

今日の一言


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」を参考にすればいいと思われ。