iIR數字濾波器設計在工程實踐中具有十分重要的作用,使用C語言實作對深化理解濾波器設計的理論和功能具有深遠的意義,凡是選擇本專案并能達到專案基本要求可以獲得90分以上的成績,
要求:報告中必須有能夠實作以下設計指標的數字低通濾波器的證明:通帶和阻帶截止頻率分別為0.2π和0.35π,通帶最大衰減為1dB,阻帶最小衰減為10dB,
提示:理論知識參考《數字信號處理》教材,
這是c語言課程設計,寫一個文章來記錄一下,方便以后查漏補缺,
基礎知識
低通濾波器的主要性能指標有以下幾個:通帶截止頻率fp、阻帶截止頻率fs、通帶衰減 ( Ap)、阻帶衰減 ( As) 以及歸一化頻率時需要用到的-3dB的轉折頻率fc,
根據給定的引數設計模擬濾波器,然后進行變數變換,求取數字濾波器的方法,稱為濾波器的間接設計,做為數字濾波器的設計基礎的模擬濾波器,稱之為原型濾波器,


模擬濾波器的設計
巴特沃斯濾波器因其在通帶內的幅值特性具有最大平坦的特性而聞名,是四種經典濾波器中最簡單的,巴特沃斯濾波器只需要兩個引數表征,濾波器的階數N和-3dB處的截止頻率
,其幅度平方函式為:


N是濾波器的階數,從幅度平方函式可以看出,N階濾波器有2N個極點,而且這2N個極點均布在一個圓上,圓的半徑為,稱之為巴特沃斯圓,巴特沃斯濾波器系統是一個線性系統,要使其穩定,其極點必須位于S平面的左半平面,所以取左半平面內的N個極點作為濾波器的極點,濾波器就是穩定的了,求出極點之后,計算模擬濾波器的系數as、bs,然后通過雙線性變換(不懂得自行查書)由模擬域到數字域,求出系數az和bz ,最后通過差分方程就可以計算濾波結果了,

次數N的計算為

巴特沃斯低通濾波器的傳遞函式,可由其振幅特性的分母多項式求得,其分母多項式

根據S解開,可以得到極點,這里,為了方便處理,我們分為兩種情況去解這個方程,當N為偶數的時候,

這里,使用了歐拉公式
,同樣的,當N為奇數的時候,

同樣的,這里也使用了歐拉公式,歸納以上,極點的解為

上式所求得的極點,是在s平面內,在半徑為Ωc的圓上等間距的點,其數量為2N個,為了使得其IIR濾波器穩定,那么,只能選取極點在S平面左半平面的點,選定了穩定的極點之后,其模擬濾波器的傳遞函式就可由下式求得,

變換為Z域

然后通過差分方程就可以計算濾波結果了

C語言的實作
1.求階數

代碼:
N = ceil(0.5*( log10 (( pow (10, Stopband_attenuation/10) - 1)/
( pow (10, Passband_attenuation/10) - 1)) / log10 (Stopband/Passband) ));
2.求極點

for(k = 0;k <= ((2*N)-1) ; k++)
{
if(Cutoff*cos((2*k+N-1)*(pi/(2*N))) < 0.0)
{
poles[count].x = -Cutoff*cos((2*k+N-1)*(pi/(2*N)));
poles[count].y = -Cutoff*sin((2*k+N-1)*(pi/(2*N)));
count++;
if (count == N) break;
}
}
這里面 poles 是復數型別_complex
_Complex是C99新增的關鍵字,表示一種基本資料型別——復數
該型別的出現主要是為了解決工程和數學計算上很多涉及到復數計算的情況
3.求模擬濾波器系數
計算出穩定的極點之后,就可以進行傳遞函式的計算了,傳遞的函式的計算,就像下式一樣

這里,為了得到模擬濾波器的系數,需要將分母乘開,很顯然,這里的極點不一定是整數,或者來說,這里的乘開需要做復數運算,其復數的乘法代碼如下,
//復數乘
_complex ComplexMul(_complex a, _complex b)
{
_complex c;
c.x = a.x*b.x - a.y*b.y;
c.y = a.y*b.x + a.x*b.y;
return c;
}
有了乘法代碼之后,我們現在簡單的情況下,看看其如何計算其濾波器系數,我們做如下假設`

這個時候,其傳遞函式為

將其乘開,其大致的關系就像下圖所示一樣,

計算的關系一目了然,這樣的話,實作就簡單多了,高階的情況下也一樣,重復這種計算就可以了,其代碼為
Res[0].x = poles[0].x;
Res[0].y = poles[0].y;
Res[1].x = 1;
Res[1].y= 0;
for(count_1 = 0;count_1 < N-1;count_1++)//N個極點相乘次數
{
for(count = 0;count <= count_1 + 2;count++)
{
if(0 == count)
{
Res_Save[count] = ComplexMul( Res[count], poles[count_1+1] );
}
else if((count_1 + 2) == count)
{
Res_Save[count].x += Res[count - 1].x;
Res_Save[count].y += Res[count - 1].y;
}
else
{
Res_Save[count] = ComplexMul( Res[count], poles[count_1+1] );
Res_Save[count].x += Res[count - 1].x;
Res_Save[count].y += Res[count - 1].y;
}
}
for(count = 0;count <= N;count++)//Res[i]=a(i),i越大次數越高
{
Res[count].x = Res_Save[count].x;
Res[count].y = Res_Save[count].y;
*(a + N - count) = Res[count].x;
}
}
*(b+N) = *(a+N);
到此,我們就可以得到一個模擬濾波器巴特沃斯低通濾波器了,
4.S變Z
公式


代碼
int Count = 0,Count_1 = 0,Count_2 = 0,Count_Z = 0;
double *Res, *Res_Save;
Res = new double[N+1]();
Res_Save = new double[N+1]();
memset(Res, 0, sizeof(double)*(N+1));
memset(Res_Save, 0, sizeof(double)*(N+1));
for(Count_Z = 0;Count_Z <= N;Count_Z++)
{
*(az+Count_Z) = 0;
*(bz+Count_Z) = 0;
}
for(Count = 0;Count<=N;Count++)
{
for(Count_Z = 0;Count_Z <= N;Count_Z++)
{
Res[Count_Z] = 0;
Res_Save[Count_Z] = 0;
}
Res_Save [0] = 1;
for(Count_1 = 0; Count_1 < N-Count;Count_1++)//計算(1-Z^-1)^N-Count的系數,
{ //Res_Save[]=Z^-1多項式的系數,從常數項開始
for(Count_2 = 0; Count_2 <= Count_1+1;Count_2++)
{
if(Count_2 == 0)
{
Res[Count_2] += Res_Save[Count_2];
}
else if((Count_2 == (Count_1+1))&&(Count_1 != 0))
{
Res[Count_2] += -Res_Save[Count_2 - 1];
}
else
{
Res[Count_2] += Res_Save[Count_2] - Res_Save[Count_2 - 1];
}
}
for(Count_Z = 0;Count_Z<= N;Count_Z++)
{
Res_Save[Count_Z] = Res[Count_Z] ;
Res[Count_Z] = 0;
}
}
for(Count_1 = (N-Count); Count_1 < N;Count_1++)//計算(1-Z^-1)^N-Count*(1+Z^-1)^Count的系數,
{ //Res_Save[]=Z^-1多項式的系數,從常數項開始
for(Count_2 = 0; Count_2 <= Count_1+1;Count_2++)
{
if(Count_2 == 0)
{
Res[Count_2] += Res_Save[Count_2];
}
else if((Count_2 == (Count_1+1))&&(Count_1 != 0))
{
Res[Count_2] += Res_Save[Count_2 - 1];
}
else
{
Res[Count_2] += Res_Save[Count_2] + Res_Save[Count_2 - 1];
}
}
for(Count_Z = 0;Count_Z<= N;Count_Z++)
{
Res_Save[Count_Z] = Res[Count_Z] ;
Res[Count_Z] = 0;
}
}
for(Count_Z = 0;Count_Z<= N;Count_Z++)
{
*(az+Count_Z) += pow(2,N-Count) * (*(as+Count)) * Res_Save[Count_Z];
*(bz+Count_Z) += (*(bs+Count)) * Res_Save[Count_Z];
}
}//最外層for回圈
for(Count_Z = N;Count_Z >= 0;Count_Z--)
{
*(bz+Count_Z) = (*(bz+Count_Z))/(*(az+0));
*(az+Count_Z) = (*(az+Count_Z))/(*(az+0));
}
5.差分方程計算濾波結果

采用濾波器直接II型結構,可以減少一半的中間快取記憶體,具體代碼如下:
double FiltButter(double *pdAz, //濾波器引數表1
double *pdBz, //濾波器引數表2
int nABLen, //引數序列的長度
double dDataIn,//輸入資料
double *pdBuf) //資料緩沖區
{
int i;
int nALen;
int nBLen;
int nBufLen;
double dOut;
if( nABLen<1 )return 0.0;
//根據引數,自動求取序列有效長度
nALen = nABLen;
for( i=nABLen-1; i; --i )
{
if( *(pdAz+i) != 0.0 )//從最后一個系數判斷是否為0
{
nALen = i+1;
break;
}
}
//printf("%lf ", nALen);
if( i==0 ) nALen = 0;
nBLen = nABLen;
for( i=nABLen-1; i; --i )
{
if( *(pdBz+i) != 0.0 )
{
nBLen = i+1;
break;
}
}
//printf("%lf ", nBLen);
if( i==0 ) nBLen = 0;
//計算緩沖區有效長度
nBufLen = nALen;
if( nALen < nBLen)
nBufLen = nBLen;
//濾波: 與系數a卷乘
dOut = ( *pdAz ) * dDataIn; // a(0) * x(i)
for( i=1; i<nALen; i++) // a(i) * w(n-i),i=1toN
{
dOut -= *(pdAz+i) * *(pdBuf + (nBufLen - 1) - i);
}
//卷乘結果保存為緩沖序列的最后一個
*(pdBuf + nBufLen - 1) = dOut;
//濾波: 與系數b卷乘
dOut = 0.0;
for( i=0; i<nBLen; i++) // b(i) * w(n-i)
{
dOut += *(pdBz+i) * *(pdBuf + (nBufLen - 1) - i);
}
//丟棄緩沖序列中最早的一個數, 最后一個數清零
for( i=0; i<nBufLen-1; i++)
{
*(pdBuf + i) = *(pdBuf + i + 1);
}
*(pdBuf + nBufLen - 1) = 0;
//回傳輸出值
return dOut;
}
完整程式
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <malloc.h>
#include <graphics.h>
#include<conio.h>//getch()函式頭檔案
using namespace std;
#define pi ((double)3.1415926)
struct DESIGN_SPECIFICATION
{
double Passband;
double Stopband;
double Passband_attenuation;
double Stopband_attenuation;
};
//復數乘
_complex ComplexMul(_complex a, _complex b)
{
_complex c;
c.x = a.x*b.x - a.y*b.y;
c.y = a.y*b.x + a.x*b.y;
return c;
}
//復數除
_complex ComplexDiv(_complex a, _complex b)
{
_complex c;
double dTmp = b.x * b.x + b.y * b.y;
//除數太小,防溢位
if (dTmp < 1.0E-300) {
c.x = 1.0E300;
c.y = 1.0E300;
return c;
}
c.x = (a.x * b.x + a.y * b.y) / dTmp;
c.y = (a.x * b.y - a.y * b.x) / dTmp;
return c;
}
//計算濾波器階數N
int Buttord(double Passband,
double Stopband,
double Passband_attenuation,
double Stopband_attenuation)
{
int N;
printf("Wp = %lf [rad/sec] \n", Passband);
printf("Ws = %lf [rad/sec] \n", Stopband);
printf("Ap = %lf [dB] \n", Passband_attenuation);
printf("As = %lf [dB] \n", Stopband_attenuation);
printf("--------------------------------------------------------\n");
N = ceil(0.5*(log10((pow(10, Stopband_attenuation / 10) - 1) /
(pow(10, Passband_attenuation / 10) - 1)) / log10(Stopband / Passband)));
return (int)N;
}
//計算S平面的濾波器系數
int Butter(int N, double Cutoff, double *a, double *b)
{
double dk = 0;
int k = 0;
int count = 0, count_1 = 0;
_complex *poles, *Res, *Res_Save;
poles = new _complex[N]();
Res = new _complex[N + 1]();
Res_Save = new _complex[N + 1]();
memset(poles, 0, sizeof(_complex)*(N));
memset(Res, 0, sizeof(_complex)*(N + 1));
memset(Res_Save, 0, sizeof(_complex)*(N + 1));
if ((N % 2) == 0) dk = 0.5;
else dk = 0;
for (k = 0; k <= ((2 * N) - 1); k++)
{
if (Cutoff*cos((2 * k + N - 1)*(pi / (2 * N))) < 0.0)
{
poles[count].x = -Cutoff * cos((2 * k + N - 1)*(pi / (2 * N)));
poles[count].y = -Cutoff * sin((2 * k + N - 1)*(pi / (2 * N)));
count++;
if (count == N) break;
}
}
printf("Pk = \n");
for (count = 0; count < N; count++)
{
printf("(%lf) + (%lf i) \n", -poles[count].x, -poles[count].y);
}
printf("--------------------------------------------------------\n");
Res[0].x = poles[0].x;
Res[0].y = poles[0].y;
Res[1].x = 1;
Res[1].y = 0;
for (count_1 = 0; count_1 < N - 1; count_1++)//N個極點相乘次數
{
for (count = 0; count <= count_1 + 2; count++)
{
if (0 == count)
{
Res_Save[count] = ComplexMul(Res[count], poles[count_1 + 1]);
}
else if ((count_1 + 2) == count)
{
Res_Save[count].x += Res[count - 1].x;
Res_Save[count].y += Res[count - 1].y;
}
else
{
Res_Save[count] = ComplexMul(Res[count], poles[count_1 + 1]);
Res_Save[count].x += Res[count - 1].x;
Res_Save[count].y += Res[count - 1].y;
}
}
for (count = 0; count <= N; count++)//Res[i]=a(i),i越大次數越高
{
Res[count].x = Res_Save[count].x;
Res[count].y = Res_Save[count].y;
*(a + N - count) = Res[count].x;
}
}
*(b + N) = *(a + N);
//*(b+N) = pow(Cutoff,N);
//------------------------列印 bs as ---------------------------------//
printf("bs = [");
for (count = 0; count <= N; count++)
{
printf("%lf ", *(b + count));
}
printf(" ] \n");
printf("as = [");
for (count = 0; count <= N; count++)
{
printf("%lf ", *(a + count));
}
printf(" ] \n");
printf("--------------------------------------------------------\n");
delete[]poles;
delete[]Res;
delete[]Res_Save;
return (int)1;
}
//雙線性Z變換,S->Z
int Bilinear(int N,
double *as, double *bs,
double *az, double *bz)
{
int Count = 0, Count_1 = 0, Count_2 = 0, Count_Z = 0;
double *Res, *Res_Save;
Res = new double[N + 1]();
Res_Save = new double[N + 1]();
memset(Res, 0, sizeof(double)*(N + 1));
memset(Res_Save, 0, sizeof(double)*(N + 1));
for (Count_Z = 0; Count_Z <= N; Count_Z++)
{
*(az + Count_Z) = 0;
*(bz + Count_Z) = 0;
}
for (Count = 0; Count <= N; Count++)
{
for (Count_Z = 0; Count_Z <= N; Count_Z++)
{
Res[Count_Z] = 0;
Res_Save[Count_Z] = 0;
}
Res_Save[0] = 1;
for (Count_1 = 0; Count_1 < N - Count; Count_1++)//計算(1-Z^-1)^N-Count的系數,
{ //Res_Save[]=Z^-1多項式的系數,從常數項開始
for (Count_2 = 0; Count_2 <= Count_1 + 1; Count_2++)
{
if (Count_2 == 0)
{
Res[Count_2] += Res_Save[Count_2];
}
else if ((Count_2 == (Count_1 + 1)) && (Count_1 != 0))
{
Res[Count_2] += -Res_Save[Count_2 - 1];
}
else
{
Res[Count_2] += Res_Save[Count_2] - Res_Save[Count_2 - 1];
}
}
for (Count_Z = 0; Count_Z <= N; Count_Z++)
{
Res_Save[Count_Z] = Res[Count_Z];
Res[Count_Z] = 0;
}
}
for (Count_1 = (N - Count); Count_1 < N; Count_1++)//計算(1-Z^-1)^N-Count*(1+Z^-1)^Count的系數,
{ //Res_Save[]=Z^-1多項式的系數,從常數項開始
for (Count_2 = 0; Count_2 <= Count_1 + 1; Count_2++)
{
if (Count_2 == 0)
{
Res[Count_2] += Res_Save[Count_2];
}
else if ((Count_2 == (Count_1 + 1)) && (Count_1 != 0))
{
Res[Count_2] += Res_Save[Count_2 - 1];
}
else
{
Res[Count_2] += Res_Save[Count_2] + Res_Save[Count_2 - 1];
}
}
for (Count_Z = 0; Count_Z <= N; Count_Z++)
{
Res_Save[Count_Z] = Res[Count_Z];
Res[Count_Z] = 0;
}
}
for (Count_Z = 0; Count_Z <= N; Count_Z++)
{
*(az + Count_Z) += pow(2, N - Count) * (*(as + Count)) * Res_Save[Count_Z];
*(bz + Count_Z) += (*(bs + Count)) * Res_Save[Count_Z];
}
}//最外層for回圈
for (Count_Z = N; Count_Z >= 0; Count_Z--)
{
*(bz + Count_Z) = (*(bz + Count_Z)) / (*(az + 0));
*(az + Count_Z) = (*(az + Count_Z)) / (*(az + 0));
}
//------------------------display---------------------------------//
printf("bz = [");
for (Count_Z = 0; Count_Z <= N; Count_Z++)
{
printf("%lf ", *(bz + Count_Z));
}
printf(" ] \n");
printf("az = [");
for (Count_Z = 0; Count_Z <= N; Count_Z++)
{
printf("%lf ", *(az + Count_Z));
}
printf(" ] \n");
printf("--------------------------------------------------------\n");
delete[]Res;
delete[]Res_Save;
return (int)1;
}
// 執行濾波
// 回傳值: 濾波處理后的數
double FiltButter(double *pdAz, //濾波器引數表1
double *pdBz, //濾波器引數表2
int nABLen, //引數序列的長度
double dDataIn,//輸入資料
double *pdBuf) //資料緩沖區
{
int i;
int nALen;
int nBLen;
int nBufLen;
double dOut;
if (nABLen < 1)return 0.0;
//根據引數,自動求取序列有效長度
nALen = nABLen;
for (i = nABLen - 1; i; --i)
{
if (*(pdAz + i) != 0.0)//從最后一個系數判斷是否為0
{
nALen = i + 1;
break;
}
}
//printf("%lf ", nALen);
if (i == 0) nALen = 0;
nBLen = nABLen;
for (i = nABLen - 1; i; --i)
{
if (*(pdBz + i) != 0.0)
{
nBLen = i + 1;
break;
}
}
//printf("%lf ", nBLen);
if (i == 0) nBLen = 0;
//計算緩沖區有效長度
nBufLen = nALen;
if (nALen < nBLen)
nBufLen = nBLen;
//濾波: 與系數a卷乘
dOut = (*pdAz) * dDataIn; // a(0) * x(i)
for (i = 1; i < nALen; i++) // a(i) * w(n-i),i=1toN
{
dOut -= *(pdAz + i) * *(pdBuf + (nBufLen - 1) - i);
}
//卷乘結果保存為緩沖序列的最后一個
*(pdBuf + nBufLen - 1) = dOut;
//濾波: 與系數b卷乘
dOut = 0.0;
for (i = 0; i < nBLen; i++) // b(i) * w(n-i)
{
dOut += *(pdBz + i) * *(pdBuf + (nBufLen - 1) - i);
}
//丟棄緩沖序列中最早的一個數, 最后一個數清零
for (i = 0; i < nBufLen - 1; i++)
{
*(pdBuf + i) = *(pdBuf + i + 1);
}
*(pdBuf + nBufLen - 1) = 0;
//回傳輸出值
return dOut;
}
int main(void)
{
int count;
double Fcutoff;
struct DESIGN_SPECIFICATION IIR_Filter;
IIR_Filter.Passband = (double)((pi*2)/10); //通帶截止頻率[rad]
IIR_Filter.Stopband = (double)(( pi*35)/100); //阻帶截止頻率[rad]
IIR_Filter.Passband_attenuation = 1; //通帶最大衰減[dB]
IIR_Filter.Stopband_attenuation = 10; //阻帶最小衰減[dB]
int N;
IIR_Filter.Passband = 2 * tan((IIR_Filter.Passband) / 2); //[rad/sec]
IIR_Filter.Stopband = 2 * tan((IIR_Filter.Stopband) / 2); //[rad/sec]
N = Buttord(IIR_Filter.Passband,
IIR_Filter.Stopband,
IIR_Filter.Passband_attenuation,
IIR_Filter.Stopband_attenuation);
printf("N: %d \n", N);
Fcutoff = IIR_Filter.Passband / (pow((pow(10, 0.1*IIR_Filter.Passband_attenuation) - 1), 1.0 / (2 * N)));
printf("Wc: %lf \n", Fcutoff);
printf("--------------------------------------------------------\n");
double *as = new double[N + 1]();
double *bs = new double[N + 1]();
memset(as, 0, sizeof(double)*(N + 1));
memset(bs, 0, sizeof(double)*(N + 1));
Butter(N, Fcutoff, as, bs);//計算模擬濾波器系數
double *az;
double *bz;
az = new double[N + 1]();
bz = new double[N + 1]();
memset(az, 0, sizeof(double)*(N + 1));
memset(bz, 0, sizeof(double)*(N + 1));
Bilinear(N, as, bs, az, bz); //模擬變為數字濾波器
//生成疊加信號
printf(" 請輸入信號1頻率 單位 Hz \n");
double w1, w2;
scanf("%lf", &w1);
printf(" 請輸入信號2頻率 單位 Hz \n");
scanf("%lf", &w2);
printf("采樣頻率為 10kHz \n");
FILE* Input_Data1;
Input_Data1 = fopen("D:\\yssj.txt", "w");
printf("生成原始疊加信號并且保存到D:\\yssj.txt\n");
double t, s1;
for (int i = 0; i < 10000; i++)//4秒,產生更多資料
{
t = i / 10000.0; //采樣頻率
s1 = sin(2 * pi *w1 * t) + sin(2 * pi *w2* t);//設定頻率為w1Hz+w2hz
fprintf(Input_Data1, "%lf,\n", s1);
}
fclose(Input_Data1);
char s[100];
int length;
double *data_Buffer;
data_Buffer = (double *)malloc(sizeof(double)*(N + 1));
memset(data_Buffer, 0, sizeof(double)*(N + 1));
double Output = 0;
FILE* Input_Data;
FILE* Output_Data;
Input_Data = fopen("E:\\yssj.txt", "r");
Output_Data = fopen("E:\\lbh.txt", "w");
length = N + 1;
long DataCnt = 0;
for (long j = 0; !feof(Input_Data); j++)
{
fscanf(Input_Data, "%s\n", &s);
DataCnt++;
}
// cout<<DataCnt<<"\n";
rewind(Input_Data);
double *D = new double[DataCnt]();
for (int i = 0; i < DataCnt; i++)
{
fscanf(Input_Data, "%s\n", &s);
D[i] = atof(s);
Output = FiltButter(az,bz,length,D[i],data_Buffer);
fprintf(Output_Data, "%lf\n", Output);
//cout<<Output<<"\n";
}
free(data_Buffer);
fclose(Input_Data);
fclose(Output_Data);
cout << "按任意鍵繪制圖形" << "\n";
_getch();
Input_Data = fopen("E:\\yssj.txt", "r");
Input_Data1 = fopen("E:\\lbh.txt", "r");
char s11[100];
long DataCnt1 = 0;
for (long j = 0; !feof(Input_Data); j++)
{
fscanf(Input_Data, "%s\n", &s);
DataCnt++;
}
for (long j = 0; !feof(Input_Data1); j++)
{
fscanf(Input_Data1, "%s\n", &s11);
DataCnt1++;
}
rewind(Input_Data);
rewind(Input_Data1);
double y1=0, x1=0;
double *D1 = new double[DataCnt]();
initgraph(800, 1080); // 初始化640x480的繪圖螢屏
for (int i = 0; i < DataCnt; i++)
{
fscanf(Input_Data, "%s\n", &s);
D1[i] = atof(s);
s1 = D1[i];
t = i / 10000.0; //采樣頻率
line(x1 * 50000, 200 + y1 * 100, t * 50000, 200 + s1 * 100);
x1 = t;
y1 = s1;
}
y1 = 0;
x1 = 0;
for (int i = 0; i < DataCnt1; i++)
{
fscanf(Input_Data1, "%s\n", &s);
D1[i] = atof(s);
s1 = D1[i];
t = i / 10000.0; //采樣頻率
line(x1 * 50000, 600 + y1 * 100, t * 50000, 600 + s1 * 100);
x1 = t;
y1 = s1;
}
// printf("Finish \n");
delete[]D;
delete[]as;
delete[]bs;
delete[]az;
delete[]bz;
_getch();
closegraph();
fclose(Input_Data);
fclose(Input_Data1);
return (int)0;
}
運行結果


參考資料:http://blog.csdn.net/zhoufan900428/article/details/9069475
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/239591.html
標籤:其他
