home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff335.lzh / SeeHear / SeeHear.c < prev    next >
C/C++ Source or Header  |  1990-03-22  |  42KB  |  1,435 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <intuition/intuition.h>
  6. #include <graphics/view.h>
  7. #include <graphics/gfxmacros.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include <devices/audio.h>
  11. #include <stdlib.h>
  12.  
  13. #define INTUITION_REV 0
  14. #define GRAPHICS_REV 0
  15. #define STATUSCON 0
  16. #define STATUSHALT 1
  17. #define STATUSGO 2
  18.  
  19. typedef struct{
  20.    ULONG oneShotHiSamples,repeatHiSamples,samplesPerHiCycle;
  21.    UWORD samplesPerSec;
  22.    UBYTE ctOctave,sCompression;
  23.    ULONG volume;
  24.    } Voice8Header;
  25.  
  26. extern struct IntuiMessage *GetMsg();
  27. extern struct MsgPort *CreatePort();
  28. extern struct Window *OpenWindow();
  29. extern struct IntuitionBase *OpenLibrary();
  30. extern struct Screen *OpenScreen();
  31. extern char *pathcat();
  32. extern void doparms();
  33. extern void refwin();
  34. extern void pr1();
  35. extern void gadbox();
  36. extern void clean();
  37. extern int dism();
  38. extern void fftlin();
  39. extern int readin();
  40. extern void findmark();
  41. extern void putmark();
  42. extern void playmark();
  43. extern void timeline();
  44. extern void distf();
  45. extern long doiff();
  46.  
  47. extern struct IntuitionBase *IntuitionBase;
  48. extern struct GfxBase *GfxBase;
  49.  
  50. struct IntuiText mn1i1t={0,1,JAM2,0,0,NULL,"About",NULL};
  51. struct MenuItem mn1i1={NULL,0,8,100,8,
  52.    ITEMTEXT|ITEMENABLED|HIGHCOMP,
  53.    NULL,(APTR)&mn1i1t,NULL,NULL,NULL};
  54. struct IntuiText mn1i0t={0,1,JAM2,0,0,NULL,"Restart",NULL};
  55. struct MenuItem mn1i0={&mn1i1,0,0,100,8,
  56.    ITEMTEXT|ITEMENABLED|HIGHCOMP,
  57.    NULL,(APTR)&mn1i0t,NULL,NULL,NULL};
  58. struct Menu mn1={NULL,100,0,100,0,
  59.    MENUENABLED,"Control",&mn1i0};
  60. struct IntuiText mn0i1t={0,1,JAM2,0,0,NULL,"Quit",NULL};
  61. struct MenuItem mn0i1={NULL,0,8,100,8,
  62.    ITEMTEXT|ITEMENABLED|HIGHCOMP,
  63.    NULL,(APTR)&mn0i1t,NULL,NULL,NULL};
  64. struct IntuiText mn0i0t={0,1,JAM2,0,0,NULL,"Open",NULL};
  65. struct MenuItem mn0i0={&mn0i1,0,0,100,8,
  66.    ITEMTEXT|ITEMENABLED|HIGHCOMP,
  67.    NULL,(APTR)&mn0i0t,NULL,NULL,NULL};
  68. struct Menu mn0={&mn1,0,0,100,0,
  69.    MENUENABLED,"File",&mn0i0};
  70. char gdundo[40];
  71. float fa4=440.;
  72. UBYTE gd31sb[]="440.0";  /* fa4 */
  73. struct StringInfo gd31s={gd31sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
  74. struct Gadget gd31={NULL,424,51,48,8,
  75.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  76.    NULL,NULL,(APTR)&gd31s,31,NULL};
  77. int gd30i=2;
  78. char gd30s[5][2]={"1","3","5","7","9"};
  79. struct IntuiText gd30gt={0,1,JAM2,0,0,NULL,&gd30s[2][0],NULL};
  80. struct Gadget gd30={&gd31,432,101,8,8,
  81.    GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  82.    &gd30gt,NULL,NULL,30,NULL};
  83. int kdfpx=0;
  84. int ndfpx=1,idfpx[8]={1,2,4,8,1,1,1,1};
  85. int npxdf=1,ipxdf[8]={1,1,1,1,1,2,4,8};
  86. char gd29s[8][5]={"  1 ","  2 ","  4 ","  8 ","  1 "," 1/2"," 1/4"," 1/8"};
  87. struct IntuiText gd29gt={0,1,JAM2,0,0,NULL,&gd29s[0][0],NULL};
  88. struct Gadget gd29={&gd30,368,41,32,8,
  89.    GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  90.    &gd29gt,NULL,NULL,29,NULL};
  91. UBYTE gd28sb[]="       0";  /* ibt0 */
  92. struct StringInfo gd28s={gd28sb,gdundo,0,9,0,0,0,0,0,0,0,0,0};
  93. struct Gadget gd28={&gd29,312,11,72,8,
  94.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  95.    NULL,NULL,(APTR)&gd28s,28,NULL};
  96. UBYTE gd27sb[]="       0";  /* ifp */
  97. struct StringInfo gd27s={gd27sb,gdundo,0,9,0,0,0,0,0,0,0,0,0};
  98. struct Gadget gd27={&gd28,496,11,72,8,
  99.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  100.    NULL,NULL,(APTR)&gd27s,27,NULL};
  101. UBYTE gd26sb[]="  0.0";  /* colfrom */
  102. struct StringInfo gd26s={gd26sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
  103. struct Gadget gd26={&gd27,296,101,48,8,
  104.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  105.    NULL,NULL,(APTR)&gd26s,26,NULL};
  106. struct IntuiText gd25gt={0,1,JAM2,0,0,NULL," IFF",NULL};
  107. struct Gadget gd25={&gd26,112,11,32,8,
  108.    GADGHCOMP,TOGGLESELECT|RELVERIFY,BOOLGADGET,NULL,NULL,
  109.    &gd25gt,NULL,NULL,25,NULL};
  110. struct IntuiText gd24gt={0,1,JAM2,0,0,NULL," <-> ",NULL};
  111. struct Gadget gd24={&gd25,152,11,40,8,
  112.    SELECTED|GADGHCOMP,TOGGLESELECT|RELVERIFY,BOOLGADGET,NULL,NULL,
  113.    &gd24gt,NULL,NULL,24,NULL};
  114. struct IntuiText gd23gt={0,1,JAM2,0,0,NULL," RAW",NULL};
  115. struct Gadget gd23={&gd24,200,11,32,8,
  116.    GADGHCOMP,TOGGLESELECT|RELVERIFY,BOOLGADGET,NULL,NULL,
  117.    &gd23gt,NULL,NULL,23,NULL};
  118. char gd22s[2][5]={" NO "," YES"};
  119. struct IntuiText gd22gt={0,1,JAM2,0,0,NULL,&gd22s[1][0],NULL};
  120. struct Gadget gd22={&gd23,440,111,32,8,
  121.    GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  122.    &gd22gt,NULL,NULL,22,NULL};
  123. char gd21s[2][5]={" NO "," YES"};
  124. struct IntuiText gd21gt={0,1,JAM2,0,0,NULL,&gd21s[1][0],NULL};
  125. struct Gadget gd21={&gd22,248,111,32,8,
  126.    GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  127.    &gd21gt,NULL,NULL,21,NULL};
  128. char gd20s[2][4]={" % "," dB"};
  129. struct IntuiText gd20gt={0,1,JAM2,0,0,NULL,&gd20s[1][0],NULL};
  130. struct Gadget gd20={&gd21,216,101,24,8,
  131.    GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  132.    &gd20gt,NULL,NULL,20,NULL};
  133. UBYTE gd19sb[]=" 2.0"; /* colstep */
  134. struct StringInfo gd19s={gd19sb,gdundo,0,5,0,0,0,0,0,0,0,0,0};
  135. struct Gadget gd19={&gd20,168,101,40,8,
  136.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  137.    NULL,NULL,(APTR)&gd19s,19,NULL};
  138. UBYTE gd18sb[]="1.000";
  139. struct StringInfo gd18s={gd18sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
  140. struct Gadget gd18={&gd19,72,91,48,8,
  141.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  142.    NULL,NULL,(APTR)&gd18s,18,NULL};
  143. UBYTE gd17sb[]=" 2"; /* itani */
  144. struct StringInfo gd17s={gd17sb,gdundo,0,3,0,0,0,0,0,0,0,0,0};
  145. struct Gadget gd17={&gd18,168,81,24,8,
  146.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  147.    NULL,NULL,(APTR)&gd17s,17,NULL};
  148. UBYTE gd16sb[]=" 0.500"; /* tline */
  149. struct StringInfo gd16s={gd16sb,gdundo,0,7,0,0,0,0,0,0,0,0,0};
  150. struct Gadget gd16={&gd17,104,71,56,8,
  151.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  152.    NULL,NULL,(APTR)&gd16s,16,NULL};
  153. UBYTE gd15sb[]="0.500";
  154. struct StringInfo gd15s={gd15sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
  155. struct Gadget gd15={&gd16,96,61,48,8,
  156.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  157.    NULL,NULL,(APTR)&gd15s,15,NULL};
  158. SHORT gd14ird[]={0xffff,0xffff,0xc000,0x0003,
  159.                  0xcfff,0xff03,0xcfff,0xff03,
  160.                  0xcfff,0xfff3,0xcfc0,0x0033,
  161.                  0xcfc0,0x0033,0xcfc0,0x0033,
  162.                  0xcfc0,0x0033,0xcfc0,0x0033,
  163.                  0xcfc0,0x0033,0xcfc0,0x0033,
  164.                  0xc0c0,0x0033,0xc0ff,0xfff3,
  165.                  0xc000,0x0003,0xffff,0xffff};
  166. struct Image gd14ir={0,0,32,16,1,gd14ird, 1, 0,NULL};
  167. struct Gadget gd14={&gd15,580,70,32,16,
  168.    GADGIMAGE|GADGHCOMP,RELVERIFY,
  169.    BOOLGADGET,(APTR)&gd14ir,NULL,NULL,NULL,NULL,14,NULL};
  170. UBYTE gd13sb[]=" 4";
  171. struct StringInfo gd13s={gd13sb,gdundo,0,3,0,0,0,0,0,0,0,0,0};
  172. struct Gadget gd13={&gd14,168,51,24,8,
  173.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  174.    NULL,NULL,(APTR)&gd13s,13,NULL};
  175. UBYTE gd12sb[]="10";
  176. struct StringInfo gd12s={gd12sb,gdundo,0,3,0,0,0,0,0,0,0,0,0};
  177. struct Gadget gd12={&gd13,128,31,24,8,
  178.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  179.    NULL,NULL,(APTR)&gd12s,12,NULL};
  180. UBYTE gd11sb[]="10000";
  181. struct StringInfo gd11s={gd11sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
  182. struct Gadget gd11={&gd12,112,21,48,8,
  183.    GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
  184.    NULL,NULL,(APTR)&gd11s,11,NULL};
  185. struct NewWindow nwin1={0,1,640,150,-1,-1,
  186.    NULL,
  187.    WINDOWCLOSE|SIMPLE_REFRESH|ACTIVATE|WINDOWDEPTH,
  188.    &gd11,NULL,"SeeHear",NULL,NULL,0,0,0,0,WBENCHSCREEN};
  189.  
  190. struct NewScreen nsc2={0,0,320,200,5,1,0,0,
  191.    CUSTOMSCREEN,NULL,"SCREEN",NULL,NULL};
  192. SHORT gd4ird[]={0xffff,0x8001,0xbff1,0xbff1,
  193.                 0xbffd,0xb805,0xb805,0xb805,
  194.                 0xb805,0xb805,0xb805,0xb805,
  195.                 0x8805,0x8ffd,0x8001,0xffff};
  196. struct Image gd4ir={0,0,16,16,1,gd4ird, 1, 0,NULL};
  197. struct Gadget gd4={NULL,290,70,16,16,
  198.    GADGIMAGE|GADGHCOMP,RELVERIFY,
  199.    BOOLGADGET,(APTR)&gd4ir,NULL,NULL,NULL,NULL,4,NULL};
  200. SHORT gd3ird[]={0xc003,0x8001,0x0000,0x0300,
  201.                 0x0600,0x0c00,0x7800,0xf000,
  202.                 0xf000,0x7800,0x0c00,0x0600,
  203.                 0x0300,0x0000,0x8001,0xc003,
  204.                      
  205.                 0x0010,0x0008,0x0004,0x0024,
  206.                 0x0012,0x0092,0x0049,0x0249,
  207.                 0x0249,0x0049,0x0092,0x0012,
  208.                 0x0024,0x0004,0x0008,0x0010};
  209. struct Image gd3ir={0,0,16,16,1,gd3ird, 1, 0,NULL};
  210. struct Image gd3is={0,0,16,16,2,gd3ird,12,16,NULL};
  211. struct Gadget gd3={&gd4,290,40,16,16,
  212.    GADGHIMAGE|GADGIMAGE|GADGDISABLED,GADGIMMEDIATE,
  213.    BOOLGADGET,(APTR)&gd3ir,(APTR)&gd3is,NULL,NULL,NULL,3,NULL};
  214. SHORT gd2isd[]={0x0000,0x07e0,0x0ff0,0x1ff8,
  215.                 0x3ffc,0x7ffe,0x7ffe,0x7ffe,
  216.                 0x7ffe,0x7ffe,0x7ffe,0x3ffc,
  217.                 0x1ff8,0x0ff0,0x07e0,0x0000,
  218.  
  219.                 0x0000,0x07e0,0x0ff0,0x1ff8,
  220.                 0x3ffc,0x7ffe,0x7ffe,0x7ffe,
  221.                 0x7ffe,0x7ffe,0x7ffe,0x3ffc,
  222.                 0x1ff8,0x0ff0,0x07e0,0x0000};
  223. struct Image gd2is={0,0,16,16,5,gd2isd,9,0x12,NULL};
  224. SHORT gd2ird[]={0x0000,0x0000,0x0280,0x0280,
  225.                 0x3ff8,0x1450,0x2448,0x0440,
  226.                 0x0820,0x0820,0x0820,0x1010,
  227.                 0x1010,0x1010,0x0000,0x0000,
  228.  
  229.                 0x0000,0x0000,0x0280,0x0280,
  230.                 0x3ff8,0x1450,0x2448,0x0440,
  231.                 0x0820,0x0820,0x0820,0x1010,
  232.                 0x1010,0x1010,0x0000,0x0000,
  233.  
  234.                 0x0000,0x0000,0x0280,0x0280,
  235.                 0x3ff8,0x1450,0x2448,0x0440,
  236.                 0x0820,0x0820,0x0820,0x1010,
  237.                 0x1010,0x1010,0x0000,0x0000};
  238. struct Image gd2ir={0,0,15,16,5,gd2ird,0xd,0x12,NULL};
  239. struct Gadget gd2={&gd3,290,11,16,16,
  240.    GADGHIMAGE|GADGIMAGE|SELECTED,TOGGLESELECT|GADGIMMEDIATE,
  241.    BOOLGADGET,(APTR)&gd2is,(APTR)&gd2ir,NULL,NULL,NULL,2,NULL};
  242. struct Image gd1ir;
  243. struct PropInfo gd1p={AUTOKNOB|FREEVERT,0,0,-1,0x1100,0,0,0,0,0};
  244. struct Gadget gd1={&gd2,308,21,11,176,
  245.    GADGHNONE|GADGIMAGE|GADGDISABLED,
  246.    RELVERIFY,PROPGADGET,(APTR)&gd1ir,NULL,NULL,NULL,
  247.    (APTR)&gd1p,1,NULL};
  248. struct NewWindow nwn2={0,1,320,199,-1,-1,
  249.    NULL,
  250.    WINDOWCLOSE|SIMPLE_REFRESH|NOCAREREFRESH,
  251.    &gd1,NULL,"SeeHear",NULL,NULL,0,0,0,0,CUSTOMSCREEN};
  252. UWORD colors[]={0x000,0x777,0x200,0x223,0x004,0x304,0x300,0x330,
  253.                 0x030,0x035,0x334,0x335,0x436,0x423,0x443,0x343,
  254.                 0x356,0x555,0x669,0x969,0x966,0x996,0x696,0x699,
  255.                 0x999,0xaaf,0xfaf,0xfaa,0xffa,0xafa,0xaff,0xfff};
  256. SHORT imdarrow[]={0x0200,0x0400,0x1800,0xff10,
  257.                          0x1800,0x0400,0x0200,
  258.                   0x0200,0x0400,0x1800,0xff10,
  259.                          0x1800,0x0400,0x0200,
  260.                   0x0200,0x0400,0x1800,0xff10,
  261.                          0x1800,0x0400,0x0200,
  262.                   0x0200,0x0400,0x1800,0xff10,
  263.                          0x1800,0x0400,0x0200,
  264.                   0x0200,0x0400,0x1800,0xff10,
  265.                          0x1800,0x0400,0x0200};
  266. int pky[12]={31,0,31,31,0,31,0,31,31,0,31,0};
  267. char *cky[12]={"A","A#","B","C","C#","D","D#","E","F","F#","G","G#"};
  268. struct MsgPort *mprt=NULL;
  269. struct Screen *scr2=NULL;
  270. struct Window *win1=NULL,*win2=NULL;
  271. struct RastPort *rp1=NULL,*rp2=NULL;
  272. struct Image imarrow={0,0,9,7,5,imdarrow,1,0,NULL};
  273. struct ViewPort *vp2;
  274. struct IntuiMessage *msg;
  275. FILE *fp=NULL;
  276. TEXT filen[34],dirn[67],pathn[100];
  277. int ie,line,linf=21,i2fft=10,nfft=1024,istep=512,jdt,imark=3,itser;
  278. int lmark[4],itani=2,nseries=0,ifani=4,npix=256,linl=198;
  279. int go=FALSE,plin=1,pbefore=1,quitnow=0,readit=FALSE;
  280. int status=-1,dbflag=1,kkeep=0,markf=0,setoff=0;
  281. char *series=NULL,*sound=NULL,*ps,prt[82];
  282. float *fseries=NULL,*smooth=NULL,cut[32],ai,ri,si,*pf;
  283. float srate=10000.,dt=.0001,tstep,tline=0.5,tser,df,dfpx,cint=279.365e-9;
  284. float fani=400.,tstepf=.5,smwid=1.,smsum,colstep=2.,colfrom=0.;
  285. long iser=0,ibt0=0,ifp=0,nfp=0,nsnd=0,msnd;
  286. struct Gadget *pgdt;
  287. Voice8Header vhdr;
  288.  
  289. void main()
  290. {
  291.    static struct IntuiText rq3bt3={0,1,JAM2,6,29,NULL,
  292.       "SeeHear, version 1.1, 1990-03-11",NULL};
  293.    static struct IntuiText rq3bt2={0,1,JAM2,6,21,NULL,
  294.       "Freely distributable for non-commercial use.",&rq3bt3};
  295.    static struct IntuiText rq3bt1={0,1,JAM2,6,11,NULL,
  296.       "2654 E. 26 St., Tulsa, OK  74114",&rq3bt2};
  297.    static struct IntuiText rq3bt={0,1,JAM2,6,3,NULL,
  298.       "Copyright 1990 by Daniel T. Johnson",&rq3bt1};
  299.    static struct IntuiText rq3nt={0,1,JAM2,6,3,NULL,"Continue",NULL};
  300.    static struct IntuiText *cit;
  301.    static USHORT nmen,numm,numi;
  302.    
  303.    si=exp(2./3.);   /* force load of ffp library */
  304.    cit=&rq3bt;
  305.    while(cit){
  306.       printf("%s\n",cit->IText);
  307.       cit=cit->NextText;
  308.    }
  309.    df=srate/nfft;
  310.    dfpx=df;
  311.    msnd=nfft+istep*(198-linf);
  312.    IntuitionBase=OpenLibrary("intuition.library",INTUITION_REV);
  313.    if(IntuitionBase==NULL) dism("IntuitionBase",0);
  314.    GfxBase=(struct GfxBase *)OpenLibrary("graphics.library", GRAPHICS_REV);
  315.    if(GfxBase==NULL) dism("GfxBase",0);
  316.  
  317.    if((mprt=CreatePort(NULL,0))==NULL) dism("mprt",0);
  318.    if((scr2=OpenScreen(&nsc2))==NULL) dism("OpenScreen",0);
  319.    ScreenToBack(scr2);
  320.    vp2=&(scr2->ViewPort);
  321.    LoadRGB4(vp2,colors,32);
  322.  
  323.    nwn2.Screen=scr2;
  324.    if((win2=OpenWindow(&nwn2))==NULL)
  325.       dism("OpenWindow",0);
  326.    win2->UserPort=mprt;
  327.    ModifyIDCMP(win2,MOUSEBUTTONS|GADGETDOWN|GADGETUP|CLOSEWINDOW|MENUPICK);
  328.    rp2=win2->RPort;
  329.    OpenWorkBench();
  330.    if((win1=OpenWindow(&nwin1))==NULL) dism("OpenWindow",0);
  331.    win1->UserPort=mprt;
  332.    ModifyIDCMP(win1,GADGETUP|MENUPICK|REFRESHWINDOW|CLOSEWINDOW);
  333.    rp1=win1->RPort;
  334.    
  335.    filen[0]=0;dirn[0]=0;
  336.    setstatus(STATUSCON);
  337.    refwin();
  338.    dism("menu File/Open to start; adjust parameters first if needed",1);
  339.  
  340. /*Main user interaction loop*/
  341.    for(;;){
  342.       if(!readit) go=FALSE;
  343.       if((msg=(struct IntuiMessage *)GetMsg(mprt))==NULL){
  344.          if(status==STATUSGO) fftlin();
  345.          else WaitPort(win2->UserPort);
  346.       }else{
  347.          switch(msg->Class){
  348.          case REFRESHWINDOW:
  349.             BeginRefresh(win1);
  350.             refwin();
  351.             EndRefresh(win1);
  352.             break;
  353.          case CLOSEWINDOW:
  354.             clean();
  355.          case GADGETDOWN:
  356.          distf(0);
  357.             pgdt=(struct Gadget *)msg->IAddress;
  358.             switch(pgdt->GadgetID){
  359.             case 2:
  360.                if(pgdt->Flags&SELECTED) setstatus(STATUSGO);
  361.                else setstatus(STATUSHALT);
  362.                break;
  363.             case 3:
  364.                pgdt->Flags|=SELECTED;
  365.                RefreshGadgets(&gd3,win2,NULL);
  366.                playmark();
  367.                pgdt->Flags^=SELECTED;
  368.                RefreshGadgets(&gd3,win2,NULL);
  369.                break;
  370.             }
  371.             break;
  372.          case GADGETUP:
  373.          distf(0);
  374.             pgdt=(struct Gadget *)msg->IAddress;
  375.             switch(pgdt->GadgetID){
  376.             case 1:
  377.                ifp=nfp*(gd1p.VertPot/65535.);
  378.                if(ifp>(nfp-nfft)) ifp=nfp-nfft;
  379.                if(fp) readin();   /*wipes out msg*/
  380.                setstatus(STATUSGO);
  381.                break;
  382.             case 4:  /*flip to WB*/
  383.                setstatus(STATUSCON);
  384.                break;
  385.             case 14:  /*flip to scr2*/
  386.                setstatus(STATUSHALT);
  387.                break;
  388.             default:
  389.                doparms();
  390.             }
  391.             break;
  392.          case MOUSEBUTTONS:
  393.          distf(0);
  394.             if(go) break;
  395.             switch(msg->Code){
  396.             case SELECTDOWN:
  397.                findmark();
  398.                break;
  399.             case SELECTUP:
  400.                putmark(1);
  401.                break;
  402.             }
  403.             break;
  404.          case MENUPICK:
  405.             nmen=msg->Code;
  406.             numm=MENUNUM(nmen);
  407.             numi=ITEMNUM(nmen);
  408.             switch(numm){
  409.             case 0:
  410.                switch(numi){
  411.                case 0:  /*Open*/
  412.                   /* Charlie Heath file requester from Fred Fish library
  413.                      AmigaLibDisk35:FileRequester/getfil.o */
  414.                   if(!get_fname(win1,"SeeHear input file",filen,dirn)) break;
  415.                   if(fp) fclose(fp);
  416.                   readit=FALSE;
  417.                   if(!pathcat(pathn,dirn,filen)) break;
  418.                   if((fp=fopen(pathn,"r"))==NULL){
  419.                      dism("Can't open file - try again",1);
  420.                      break;
  421.                   }
  422.                   fseek(fp,0,2);
  423.                   nfp=ftell(fp);
  424.                   rewind(fp);
  425.                   if(nfp<nfft){
  426.                      fclose(fp);fp=NULL;
  427.                      dism("Input file short - try again",2);
  428.                   }
  429.                   dism("Reading input file",1);
  430.                   if(!setoff){
  431.                      ifp=0;
  432.                      ibt0=0;
  433.                   }
  434.                   if(!readin()) break;
  435.                   dism("SeeHear analysis underway",1);
  436.                   setstatus(STATUSGO);
  437.                   break;
  438.                case 1:  /*Quit*/
  439.                   clean();
  440.                   break;
  441.                }
  442.                break;
  443.             case 1:
  444.                switch(numi){
  445.                case 0:  /*Restart*/
  446.                   if(!fp){
  447.                      dism("must Open a File first",1);
  448.                      break;
  449.                   }
  450.                   dism("Reading input file",1);
  451.                   if(!readin()) break;
  452.                   dism("SeeHear analysis underway",1);
  453.                   setstatus(STATUSGO);
  454.                   break;
  455.                case 1:
  456.                   AutoRequest(win1,&rq3bt,NULL,&rq3nt,0,0,400,100);
  457.                   break;
  458.                }
  459.                break;
  460.             }
  461.             break;
  462.          }
  463.          ReplyMsg(msg);
  464.       }
  465.    }
  466. }
  467. /**************************************/
  468. void clean()
  469. {
  470.    if(series) fftcr(series,0);
  471.    if(fp) fclose(fp);
  472.    if(win2){
  473.       win2->UserPort=NULL;
  474.       CloseWindow(win2);
  475.    }
  476.    if(win1){
  477.       win1->UserPort=NULL;
  478.       CloseWindow(win1);
  479.    }
  480.    if(mprt){
  481.       DeletePort(mprt);
  482.    }
  483.    if(scr2) CloseScreen(scr2);
  484.    if(fseries) free((char *)fseries);
  485.    if(smooth) free((char *)smooth);
  486.    if(series) FreeMem(series,nseries);
  487.    if(sound) FreeMem(sound,nsnd);
  488.    exit(0);
  489. }
  490. /**************************************/
  491. void fftlin()
  492. {
  493.    register short i,j,k,l;
  494.    
  495.    if((iser+nfft)>nsnd) setstatus(STATUSHALT);
  496.    if(line>198) setstatus(STATUSHALT);
  497.    if(status!=STATUSGO) return;
  498.    for(ps=sound+iser,i=0;i<nfft;++i,++ps){
  499.       series[i]=fseries[i]=smooth[i]*(*ps);
  500.    }
  501.    fftcr(fseries,i2fft);
  502.    for(pf=fseries,i=0;i<npix;i+=npxdf){
  503.       if(ndfpx>1){
  504.          for(j=0,ai=0.;j<ndfpx;++j){
  505.             ri=*pf++;
  506.             si=*pf++;
  507.             ai+=(ri*ri+si*si);
  508.          }
  509.          ai/=ndfpx;
  510.       }else{
  511.             ri=*pf++;
  512.             si=*pf++;
  513.             ai=(ri*ri+si*si);
  514.       }
  515.       for(j=16,k=0,l=j;j;j>>=1,l=k|j) if(ai>cut[l]) k=l;
  516.       if(k<2) k=2;
  517.       SetAPen(rp2,k);
  518.       for(j=0;j<npxdf;++j){
  519.          WritePixel(rp2,18+i+j,line);
  520.       }
  521.    }
  522.    if(plin) play(series,nfft,jdt);
  523.    if(tser>=tline){
  524.       ++itser;
  525.       timeline();
  526.       tser=tser-tline;
  527.    }
  528.    tser+=tstep;
  529.    iser+=istep;
  530.    ++line;
  531. }
  532. /**************************************/
  533. int readin()
  534. {
  535.    static int i,j,k;
  536.    static float f;
  537.    
  538.    setstatus(STATUSCON);
  539.    readit=FALSE;
  540.    if(!fp){
  541.       dism("must Open a File first",1);
  542.       return(FALSE);
  543.    }
  544.    if(series) FreeMem(series,nseries);
  545.    if((series=(char *)AllocMem(nfft,MEMF_CHIP|MEMF_CLEAR))==NULL) 
  546.       dism("AllocMem series",0);
  547.    nseries=nfft;
  548.    if(fseries) free((char *)fseries);
  549.    if((fseries=(float *)calloc(nfft,4))==NULL) 
  550.       dism("calloc fseries",0);
  551.    if(smooth) free((char *)smooth);
  552.    if((smooth=(float *)calloc(nfft,4))==NULL) 
  553.       dism("calloc smooth",0);
  554.    if(sound) FreeMem(sound,nsnd);
  555.    sound=NULL;
  556.    msnd=nfft+istep*(198-linf);
  557.    SetDrMd(rp2,JAM1);
  558.    BNDRYOFF(rp2);
  559.    SetAPen(rp2,0);
  560.    RectFill(rp2,0,10,274,198);
  561.    kkeep=0;
  562.    SetAPen(rp2,1);
  563.    RectFill(rp2,18,linf,273,198);
  564.    for(k=0,f=fa4/8.,j=0;j<256;f*=1.0594631,k=(k+1)%12){
  565.       j=.5+f/dfpx;
  566.       SetAPen(rp2,pky[k]);
  567.       if(3<j&&j<253){
  568.          RectFill(rp2,j+18,linf-2,j+18,189);
  569.          Move(rp2,j+15,197-8*k);
  570.          Text(rp2,cky[k],strlen(cky[k]));
  571.       }
  572.    }
  573.    for(k=291,i=2;k<306;k+=8)
  574.    for(j=90;j<180;++i,j+=6){
  575.       SetAPen(rp2,i);
  576.       RectFill(rp2,k,j,k+5,j+5);
  577.    }
  578.    dt=1./srate;
  579.    jdt=dt/cint;
  580.    df=1./(dt*nfft);
  581.    dfpx=ndfpx*df/npxdf;
  582.    npix=(nfft*npxdf)/(2*ndfpx);
  583.    if(npix>256) npix=256;
  584.    tstep=istep*dt;
  585.    if(gd23.Flags&SELECTED){
  586.       fseek(fp,0,2);
  587.       nfp=ftell(fp)-ibt0;
  588.    }else{
  589.       if(ibt0=doiff(&vhdr,fp)){
  590.          nfp=vhdr.oneShotHiSamples;
  591.          srate=i=vhdr.samplesPerSec;
  592.          dt=1./srate;
  593.          jdt=dt/cint;
  594.          sprintf(gd11sb,"%5d",i);
  595.          if(gd24.Flags&SELECTED){
  596.             gd25.Flags|=SELECTED;
  597.             gd24.Flags&=~SELECTED;
  598.             gd23.Flags&=~SELECTED;
  599.          }
  600.          RefreshGadgets(&gd11,win1,NULL);
  601.          refwin();
  602.       }else{
  603.          dism("not IFF, doing RAW",1);
  604.          gd23.Flags|=SELECTED;
  605.          gd24.Flags&=~SELECTED;
  606.          gd25.Flags&=~SELECTED;
  607.       }
  608.    }
  609.    if(ifp>(nfp-nfft)) ifp=nfp-nfft;
  610.    if(nfp>msnd) gd1p.VertBody=(61440.*msnd)/nfp;
  611.    else gd1p.VertBody=61440;
  612.    gd1p.VertPot=(65535.*ifp)/nfp;
  613.    sprintf(gd27sb,"%8ld",ifp);
  614.    sprintf(gd28sb,"%8ld",ibt0);
  615.    RefreshGadgets(&gd27,win1,NULL);
  616.    iser=0;
  617.    tser=ifp*dt/tline;
  618.    itser=tser;
  619.    tser=ifp*dt-itser*tline;
  620.    j=nfft/2;
  621.    f=smwid*istep*.5;
  622.    for(i=0,smsum=0.;i<nfft;++i){
  623.       ri=(i-j)/f;
  624.       smsum+=smooth[i]=exp(-ri*ri);
  625.    }
  626.    if(dbflag){
  627.       si=pow(10.,(-colstep/10.));
  628.       ri=128.*smsum*pow(10.,(colfrom/20.));
  629.       ri=ri*ri*si;
  630.       for(i=31;i>=0;--i,ri*=si) cut[i]=ri;
  631.    }else{
  632.       ri=128.*smsum;
  633.       si=ri*colstep/100.;
  634.       ri=ri*colfrom/100.;
  635.       ri-=si;
  636.       for(i=31;i>=0;--i,ri-=si){
  637.          if(ri>0) cut[i]=ri*ri;
  638.          else cut[i]=cut[i+1];
  639.       }
  640.    }
  641.    fseek(fp,ibt0+ifp,0);
  642.    nsnd=nfp-ifp;
  643.    if(nsnd>msnd) nsnd=msnd;
  644.    if(nsnd<nfft) dism("file short - Open another",1);
  645.    if((sound=(char *)AllocMem(nsnd,MEMF_CHIP|MEMF_CLEAR))==NULL) 
  646.       dism("AllocMem sound",0);
  647.    if(fread(sound,1,nsnd,fp)!=nsnd) dism("file length trouble",1);
  648.    line=linf-1;
  649.    timeline();
  650.    line=linf;
  651.    imark=3;
  652.    lmark[3]=linf;
  653.    linl=linf+(nsnd-nfft)/istep;
  654.    lmark[1]=linl;
  655.    lmark[2]=(lmark[1]+lmark[3])/2;
  656.    putmark(0);
  657.    if(pbefore) playmark();
  658.    SetAPen(rp2,1);
  659.    for(f=0.,i=0;i<256;i=.5+(f+=fani)/dfpx){
  660.       j=.5+f/100.;
  661.       sprintf(prt,"%2d\0",j);
  662.       Move(rp2,i+6,18);
  663.       Text(rp2,prt,2);
  664.    }
  665.    readit=TRUE;
  666.    setoff=FALSE;
  667.    return(TRUE);
  668. }
  669. /**************************************/
  670. void findmark()
  671. {
  672.    register int i;
  673.    for(i=3;i;--i){
  674.       if(msg->MouseX>=275&&
  675.          msg->MouseX<=283&&
  676.          msg->MouseY>=lmark[i]-3&&
  677.          msg->MouseY<=lmark[i]+3) break;
  678.    }
  679.    imark=i;
  680.    if(imark){
  681.       imarrow.PlanePick=27;
  682.       DrawImage(rp2,&imarrow,275,lmark[imark]-3);
  683.       markf=1;
  684.    }
  685.    return;
  686. }
  687. /**************************************/
  688. void putmark(ifm)
  689. int ifm;
  690. {
  691.    register int i;
  692.  
  693.    if(imark&&
  694.       ifm&&
  695.       msg->MouseX>=18&&
  696.       msg->MouseX<=273&&
  697.       msg->MouseY>=linf&&
  698.       msg->MouseY<=linl) lmark[imark]=msg->MouseY;
  699.    switch(imark){
  700.    case 1:
  701.       if(lmark[2]>lmark[1]) lmark[2]=lmark[1];
  702.       if(lmark[3]>lmark[1]) lmark[3]=lmark[1];
  703.       break;
  704.    case 2:
  705.       if(lmark[1]<lmark[2]) lmark[1]=lmark[2];
  706.       if(lmark[3]>lmark[2]) lmark[3]=lmark[2];
  707.       if(markf) distf(msg->MouseX);
  708.       else distf(0);
  709.       break;
  710.    case 3:
  711.       if(lmark[1]<lmark[3]) lmark[1]=lmark[3];
  712.       if(lmark[2]<lmark[3]) lmark[2]=lmark[3];
  713.       break;
  714.    }
  715.    SetAPen(rp2,0);
  716.    RectFill(rp2,275,linf-3,283,198);
  717.    for(i=1;i<=3;++i){
  718.       if(i==imark) imarrow.PlanePick=29;
  719.       else imarrow.PlanePick=1;
  720.       DrawImage(rp2,&imarrow,275,lmark[i]-3);
  721.    }
  722.    markf=0;
  723.    return;
  724. }
  725. /**************************************/
  726. void playmark()
  727. {
  728.    static FILE *tout=NULL;
  729.    register long i,j;
  730.    static long *kser=NULL;
  731.    static SHORT blip[]={0x7f81,0x7f81,0x7f81,0x7f81,
  732.                         0x7f81,0x7f81,0x7f81,0x7f81};
  733.    switch(imark){
  734.    case 1:
  735.       i=istep*(lmark[3]-linf);
  736.       j=istep*(lmark[2]-lmark[3]);
  737.       if(j>0) play(sound+i,j,jdt);
  738.       i+=j;
  739.       play(blip,16,jdt);
  740.       play(sound+i,nfft,jdt);
  741.       play(blip,16,jdt);
  742.       i+=nfft;
  743.       j=nfft+istep*(lmark[1]-linf)-i;
  744.       if(j>0) play(sound+i,j,jdt);
  745.       break;
  746.    case 2:
  747.       tout=fopen("ram:SeeHear.temp","w");
  748.       kser=(long *)fseries;
  749.       kser[0]=i2fft;kser[1]=nfft;
  750.       if(tout) fwrite((char *)kser,4,2,tout);
  751.       ps=sound+istep*(lmark[2]-linf);
  752.       for(i=0;i<nfft;++i,++ps) kser[i]=*ps;
  753.       if(tout) fwrite((char *)kser,4,nfft,tout);
  754.       ps=sound+istep*(lmark[2]-linf);
  755.       for(i=0;i<nfft;++i,++ps) series[i]=kser[i]=smooth[i]*(*ps);
  756.       if(tout) fwrite((char *)kser,4,nfft,tout);
  757.       play(series,nfft,jdt);
  758.       for(i=0;i<nfft;++i) fseries[i]=series[i];
  759.       fftcr(fseries,i2fft);
  760.       for(i=0;i<nfft;++i) kser[i]=fseries[i];
  761.       if(tout) fwrite((char *)kser,4,nfft,tout);
  762.       if(tout) fclose(tout);
  763.       break;
  764.    case 3:
  765.       i=istep*(lmark[3]-linf);
  766.       j=nfft+istep*(lmark[1]-lmark[3]);
  767.       play(sound+i,j,jdt);
  768.       break;
  769.    default:
  770.       play(sound,nsnd,jdt);
  771.    }
  772.    return;
  773. }
  774. /**************************************************/
  775. void timeline()
  776. {
  777.    register short i;
  778.    static float f;
  779.  
  780.    SetAPen(rp2,27);
  781.    for(f=0.,i=0;i<256;i=.5+(f+=fani)/dfpx) WritePixel(rp2,i+18,line);
  782.    if(fani/dfpx>7.5){
  783.       SetAPen(rp2,22);
  784.       for(f=fani/2.,i=.5+f/dfpx;i<256;i=.5+(f+=fani)/dfpx)
  785.          WritePixel(rp2,i+18,line);
  786.    }
  787.    if(fani/dfpx>15.5){
  788.       SetAPen(rp2,18);
  789.       for(f=fani/4.,i=.5+f/dfpx;i<256;i=.5+(f+=fani/2.)/dfpx)
  790.          WritePixel(rp2,i+18,line);
  791.    }
  792.    if(!(itser%itani)){
  793.       SetAPen(rp2,1);
  794.       i=.5+itser*tline;
  795.       sprintf(prt,"%2d",i);
  796.       Move(rp2,0,line+3);
  797.       Text(rp2,prt,2);
  798.       WritePixel(rp2,17,line);
  799.    }
  800. }
  801. /****************************************************/
  802. int dism(dmes,dk)
  803. char *dmes;
  804. int dk;
  805. {
  806.    static struct IntuiText rq1bt={0,1,JAM2,6,3,NULL,"Warning",NULL};
  807.    static struct IntuiText rq2bt={0,1,JAM2,6,3,NULL,"ERROR",NULL};
  808.    static struct IntuiText rq1pt={0,1,JAM2,6,3,NULL,"Continue",NULL};
  809.    static struct IntuiText rq1nt={0,1,JAM2,6,3,NULL,"Quit",NULL};
  810.  
  811.    setstatus(STATUSCON);
  812.    SetAPen(rp1,0);
  813.    RectFill(rp1,4,125,635,148);
  814.    SetAPen(rp1,1);
  815.    Move(rp1,16,135);
  816.    Text(rp1,dmes,strlen(dmes));
  817.    if(dk==0){
  818.       Move(rp1,100,147);
  819.       SetAPen(rp1,3);
  820.       Text(rp1,"FATAL ERROR - must exit",23);
  821.       AutoRequest(win1,&rq2bt,NULL,&rq1nt,0,0,250,50);
  822.       clean();
  823.    }else if(dk==2){
  824.       if(AutoRequest(win1,&rq1bt,&rq1pt,&rq1nt,0,0,250,50));
  825.       else clean();
  826.    }
  827.    return(dk);
  828. }
  829. /************************************************/
  830. char *pathcat(pcpn,pcdn,pcfn)
  831. char *pcpn,*pcdn,*pcfn;
  832. {
  833.    static int i;
  834.    static char pcc=':';
  835.    i=strlen(pcdn);
  836.    if(i<1){
  837.       strncpy(pcpn,pcfn,30);
  838.    }else{
  839.       strncpy(pcpn,pcdn,60);
  840.       if(pcdn[i-1]!=pcc) strcat(pcpn,"/");
  841.       strncat(pcpn,pcfn,30);
  842.    }
  843.    if(strlen(pcpn)<1) return(NULL);
  844.    else return(pcpn);
  845. }
  846. /***********************************************/
  847. void doparms()
  848. {
  849.    static int i;
  850.    
  851.    switch(pgdt->GadgetID){
  852.    case 11:
  853.       sscanf(gd11sb,"%f",&srate);
  854.       i=srate;
  855.       if(i<1000) i=1000;
  856.       if(i>27000) i=27000;
  857.       srate=i;
  858.       dt=1./srate;
  859.       jdt=dt/cint;
  860.       sprintf(gd11sb,"%5d",i);
  861.       readit=FALSE;
  862.       break;
  863.    case 12:
  864.       sscanf(gd12sb,"%d",&i2fft);
  865.       if(i2fft<6) i2fft=6;
  866.       if(i2fft>14) i2fft=14;
  867.       sprintf(gd12sb,"%2d",i2fft);
  868.       for(nfft=64,i=6;i<i2fft;++i) nfft+=nfft;
  869.       istep=tstepf*nfft;
  870.       if(istep<1) istep=1;
  871.       if(istep>(16*nfft)) istep=16*nfft;
  872.       tstepf=(istep+0.)/nfft;
  873.       sprintf(gd15sb,"%5.3f",tstepf);
  874.       if(i2fft<=5) kdfpx=7;
  875.       else if(i2fft<=8) kdfpx=13-i2fft;
  876.       else if(i2fft<=10) kdfpx=0;
  877.       else if(i2fft<=13) kdfpx=i2fft-10;
  878.       else kdfpx=3;
  879.       gd29gt.IText=(UBYTE *)gd29s[kdfpx];
  880.       ndfpx=idfpx[kdfpx];
  881.       npxdf=ipxdf[kdfpx];
  882.       readit=FALSE;
  883.       break;
  884.    case 13:
  885.       sscanf(gd13sb,"%d",&ifani);
  886.       if(ifani<1) ifani=1;
  887.       if(ifani>80) ifani=80;
  888.       sprintf(gd13sb,"%2d",ifani);
  889.       fani=100*ifani;
  890.       break;
  891.    case 15:
  892.       sscanf(gd15sb,"%f",&tstepf);
  893.       istep=tstepf*nfft;
  894.       if(istep<1) istep=1;
  895.       if(istep>(16*nfft)) istep=16*nfft;
  896.       tstepf=(istep+0.)/nfft;
  897.       sprintf(gd15sb,"%5.3f",tstepf);
  898.       readit=FALSE;
  899.       break;
  900.    case 16:
  901.       sscanf(gd16sb,"%f",&tline);
  902.       if(tline<.001) tline=.001;
  903.       i=tline/(dt*istep);
  904.       if(i<4) tline=4*istep*dt;
  905.       if(tline>99.) tline=99.;
  906.       sprintf(gd16sb,"%6.3f",tline);
  907.       break;
  908.    case 17:
  909.       sscanf(gd17sb,"%d",&itani);
  910.       if(itani<1) itani=1;
  911.       if(itani>99) itani=99;
  912.       sprintf(gd17sb,"%2d",itani);
  913.       break;
  914.    case 18:
  915.       sscanf(gd18sb,"%f",&smwid);
  916.       if(smwid<=.01) smwid=.01;
  917.       if(smwid>99.) smwid=99.;
  918.       sprintf(gd18sb,"%5.2f",smwid);
  919.       readit=FALSE;
  920.       break;
  921.    case 19:
  922.       sscanf(gd19sb,"%f",&colstep);
  923.       if(colstep<.1) colstep=.1;
  924.       if(colstep>99.) colstep=99.;
  925.       sprintf(gd19sb,"%4.1f",colstep);
  926.       readit=FALSE;
  927.       break;
  928.    case 20:
  929.       dbflag=(dbflag+1)%2;
  930.       gd20gt.IText=(UBYTE *)gd20s[dbflag];
  931.       readit=FALSE;
  932.       break;
  933.    case 21:
  934.       pbefore=(pbefore+1)%2;
  935.       gd21gt.IText=(UBYTE *)gd21s[pbefore];
  936.       break;
  937.    case 22:
  938.       plin=(plin+1)%2;
  939.       gd22gt.IText=(UBYTE *)gd22s[plin];
  940.       break;
  941.    case 23:
  942.       gd23.Flags|=SELECTED;
  943.       gd24.Flags&=~SELECTED;
  944.       gd25.Flags&=~SELECTED;
  945.       break;
  946.    case 24:
  947.       gd24.Flags|=SELECTED;
  948.       gd23.Flags&=~SELECTED;
  949.       gd25.Flags&=~SELECTED;
  950.       break;
  951.    case 25:
  952.       gd25.Flags|=SELECTED;
  953.       gd23.Flags&=~SELECTED;
  954.       gd24.Flags&=~SELECTED;
  955.       break;
  956.    case 26:
  957.       sscanf(gd26sb,"%f",&colfrom);
  958.       if(dbflag){
  959.          if(colfrom>99.) colfrom=99.;
  960.          if(colfrom<-99.) colfrom=-99.;
  961.       }else{
  962.          if(colfrom>999.) colfrom=999.;
  963.          if(colfrom<0.) colfrom=0.;
  964.       }
  965.       sprintf(gd26sb,"%5.1f",colfrom);
  966.       break;
  967.    case 27:
  968.       sscanf(gd27sb,"%ld",&ifp);
  969.       if(ifp<0) ifp=0;
  970.       sprintf(gd27sb,"%8ld",ifp);
  971.       readit=FALSE;
  972.       setoff=TRUE;
  973.       break;
  974.    case 28:
  975.       sscanf(gd28sb,"%ld",&ibt0);
  976.       if(ibt0<0) ibt0=0;
  977.       sprintf(gd28sb,"%8ld",ibt0);
  978.       readit=FALSE;
  979.       setoff=TRUE;
  980.       break;
  981.    case 29:
  982.       kdfpx=(kdfpx+1)%8;
  983.       gd29gt.IText=(UBYTE *)gd29s[kdfpx];
  984.       ndfpx=idfpx[kdfpx];
  985.       npxdf=ipxdf[kdfpx];
  986.       break;
  987.    case 30:
  988.       gd30i=(gd30i+1)%5;
  989.       gd30gt.IText=(UBYTE *)gd30s[gd30i];
  990.       break;
  991.    case 31:
  992.       sscanf(gd31sb,"%f",&fa4);
  993.       if(fa4<220.) fa4=220.;
  994.       if(fa4>880.) fa4=880.;
  995.       sprintf(gd31sb,"%5.1f",fa4);
  996.       break;
  997.    }
  998.    dt=1./srate;
  999.    jdt=dt/cint;
  1000.    df=1./(dt*nfft);
  1001.    dfpx=ndfpx*df/npxdf;
  1002.    tstep=istep*dt;
  1003.    iser=0;
  1004.    tser=ifp*dt/tline;
  1005.    itser=tser;
  1006.    tser=ifp*dt-itser*tline;
  1007.    RefreshGadgets(&gd11,win1,NULL);
  1008.    refwin();
  1009. }
  1010. /******************************************/
  1011. void refwin()
  1012. {
  1013.    pr1(16,17,"File format");
  1014.    gadbox(112,17,15);
  1015.    pr1(248,17,"t0 byte");
  1016.    gadbox(312,17,9);
  1017.    pr1(392,17,"start offset");
  1018.    gadbox(496,17,9);
  1019.    pr1(16,27,"Sample rate");
  1020.    gadbox(112,27,6);
  1021.    sprintf(prt,"Hz; interval%8.3f us",(1.e6/srate));
  1022.    pr1(168,27,prt);
  1023.    sprintf(prt,"%8d samples",nfp);
  1024.    pr1(400,27,prt);
  1025.    pr1(16,37,"FFT length 2^");
  1026.    gadbox(128,37,3);
  1027.    sprintf(prt,"=%5d samples;%8.3f ms time slice",
  1028.       nfft,(nfft*1.e3/srate));
  1029.    pr1(160,37,prt);
  1030.    sprintf(prt,"frequency step%6.2f Hz %6.2f Hz/pixel",df,dfpx);
  1031.    pr1(48,47,prt);
  1032.    gadbox(368,47,4);
  1033.    pr1(408,47,"steps/pixel");
  1034.    pr1(16,57,"Frequency annotate");
  1035.    gadbox(168,57,3);
  1036.    sprintf(prt,"hundred Hz;%5.1f pixels",(fani/dfpx));
  1037.    pr1(200,57,prt);
  1038.    pr1(400,57,"A=");
  1039.    gadbox(424,57,6);
  1040.    pr1(480,57,"Hz");
  1041.    pr1(16,67,"Time step");
  1042.    gadbox(96,67,6);
  1043.    sprintf(prt,"of FFT; %5d samples;%8.3f ms",istep,(istep*1.e3/srate));
  1044.    pr1(152,67,prt);
  1045.    pr1(16,77,"Time lines");
  1046.    gadbox(104,77,7);
  1047.    sprintf(prt,"s =%5.1f pixels (time steps)",(tline/(dt*istep)));
  1048.    pr1(168,77,prt);
  1049.    pr1(48,87,"annotate every");
  1050.    gadbox(168,87,3);
  1051.    sprintf(prt,"time lines =%5.1f pixels",(itani*tline/(dt*istep)));
  1052.    pr1(200,87,prt);
  1053.    pr1(16,97,"Smooth");
  1054.    gadbox(72,97,6);
  1055.    sprintf(prt,"of time step = %5.3f of FFT =%8.3f ms",(tstepf*smwid),
  1056.       (smwid*istep*1.e3/srate));
  1057.    pr1(128,97,prt);
  1058.    pr1(16,107,"Color change every");
  1059.    gadbox(168,107,5);
  1060.    gadbox(216,107,3);
  1061.    pr1(248,107,"below");
  1062.    gadbox(296,107,6);
  1063.    pr1(352,107,"Peak seek");
  1064.    gadbox(432,107,1);
  1065.    pr1(448,107,"pixels");
  1066.    pr1(16,117,"Play sound before analysis?");
  1067.    gadbox(248,117,4);
  1068.    pr1(296,117,"during analysis?");
  1069.    gadbox(440,117,4);
  1070. }
  1071. /******************************************/
  1072. void gadbox(x,y,n)
  1073. int x,y,n;
  1074. {
  1075.    int xa,xb,ya,yb;
  1076.    xa=x-1;xb=x+8*n;ya=y-7;yb=y+2;
  1077.    SetAPen(rp1,3);
  1078.    Move(rp1,xa,ya);
  1079.    Draw(rp1,xb,ya);
  1080.    Draw(rp1,xb,yb);
  1081.    Draw(rp1,xa,yb);
  1082.    Draw(rp1,xa,ya);
  1083.    SetAPen(rp1,1);
  1084. }
  1085. /******************************************/
  1086. void pr1(x,y,s)
  1087. int x,y;
  1088. char *s;
  1089. {
  1090.    SetAPen(rp1,1);
  1091.    Move(rp1,x,y);
  1092.    Text(rp1,s,strlen(s));
  1093. }
  1094. /******************************************/
  1095. int setstatus(newstat)
  1096. int newstat;
  1097. {
  1098.    switch(newstat){
  1099.    case STATUSCON:
  1100.       for(pgdt=win2->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
  1101.          if(!(pgdt->Flags&GADGDISABLED)) OffGadget(pgdt,win2,NULL);
  1102.       OnGadget(&gd4,win2,NULL);
  1103.       gd2.Flags|=SELECTED;
  1104.       gd2.Flags^=SELECTED;
  1105.       RefreshGadgets(&gd1,win2,NULL);
  1106.       WBenchToFront();
  1107. /*      WindowToFront(win1); */
  1108.       SetMenuStrip(win1,&mn0);
  1109.       for(pgdt=win1->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
  1110.          if(pgdt->Flags&GADGDISABLED) OnGadget(pgdt,win1,NULL);
  1111.       status=STATUSCON;
  1112.       return(TRUE);
  1113.    case STATUSHALT:
  1114.       if(status==STATUSCON){
  1115.          for(pgdt=win1->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
  1116.             if(!(pgdt->Flags&GADGDISABLED)) OffGadget(pgdt,win1,NULL);
  1117.          OnGadget(&gd14,win1,NULL);
  1118.          RefreshGadgets(&gd11,win1,NULL);
  1119.          ClearMenuStrip(win1);
  1120.       }
  1121.       ScreenToFront(scr2);
  1122.       for(pgdt=win2->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
  1123.          if(pgdt->Flags&GADGDISABLED) OnGadget(pgdt,win2,NULL);
  1124.       gd2.Flags|=SELECTED;
  1125.       gd2.Flags^=SELECTED;
  1126.       RefreshGadgets(&gd1,win2,NULL);
  1127.       status=STATUSHALT;
  1128.       return(TRUE);
  1129.    case STATUSGO:
  1130.       if(!readit){
  1131.          return(FALSE);
  1132.       }
  1133.       if(status==STATUSCON){
  1134.          for(pgdt=win1->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
  1135.             if(!(pgdt->Flags&GADGDISABLED)) OffGadget(pgdt,win1,NULL);
  1136.          OnGadget(&gd14,win1,NULL);
  1137.          RefreshGadgets(&gd11,win1,NULL);
  1138.          ClearMenuStrip(win1);
  1139.          ScreenToFront(scr2);
  1140.          for(pgdt=win2->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
  1141.             if(pgdt->Flags&GADGDISABLED) OnGadget(pgdt,win2,NULL);
  1142.       }
  1143.       OffGadget(&gd1,win2,NULL);
  1144.       OffGadget(&gd3,win2,NULL);
  1145.       gd2.Flags|=SELECTED;
  1146.       RefreshGadgets(&gd1,win2,NULL);
  1147.       status=STATUSGO;
  1148.       return(TRUE);
  1149.    default:
  1150.       dism("Status error",0);
  1151.    }
  1152.    return(FALSE);
  1153. }
  1154. /******************************************/
  1155. long doiff(v,p)
  1156. Voice8Header *v;
  1157. FILE *p;
  1158. {
  1159.    long *k,ip;
  1160.    char cf[12];
  1161.    
  1162.    k=(long *)(cf+4);
  1163.    rewind(p);
  1164.    if(fread(cf,1,12,p)<12) return(0);
  1165.    if(strncmp(cf,"FORM",4)) return(0);
  1166.    if(strncmp(cf+8,"8SVX",4)) return(0);
  1167.    if(fread(cf,1,8,p)<8) return(0);
  1168.    if(strncmp(cf,"VHDR",4)) return(0);
  1169.    if(fread((char *)v,1,20,p)<20) return(0);
  1170.    ip=12;
  1171.    while(strncmp(cf,"BODY",4)) {
  1172.       ip+=(*k+8);
  1173.       if(fseek(p,ip,0)) return(0);
  1174.       if(fread(cf,1,8,p)<8) return(0);
  1175.    }
  1176.    return(ip+8);
  1177. }
  1178. /***********************************************/
  1179. void distf(ii)
  1180. int ii;
  1181. {
  1182.    static float t,f,fl,y0,y1,y2,r;
  1183.    static char ckeep[20],*ckp;
  1184.    static int i,is,ifl,j,k,k0,k1,k2;
  1185.    
  1186.    if(ii){
  1187.       t=dt*(ifp+istep*(lmark[2]-linf)+nfft/2);
  1188.       j=lmark[2];
  1189.       k0=0;
  1190.       for(is=ii-gd30i;is<=ii+gd30i;++is){
  1191.          k=is;
  1192.          if(k<18) k=18;
  1193.          if(k>273) k=273;
  1194.          k1=ReadPixel(rp2,k,j);
  1195.          if(k1>k0) {i=k;k0=k1;}
  1196.       }
  1197.       k=i-npxdf;if(k<18) k=18;
  1198.       k1=ReadPixel(rp2,k,j);if(k1>k0) k1=k0;
  1199.       k=i+npxdf;if(k>273) k=273;
  1200.       k2=ReadPixel(rp2,k,j);if(k2>k0) k2=k0;
  1201.       if(k1<k2){
  1202.          k=k1;k1=k2;k2=k;
  1203.          k=1;
  1204.       }else if(k1>k2) k=-1;
  1205.       else k=0;
  1206.       if(k&&gd30i){
  1207.          y0=log(cut[k0]);
  1208.          y1=log(cut[k1]);
  1209.          y2=log(cut[k2]);
  1210.          if(y0>y2) r=(y0-y1)/(y0-y2);
  1211.          else r=1.;
  1212.          r=k*(1.-r)/(2.*r+2.);
  1213.       }else r=0.;
  1214.       f=dfpx*(i+r-18);
  1215.       if(f<1.) f=1.;
  1216.       fl=120.+17.31234*(log(f)-log(fa4));
  1217.       ifl=fl+.5;
  1218.       fl=fl-ifl;
  1219.       SetAPen(rp2,0);
  1220.       RectFill(rp2,74,0,319,8);
  1221.       SetAPen(rp2,1);
  1222.       kkeep=i;
  1223.       k=ReadPixel(rp2,i,j);
  1224.       sprintf(prt,"%5.2f s  %5.0f Hz  %s%+4.2f %d\0",t,f,cky[ifl%12],fl,k);
  1225.       Move(rp2,74,7);
  1226.       Text(rp2,prt,strlen(prt));
  1227.       SetAPen(rp2,0);
  1228.       for(k=2,ckp=ckeep;k<4;++k){
  1229.          *ckp++=ReadPixel(rp2,kkeep+k,j);
  1230.          WritePixel(rp2,kkeep+k,j);
  1231.          *ckp++=ReadPixel(rp2,kkeep,j+k);
  1232.          WritePixel(rp2,kkeep,j+k);
  1233.          *ckp++=ReadPixel(rp2,kkeep-k,j);
  1234.          WritePixel(rp2,kkeep-k,j);
  1235.          *ckp++=ReadPixel(rp2,kkeep,j-k);
  1236.          WritePixel(rp2,kkeep,j-k);
  1237.       }
  1238.       for(j=-1;j<=1;++j)
  1239.       for(k=-1;k<=1;++k){
  1240.          SetAPen(rp2,ReadPixel(rp2,kkeep+j*npxdf,lmark[2]+k*npxdf));
  1241.          RectFill(rp2,314+3*j,3+3*k,316+3*j,5+3*k);
  1242.       }
  1243.       k=ReadPixel(rp2,kkeep,lmark[2]);
  1244.       SetAPen(rp2,k);
  1245.       k=90+6*(k-2);
  1246.       if(k>174) {k-=90;j=298;}
  1247.       else j=290;
  1248.       if(k>89) RectFill(rp2,j,k,j,k+5);
  1249.       if(k>89) RectFill(rp2,j+7,k,j+7,k+5);
  1250.       k=ReadPixel(rp2,kkeep-npxdf,lmark[2]);
  1251.       SetAPen(rp2,k);
  1252.       k=90+6*(k-2);
  1253.       if(k>174) {k-=90;j=298;}
  1254.       else j=290;
  1255.       if(k>89) RectFill(rp2,j,k,j,k+5);
  1256.       k=ReadPixel(rp2,kkeep+npxdf,lmark[2]);
  1257.       SetAPen(rp2,k);
  1258.       k=90+6*(k-2);
  1259.       if(k>174) {k-=90;j=298;}
  1260.       else j=290;
  1261.       if(k>89) RectFill(rp2,j+7,k,j+7,k+5);
  1262.    }else if(kkeep){
  1263.       j=lmark[2];
  1264.       for(k=2,ckp=ckeep;k<4;++k){
  1265.          SetAPen(rp2,*ckp++);WritePixel(rp2,kkeep+k,j);
  1266.          SetAPen(rp2,*ckp++);WritePixel(rp2,kkeep,j+k);
  1267.          SetAPen(rp2,*ckp++);WritePixel(rp2,kkeep-k,j);
  1268.          SetAPen(rp2,*ckp++);WritePixel(rp2,kkeep,j-k);
  1269.       }
  1270.       SetAPen(rp2,0);
  1271.       RectFill(rp2,74,0,319,8);
  1272.       RectFill(rp2,290,90,290,179);
  1273.       RectFill(rp2,297,90,298,179);
  1274.       RectFill(rp2,305,90,305,179);
  1275.    }
  1276. }
  1277. /*******************************************************************/
  1278. /* fast fourier transform subroutine */
  1279. int fftcr(x,nt)
  1280. float *x;
  1281. int nt;
  1282. {
  1283.    static short *mf=NULL,nb,ib,na,n2a,n4a,ia,ie;
  1284.    static int ne,nf,ns,ntp=-1;
  1285.    register short i,j,k,l;
  1286.    static float *sine=NULL,rk,sk,fr,fs,gr,gs,hr,hs;
  1287.    register float *ri,*si,*rh,*sh;
  1288.    static double pi,w,dw;
  1289.  
  1290.    if(nt!=ntp){
  1291.       pi=4.*atan(1.);
  1292.       ntp=0;
  1293.       if(mf) free((char *)mf);
  1294.       if(sine) free((char *)sine);
  1295.       if(nt<4||nt>16) return(4);
  1296.       ne=nt-1;
  1297.       for(i=1,ns=1;i<ne;++i) ns+=ns;
  1298.       nf=ns+ns;
  1299.       if((mf=(short *)calloc(2,nf))==NULL) return(1);
  1300.       if((sine=(float *)calloc(4,ns+1))==NULL) return(2);
  1301.       sine[0]=0.;
  1302.       dw=-pi/nf;
  1303.       for(i=1,w=dw;i<ns;++i,w+=dw)
  1304.          sine[i]=sin(w);
  1305.       sine[ns]=-1.;
  1306.       for(k=0;k<nf;++k){
  1307.          for(i=ns,j=1,l=0;i;i>>=1,j<<=1)
  1308.             if(j&k) l|=i;
  1309.          mf[k]=l;
  1310.       }
  1311.       ntp=nt;
  1312.    }
  1313.  
  1314.    na=ns;n2a=nf;n4a=4*na;
  1315.    nb=1;
  1316.    for(ie=0;ie<ne;++ie){
  1317.       for(ib=0,i=0;ib<nb;++ib,i+=n4a){
  1318.          k=mf[ib];
  1319.          if(k>ns){
  1320.             rk=sine[k-ns];
  1321.             sk=sine[nf-k];
  1322.          }
  1323.          else{
  1324.             rk=-sine[ns-k];
  1325.             sk=sine[k];
  1326.          }
  1327.          ri=x+i;
  1328.          si=ri+1;
  1329.          rh=ri+n2a;
  1330.          sh=rh+1;
  1331.          for(ia=0;ia<na;++ia){
  1332.             gr=*rh*rk-*sh*sk;
  1333.             gs=*rh*sk+*sh*rk;
  1334.             *rh=*ri-gr;
  1335.             *sh=*si-gs;
  1336.             *ri=*ri+gr;
  1337.             *si=*si+gs;
  1338.             ri+=2;
  1339.             si+=2;
  1340.             rh+=2;
  1341.             sh+=2;
  1342.          }
  1343.       }
  1344.       na>>=1;
  1345.       n2a>>=1;
  1346.       n4a>>=1;
  1347.       nb<<=1;
  1348.    }
  1349.    /* unscramble */
  1350.    for(j=0;j<nf;++j){
  1351.       k=mf[j];
  1352.       if(k>j){
  1353.          ri=x+(j<<1);
  1354.          si=ri+1;
  1355.          rh=x+(k<<1);
  1356.          sh=rh+1;
  1357.          gr=*ri;
  1358.          gs=*si;
  1359.          *ri=*rh;
  1360.          *si=*sh;
  1361.          *rh=gr;
  1362.          *sh=gs;
  1363.       }
  1364.    }
  1365.    /* rearrange for real input */
  1366.    ri=x+2;
  1367.    si=ri+1;
  1368.    rh=x+2*(nf-1);
  1369.    sh=rh+1;
  1370.    for(k=1;k<ns;++k){
  1371.       gr=*ri+*rh;
  1372.       gs=*si+*sh;
  1373.       hr=*ri-*rh;
  1374.       hs=*si-*sh;
  1375.       rk=sine[ns-k];
  1376.       sk=sine[k];
  1377.       fr=rk*gs-sk*hr;
  1378.       *ri=gr-fr;
  1379.       *rh=gr+fr;
  1380.       fs=sk*gs+rk*hr;
  1381.       *si=hs+fs;
  1382.       *sh=fs-hs;
  1383.       ri+=2;
  1384.       si+=2;
  1385.       rh-=2;
  1386.       sh-=2;
  1387.    }
  1388.    *ri=2.**ri;
  1389.    *si=-2.**si;
  1390.    ri=x;
  1391.    si=ri+1;
  1392.    gr=*ri+*si;
  1393.    *si=*ri-*si;
  1394.    *ri=gr;
  1395.    return(0);
  1396. }
  1397. /**************************************/
  1398. int play(smp,nsm,ism)
  1399. BYTE *smp; /* pointer to sound array (word aligned, chip access) */
  1400. int nsm;   /* length of smp (in bytes; even) */
  1401. int ism;   /* sound sample interval (clock periods of 279.365 ns) */
  1402. {
  1403.    struct IOAudio *ioa0=NULL;
  1404.    struct MsgPort *msg0=NULL;
  1405.    int ie; /* error code */
  1406.    static BYTE alr[]={1}; /* allocation mask for channel 0 */
  1407.    
  1408.    ioa0=(struct IOAudio *)calloc(sizeof(struct IOAudio),1);
  1409.    ie=1;if(ioa0==NULL) goto exitplay;
  1410.    msg0=(struct MsgPort *)CreatePort("play0",0);
  1411.    ie=2;if(msg0==NULL) goto exitplay;
  1412.    ioa0->ioa_Data=alr;
  1413.    ioa0->ioa_Length=1;
  1414.    ioa0->ioa_Request.io_Message.mn_Node.ln_Pri=127; /* maximum */
  1415.    ioa0->ioa_Request.io_Message.mn_ReplyPort=msg0;
  1416.    ie=3;if(OpenDevice("audio.device",0,ioa0,0)!=0) goto exitplay;
  1417.    ioa0->ioa_Data=smp;
  1418.    ioa0->ioa_Length=nsm;
  1419.    ioa0->ioa_Period=ism;
  1420.    ioa0->ioa_Volume=64; /* maximum */
  1421.    ioa0->ioa_Cycles=1;  /* once thru */
  1422.    ioa0->ioa_Request.io_Command=CMD_WRITE;
  1423.    ioa0->ioa_Request.io_Flags=ADIOF_PERVOL;
  1424.    BeginIO(ioa0);
  1425.    WaitIO(ioa0);
  1426.    ie=0;
  1427. exitplay:
  1428.    if(msg0) DeletePort(msg0);
  1429.    if(ioa0){
  1430.       if(ioa0->ioa_Request.io_Device) CloseDevice(ioa0);
  1431.       free((char *)ioa0);
  1432.    }
  1433.    return(ie);
  1434. }
  1435.