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