/* lc -Lm ... */

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <graphics/gfx.h>
#include <graphics/rastport.h>
#include <math.h>


#define PROJEKT 0
#define LOAD_SAMPLE 0
#define INFO 1
#define PREFS 2
#define QUIT 3

#define MODE_A  0
#define MODE_B  1
#define MODE_AB 2

ULONG *aud0lc  = (ULONG *)0xdff0a0;
UWORD *aud0len = (UWORD *)0xdff0a4;
UWORD *aud0per = (UWORD *)0xdff0a6;
UWORD *aud0vol = (UWORD *)0xdff0a8;
UWORD *dmacon  = (UWORD *)0xdff096;
UBYTE *bfe001  = (UBYTE *)0xbfe001;


struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *my_screen;
struct Window *my_window;
struct MsgPort wrport;

short scos[2048];
long A[5000];

short locx=0,locy=0;
BOOL pressed=FALSE;
BOOL sample=FALSE;
BOOL cos_done=FALSE;
BYTE *sample_mem;
long sample_len;
short sfreq= 13000;
short lfreq= 10;
short hfreq= 3000;
short ptx1=-1, ptx2=-1;
short optx1=-1, optx2=-1;
long start, range;
short res= 4;
int max_A=-1;
short max_ampl= 100;
UBYTE c_mode= MODE_AB;


/**********************************************************
			SCREEN, WINDOW, GADGETS
***********************************************************/
SHORT st_points[]=
{
   0,  0,
 100,  0,
 100, 10,
   0, 10,
   0,  0
};

struct Border st_border=
{
  0, 0, 1, 0, JAM1, 5, st_points, NULL,
};

/**************GADGET6:Play*********************/

struct IntuiText st_text6=
{
  2,0,JAM1,34, 2,NULL,"Play",NULL,
};

struct Gadget st_gadget6=
{
  NULL,530,88,101,11,GADGHCOMP|GADGDISABLED,RELVERIFY|STRINGCENTER,
  BOOLGADGET,(APTR)&st_border,NULL,&st_text6,NULL,NULL,0,NULL
};

/**************GADGET5:Coefficients*********************/

struct IntuiText st_text5=
{
  2,0,JAM1,34, 2,NULL,"C(r)",NULL,
};

struct Gadget st_gadget5=
{
  &st_gadget6,424,88,101,11,GADGHCOMP|GADGDISABLED,RELVERIFY|STRINGCENTER,
  BOOLGADGET,(APTR)&st_border,NULL,&st_text5,NULL,NULL,0,NULL
};

/**************GADGET4:Edit Freehand*********************/

struct IntuiText st_text4=
{
  2,0,JAM1,18, 2,NULL,"Freehand",NULL,
};

struct Gadget st_gadget4=
{
  &st_gadget5,318,88,101,11,GADGHCOMP|GADGDISABLED,RELVERIFY|STRINGCENTER,
  BOOLGADGET,(APTR)&st_border,NULL,&st_text4,NULL,NULL,0,NULL
};

/**************GADGET3:Stop*********************/

struct IntuiText st_text3=
{
  2,0,JAM1,34, 2,NULL,"Stop",NULL,
};

struct Gadget st_gadget3=
{
  &st_gadget4,212,88,101,11,GADGHCOMP|GADGDISABLED,RELVERIFY|STRINGCENTER,
  BOOLGADGET,(APTR)&st_border,NULL,&st_text3,NULL,NULL,0,NULL
};

/**************GADGET2:Analyze*********************/

struct IntuiText st_text2=
{
  2,0,JAM1,22, 2,NULL,"Analyze",NULL,
};

struct Gadget st_gadget2=
{
  &st_gadget3,106,88,101,11,GADGHCOMP|GADGDISABLED,RELVERIFY|STRINGCENTER,
  BOOLGADGET,(APTR)&st_border,NULL,&st_text2,NULL,NULL,0,NULL
};

/**************GADGET1:Load*********************/

struct IntuiText st_text1=
{
  2,0,JAM1,18, 2,NULL,"AnalyzeT",NULL,
};

struct Gadget st_gadget1=
{
  &st_gadget2,0,88,101,11,GADGHCOMP|GADGDISABLED,RELVERIFY|STRINGCENTER,
  BOOLGADGET,(APTR)&st_border,NULL,&st_text1,NULL,NULL,0,NULL
};

/***********************************************/


struct NewScreen my_new_screen=
{
  0,0,640,256,3,0,1,
  HIRES,CUSTOMSCREEN|SHOWTITLE,NULL,"Spectrum Analyzer",NULL,NULL
};
struct NewWindow my_new_window=
{
  0,10,640,246,0,1,
  GADGETUP|MENUPICK|MOUSEMOVE|MOUSEBUTTONS,ACTIVATE|REPORTMOUSE|BORDERLESS,
  &st_gadget1,NULL,NULL,NULL,NULL,10,10,640,256,CUSTOMSCREEN
};

/**********************************************************
			MENU 0: Menü
***********************************************************/
/*********************** Item3: QUIT *******************/
struct IntuiText text0_3=
{
  2,0,JAM1,CHECKWIDTH,1,
  NULL,"Quit",NULL
};
struct MenuItem item0_3=
{
  NULL,0,40,120,10,
  ITEMTEXT|ITEMENABLED|HIGHCOMP,
  NULL,(APTR) &text0_3,
  NULL,0,NULL,MENUNULL,
};

/*********************** Item0: Prefs ******************/

struct IntuiText text0_2=
{
  2,0,JAM1,CHECKWIDTH,1,
  NULL,"Prefs",NULL
};
struct MenuItem item0_2=
{
  &item0_3,0,20,120,10,
  ITEMTEXT|ITEMENABLED|HIGHCOMP,
  NULL,(APTR) &text0_2,
  NULL,0,NULL,MENUNULL,
};

/*********************** Item0: Info  ******************/

struct IntuiText text0_1=
{
  2,0,JAM1,CHECKWIDTH,1,
  NULL,"Info",NULL
};
struct MenuItem item0_1=
{
  &item0_2,0,10,120,10,
  ITEMTEXT|ITEMENABLED|HIGHCOMP,
  NULL,(APTR) &text0_1,
  NULL,0,NULL,MENUNULL,
};

/*********************** Item0:  Load Sample ******************/

struct IntuiText text0_0=
{
  2,0,JAM1,CHECKWIDTH,1,
  NULL,"Load",NULL
};
struct MenuItem item0_0=
{
  &item0_1,0,0,120,10,
  ITEMTEXT|ITEMENABLED|HIGHCOMP,
  NULL,(APTR) &text0_0,
  NULL,0,NULL,MENUNULL,
};

/***********************  MENU   *************************/
struct Menu menu0=
{
  NULL,0,0,70,0,MENUENABLED,"Projekt",&item0_0
};


/**********************************************************
                       GADGETS ON/OFF
***********************************************************/
#define GADGET_ON( i, g )                                          \
{ SetAPen( my_window->RPort, 0 );                                  \
  RectFill( my_window->RPort, (i-1)*106, 88, (i-1)*106+102, 99 );  \
  OnGadget( g, my_window, NULL );  }  

#define GADGET_OFF( g )   OffGadget( g, my_window, NULL );


/**********************************************************
			ALL_GADGETS
***********************************************************/
void all_gadgets_off( BOOL gad3 )
{
  GADGET_OFF( &st_gadget1 )
  GADGET_OFF( &st_gadget2 )
  if( gad3==TRUE )  GADGET_ON( 3, &st_gadget3 )
  else              GADGET_OFF( &st_gadget3 )
  GADGET_OFF( &st_gadget4 )
  GADGET_OFF( &st_gadget5 )
  GADGET_OFF( &st_gadget6 )
}


void all_gadgets_on()
{
  if( sample==TRUE )  GADGET_ON( 1, &st_gadget1 )
  if( sample==TRUE )  GADGET_ON( 2, &st_gadget2 )
  GADGET_OFF( &st_gadget3 )
  GADGET_ON( 4, &st_gadget4 )
  if( (int)max_A != -1 )  GADGET_ON( 5, &st_gadget5 )
  if( sample==TRUE )  GADGET_ON( 6, &st_gadget6 )
}


/**********************************************************
			WARNUNG
***********************************************************/
SHORT wa_points[]=
{
   0,  0,
  70,  0,
  70, 10,
   0, 10,
   0,  0
};

struct Border wa_border=
{
  0, 0, 1, 0, JAM1, 5, wa_points, NULL,
};

struct IntuiText wa_text=
{
  1,0,JAM1,28, 2,NULL,"OK",NULL,
};

struct Gadget wa_gadget=
{
  NULL,114,55,71,11,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&wa_border,
  NULL,&wa_text,NULL,NULL,0,NULL
};

struct Window *wa_window;

struct NewWindow new_wa_window=
{
  170,78,300,70,2,1,
  GADGETUP,ACTIVATE,&wa_gadget,NULL,NULL,NULL,NULL,
  0,0,0,0,CUSTOMSCREEN
};



void Warnung( char *titel, char *text1, char *text2, char *text3 )
{
BOOL close_me= FALSE;
ULONG class;
struct IntuiMessage *wa_message;

  new_wa_window.Title = (UBYTE *)titel;
  wa_window = (struct Window *) OpenWindow( &new_wa_window );
  if(wa_window == NULL)
    return;

  Move( wa_window->RPort, 6, 18 );
  if( text1 ) Text( wa_window->RPort, text1, strlen(text1) );
  Move( wa_window->RPort, 6, 28 );
  if( text2 ) Text( wa_window->RPort, text2, strlen(text2) );
  Move( wa_window->RPort, 6, 38 );
  if( text3 ) Text( wa_window->RPort, text3, strlen(text3) );

  while( close_me == FALSE )
  {
    Wait( 1 << wa_window->UserPort->mp_SigBit );

    wa_message = (struct IntuiMessage *) GetMsg( wa_window->UserPort );
    if(wa_message)
    {
      class = wa_message->Class;
      ReplyMsg( wa_message );

      if( class==GADGETUP )
        close_me = TRUE;
    }
  }
  CloseWindow( wa_window );
}

/**********************************************************
			FILEREQUESTER
***********************************************************/
char vname[70];


SHORT si_points[]=
{
   0,  0,
  70,  0,
  70, 10,
   0, 10,
   0,  0
};

struct Border si_border=
{
  0, 0, 1, 0, JAM1, 5, si_points, NULL,
};

SHORT fr_points2[]=
{
   0,  0,
  30,  0,
  30, 10,
   0, 10,
   0,  0
};

struct Border fr_border2=
{
  0, 0, 1, 0, JAM1, 5, fr_points2, NULL,
};

SHORT fr_points[]=
{
   -2,-2,
   226,-2,
   226,9,
   -2,9,
   -2,-2
};

struct Border fr_border=
{
  0, 0, 1, 0, JAM1, 5, fr_points, NULL,
};

struct IntuiText fr_text7=
{
  1,2,JAM1,11, 2,NULL,"/",NULL,
};

struct Gadget fr_gadget7=
{
  NULL,158,115,31,11,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&fr_border2,
  NULL,&fr_text7,NULL,NULL,0,NULL
};

struct IntuiText fr_text6=
{
  1,2,JAM1,11, 2,NULL,":",NULL,
};

struct Gadget fr_gadget6=
{
  &fr_gadget7,97,115,31,11,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&fr_border2,
  NULL,&fr_text6,NULL,NULL,0,NULL
};

struct IntuiText fr_text5=
{
  1,2,JAM1,-49, 0,NULL,"Drawer",NULL,
};

UBYTE fr_buffer2[120];
UBYTE fr_undo_buffer2[120];

struct StringInfo fr_string_info2=
{
  fr_buffer2,
  fr_undo_buffer2,0,119,0,
  0,0,0,0,0,NULL,NULL,NULL
};

struct Gadget fr_gadget5=
{
  &fr_gadget6,54,82,224,8,GADGHCOMP,
  RELVERIFY,STRGADGET,(APTR) &fr_border,
  NULL,&fr_text5,
  NULL,(APTR) &fr_string_info2,0,NULL
};

struct IntuiText fr_text4=
{
  1,2,JAM1,-49, 0,NULL,"File",NULL,
};

UBYTE fr_buffer1[33];
UBYTE fr_undo_buffer1[33];

struct StringInfo fr_string_info1=
{
  fr_buffer1,
  fr_undo_buffer1,0,32,0,
  0,0,0,0,0,NULL,NULL,NULL
};

struct Gadget fr_gadget4=
{
  &fr_gadget5,54,97,224,8,GADGHCOMP,
  RELVERIFY,STRGADGET,(APTR) &fr_border,
  NULL,&fr_text4,
  NULL,(APTR) &fr_string_info1,0,NULL
};

struct Image fr_image3;

struct PropInfo fr_prop_info3=
{
  FREEVERT|AUTOKNOB,
  0,0,
  0,MAXBODY * 1/15,
  0,0,0,0,0,0
};

struct Gadget fr_gadget3=
{
  &fr_gadget4,260,12,21,66,
  GADGHNONE,GADGIMMEDIATE|RELVERIFY,PROPGADGET,
  (APTR) &fr_image3,NULL,NULL,
  NULL,(APTR) &fr_prop_info3,
  0,NULL 
};

struct IntuiText fr_text2=
{
  1,2,JAM1,11, 2,NULL,"CANCEL",NULL,
};

struct Gadget fr_gadget2=
{
  &fr_gadget3,208,115,71,11,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&si_border,
  NULL,&fr_text2,NULL,NULL,0,NULL
};

struct IntuiText fr_text1=
{
  1,2,JAM1,27, 2,NULL,"OK",NULL,
};

struct Gadget fr_gadget1=
{
  &fr_gadget2,6,115,71,11,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&si_border,
  NULL,&fr_text1,NULL,NULL,0,NULL
};

struct Window *fr_window;

struct NewWindow new_fr_window=
{
  177,50,285,130,0,1,
  MOUSEMOVE|MOUSEBUTTONS|GADGETDOWN|GADGETUP,
  REPORTMOUSE|ACTIVATE|WINDOWDRAG,
  &fr_gadget1,NULL,NULL,NULL,NULL,
  0,0,0,0,CUSTOMSCREEN
};

BOOL close_fr= FALSE;
BOOL newdir=FALSE;
BOOL fr_result=TRUE;
BOOL potgadsel=FALSE;
BOOL readdfx=FALSE;
int dtype;
int curi=0;
int maxi;
int cursel=-1;
int oldcursel=-1;
int oldmaxi=-1;
int oldcuri=-1;
struct FileInfoBlock *f_info;

struct datei {
  int next;
  char name[33];
};

struct datei datei[200];

void parentd()
{
int i;

  i=strlen(fr_buffer2);
  if( i==0 ) return;

  while( i>=0 )
  {
    i--;
    if( fr_buffer2[i]==':' )
    {
      fr_buffer2[i+1]=0;
      return;
    }
    if( fr_buffer2[i]=='/' )
    {
      fr_buffer2[i]=0;
      return;
    }
  }
  fr_buffer2[0]=0;
}

void testmsg()
{
ULONG class;
USHORT code;
int    mx,my;
APTR iaddress;
struct IntuiMessage *fr_message;
int n;
LONG a;

  while(fr_message=(struct IntuiMessage *)GetMsg( fr_window->UserPort))
  {
    class = fr_message->Class; 
    code = fr_message->Code;
    mx = fr_message->MouseX;
    my = fr_message->MouseY;
    iaddress = fr_message->IAddress;
    ReplyMsg( fr_message );

    if( class==MOUSEMOVE && potgadsel==TRUE )
    {
      a= (LONG)fr_prop_info3.VertPot*(maxi-7)/MAXPOT;
      for( curi=0; a>0; a-- )
      {
        curi= datei[curi].next;
      }
    }
    if( class==MOUSEBUTTONS && code==SELECTDOWN &&
        mx>2 && mx<258 && my>12 && my<77 )
    {
      n= (my-13)/8;
      if( n>maxi ) return;
      for( cursel=curi; n>0; n-- )
      {
        cursel= datei[cursel].next;
      }
      if( datei[cursel].name[0]=='(' )
      {
        if( datei[cursel].name[2]=='e' || datei[cursel].name[2]=='o' )
          fr_buffer2[0]=0;
        if( strlen(fr_buffer2)!=0 &&
            fr_buffer2[strlen(fr_buffer2)-1]!=':' &&
            fr_buffer2[strlen(fr_buffer2)-1]!='/'     )
        {
          strcat( fr_buffer2, "/" );
        }
        strcat( fr_buffer2, &(datei[cursel].name[6]) );
        newdir=TRUE;
      }
      else
      {
        if( !strcmp( datei[cursel].name, fr_buffer1 ) )
        {
          close_fr=TRUE;
          fr_result=TRUE;
        }
        if( datei[cursel].name[0]==':' || datei[cursel].name[0]=='/' )
        {
          if( datei[cursel].name[0]==':' )
          {
            newdir=TRUE;
            readdfx=TRUE;
          }
          if( datei[cursel].name[0]=='/' )
          {
            parentd();
            newdir=TRUE;
          }
        }
        else
        {
          strcpy( fr_buffer1, datei[cursel].name );
        }
      }
      RefreshGadgets( &fr_gadget4, fr_window, NULL );
    }

    if( class==GADGETDOWN && iaddress == (APTR)&fr_gadget3 )
    {
      potgadsel = TRUE;
      a= (LONG)fr_prop_info3.VertPot*(maxi-7)/MAXPOT;
      for( curi=0; a>0; a-- )
      {
        curi= datei[curi].next;
      }
    }

    if( class==GADGETUP )
    {
      if( iaddress == (APTR)&fr_gadget1 )
      {
        close_fr = TRUE;
        fr_result = TRUE;
      }
      if( iaddress == (APTR)&fr_gadget2 )
      {
        close_fr = TRUE;
        fr_result = FALSE;
      }
      if( iaddress == (APTR)&fr_gadget3 )
      {
        potgadsel = FALSE;
      }
      if( iaddress == (APTR)&fr_gadget5 )
      {
        newdir = TRUE;
      }
      if( iaddress == (APTR)&fr_gadget6 )
      {
        newdir = TRUE;
        readdfx=TRUE;
        cursel= -1;
        oldcursel= -2;
      }
      if( iaddress == (APTR)&fr_gadget7 )
      {
        parentd();
        newdir = TRUE;
        RefreshGadgets( &fr_gadget4, fr_window, NULL );
      }
    }
  }
}

BOOL strvgl( char *str1, char *str2 )
{
  for(;;)
  {
    if( *str1>*str2 ) return( FALSE );
    if( *str1<*str2 ) return( TRUE );
    str1++;
    str2++;
  }
}

void adddatei( char *str, LONG type )
{
int i;
int lasti;
char tstr[32]="";

  if( type>=0L )      strcpy( tstr, "(dir) " );
  if( readdfx==TRUE )
  {
    if( dtype == DLT_DEVICE ) strcpy( tstr, "(dev) " );
    if( dtype == DLT_VOLUME ) strcpy( tstr, "(vol) " );
  }
  strcat( tstr, str );
  i=datei[0].next;
  lasti=0;
  while( i!=-1 )
  {
    if( strvgl( tstr, datei[i].name ) == TRUE ) break;
    lasti=i;
    i=datei[i].next;
  }
  maxi++;
  datei[maxi].next=datei[lasti].next;
  datei[lasti].next=maxi;
  strcpy( datei[maxi].name, tstr );
}

void rethinkfiledi()
{
int i,y,c,l;
char nix[]="                                ";

  if( curi==oldcuri && cursel==oldcursel && maxi==oldmaxi ) return;
  oldcuri=curi;
  oldmaxi=maxi;
  oldcursel=cursel;

  i=curi;
  for( c=0, y=19; c<8; c++, y+=8 )
  {
    if( i==cursel )
    {
      SetAPen( fr_window->RPort, 0 );
      SetBPen( fr_window->RPort, 1 );
    }
    else
    {
      SetAPen( fr_window->RPort, 1 );
      SetBPen( fr_window->RPort, 0 );
    }
    l= strlen(datei[i].name);
    if( l>32 ) l=32;
    Move( fr_window->RPort, 3, y );
    Text( fr_window->RPort, datei[i].name, l );  
    Move( fr_window->RPort, 8*l+3, y );
    Text( fr_window->RPort, nix, 31-l );  
    i=datei[i].next;
    if( i==-1 ) return;
  }
}

char drives[]= "\
df0:\000df1:\000df2:\000df3:\000df4:\000\
dh0:\000dh1:\000dh2:\000dh3:\000\
DF0:\000DF1:\000DF2:\000DF3:\000DF4:\000\
DH0:\000DH1:\000DH2:\000DH3:\000";

BOOL testdrive( char *str )
{
int i;

  for( i=0; i<90; i+=5 )
  {
    if( !strcmp( str, &(drives[i]) ) ) return( TRUE );
  }
  return( FALSE );
}

void readdrives()
{
struct DosLibrary *DosBase;
struct RootNode   *rnode;
struct DosInfo    *dinfo;
struct DosList    *dlist;
int i,c;
char str[33];
char *rstr;
BOOL found_df0= FALSE;

  maxi=0;
  datei[0].next=-1;

  DosBase = (struct DosLibrary *)OpenLibrary( "dos.library",0L );
  rnode = (struct RootNode *)        (DosBase->dl_Root);
  dinfo = (struct DosInfo *)    BADDR(rnode->rn_Info);
  dlist = (struct DosList *)    BADDR(dinfo->di_DevInfo);
  while( dlist->dol_Next != NULL )
  {
    if( dlist->dol_Type != DLT_DIRECTORY )
    {
      rstr= (char *)BADDR( dlist->dol_Name );
      i= rstr[0];
      for( c=0; i>0; i-- )
      {
        c++;
        str[c-1]= rstr[c];
      }
      if( dlist->dol_Type == DLT_DEVICE )
      {
        str[c]=':';
        str[c+1]=0;
        if( testdrive(str)==TRUE )
        {  
          dtype=DLT_DEVICE;
          adddatei( str, 1 );
          if( !strcmp( str, "df0:" ) )  found_df0=TRUE;
          if( !strcmp( str, "DF0:" ) )  found_df0=TRUE;
        } 
      }
      else
      {
        str[c]=':';
        str[c+1]=0;
        dtype=DLT_VOLUME;
        adddatei( str, 1 );
      }
    }
    dlist= (struct DosList *)BADDR(dlist->dol_Next);
  } 
  if( found_df0==FALSE )
  {
    dtype=DLT_DEVICE;
    adddatei( "DF0:", 1 );
  }

  CloseLibrary( DosBase );
}

BOOL readdir( char *ndir )
{
struct FileLock   *lock;
LONG a;

  cursel=-1;
  newdir=FALSE;

  SetAPen( fr_window->RPort, 0 );
  RectFill( fr_window->RPort, 3,13,257,77 );

  if( readdfx==TRUE )
  {
    readdrives();
    readdfx=FALSE;
    return( TRUE );
  }

  if( !(lock = (struct FileLock *)Lock(ndir, ACCESS_READ)) )
  {
    Warnung("ERROR",
            "Directory not found.",NULL,NULL);
    return( FALSE );
  }
  if( !Examine( lock, f_info ) )
  {
    UnLock( lock );
    return( TRUE );
  }

  maxi=0;
  datei[0].next=-1;

  while( ExNext( lock, f_info ) != FALSE )
  {
    adddatei( f_info->fib_FileName, f_info->fib_DirEntryType );
    a= (LONG)fr_prop_info3.VertPot*(maxi-7)/MAXPOT;
    for( curi=0; a>0; a-- )
    {
      curi= datei[curi].next;
    }
    rethinkfiledi();
    testmsg();
    if( newdir==TRUE || close_fr==TRUE ) break;
  }
  UnLock( lock );
  return( TRUE );
}

BOOL FReq( char *tits )
{
  ClearMenuStrip( my_window );
  new_fr_window.Title = (UBYTE *)tits;
  fr_window = (struct Window *) OpenWindow( &new_fr_window );
  if(fr_window == NULL)
  {
    SetMenuStrip( my_window, &menu0 );
    return(FALSE);
  }

  if( !(f_info = (struct FileInfoBlock *)
  AllocMem( sizeof(struct FileInfoBlock), MEMF_CHIP|MEMF_CLEAR ) ) )
  {
    CloseWindow( fr_window );
    SetMenuStrip( my_window, &menu0 );
    return(FALSE);
  }

  SetDrMd( fr_window->RPort, JAM2 );
  close_fr=FALSE;

  datei[0].next=-1;
  strcpy( datei[0].name,"/" );
  maxi=0;

  readdir( fr_buffer2 );
  if( newdir==TRUE ) readdir( fr_buffer2 );

  while( close_fr == FALSE )
  {
    Wait( 1 << fr_window->UserPort->mp_SigBit );
    testmsg();
    if( newdir==TRUE ) readdir( fr_buffer2 );
    rethinkfiledi();
  }
  FreeMem( f_info, sizeof( struct FileInfoBlock ) );
  CloseWindow( fr_window );
  SetMenuStrip( my_window, &menu0 );

  if( fr_buffer1[0]==0 ) return( FALSE );
  strcpy( vname, fr_buffer2 );
  if( strlen(vname)>0 && vname[strlen(vname)-1] != ':' )
    strcat( vname, "/" );
  strcat( vname, fr_buffer1 );
  return( fr_result );
}

/**********************************************************
			LOAD_SAMPLE
***********************************************************/
BOOL load_sample()
{
struct FileHandle *fh;

  fh= (struct FileHandle *)Open( (UBYTE *)vname, MODE_OLDFILE );
  if( fh==0 )
  { 
    Warnung( "ERROR", NULL, "Could not open sample file.", NULL );
    return( FALSE );
  }

  sample_len= Read( fh, (UBYTE *)sample_mem, 50000L );
  if( sample_len == 0 )
  {
    Warnung( "ERROR", NULL, "Could not read sample file.", NULL );
    Close( fh );
    return( FALSE );
  }
  if( sample_len < 640L )  sample_len= 640;
  if( sample_len == 50000L )
  {
    Warnung( "ERROR", NULL, "Sample file is too long.", 
             "Only 50kb loaded." );
  }
  Close( fh );
}

/**********************************************************
			DRAW_SAMPLE
***********************************************************/
void draw_sample()
{
long i;

  SetAPen( my_window->RPort, 0 );
  RectFill( my_window->RPort, 0, 0, 639, 86 );

  SetAPen( my_window->RPort, 1 );
  Move( my_window->RPort, 0, 43 );
  Draw( my_window->RPort, 639, 43 );

  SetAPen( my_window->RPort, 3 );
  for( i=0; i<sample_len; i++ )
  {
    WritePixel( my_window->RPort,
                (short)(i*639L/sample_len),
                ((short)sample_mem[i]+131)/3  );
  }
}

/**********************************************************
			PRINT
***********************************************************/
void Print( char *str, short x, short y, short col )
{
  Move( my_window->RPort, x, y );
  SetAPen( my_window->RPort, col );
  SetBPen( my_window->RPort, 1 );
  Text( my_window->RPort, str, strlen(str) );
}

/**********************************************************
	 	STANDARD STRING-GADGET
***********************************************************/
SHORT points[]=
{
   -7, -4,
  200, -4,
  200, 11,
   -7, 11,
   -7, -4
};

struct Border border=
{
  0, 0,  1,  0,  JAM1,  5,  points,  NULL,
};

struct IntuiText text=
{
  1,0,JAM1,-51,-15,NULL,NULL,NULL,
};

UBYTE buffer[25], undo_buffer[25];

struct StringInfo string_info=
{
  buffer,undo_buffer,
  0,25,0,0,0,0,0,0,NULL,NULL,NULL,
};

struct Gadget gadget=
{
  NULL,68,30,198,8,
  GADGHCOMP,
  LONGINT|STRINGCENTER|RELVERIFY|GADGIMMEDIATE,
  STRGADGET,(APTR) &border,NULL,&text,
  NULL,(APTR) &string_info,0,NULL
};

struct Window *strwindow;

struct NewWindow new_strwindow=
{
  160,90,320,50,0,1,
  GADGETUP,
  SMART_REFRESH|WINDOWDRAG|ACTIVATE,
  &gadget, NULL,NULL,NULL,NULL,
  0,0,0,0,CUSTOMSCREEN
};

long StrWindow(char *titel, long def)
{
ULONG class;
struct IntuiMessage *message;

  sprintf(buffer,"%d",(long)def);
  text.IText = (UBYTE *)titel;
  strwindow = (struct Window *) OpenWindow( &new_strwindow );
  if(strwindow)
  {
    ActivateGadget( (struct Gadget *)&gadget,
                    (struct Window *)strwindow, NULL );

    for(;;)
    {
      Wait( 1 << strwindow->UserPort->mp_SigBit );
      message = (struct IntuiMessage *) GetMsg( strwindow->UserPort );
      if(message)
      {
        class = message->Class;
        ReplyMsg( message );
        if( class==GADGETUP ) break;
      }
    }
  }
  else
    DisplayBeep(NULL);

  CloseWindow( strwindow );
  return( string_info.LongInt );
}

/**********************************************************
			GET_RANGE
***********************************************************/
void display_c( char *str )
{
  SetDrMd( &(my_screen->RastPort), JAM2 );
  Move( &(my_screen->RastPort), 280, 7 );
  SetAPen( &(my_screen->RastPort), 0 );
  SetBPen( &(my_screen->RastPort), 1 );
  Text( &(my_screen->RastPort), str, strlen(str) );
}

void get_range()
{
char str[40];

  if( ptx1==ptx2 )
  {
    start= 0;
    range= sample_len;
  }
  else
  {
    if( ptx1>ptx2 )
    {
      start= ((long)ptx2)*sample_len/639L;
      range= ((long)ptx1)*sample_len/639L - start;
    }
    else
    {
      start= ((long)ptx1)*sample_len/639L;
      range= ((long)ptx2)*sample_len/639L - start;
    }
  }
  sprintf(str, "Start=%d Range=%d          \000", start, range );
  display_c( str );
}

/**********************************************************
			FREEHAND
***********************************************************/
void freehand()
{
BOOL an_break= FALSE;
APTR iaddress;
ULONG class;
USHORT code;
struct IntuiMessage *message;
int mx,my;

  all_gadgets_off( TRUE );
  ClearMenuStrip( my_window );

  sample_len= 640;
  ptx1= -1;
  ptx2= -1;
  optx1= -1;
  optx2= -1;
  get_range();

  SetAPen( my_window->RPort, 0 );
  RectFill( my_window->RPort, 0, 0, 639, 86 );

  draw_sample();

  for(;;)
  {
    while(message=(struct IntuiMessage *) GetMsg( my_window->UserPort ))
    {
      class = message->Class;
      code = message->Code;
      mx = message->MouseX;
      my = message->MouseY;
      iaddress = message->IAddress;
      ReplyMsg( message );

      if( class==GADGETUP && iaddress == (APTR)&st_gadget3)  an_break= TRUE;
      if(class == MOUSEMOVE && pressed==TRUE )
      {
        SetAPen( my_window->RPort, 0 );
        Move( my_window->RPort, mx, 0 );
        Draw( my_window->RPort, mx, 86 );
        SetAPen( my_window->RPort, 1 );
        WritePixel( my_window->RPort, mx, 43 );
        SetAPen( my_window->RPort, 3 );
        WritePixel( my_window->RPort, mx, my );
        sample_mem[(long)mx]= 3*my-131;
      }
      if(class == MOUSEBUTTONS && code==SELECTDOWN && my>0 && my<87 )
        pressed=TRUE;
      if(class == MOUSEBUTTONS && code==SELECTUP )
        pressed=FALSE;
    }

    if( an_break== TRUE )  break;
  }

  draw_sample();

  sample= TRUE;

  get_range();
  SetMenuStrip( my_window, &menu0 );
  all_gadgets_on();
}

/**********************************************************
			GET_B
***********************************************************/
double get_b( long r )
{
double a;
long t, av=0, rw;

  rw= (r <<19) /range;

  for( t=start; t<(range+start); t++ )
  {
    av+= (long)((short)sample_mem[t] * scos[ (((rw*t) >>8) +1536) &2047L ]);
  }
  a= 2 * (double)av / (double)range / 1024;
  return( a ); 
}

/**********************************************************
			GET_A
***********************************************************/
double get_a( long r )
{
double a;
long t, av=0, rw;

  rw= (r <<19) /range;

  for( t=start; t<(range+start); t++ )
  {
    av+= (long)((short)sample_mem[t] * scos[ ((rw*t) >>8) &2047L ]);
  }
  a= 2 * (double)av / (double)range / 1024;
  return( a ); 
}

/**********************************************************
			ANALYZE
***********************************************************/
double analyze( long r, UBYTE mode )
{
double a,b;

  if( mode==MODE_A )  return( get_a(r) ); 
  if( mode==MODE_B )  return( get_b(r) ); 
  if( mode==MODE_AB )
  {
    a= get_a(r);
    b= get_b(r);
    return( sqrt(a*a+b*b) ); 
  }
}

/**********************************************************
			ANALYZE_T
***********************************************************/

void analyze_t()
{
int i, c, u, y;
double a;
long h;
BOOL an_break= FALSE;
APTR iaddress;
ULONG class;
USHORT code;
struct IntuiMessage *message;
int min_r, max_r, ran_r;
char str[40];


  if( lfreq>=hfreq )
  {
    Warnung("ERROR\000","Max analyzing frequency\000",
                        "is lower than min\000",
                        "frequency.\000");
    return;
  }

  range/= 49; 
  min_r= (int)( (long)lfreq * (long)range / (long)sfreq );
  max_r= (int)( (long)hfreq * (long)range / (long)sfreq );
  ran_r= ( max_r - min_r ) / 23;

  if( ran_r<=0 )  ran_r= 1; 

  if( max_r>=5000 )
  {
    Warnung("ERROR\000","Overflow !\000","Decrease analyzing\000",
            "frequency or range.\000");
    return;
  }


  all_gadgets_off( TRUE );
  ClearMenuStrip( my_window );

  SetAPen( my_window->RPort, 0 );
  RectFill( my_window->RPort, 0, 100, 639, 245 );
  SetAPen( my_window->RPort, 4 );

  for( i=115; i<=235; i+=5 )
  {
    Move( my_window->RPort, 1, i );
    Draw( my_window->RPort, 638, i );
  }
    
  for( i=1; i<=638; i+=13 )
  {
    Move( my_window->RPort, i, 115 );
    Draw( my_window->RPort, i, 235 );
  }
    

  for( i=2; i<639; i+=13 )
  {
    while(message=(struct IntuiMessage *) GetMsg( my_window->UserPort ))
    {
      class = message->Class;
      code = message->Code;
      iaddress = message->IAddress;
      ReplyMsg( message );

      if( class==GADGETUP && iaddress == (APTR)&st_gadget3)  an_break= TRUE;
    }

    if( an_break== TRUE )  break;

    sprintf( str, "Analyzing [%d..%d]     \000", start, start+range );
    display_c( str );

    for( c=min_r; c<=max_r; c++ )
      A[c]= (long)(analyze( (long)c, MODE_AB ) * 1024);

    for( c=0, y=116; c<24; c++, y+=5 )
    {
      a=0;
      for( u= ran_r*c+min_r; u< ran_r*(c+1)+min_r; u++ )
      {
        h=  (long)A[u];
        a+= (double)(h*h);
      }
      a=  sqrt(a);
      a/= ((long)ran_r * 1024L);

      SetAPen( my_window->RPort, 1 );
      if( a>2 )   SetAPen( my_window->RPort, 4 );
      if( a>4 )  SetAPen( my_window->RPort, 5 );
      if( a>8 )  SetAPen( my_window->RPort, 6 );
      if( a>16 )  SetAPen( my_window->RPort, 7 );
      RectFill( my_window->RPort, i, y, i+11, y+3 );
    }

    start+= range;
  }

  SetDrMd( my_window->RPort, JAM1 );

  SetAPen( my_window->RPort, 3 );
  for( i=0; i<=12; i++ )
  {
    sprintf(str, "%d Hz\000", (long)(hfreq-lfreq)*(long)i/12L+(long)lfreq);
    c= (int)TextLength( my_window->RPort, str, strlen(str) );
    Move( my_window->RPort, 320-(c/2), i*10+118 );
    Text( my_window->RPort, str, strlen(str) );
  }

  max_A= -1;   /* A(r) Gadget off */
  get_range();
  SetMenuStrip( my_window, &menu0 );
  all_gadgets_on();
}


/**********************************************************
			ANALYZE_A
***********************************************************/
void analyze_a()
{
int i;
double a;
BOOL an_break= FALSE;
APTR iaddress;
ULONG class;
USHORT code;
struct IntuiMessage *message;
char str[40];


  all_gadgets_off( TRUE );
  ClearMenuStrip( my_window );

  SetAPen( my_window->RPort, 0 );
  RectFill( my_window->RPort, 0, 100, 639, 245 );
  SetAPen( my_window->RPort, 1 );
  if( c_mode!= MODE_AB )
  {
    Move( my_window->RPort, 0, 200 );
    Draw( my_window->RPort, 639, 200 );
  }
  else
  {
    Move( my_window->RPort, 0, 245 );
    Draw( my_window->RPort, 639, 245 );
  }

  get_range();

  display_c( "                           \000" );

  for( i=0; i<640/res; i++ )
  {
    while(message=(struct IntuiMessage *) GetMsg( my_window->UserPort ))
    {
      class = message->Class;
      code = message->Code;
      iaddress = message->IAddress;
      ReplyMsg( message );

      if( class==GADGETUP && iaddress == (APTR)&st_gadget3)  an_break= TRUE;
    }

    if( an_break== TRUE )  break;

    sprintf( str, "Computing A(%d)   \000", i+1 );
    display_c( str );
    a= analyze( (long)(i+1), c_mode ) * 3.3;
    A[i]= (long)(a*65536);
    SetAPen( my_window->RPort, 2 );
    if( c_mode!= MODE_AB )
    {
      a*= (double)99 / (double)max_ampl;
      if( a>0 )
      {
        if( a>99 )  a= 99;
        RectFill( my_window->RPort, i*res, 200-(short)a, (i+1)*res-1, 200 );
      }
      else
      {
        if( a<-44 )  a= -44;
        RectFill( my_window->RPort, i*res, 200, (i+1)*res-1, 200-(short)a );
      }
    }
    else
    {
      a*= (double)99 / (double)max_ampl;
      if( a>144 )  a= 144;
      RectFill( my_window->RPort, i*res, 245-(short)a, (i+1)*res-1, 245 );
    }
  }

  max_A= i-1;   /* highest possible A(r) */

  sprintf(str, "Start=%d Range=%d          \000", start, range );
  display_c( str );

  get_range();
  SetMenuStrip( my_window, &menu0 );
  all_gadgets_on();
}

/**********************************************************
			INFO
***********************************************************/
struct Gadget in_gadget=
{
  NULL,214,215,71,11,GADGHCOMP|GADGDISABLED,RELVERIFY,BOOLGADGET,
  (APTR)&wa_border, NULL,&wa_text,NULL,NULL,0,NULL
};

struct Window *in_window;

struct NewWindow new_in_window=
{
  70,5,500,230,2,1,
  GADGETUP,ACTIVATE,&in_gadget,NULL,"Info",NULL,NULL,
  0,0,0,0,CUSTOMSCREEN
};

void printli( char *cpoi, int farbe, int x, int y )
{
  SetAPen( in_window->RPort, farbe );
  while( *cpoi!=0 )
  {
    Move( in_window->RPort, x, y );
    Text( in_window->RPort, cpoi, strlen(cpoi) );
    y+=8;
    while( *cpoi!=0 ) cpoi++;
    cpoi++;
  }
}

void info()
{
BOOL close_me= FALSE;
ULONG class;
struct IntuiMessage *in_message;
int i;

char infte1[]= "\
               Spectrum Analyzer V1.0\000";

char infte2[]="\
description             Spectrum  Analyzer V1.0 is a tool\000\
                        which   computes  the   frequency\000\
                        spectrum   of  any   time-related\000\
                        function.  It  is  normally  used\000\
                        for analyzing audio samples.\000\
 \000\
compatibility           Spectrum  Analyzer  V1.0 can read\000\
                        only    raw-formatted    (binary)\000\
                        files, which must have the follo-\000\
                        wing structure: BYTE1, BYTE2, ...\000\
                        Spectrum  Analyzer  V1.0  accepts\000\
                        files of up to 50kB.\000\
 \000\
author                  Thomas Henne\000\
                        Lange Elle 24\000\
                        86438 Kissing\000\
                        Germany\000\
 \000\
date of compilation     18.9.1994\000";

char infte3[]= "\
PLEASE WAIT\000";

  all_gadgets_off(FALSE);

  in_window = (struct Window *) OpenWindow( &new_in_window );
  if(in_window == NULL)
  {
    DisplayBeep(NULL);
    return;
  }

  printli( infte1, 2, 18, 20 ); 
  printli( infte2, 1, 18, 38 ); 

  if( cos_done == FALSE )
  {
    printli( infte3, 3, 206, 205 ); 
    for( i=0; i<2048; i++ )
    {
      scos[i]= (short)(cos( (double)i/325.9493 ) * 1024); 
    }
    printli( infte3, 0, 206, 205 ); 
    cos_done= TRUE;
  }

  SetAPen( in_window->RPort, 0 );
  RectFill( in_window->RPort, 214, 215, 285, 226 );
  OnGadget( &in_gadget, in_window, NULL );  

  while( close_me == FALSE )
  {
    Wait( 1 << in_window->UserPort->mp_SigBit );

    in_message = (struct IntuiMessage *) GetMsg( in_window->UserPort );
    if(in_message)
    {
      class = in_message->Class;
      ReplyMsg( in_message );

      if( class==GADGETUP )
        close_me = TRUE;
    }
  }
  CloseWindow( in_window );

  all_gadgets_on();
}

/**********************************************************
		 	PREFERENCES
***********************************************************/

#define GADNUM 5

UBYTE pr_buffer[10*GADNUM], pr_undo_buffer[10*GADNUM];

/*************** GADGET 100*****************/

struct IntuiText pr_text100= 
{
  1,0,JAM1,-350,2,NULL,
  "coefficients...............................\000",NULL,
};

struct Gadget pr_gadget100=
{
  NULL,360,60,74,8,GADGHCOMP,RELVERIFY,BOOLGADGET,
  NULL, NULL,&pr_text100,NULL,NULL,0,NULL
};

/*************** GADGET 99*****************/

struct Gadget pr_gadget99=
{
  &pr_gadget100,175,135,71,11,GADGHCOMP,RELVERIFY,BOOLGADGET,
  (APTR)&wa_border, NULL,&wa_text,NULL,NULL,0,NULL
};

/*************** GADGET 5*****************/

struct IntuiText pr_text5= 
{
  1,0,JAM1,-350,2,NULL,
  "max amplitude drawn [10..500]..............\000",NULL,
};

struct StringInfo pr_string_info5=
{
  &pr_buffer[40], &pr_undo_buffer[40],
  0,10,0,0,0,0,0,0,NULL,NULL,NULL,
};

struct Gadget pr_gadget5=
{
  &pr_gadget99,360,48,74,8,
  GADGHCOMP,
  LONGINT|STRINGRIGHT|RELVERIFY|GADGIMMEDIATE,
  STRGADGET,NULL,NULL,&pr_text5,
  NULL,(APTR) &pr_string_info5,0,NULL
};

/*************** GADGET 4*****************/

struct IntuiText pr_text4= 
{
  1,0,JAM1,-350,2,NULL,
  "sampling frequency [1..30000 Hz]...........\000",NULL,
};

struct StringInfo pr_string_info4=
{
  &pr_buffer[30], &pr_undo_buffer[30],
  0,10,0,0,0,0,0,0,NULL,NULL,NULL,
};

struct Gadget pr_gadget4=
{
  &pr_gadget5,360,12,74,8,
  GADGHCOMP,
  LONGINT|STRINGRIGHT|RELVERIFY|GADGIMMEDIATE,
  STRGADGET,NULL,NULL,&pr_text4,
  NULL,(APTR) &pr_string_info4,0,NULL
};

/*************** GADGET 3*****************/

struct IntuiText pr_text3= 
{
  1,0,JAM1,-350,2,NULL,
  "max analyzing frequency [1..30000 Hz]......\000",NULL,
};

struct StringInfo pr_string_info3=
{
  &pr_buffer[20], &pr_undo_buffer[20],
  0,10,0,0,0,0,0,0,NULL,NULL,NULL,
};

struct Gadget pr_gadget3=
{
  &pr_gadget4,360,84,74,8,
  GADGHCOMP,
  LONGINT|STRINGRIGHT|RELVERIFY|GADGIMMEDIATE,
  STRGADGET,NULL,NULL,&pr_text3,
  NULL,(APTR) &pr_string_info3,0,NULL
};

/*************** GADGET 2*****************/

struct IntuiText pr_text2= 
{
  1,0,JAM1,-350,2,NULL,
  "min analyzing frequency [1..30000 Hz]......\000",NULL,
};

struct StringInfo pr_string_info2=
{
  &pr_buffer[10], &pr_undo_buffer[10],
  0,10,0,0,0,0,0,0,NULL,NULL,NULL,
};

struct Gadget pr_gadget2=
{
  &pr_gadget3,360,96,74,8,
  GADGHCOMP,
  LONGINT|STRINGRIGHT|RELVERIFY|GADGIMMEDIATE,
  STRGADGET,NULL,NULL,&pr_text2,
  NULL,(APTR) &pr_string_info2,0,NULL
};

/*************** GADGET 1*****************/

struct IntuiText pr_text1= 
{
  1,0,JAM1,-350,2,NULL,
  "resolution [1..10 pixels]..................\000",NULL,
};

struct StringInfo pr_string_info1=
{
  &pr_buffer[0], &pr_undo_buffer[0],
  0,10,0,0,0,0,0,0,NULL,NULL,NULL,
};

struct Gadget pr_gadget1=
{
  &pr_gadget2,360,36,74,8,
  GADGHCOMP,
  LONGINT|STRINGRIGHT|RELVERIFY|GADGIMMEDIATE,
  STRGADGET,NULL,NULL,&pr_text1,
  NULL,(APTR) &pr_string_info1,0,NULL
};

/******************************************/

struct Window *pr_window;

struct NewWindow new_pr_window=
{
  100,50,440,150,0,1,
  GADGETUP,
  SMART_REFRESH|WINDOWDRAG|ACTIVATE,
  &pr_gadget1, NULL,"Preferences",NULL,NULL,
  0,0,0,0,CUSTOMSCREEN
};

struct limit {
  struct Gadget *gadget;
  long a;
  long b;
};

struct limit limits[GADNUM];

void prefs()
{
APTR iaddress;
ULONG class;
struct IntuiMessage *message;
long h;
int i;
BOOL pr_break= FALSE;

  all_gadgets_off( FALSE );
  ClearMenuStrip( my_window );

  sprintf(&pr_buffer[0], "%d",(long)res);
  sprintf(&pr_buffer[10],"%d",(long)lfreq);
  sprintf(&pr_buffer[20],"%d",(long)hfreq);
  sprintf(&pr_buffer[30],"%d",(long)sfreq);
  sprintf(&pr_buffer[40],"%d",(long)max_ampl);

  limits[0].gadget= &pr_gadget1;
  limits[0].a= 1;
  limits[0].b= 10;

  limits[1].gadget= &pr_gadget2;
  limits[1].a= 1;
  limits[1].b= 30000;

  limits[2].gadget= &pr_gadget3;
  limits[2].a= 1;
  limits[2].b= 30000;

  limits[3].gadget= &pr_gadget4;
  limits[3].a= 1;
  limits[3].b= 30000;

  limits[4].gadget= &pr_gadget5;
  limits[4].a= 10;
  limits[4].b= 500;

  pr_window = (struct Window *) OpenWindow( &new_pr_window );
  if(pr_window)
  {
/*    ActivateGadget( (struct Gadget *)&pr_gadget1,
                    (struct Window *)pr_window, NULL );
*/

    SetAPen( pr_window->RPort, 1 );
    SetDrMd( pr_window->RPort, JAM2 );
    Move( pr_window->RPort, 370, 66 );
    switch( c_mode )
    {
    case MODE_B:
      Text( pr_window->RPort, "      B", 7 );
      break;
    case MODE_AB:
      Text( pr_window->RPort, "A^2+B^2", 7 );
      break;
    case MODE_A:
      Text( pr_window->RPort, "      A", 7 );
      break;
    }

    Move( pr_window->RPort, 360, 20 );
    Draw( pr_window->RPort, 434, 20 );
    Move( pr_window->RPort, 360, 44 );
    Draw( pr_window->RPort, 434, 44 );
    Move( pr_window->RPort, 360, 56 );
    Draw( pr_window->RPort, 434, 56 );
    Move( pr_window->RPort, 360, 68 );
    Draw( pr_window->RPort, 434, 68 );
    Move( pr_window->RPort, 360, 92 );
    Draw( pr_window->RPort, 434, 92 );
    Move( pr_window->RPort, 360, 104 );
    Draw( pr_window->RPort, 434, 104 );

    for(;;)
    {
      Wait( 1 << pr_window->UserPort->mp_SigBit );
      message = (struct IntuiMessage *) GetMsg( pr_window->UserPort );
      if(message)
      {
        class = message->Class;
        iaddress = message->IAddress;
        ReplyMsg( message );
        if( class==GADGETUP )
        {
          if( iaddress == (APTR)&pr_gadget99 )  pr_break= TRUE;
          if( iaddress == (APTR)&pr_gadget100 )
          {
            Move( pr_window->RPort, 370, 66 );
            switch( c_mode )
            {
            case MODE_A:
              c_mode= MODE_B;
              Text( pr_window->RPort, "      B", 7 );
              break;
            case MODE_B:
              c_mode= MODE_AB;
              Text( pr_window->RPort, "A^2+B^2", 7 );
              break;
            case MODE_AB:
              c_mode= MODE_A;
              Text( pr_window->RPort, "      A", 7 );
              break;
            }
          }
          for( i=0; i<GADNUM; i++ )
          {
            h= (long)atoi( &pr_buffer[i*10] );
            if( h<limits[i].a || h>limits[i].b )
            {
              DisplayBeep( NULL );
              ActivateGadget( (struct Gadget *)limits[i].gadget,
                              (struct Window *)pr_window, NULL );

              pr_break= FALSE;
            }
          }
          if( pr_break )  break;
        }
      }
    }
  }
  else
    DisplayBeep(NULL);

  res=      (short)atoi( &pr_buffer[0] );
  lfreq=    (short)atoi( &pr_buffer[10] );
  hfreq=    (short)atoi( &pr_buffer[20] );
  sfreq=    (short)atoi( &pr_buffer[30] );
  max_ampl= (short)atoi( &pr_buffer[40] );

  CloseWindow( pr_window );

  SetMenuStrip( my_window, &menu0 );
  all_gadgets_on();
}

/**********************************************************
			DISPLAY_A
***********************************************************/


SHORT di_points[]=
{
   0,  0,
  70,  0,
  70, 10,
   0, 10,
   0,  0
};

struct Border di_border=
{
  0, 0, 1, 0, JAM1, 5, di_points, NULL,
};


struct Image di_image2;

struct PropInfo di_prop_info2=
{
  FREEVERT|AUTOKNOB,
  0,0,
  0,MAXBODY * 1/30,
  0,0,0,0,0,0
};

struct Gadget di_gadget2=
{
  NULL,260,12,21,160,
  GADGHNONE,GADGIMMEDIATE|RELVERIFY,PROPGADGET,
  (APTR) &di_image2,NULL,NULL,
  NULL,(APTR) &di_prop_info2,
  0,NULL 
};

struct IntuiText di_text1=
{
  1,2,JAM1,27, 2,NULL,"OK",NULL,
};

struct Gadget di_gadget1=
{
  &di_gadget2,107,187,71,11,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&di_border,
  NULL,&di_text1,NULL,NULL,0,NULL
};

struct Window *di_window;

struct NewWindow new_di_window=
{
  177,30,285,200,0,1,
  MOUSEMOVE|MOUSEBUTTONS|GADGETDOWN|GADGETUP,
  REPORTMOUSE|ACTIVATE|WINDOWDRAG,
  &di_gadget1,NULL,"Coefficients C(r)\000",NULL,NULL,
  0,0,0,0,CUSTOMSCREEN
};

BOOL close_di;
long cur_pos=0;
long max_pos;

void testdimsg()
{
ULONG class;
USHORT code;
APTR iaddress;
struct IntuiMessage *di_message;

  while(di_message=(struct IntuiMessage *)GetMsg( di_window->UserPort))
  {
    class = di_message->Class; 
    code = di_message->Code;
    iaddress = di_message->IAddress;
    ReplyMsg( di_message );

    if( class==MOUSEMOVE && potgadsel==TRUE )
    {
      cur_pos= (LONG)di_prop_info2.VertPot*(max_pos-19)/MAXPOT;
      if( cur_pos<0 )  cur_pos= 0;
    }

    if( class==GADGETDOWN && iaddress == (APTR)&di_gadget2 )
    {
      potgadsel = TRUE;
      cur_pos= (LONG)di_prop_info2.VertPot*(max_pos-19)/MAXPOT;
      if( cur_pos<0 )  cur_pos= 0;
    }

    if( class==GADGETUP )
    {
      if( iaddress == (APTR)&di_gadget1 )
      {
        close_di = TRUE;
      }
      if( iaddress == (APTR)&di_gadget2 )
      {
        potgadsel = FALSE;
      }
    }
  }
}

void rethinkdi()
{
int i,y,l;
long f;
char str[40];
char nix[]="                                ";

  SetAPen( di_window->RPort, 1 );
  SetBPen( di_window->RPort, 0 );

  for( i=cur_pos, y=19; i<(cur_pos+20L); i++, y+=8 )
  {
    f= (long)(i+1) * (long)sfreq / (long)range;
    sprintf( str, "%3d %7dHz   %4.3f\000", i+1, f, (double)A[i]/65536 );
    l= strlen( str );
    Move( di_window->RPort, 15, y );
    Text( di_window->RPort, str, l );  
    Move( di_window->RPort, 8*l+15, y );
    Text( di_window->RPort, nix, 30-l );  
    if( i==max_pos )  break;
  }
}


void display_A()
{
  all_gadgets_off( FALSE );

  ClearMenuStrip( my_window );
  di_window = (struct Window *) OpenWindow( &new_di_window );
  if(di_window == NULL)
  {
    SetMenuStrip( my_window, &menu0 );
    all_gadgets_on();
    return;
  }

  SetDrMd( di_window->RPort, JAM2 );
  close_di=FALSE;

  SetAPen( di_window->RPort, 0 );
  RectFill( di_window->RPort, 3,13,257,77 );

  max_pos= (long)(max_A);
  cur_pos= (long)di_prop_info2.VertPot*(max_pos-19)/MAXPOT;
  if( cur_pos<0 )  cur_pos= 0;

  rethinkdi();

  while( close_di == FALSE )
  {
    Wait( 1 << di_window->UserPort->mp_SigBit );
    testdimsg();
    rethinkdi();
  }

  CloseWindow( di_window );
  SetMenuStrip( my_window, &menu0 );
  all_gadgets_on();
}

/**********************************************************
			PLAY
***********************************************************/
void play()
{
  all_gadgets_off(FALSE);
  Forbid();

  *aud0lc=  (ULONG)&sample_mem[start];
  *aud0len= (UWORD)range/2;
  *aud0per= (UWORD)((long)3546895L/(long)sfreq);
  *aud0vol= (UWORD)64;

  *dmacon= (UWORD)0x8001;
  while( (*bfe001 & 0x40)==0x40 );
  *dmacon= (UWORD)0x1;

  Permit();
  all_gadgets_on();
}

/**********************************************************
			OPEN AND CLOSE
***********************************************************/
void CloseA(void)
{
  if(sample_mem)           FreeMem( sample_mem,50000L );
  if(my_window->MenuStrip) ClearMenuStrip( my_window );
  if(my_window)            CloseWindow( my_window );
  if(my_screen)            CloseScreen( my_screen );
  if(GfxBase)              CloseLibrary( GfxBase );
  if(IntuitionBase)        CloseLibrary( IntuitionBase );
  exit(0);
}

void OpenA()
{
  IntuitionBase = (struct IntuitionBase *)
                  OpenLibrary( "intuition.library", 0 );
  if( IntuitionBase == NULL ) CloseA();

  GfxBase = (struct GfxBase *)
                  OpenLibrary( "graphics.library", 0 );
  if( GfxBase == NULL ) CloseA();

  my_screen = (struct Screen *) OpenScreen( &my_new_screen );
  if( my_screen == NULL ) CloseA();

  my_new_window.Screen = my_screen;
  new_wa_window.Screen = my_screen;
  new_fr_window.Screen = my_screen;
  new_di_window.Screen = my_screen;
  new_pr_window.Screen = my_screen;
  new_in_window.Screen = my_screen;
  new_strwindow.Screen = my_screen;
  my_window = (struct Window *) OpenWindow( &my_new_window );
  if( my_window == NULL ) CloseA();

  sample_mem = (BYTE *)AllocMem( 50000L, MEMF_CHIP );
  if( sample_mem == 0 ) CloseA();

  SetMenuStrip( my_window, &menu0 );

}



/**********************************************************
			MENU
***********************************************************/
short menu()
{
APTR iaddress;
ULONG class;
USHORT code;
struct IntuiMessage *message;
int mx,my;

  while(message=(struct IntuiMessage *) GetMsg( my_window->UserPort ))
  {
    class = message->Class;
    code = message->Code;
    mx = message->MouseX;
    my = message->MouseY;
    iaddress = message->IAddress;
    ReplyMsg( message );

    if(class == MOUSEMOVE)
    {
      if( pressed==TRUE )
      {
        SetAPen( my_window->RPort, 2 );
        SetDrMd( my_window->RPort, COMPLEMENT|JAM1 );
        while( VBeamPos()<200 );
        if( optx1!=optx2 )
        { 
          if( optx1<optx2 )
            RectFill( my_window->RPort, optx1, 0, optx2, 86 );
          else
            RectFill( my_window->RPort, optx2, 0, optx1, 86 );
        }
        ptx2= mx;
        optx1= ptx1;
        optx2= ptx2;
        if( ptx1!=ptx2 )
        { 
          if( ptx1<ptx2 )
            RectFill( my_window->RPort, ptx1, 0, ptx2, 86 );
          else
            RectFill( my_window->RPort, ptx2, 0, ptx1, 86 );
        }
        SetDrMd( my_window->RPort, JAM1 );
      
        get_range();
      }
    }
    if(class == MOUSEBUTTONS && code==SELECTDOWN )
    {
      if( my>0 && my<87 && sample==TRUE )
      {
        pressed=TRUE;
        ptx1= mx;
      }
    }
    if(class == MOUSEBUTTONS && code==SELECTUP )
    {
      pressed=FALSE;
      get_range();
    }
    if( class==GADGETUP )
    {
      if( iaddress == (APTR)&st_gadget1)
      {      
        get_range();
        if( range<3000 )
          Warnung( "ERROR",NULL,"Range must be > 3000 bytes",
                   "(AnalyzeT)" );
        else
          analyze_t();
      }
      if( iaddress == (APTR)&st_gadget2)
      {      
        analyze_a();
      }
      if( iaddress == (APTR)&st_gadget4)
      {      
        freehand();
      }
      if( iaddress == (APTR)&st_gadget5)
      {      
        display_A();
      }
      if( iaddress == (APTR)&st_gadget6)
      {      
        play();
      }
    }
    if(class == MENUPICK)
    {
      if( code != MENUNULL && MENUNUM(code)==PROJEKT )
      {
        switch( ITEMNUM(code) )
        {
        case LOAD_SAMPLE:
          if( FReq("Load Binary Sample")==FALSE )   break;
          if( load_sample()==FALSE )   break;
          draw_sample();
          ptx1= -1;
          ptx2= -1;
          optx1= -1;
          optx2= -1;
          sample= TRUE;
          get_range();
          all_gadgets_on();
          break;
        case INFO:
          info();
          break;
        case PREFS:
          prefs();
          break;
        case QUIT:
          CloseA();
          break;
        }
      }
    }
  }
  return(TRUE);
}

/**********************************************************
			   MAIN
***********************************************************/
void _main()
{

  OpenA();

  SetRGB4( &(my_screen->ViewPort), 0, 8,5,3 );
  SetRGB4( &(my_screen->ViewPort), 1, 0,0,0 );
  SetRGB4( &(my_screen->ViewPort), 2, 0,11,1 );
  SetRGB4( &(my_screen->ViewPort), 3, 15,15,7 );
  SetRGB4( &(my_screen->ViewPort), 4, 3,3,3 );
  SetRGB4( &(my_screen->ViewPort), 5, 6,6,6 );
  SetRGB4( &(my_screen->ViewPort), 6, 9,9,9 );
  SetRGB4( &(my_screen->ViewPort), 7, 12,12,12 );

  info();

  for(;;)
  {
    Wait( 1 << my_window->UserPort->mp_SigBit );
    menu();
  }
}



