DiBR
обычная кошмарная
домашняя страничка
Ежекакполучится околокомпьютерное обозрение
 
  <<<  предыдущий Tech! archive #462 следующий  >>>  
   Последний выпуск       Архив       Ссылки       Полезности       humor.filtered       Фотки       О сайте   
          Это - достаточно беспорядочный архив сообщений конференций сети fidonet, которые на момент их прочтения мной показались полезными или интересными. Многие устарели, многие узкоспецифичны и малоинтересны, но может оказаться и что-то новое...
         
- __techs (2:5015/42) ----------------------------------------------- __techs -
Msg  : 462 of 1000                         Scn
From : Vadim Radionov                      2:4616/8.8      14 Aug 97  17:36:20
To   : Sergey Trapeznikov                                  16 Aug 97  15:32:54
Subj : Re: Fast Fourier Transform
-------------------------------------------------------------------------------
@AREA:NICE.SOURCES
@ Скопиpовано из области 'NICE.SOURCES'
@ Скопиpовано из области 'NETMAIL'
Здравствуйте, Sergey!

■ Quoting message from Sergey Trapeznikov to All
■ [12 Aug 97 at 21:22]

ST>   У меня имеются данные, соответствующие оцифpованному звуку. Хотелось бы
в
ST> pеальном вpемени пpоизводить pазложение в частотный спектp.
ST> Иначе говоpя хочется написать частотный индикатоp для пpоги, котоpая
ST> пpигpывает звуки. Если у кого-либо есть какая-нибудь инфа по этому поводу,
ST> то я pад буду ее почитать. Любые исходники пpиветствуются.

Могу предложить альтернативу: не FFT использовать,
а быстрое преобразованние Уолша. В нем применяется целочисленная арифметика.

Вот кусок из программы:

---- Cut ----

//------------------------------------------------------------------------
// Файл fwt.cpp
// Автор: Радионов В.
// Hазначение: Управление цветомузыкой
// Примечание: текст написан для Watcom C++, работает только в модели FLAT
//------------------------------------------------------------------------

unsigned short BinInvCode( unsigned short n )
{
 unsigned short mask=0x80,r=0;
 for( int i=0; i<8; i++, mask>>=1,n>>=1 )
   if( n & 1 ) r|=mask;
 return r;
}

unsigned UnGray( unsigned short n )
{
 unsigned short mask=0x80,r=n;
 int s=0;
 for( int i=0; i<8; i++, mask>>=1 )
 {
   if( s ) r^=mask;
   if( n & mask ) s^=1;
 }
 return r;
}

unsigned short h2w( unsigned short n )
{
 return( UnGray( BinInvCode( n ) ) );
}

void reorder( short *a, int )
{
 static short a1[256];
 for( int i=0; i< 256; i++ )
 {
  a1[h2w(i)]=a[i];
 }
 for( i=0;i< 256; i++ )
  a[i]=a1[i];
}

static int doReorder = 1;

extern "C" void cdecl toggleReorder();
void cdecl toggleReorder()
{
 doReorder = !doReorder;
}


// Быстрое Уолш преобразование

const short n = 256;
const short r = 8;
short Frame[ n + 80 ];                // Kадр, сыгранный только что.

extern "C" void __cdecl FWT( short * );
extern "C" void __cdecl drawSpectrum();

void __cdecl FWT( short *v0 )
{
 short *v1 = Frame;
 int n2=n/2;
 for( int j=1; j<=r; j++ )
 {
   for( int i=0; i<n2; i++ )
   {
     v1[i]=v0[2*i]+v0[2*i+1];
     v1[i+n2]=v0[2*i]-v0[2*i+1];
   }
   short *tmp=v0; v0=v1; v1=tmp;       // swap( v0,v1);
 }


// Reorder
 if( doReorder )  reorder( v0, n );


// if( !( r&1 ) )
   for( int i=0; i< n;i++ )
    v1[i]=v0[i]>>=6;
}


short mod( short arg );
#pragma aux mod = \\
 "test ax, 8000h" \\
 "jz Skip" \\
 "neg ax" \\
 "Skip:"  \\
 parm [ax] \\
 value [ ax ];

int startPos = 0;

extern "C" void cdecl shiftPos();
void cdecl shiftPos()
{
 if( startPos + 80  < 256 )
   startPos += 80;
 else
  startPos = 0;
}

void __cdecl drawSpectrum()
{
 char *video=(char *)0xb8000;
 for( int y=0; y<25; y++)
  for( int x=0; x<80; x++,video+=2 )
    if( ( mod(Frame[startPos + x])/ 2 ) > (25-y) ) { *video='█'; video[1]=3;
}
    else *video=' ';
}

extern "C" void cdecl _init_video();
//extern "C" void cdecl _done_video();
extern "C" void _bar( short x0, short y0, short x1, short y1, short color );

void setpal(char color,char R,char G, char B);
#pragma aux setpal = \\
       "mov dx,0x3C8" \\
       "mov al,bh" \\
       "out dx,al" \\
       "inc dx" \\
       "mov al,bl" \\
       "out dx,al" \\
       "mov al,ch" \\
       "out dx,al" \\
       "mov al,cl" \\
       "out dx,al" \\
       parm [bh] [bl] [ch] [cl];


void cdecl  _init_video()
{
// #pragma aux _init_video = \\
//   "mov ax, 000Dh " \\
//   "int 10h";
  setpal( 16, 30, 00, 0 );
  setpal( 17, 30, 30, 0 );
  setpal( 18, 0, 0, 30 );
}

void  _done_video()
{
#pragma aux _done_video = \\
  "mov ax, 0003h " \\
  "int 10h";
}

void _bar( short x0, short y0, short x1, short y1, short color )
{
 char *video = ( char *)0xA0000 + y0*320 + x0;
 short width = x1 - x0;
 for( short y = y0; y <= y1; y++ )
 {
  for( short c = width; c; c-- )
    *video++ = color;
  video += 320 - width;
 }
}

extern "C" void cdecl draw_bars();
void cdecl draw_bars()
{
 _bar( 50, 50, 100, 100, 16 );
 _bar( 150, 50, 200, 100, 17 );
 _bar( 250, 50, 300, 100, 18 );
}

extern "C" void cdecl control_bars( short l1, short l2, short l3 );
void cdecl control_bars( short l1, short l2, short l3 )
{
static short _l1 = 0, _l2 = 0, _l3 = 0;
static short b1 = 0, b2 = 0, b3 = 0;
l1 = mod( l1 );
l2 = mod( l2 );
l3 = mod( l3 );
if( l1 > _l1 ) _l1 = l1; // _l1++;
if( l2 > _l2 ) _l2 = l2; // _l2++;
if( l3 > _l3 ) _l3 = l3; // _l3++;

if( l1 < _l1 ) _l1--;
if( l2 < _l2 ) _l2--;
if( l3 < _l3 ) _l3--;

if( l1 != _l1 ) setpal( 16, _l1 * 2, 0, 0 );
if( l2 != _l2 ) setpal( 17, _l2 * 2, _l2 * 2, 0 );
if( l3 != _l3 ) setpal( 18, 0 , 0, _l3 * 2 );
}

---- Сut ----

K сожалению ( или к счастью ), это единственный модуль на С++,
главная же процедура спектрального анализа написана на asm:

;----------------------------------
; Спектральный анализ
;----------------------------------
proc doSpectrum
    cmp  [ FrameReady ], 0
    je   end_spec
    mov  eax, offset Frame
    call CopyFrame
    mov  eax, offset Frame
    push eax
    call _FWT
    pop  eax
    call _drawSpectrum
    movzx eax, [ word Frame + 40 ]
    push  eax
    movzx eax, [ word Frame + 20 ]
    push  eax
    movzx eax, [ word Frame + 2 ]
    push  eax
    call _control_bars
    add  esp, 12
;     call delay
    mov [ FrameReady ], 0
end_spec:
    ret
endp



С наилучшими пожеланиями - Вадим.
--- TM-Ed 1.14+
* Origin: ->> TM-Ed default Origin <<- (2:4616/8.8)






<<<

архив dibr

>>>'