- Kod: Zaznacz cały
faktualne+=fdt; // tutaj obliczam aktualną częstotliwość dla której liczę:
for ( int i=0; i < syg1.Length; i++) // w tej pętli obliczam 1 sygnał którym jest sinu o aktualnej częstotliwości.
{
syg1[i][1]=sin(2*M_PI*faktualne*(syg1[i][0])*syg1_pot);
}
double a=0;
double b=0;
int e=0;
for ( int i=0; i<syg2.Length; i++) // w tej pętli obliczam odpowiedź układu ( w tym przypadku filtru )
{
b=0;
for ( int j=0; j<tb.Length; j++) // dla współczynników b
{
if (tb[j]!=0)
if (i >= j)
b+=tb[j]*syg1[i-j][1];
}
e=i;
a=0;
for ( int j=0; j<ta.Length; j++) // i dla // dla współczynników a
{
if (tb[j]!=0)
if (e>=0)
a+=ta[j]*syg2[e][1];
e--;
}
syg2[i][1]=b-a;
}
// współczynników a i b jest w sumie 64, przeważnie są zerami
double smax=0;
double fmax=0;
for (int i=gustalenia; i<syg1.Length ;i++) // w tej pętli obliczam wartości maksymalne dla sinusa
{ // i dla odpowiedzi filtru. Dla sinusa nie mogę przyjąć 1 dlatego, że
if ( syg1[i][1]>smax) smax=syg1[i][1]; // muszę przyjąć maksymalną wygenerowaną próbkę
if ( syg2[i][1]>fmax) fmax=syg2[i][1];
}
syg3[krok][1]=1.0*(fmax/smax); // obliczenie wzmocnienia prościej tego nie da się zrobić.
bool wgore=0;
int pprzeg=-1;
for (int k=syg2.Length-1; k>gustalenia; k--) // szukam punktu przegięcia sinusojdy
{ // ale tylko dla wartości dodatnich
if ( syg2[k][1]<syg2[k-1][1] )
{
wgore=1;
}
if ( syg2[k][1]>syg2[k-1][1] && wgore==1 && syg2[k][1]>0)
{
pprzeg=k;
break;
}
}
if ( pprzeg>-1) // jeżeli jest wartość przegięcia to mamy kolejne obliczenia
{ // przeważnie jej nie ma dla pierwszych 20-30 kroków
double czasprobki=syg2[pprzeg][0];
double czaszera=0;
for (int i=gustalenia; i<syg1.Length-1; i++) // ustalamy czas pierwszej sinusojdy ( rozpoczęcia sinusa )
{
if ( syg1[i][1] <0 && syg1[i+1][1] >=0 )
{
czaszera=syg1[i][0];
break;
}
}
double okres=1.0/faktualne;
okres*=1.0/syg1_pot;
for (;;) // w tej pętli obliczamy ile okresów zmieści się do czasu przegięcia od
{ // chwili pierwszego sinusa
if (czaszera<=czasprobki)
{
czasprobki-=okres;
}
if (czasprobki<0)
break;
}
czasprobki+=okres;
czasprobki=czasprobki-okres/4;
syg4[krok][1]=360.0*czasprobki/okres; // obliczamy przesuniecie fazowe filtra
if (syg4[krok][1]<0) syg4[krok][1]=0; // jezeli jest ujemy to zbijamy do zera
} else
{
syg4[krok][1]=0; // tak samo jak nie ma punktu przebięcia
}
jakby wykonać to raz to niema żadnego problemu, ale cały algorytm mogę wykonać do 2048 razy za każdym razem z inną częstotliwością, więc trzeba za każdym razem generować sinusa ( można spróbować generować do tak jak dla DFT ), syg1.Legenth może mieć wartość do 16384 ( czyli dość sporo ) mój kod przy maksymalnej ilości wszystkiego wykonuje się w czasie powyżej 4 minut, a wiem że podobny kod realizujący to samo (ten sam algorytm, działanie nie kod) wykonuje się w okolicy 10 sec. Spokojnie mnie zadowoli zejście w okolicy 30 sec.
Chciałbym wszystko upakować w jak najmniejszą liczbę pętli, bo to chyba zabiera najwięcej czasu i generacja sinusa.