//==================================================================== #include #pragma hdrstop //debug 2005/03/12 Hal.T #include "sindo.h" //==================================================================== Sindo_Base::Sindo_Base() { fft = 0; Kfil = 0; buf = 0; mbuf = 0; vbuf = 0; abuf = 0; //debug 2005/03/12 Hal.T Init(); } //---------------------------------------------- Sindo_Base::~Sindo_Base() { if(fft ) delete fft; if(Kfil) delete [] Kfil; if(buf ) delete [] buf; if(mbuf) delete [] mbuf; if(vbuf) delete [] vbuf; if(abuf) delete [] abuf; } //---------------------------------------------- //初期化 void Sindo_Base::Init(void) { LN = 11; //FFT bit これを変化させると計算サイズが内部変化する AN = pow(2,LN); //2^LN //1024 dT = 0.01; //毎秒100サンプル interval = 50; //計測震度の計算間隔、サンプル数単位で表現する it = 0; //計測震度の計算勘定 //-------------------- //バッファの初期化 if(buf) delete [] buf; buf = new V3D [AN]; if(vbuf) delete [] vbuf; vbuf = new V3D [AN]; if(abuf) delete [] abuf; abuf = new double [AN]; if(mbuf) delete [] mbuf; mbuf = new V3D [interval]; mbufN = 0; //-------------------- //FFTの初期化 if(fft) delete fft; fft = new FFT(LN); KeisokuSindo = 0.0; KCal = 0; //-------------------- //フィルタの初期化 if(Kfil) delete [] Kfil; Kfil = new double [AN]; double FreqStep = 1.0/(dT*AN); int i; double f, d; Kfil[0] = 0.0; for(i = 1; i0) { //一時バッファへのコピー //コピー可能量 interval - mbufN int mcv = interval - mbufN; int cpN; //コピーする個数 if(n <= mcv) { cpN = n; } else { cpN = mcv; } memcpy(&mbuf[mbufN], gal, cpN*sizeof(V3D)); mbufN += cpN; gal += cpN; //次へ進めておく n -= cpN; if(mbufN == interval) { //計測震度の計算をする //過去データの移動 memmove(&buf[0], &buf[interval], (AN - interval)*sizeof(V3D)); //一時バッファからのコピー memcpy(&buf[AN - interval], mbuf, interval*sizeof(V3D)); mbufN = 0; //一時バッファの数をクリアしておく //計測震度の計算 KST = Calc(); //計測震度の計算 if(KST>KeisokuSindo) KeisokuSindo = KST; KCal = 1; } } return KCal; } //---------------------------------------------- //計測震度を得る、計算そのものは終わっている double Sindo_Base::get_sindo(void) { return KeisokuSindo; } //---------------------------------------------- //計算の実行 double Sindo_Base::Calc(void) { //buffからFFTに送ってフィルタ計算をする //X軸 for(int n=0; nsrc[n].x = buf[n].x; fft->src[n].y = 0.0; } fft->fft_cnv(1); //順FFT //マスクをかける for(int n=0; nsrc[n] *= Kfil[n]; //複素×ダブル } fft->fft_cnv(-1); //逆FFT for(int n=0; nsrc[n].abs(); //複素になっている、絶対値として扱おう } //Y軸 for(int n=0; nsrc[n].x = buf[n].y; fft->src[n].y = 0.0; } fft->fft_cnv(1); //順FFT //マスクをかける for(int n=0; nsrc[n] *= Kfil[n]; //複素×ダブル } fft->fft_cnv(-1); //逆FFT for(int n=0; nsrc[n].abs(); //複素になっている、絶対値として扱おう } //Z軸 for(int n=0; nsrc[n].x = buf[n].z; fft->src[n].y = 0.0; } fft->fft_cnv(1); //順FFT //マスクをかける for(int n=0; nsrc[n] *= Kfil[n]; //複素×ダブル } fft->fft_cnv(-1); //逆FFT for(int n=0; nsrc[n].abs(); //複素だ、絶対値として扱おう } //ベクトル合成と規格化 double kikaku = 1.0/AN; for(int n=0; n=0; n--) { histgram[n]+=histgram[n+1]; if(histgram[n] >= tn300) break; } double kg = n * smax / divh; KeisokuSindo = 2.0 * log10(kg) + 0.94; if(KeisokuSindo < 0.0) KeisokuSindo = 0.0; KeisokuSindo = round(KeisokuSindo, 1); //vecmath.h return KeisokuSindo; } //==================================================================== static char *IniFileName = "NoiseData.csv"; Sindo::Sindo() : Sindo_Base() { d_num = noise_cal = 0; NoiseData = new V3D [AN]; //ポインタの初期化 for(int n=0; n AN) { d_num = 0; noise_cal = 1; } return Sindo_Base::set_gal(gal, n); } //---------------------------------------------- //計算の実行 新しいバージョンに置き換える (Sindo_Base::Calc はvirtual指示) double Sindo::Calc(void) { V2D v2zero; //buffからFFTに送ってフィルタ計算をする //X軸 ============================= for(int n=0; nsrc[n].x = buf[n].x; fft->src[n].y = 0.0; } fft->fft_cnv(1); //順FFT if(noise_cal) { for(int n=1; nsrc[n].abs())*0.1; } } for(int n=1; nsrc[n].abs(); if(NoiseData[n].x < vk) { fft->src[n] *= (vk*vk-NoiseData[n].x*NoiseData[n].x)/(vk*vk); } else fft->src[n] = v2zero; } //マスクをかける for(int n=0; nsrc[n] *= Kfil[n]; //複素×ダブル } fft->fft_cnv(-1); //逆FFT for(int n=0; nsrc[n].abs(); //複素になっている、絶対値として扱おう } //Y軸 ============================= for(int n=0; nsrc[n].x = buf[n].y; fft->src[n].y = 0.0; } fft->fft_cnv(1); //順FFT if(noise_cal) { for(int n=1; nsrc[n].abs())*0.1; } } for(int n=1; nsrc[n].abs(); if(NoiseData[n].y < vk) { fft->src[n] *= (vk*vk-NoiseData[n].y*NoiseData[n].y)/(vk*vk); } else fft->src[n] = v2zero; } //マスクをかける for(int n=0; nsrc[n] *= Kfil[n]; //複素×ダブル } fft->fft_cnv(-1); //逆FFT for(int n=0; nsrc[n].abs(); //複素になっている、絶対値として扱おう } //Z軸 ============================= for(int n=0; nsrc[n].x = buf[n].z; fft->src[n].y = 0.0; } fft->fft_cnv(1); //順FFT if(noise_cal) { for(int n=1; nsrc[n].abs())*0.1; } } for(int n=1; nsrc[n].abs(); if(NoiseData[n].z < vk) { fft->src[n] *= (vk*vk-NoiseData[n].z*NoiseData[n].z)/(vk*vk); } else fft->src[n] = v2zero; } //マスクをかける for(int n=0; nsrc[n] *= Kfil[n]; //複素×ダブル } fft->fft_cnv(-1); //逆FFT for(int n=0; nsrc[n].abs(); //複素だ、絶対値として扱おう } //ベクトル合成と規格化 double kikaku = 1.0/AN; for(int n=0; n=0; n--) { histgram[n]+=histgram[n+1]; if(histgram[n] >= tn300) break; } double kg = n * smax / divh; KeisokuSindo = 2.0 * log10(kg) + 0.94; if(KeisokuSindo < 0.0) KeisokuSindo = 0.0; KeisokuSindo = round(KeisokuSindo, 2); //vecmath.h @ noise_cal = 0; return KeisokuSindo; } //---------------------------------------------- void Sindo::reset_noise(void) { V3D zero; // = all zero for(int n=1; n