По FFT, может и не нужно никому, но
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено ВН 07 февраля 2003 г. 17:19


просто уже из желания победить html.
Вчера пытался вставить программу в окно Овет, так html съел половину.
Дремуч и темен я в html. Сегодня ув. Xan немного просветил меня по этому вопросу. Но не до конца.
Все же решил попробовать. Правда в нескольких местах используется сишнофортрановская смесь, т.к. не удалось победить нелюбовь html к знаку меньше.
2 варианта. 1-ый - float, 2-ой - int с бл. плав. запятой. Длина 256. Прямое. Обратное - изменением знаков в бабочке и делением результата на длину.
1 вариант, float.
float DAT[512];
float KOEFF[256];
int bitrev128(int i)
{
int j=((i&1)<<6) | ((i&2)<<4) | ((i&4)<<2) | | ((i&16)>>2) | ((i&32)>>4) |((i&64)>>6);
return j;
}
int bitrev256(int i)
{
int j=((i&1)<<7) | ((i&2)<<5) | ((i&4)<<3) | ((i&8)<<1) | ((i&16)>>1) | ((i&32)>>3) | ((i&64)>>5) |((i&128)>>7);
return j;
}
void fft(void)
{
float RA,IA,RB,IB,RW,IW;
float RE,IM;
float LI;
int NSUBSTAG,NBATTER;
int n,m,l,k,j,i,ll,mm;
NSUBSTAG=1;
NBATTER=128;
for(n=0;n<8;n++)
{
mm=2*NBATTER;
for(m=0;m.LT.NSUBSTAG;m++)
{
k=bitrev128(m);
RW=KOEFF[k+64];
IW=KOEFF[k];
for(l=0;l.LT.NBATTER;l++)
{
k=4*m*NBATTER+2*l;
ll=k+mm;
RA=DAT[k];
IA=DAT[k+1];
RB=DAT[ll];
IB=DAT[ll+1];
RE=RB*RW+IB*IW;
IM=IB*RW-RB*IW;
DAT[k]=RA+RE;
DAT[k+1]=IA+IM;
DAT[ll]=RA-RE;
DAT[ll+1]=IA-IM;
}
}
NBATTER>>=1;
NSUBSTAG<<=1;
}
for(i=0;i<256;i++)
{
j=bitrev256(i);
if(i>=j) continue;
RE=DAT[2*i];
IM=DAT[2*i+1];
DAT[2*i]=DAT[2*j];
DAT[2*i+1]=DAT[2*j+1];
DAT[2*j]=RE;
DAT[2*j+1]=IM;
}
}
Вариант 2. int c бл. плав. запятой. Она и возвращается.
Функции bitrev128,bitrev256 - те же. Ф-ии shiftcalcul,
nrmlzarr - для блочной ПЗ.
int DAT[512];
int KOEFF[256];
int shiftcalcul(void)
{
int i,j,k,l;
j=0;
for(i=0;i<512;i++)
{
k=DAT[i];
if(k<0)
{
if(k==0x8000) k=32767;
else k=-k;
}
if(k>j) j=k;
}
if(!j) return 13;
k=0x4000;
for(i=0;i<15;i++)
{
if((j&k)) {l=i;break;}
k>>=1;
}
return (l-2);
}

void nrmlzarr(int shft)
{
int i,j;
if(!shft) return;
if(shft<0)
{
j=-shft;
for(i=0;i<512;i++) DAT[i]>>=j;
}
else for(i=0;i<512;i++) DAT[i]<<=shft;
}
int fft(void)
{
long RB,IB,RW,IW,LI;
int RE,IM,RA,IA;
int EXP,NSUBSTAG,NBATTER;
int n,m,l,k,j,i,ll,mm;
NSUBSTAG=1;
NBATTER=128;
EXP=0;
for(n=0;n<8;n++)
{
j=shiftcalcul();
EXP-=j;
nrmlzarr(j);
mm=2*NBATTER;
for(m=0;m.LT.NSUBSTAG;m++)
{
k=bitrev128(m);
RW=(long)KOEFF[k+64];
IW=(long)KOEFF[k];
for(l=0;l.LT.NBATTER;l++)
{
k=4*m*NBATTER+2*l;
ll=k+mm;
RA=DAT[k];
IA=DAT[k+1];
RB=(long)DAT[ll];
IB=(long)DAT[ll+1];
LI=(RB*RW+IB*IW)<<1;
RE=(int)(LI>>16);
LI=(IB*RW-RB*IW)<<1;
IM=(int)(LI>>16);
DAT[k]=RA+RE;
DAT[k+1]=IA+IM;
DAT[ll]=RA-RE;
DAT[ll+1]=IA-IM;
}
}
NBATTER>>=1;
NSUBSTAG<<=1;
}
for(i=0;i<256;i++)
{
j=bitrev256(i);
if(i>=j) continue;
RE=DAT[2*i];
IM=DAT[2*i+1];
DAT[2*i]=DAT[2*j];
DAT[2*i+1]=DAT[2*j+1];
DAT[2*j]=RE;
DAT[2*j+1]=IM;
}
return EXP;
}


Сишнофортрановская смесь: .LT. - вместо знака <.
DAT: четные - real, нечетные - imidg.
KOEFF[i]=sin(2*pi*i/256).
Для целых - [32767.*sin(2*pi*i/256)]; [] -целая часть.

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru