#define SAMPLING 4
#define ON TRUE
#define OFF FALSE
extern struct NewWindow NewRequestWindow;
extern struct Window *RequestWindow,*MyWindow;
extern struct Gadget GGContinue;
extern struct IntuiText TextWindow;
extern USHORT LinesReq1[];
extern USHORT LinesReq2[];
extern struct Border BorderReq2;
extern struct Window *DisplayWindow;

extern void IntHandler();

struct SoundParts { UWORD Length;
                    APTR Location;
                    struct SoundParts *NextOne; };

struct SoundParts *FirstSoundPart[4];
struct IntVariables { struct SoundParts *CurrentSoundPart;
                      BOOL *Modus;
                      UWORD *IntCount;
                      UWORD *CurrentInt; } IntVariables[4];

extern ULONG  start[5],end[4],length[5],allocated[4],regstart,regend,posbackup;
extern ULONG  oneshot[4],startpos[4],class,ChunkID,ChunkLength,counter[4],countpos;
extern UBYTE  i,Current,track;
extern UWORD  sample,rest,x1,y1;
extern UBYTE  rate,hi,current,x,y,currenty[4];
extern UWORD  CurrentInt[4],IntCount[4];
extern UWORD  mask[4];
extern UWORD  AudioBits;
extern BOOL PLAYING,Status[4],Modus[4];
extern ULONG volume[5],period[5],samplingrate[4];
extern ULONG MyFile;
extern FILE *MYFILE;
extern struct RastPort *RastPort;

extern ULONG *parameter[6],*parapointer;
extern ULONG PotiStart[6];
extern ULONG PotiDiv[6];
extern ULONG MaxiPart[6];
extern ULONG MaxValue[6];
extern ULONG SetValue,Divisor;

extern char BufferStart[4][7];
extern char BufferLength[4][7];
extern char BufferPeriod[4][4];
extern char BufferRate[4][6];
extern char BufferShot[4][7];
extern char BufferVolume[4][3];
extern char Not_Allocated[];

extern struct Gadget *TempLength[4];
extern struct Gadget *TempVolume[4];
extern struct Gadget *TempPeriod[4];
extern struct Gadget *TempRate[4];
extern struct Gadget *TempOneShot[4];
extern struct Gadget *TempCount[4];
extern struct Gadget *TempShotLength[4];

extern struct IntuiText TextFreeMem;
extern struct IntuiText TextOn;
extern struct IntuiText TextOFF;
extern struct IntuiText TextCurrent[4];

extern ULONG FORM_ID;
extern ULONG _8SVX_ID;
extern ULONG VHDR_ID;
extern ULONG NAME_ID;
extern ULONG AUTH_ID;
extern ULONG ANNO_ID;
extern ULONG C_ID;
extern ULONG BODY_ID;

struct VHDR { ULONG Length;
              ULONG OneShotHiSamples;
              ULONG RepeatPart;
              ULONG SamplesPerHiCycle;
              UWORD SamplesPerSecond;
              UBYTE Octaves;
              UBYTE Packed;
              ULONG Volume; };

struct FSound { ULONG length;
                UWORD samplingrate; };

struct BODY { ULONG BODY_ID;
              ULONG Length; };

struct IFF { ULONG FORM_ID;
             ULONG Length;
             ULONG _8SVX_ID;
             ULONG VHDR_ID;
             struct VHDR VHDR;
             struct BODY BODY; };

extern struct FSound FSound;
extern struct VHDR VHDR;
extern struct IFF *IFF;

extern struct GfxBase *GfxBase;
extern struct IntuitionBase *IntuitionBase;
struct Custom *CustomBase=0xdff000;
extern struct PropInfo OneShotInfo[4];

DisplayRequest(Text)

 char *Text;

{
 WindowRequest(Text,&GGContinue);
}

WindowRequest(Text,MyGadget)

 char *Text;
 struct Gadget *MyGadget;

{
 UWORD pixels;
 struct RastPort *RPort;
 struct IntuiMessage *ThisMsg;
 struct Gadget *ThisGadget;
 USHORT width,left,between;

 pixels=strlen(Text) * 8 + 40;
 NewRequestWindow.FirstGadget=ThisGadget=MyGadget;
 NewRequestWindow.LeftEdge=(640-pixels)/2;
 NewRequestWindow.Width=pixels;
 TextWindow.IText=Text;
 TextWindow.TopEdge=NewRequestWindow.Height/2-4;
 TextWindow.LeftEdge=20;
 LinesReq1[2]=pixels-1;
 LinesReq2[2]=pixels-4;
 LinesReq1[4]=pixels-1;
 LinesReq2[4]=pixels-4;
 if (MyGadget)
    {
     TextWindow.TopEdge=5;
     width=MyGadget->Width;
     if (ThisGadget->NextGadget) between=ThisGadget->NextGadget->LeftEdge-ThisGadget->LeftEdge;
     while (ThisGadget->NextGadget)
           {
            width += between;
            ThisGadget = ThisGadget->NextGadget;
           }
     ThisGadget=MyGadget;
     left=(pixels-width)/2;
     do
        {
         ThisGadget->LeftEdge=left;
         left += between;
         ThisGadget = ThisGadget->NextGadget;
        }
     while (ThisGadget);
    }
 if (!(RequestWindow=OpenWindow(&NewRequestWindow))) return;
 RPort=RequestWindow->RPort;
 SetRast(RPort,0);
 if (MyGadget) RefreshGadgets(MyGadget,RequestWindow,0);
 PrintIText(RPort,&TextWindow,0,0);
 DrawBorder(RPort,&BorderReq2,0,0);
 if (!MyGadget) return;
 WaitPort(RequestWindow->UserPort);
 ThisMsg=GetMsg(RequestWindow->UserPort);
 CloseWindow(RequestWindow);
 return(((struct Gadget *)ThisMsg->IAddress)->GadgetID);
}

DisplayFreeMem()
{
 ULONG FreeMem;

 Forbid();
 FreeMem=AvailMem(MEMF_CHIP);
 Permit();
 Number_to_String(TextFreeMem.IText,FreeMem,5);
 PrintIText(RastPort,&TextFreeMem,0,0);
}

Number_to_String(Buffer,number,len)

 char *Buffer;
 ULONG number;
 UBYTE len;

{
 UBYTE count,count1;

 for (count=0;count<=len;count++)
      {
       Buffer[len-count]=48+number%10;
       number = number/10;
      }
 count=0;
 while ((Buffer[0]==48) && (count<len))
        {
         for (count1=0;count1<=len-count;count1++) Buffer[count1]=Buffer[count1+1];
         count++;
        }
}

BYTE FreeTrack()
{
 BYTE i;

 for (i=0;i<=3;i++)
       if (!start[i]) return(i);
 DisplayRequest("There's no free track!");
 return(4);
}

BYTE Memory(channel,amout)

 UBYTE channel;
 ULONG amout;

{
 if (!(start[channel]=AllocMem(amout,MEMF_CHIP|MEMF_CLEAR)))
    {
     DisplayRequest("Not enough chip memory!");
     AudioBits &= (mask[channel]^15);
     SetStatus(channel);
     return(FALSE);
    }
 length[channel]=allocated[channel]=end[channel]=amout;
 startpos[channel]=0;
 MaxiPart[0]=MaxiPart[1]=(100*allocated[channel])/128;
 MaxiPart[5]=(100*length[channel])/128;
 DisplayFreeMem();
 Number_to_String(BufferLength[channel],amout,5);
 OnlyRefresh(TempLength[channel],MyWindow);
 return(TRUE);
}

ClearTrack(Channel)

 UBYTE Channel;

{
 FreeMem(start[Channel],allocated[Channel]);
 DisplayFreeMem();
 allocated[Channel]=start[Channel]=end[Channel]=startpos[Channel]=length[Channel]=0;
 for (i=0;i<=6;i++) BufferLength[Channel][i]=" empty"[i];
 OnlyRefresh(TempLength[Channel],MyWindow);
 for (i=0;i<=6;i++) BufferStart[Channel][i]=" begin"[i];
 OnlyRefresh(TempCount[Channel],MyWindow);
 AudioBits &= ( mask[Channel] ^ 15 );
 SetStatus(Channel);
}

BOOL LoadIFF()
{
 ULONG Length;
 UBYTE nothing;
 ULONG ChunkID;

 Read(MyFile,&ChunkID,4);
 if (ChunkID != FORM_ID)
    {
     DisplayRequest("This is not an IFF file!");
     Close(MyFile);
     return(FALSE);
    }
 Read(MyFile,&Length,4);
 Read(MyFile,&ChunkID,4);
 if (ChunkID != _8SVX_ID)
    {
     DisplayRequest("This is IFF, but not IFF 8SVX!");
     Close(MyFile);
     return(FALSE);
    }
 do
   {
    Read(MyFile,&ChunkID,4);
    if (ChunkID == VHDR_ID) Read(MyFile,&VHDR,sizeof(struct VHDR));
    if ((ChunkID != VHDR_ID) && (ChunkID != BODY_ID) )
       {
        Read(MyFile,&Length,4);
        if (Length % 2) Length+=1;
        for (i=0;i<Length;i++) Read(MyFile,&nothing,1);
       }
   }
 while (ChunkID != BODY_ID);
}

SaveIFF()
{
 UBYTE i;
 ULONG BodyLength;

 BodyLength=length[track];
 IFF->VHDR.Length=20;
 IFF->VHDR.OneShotHiSamples=oneshot[track]>>4;
 IFF->VHDR.RepeatPart=(length[track]-oneshot[track])>>4;
 IFF->VHDR.SamplesPerHiCycle=4;
 IFF->VHDR.SamplesPerSecond=samplingrate[track];
 IFF->VHDR.Octaves=5;
 IFF->VHDR.Packed=0;
 IFF->VHDR.Volume=65536;
 IFF->FORM_ID=FORM_ID;
 IFF->_8SVX_ID=_8SVX_ID;
 IFF->VHDR_ID=VHDR_ID;
 IFF->BODY.BODY_ID=BODY_ID;
 IFF->BODY.Length=BodyLength;
 for (i=0;i<4;i++)
      {
       BodyLength/=2;
       IFF->BODY.Length+=BodyLength;
      }
 IFF->Length=sizeof(struct IFF)+IFF->BODY.Length-8;
 fwrite(IFF,sizeof(struct IFF),1,MYFILE);
}

InitPeriod(Number)

 UWORD Number;

{
 samplingrate[track]=Number;
 if (Number)  period[track]=3580000/Number;
 Number_to_String(BufferPeriod[track],period[track],2);
 OnlyRefresh(TempPeriod[track],MyWindow);
 Number_to_String(BufferRate[track],samplingrate[track],4);
 OnlyRefresh(TempRate[track],MyWindow);
}

GoodBye()
{
 Stop();
 if (MyWindow) { ClearMenuStrip(MyWindow);
                  CloseWindow(MyWindow); }
 if ( GfxBase) CloseLibrary(GfxBase);
 if (IntuitionBase) CloseLibrary(IntuitionBase);
 for (i=0;i<=3;i++)
      {
       if (start[i]) FreeMem(start[i],allocated[i]);
      }
 exit();
}

Record(start,end)

 ULONG start,end;

{
 ULONG OldStack;

 rate=period[Current]/5;
 SoundOn(4);
 Disable();
 Forbid();
 OldStack=SuperState();
 regstart=start;
 regend=end;
 
#asm
         movem.l d0/d1/d2/a1/a2,-(a7)
         move.b  #%00000000,$bfe301
         move.b  $bfd200,d0
         andi.b  #%11111010,d0
         ori.b   #%00000100,d0
         move.b  d0,$bfd200
         move.l  _regstart,a1
         move.l  _regend,a2
         move.b  _rate,$bfd400
         move.b  #0,$bfd500
         move.b  #%01111110,$bfdd00
         move.b  #%10000001,$bfdd00
         move.b  #%10010101,$bfde00
         clr.l   d0
digit1:  andi.b  #%00000001,$bfdd00
         beq.s   digit1
         move.b  $bfe101,d0
         ori.b   #%00000100,$bfd000
         andi.b  #%11111011,$bfd000
         eori.b  #128,d0
         move.b  d0,_sample
         move.b  d0,_sample+1
         move.b  d0,(a1)+
         cmpa.l  a1,a2
         bne     digit1
mouse1:  andi.b  #64,$bfe001
         beq     mouse1
         movem.l (a7)+,d0/d1/d2/a1/a2
#endasm

 UserState(OldStack);
 Permit();
 Enable();
 SoundOFF(0);
}

Adjust()
{
 rate=period[Current]/5;
 Stop();
 SoundOn(4);
 Disable();
 Forbid();
 
#asm
         movem.l d0/d1/d2/a1/a2,-(a7)
         move.b  #%00000000,$bfe301
         move.b  $bfd200,d0
         andi.b  #%11111010,d0
         ori.b   #%00000100,d0
         move.b  d0,$bfd200
         lea     Block,a1
         move.l  #0,d0
set:     move.w  #8,(a1,d0)
         add.w   #2,d0
         cmp.w   #512,d0
         bne.s   set
         move    #0,Block
         move    #$0f00,Block+254
         move    #$0f00,Block+256
         move.b  _rate,$bfd400
         move.b  #0,$bfd500
         move.b  #%01111110,$bfdd00
         move.b  #%10000001,$bfdd00
         move.b  #%10010101,$bfde00
         clr.l   d0
adigit1: andi.b  #%00000001,$bfdd00
         beq.s   adigit1
         ori.b   #%00000100,$bfd000
         andi.b  #%11111011,$bfd000
abusy1:  andi.b  #%00000001,$bfd000
         beq.s   abusy1
         clr.l   d0
         move.b  $bfe101,d0
         eori.b  #128,d0
         move.b  d0,_sample
         move.b  d0,_sample+1
         asl     #1,d0
         move.w  (a1,d0),$dff180
         andi.b  #64,$bfe001
         bne     adigit1
amouse1: andi.b  #64,$bfe001
         beq     amouse1
         movem.l (a7)+,d0/d1/d2/a1/a2
         global  Block,512
#endasm

 Permit();
 Enable();
 SoundOFF(0);
}

Test()
{
 ULONG OldStack;

 rate=period[Current]/5;
 SoundOn(4);
 Disable();
 Forbid();
 OldStack=SuperState();

#asm
         movem.l d0/d1/d2,-(a7)
         move.b  #%00000000,$bfe301
         move.b  $bfd200,d0
         andi.b  #%11111010,d0
         ori.b   #%00000100,d0
         move.b  d0,$bfd200
         move.b  _rate,$bfd400
         move.b  #0,$bfd500
         move.b  #%01111110,$bfdd00
         move.b  #%10000001,$bfdd00
         move.b  #%10010101,$bfde00
         clr     d0
digit:   andi.b  #%00000001,$bfdd00
         beq.s   digit
         ori.b   #%00000100,$bfd000
         andi.b  #%11111011,$bfd000
busy:    andi.b  #%00000001,$bfd000
         beq     busy
         move.b  $bfe101,d0
         eori.b  #128,d0
         move.b  d0,_sample
         move.b  d0,_sample+1
         andi.b  #64,$bfe001
         bne     digit
mouse:   andi.b  #64,$bfe001
         beq     mouse
         movem.l (a7)+,d0/d1/d2
#endasm

 UserState(OldStack);
 Permit();
 Enable();
 SoundOFF(0);
}

WaitSound()
{
 Forbid();
 Disable();

#asm
         move.b  #%00000000,$bfe301
         move.b  $bfd200,d0
         andi.b  #%11111010,d0
         ori.b   #%00000100,d0
         move.b  d0,$bfd200
         move.b  #0,d1
wait1:   ori.b   #%00000100,$bfd000
         andi.b  #%11111011,$bfd000
wait:    andi.b  #%00000001,$bfd000
         beq     wait
         move.b  $bfe101,d0
         andi.b  #127,d0
         asr.b   #2,d0
         beq.s   wait1
         cmp.b   #31,d0
         beq.s   wait1

#endasm

 Permit();
 Enable();
}

SoundOn(Channel)

 UBYTE Channel;

{
 if (Channel==SAMPLING)
     {
      CustomBase->aud[0].ac_ptr=&sample;
      CustomBase->aud[0].ac_len=1;
      CustomBase->aud[0].ac_per=124;
      CustomBase->aud[0].ac_vol=64;
      CustomBase->dmacon=DMAF_SETCLR|1;
      return;
     }
 InitSoundPart(Channel);
 CustomBase->aud[Channel].ac_vol=(UWORD)volume[Channel];
 CustomBase->aud[Channel].ac_per=(UWORD)period[Channel];
 CurrentInt[Channel]=0;
 CustomBase->intreq=INTF_SETCLR|(mask[Channel]<<7);
 CustomBase->intena=INTF_SETCLR|(mask[Channel]<<7);
 CustomBase->dmacon=DMAF_MASTER|DMAF_SETCLR|mask[Channel];
}

SoundOFF(Channel)

 UBYTE Channel;

{
 CustomBase->intena=mask[Channel]<<7;
 CustomBase->dmacon = mask[Channel];
}

Play()
{
 for (i=0;i<4;i++)
      {
       if(AudioBits&mask[i]) SoundOn(i);
      }
 PLAYING=TRUE;
}

Stop()
{
 for (i=0;i<4;i++) SoundOFF(i);
 PLAYING=FALSE;
}

Reverse(Channel)

 UBYTE Channel;

{
 register UBYTE *s,*e;
 register UBYTE swap;

 s=(UBYTE *)(start[Channel]+startpos[Channel]);
 e=(UBYTE *)(start[Channel]+end[Channel]);

 do
   {
    swap=*s;
    *s++=*e;
    *e--=swap;
   }
 while (e>s);
}

Copy(Channel)

 UBYTE Channel;

{
 register UBYTE *s1,*s2;
 register ULONG e;

 s1=(UBYTE *)(start[Current]+startpos[Current]);
 s2=(UBYTE *)(start[Channel]+startpos[Channel]);
 e=start[Current]+end[Current];

 while (e>s1) *s2++=*s1++;
}

Mix(Channel)

 UBYTE Channel;

{
 register char *s1,*s2;
 register ULONG e;

 s1=(char *)(start[Current]+startpos[Current]);
 s2=(char *)(start[Channel]+startpos[Channel]);
 e=MIN(length[Current],length[Channel]);

 while (e--) *s2++=( *s2 + *s1++)>>1;
}

BOOL Concat(Source,Dest)

 UBYTE Source,Dest;

{
 register char *s,*s2;
 register ULONG e;
 ULONG NewStart,NewLength;

 NewLength=length[Source]+allocated[Dest];
 if (!(NewStart=AllocMem(NewLength,MEMF_CHIP|MEMF_CLEAR))) return(FALSE);
 s2=NewStart;
 s=start[Dest];
 e=0;
 do {
     *s2++=*s++;
     e++;
    } while (e!=allocated[Dest]);
 s=start[Source]+startpos[Source];;
 e=0;
 do {
     *s2++=*s++;
     e++;
    } while (e!=length[Source]);
 FreeMem(start[Dest],allocated[Dest]);
 DisplayFreeMem();
 start[Dest]=NewStart;
 allocated[Dest]=NewLength;
 RefreshOneShot(Dest);
 return(TRUE);
}

SetStatus(Number)

 UBYTE Number;

{
 SetDrMd(RastPort,JAM2);
 if (AudioBits & mask[Number])
     {
      SetAPen(RastPort,0);
      RectFill(RastPort,114+Number*132,50,114+Number*132+24,57);
      PrintIText(RastPort,&TextOn,118+Number*132,50);
      if (PLAYING) SoundOn(Number);
      Status[Number]=ON;
     }
 else
     {
      PrintIText(RastPort,&TextOFF,114+Number*132,50);
      if (PLAYING) SoundOFF(Number);
      Status[Number]=OFF;
     }
}

WriteBody(Octaves)

 UBYTE Octaves;

{
 ULONG Count;
 char i,DataPart;
 SHORT sum;
 char *DataStart;
 ULONG DataLength;

 WindowRequest("Saving track...",0);
 DataLength=length[track];
 DataPart=1<<(Octaves-1);
 DataLength>>=(Octaves-1);
 while (DataPart)
        {
         DataStart=start[track]+startpos[track];
         for (Count=0;Count<DataLength;Count++)
              {
               sum=0;
               for (i=0;i<DataPart;i++) sum += *DataStart++;
               putc((char)(sum/DataPart),MYFILE);
              }
         DataPart>>=1;
         DataLength<<=1;
        }
 fclose(MYFILE);
 CloseWindow(RequestWindow);
}

LoadBody()
{
 WindowRequest("Loading file...",0);
 Read(MyFile,start[track],length[track]);
 Close(MyFile);
 CloseWindow(RequestWindow);
 AudioBits |= mask[track];
 SetStatus(track);
}

BOOL AllocationCheck(Channel)

 UBYTE Channel;

{
 if (!start[Channel])
    {
     for (i=0;i<=6;i++) BufferStart[Channel][i]=" begin"[i];
     OnlyRefresh(TempCount[Channel],MyWindow);
     for (i=0;i<=6;i++) BufferLength[Channel][i]=" empty"[i];
     OnlyRefresh(TempLength[Channel],MyWindow);
     Not_Allocated[6]=49+Channel;
     DisplayRequest(Not_Allocated);
     return(FALSE);
    }
 return(TRUE);
}

SelectTrack(Number)

 UBYTE Number;

{
 SetDrMd(RastPort,COMPLEMENT);
 RectFill(RastPort,105+Current*132,34,105+Current*132+39,44);
 Current=Number;
 if (Current==4) Current=0;
 RectFill(RastPort,105+Current*132,34,105+Current*132+39,44);
 PrintIText(RastPort,&TextCurrent[Current],79,11);
}

SetVolume(Number,Volume)

 UBYTE Number;
 ULONG Volume;

{
 if (Volume>64)
    {
     Number_to_String(BufferVolume[Number],volume[Number],1);
     OnlyRefresh(TempVolume[Number],MyWindow);
     return;
    }
 volume[Number]=Volume;
 Number_to_String(BufferVolume[Number],volume[Number],1);
 OnlyRefresh(TempVolume[Number],MyWindow);
 CustomBase->aud[Number].ac_vol=(UWORD)volume[Number];
}

SetEnd(Number,End)

 UBYTE Number;
 ULONG End;

{
 if (!AllocationCheck(Number)) return;
 if ( End<=startpos[Number] ) End=startpos[Number]+MaxiPart[currenty[Number]]/100;
 if ( End>allocated[Number] ) End=end[Number];
 end[Number]=End;
 length[Number]=end[Number]-startpos[Number];
 Number_to_String(BufferLength[Number],end[Number],5);
 OnlyRefresh(TempLength[Number],MyWindow);
 MaxiPart[5]=100*length[Number]/128;
 if (oneshot[Number]>length[Number])
     {
      oneshot[Number]=0;
      Number_to_String(BufferShot[Number],oneshot[Number],5);
      OnlyRefresh(TempShotLength[Number],MyWindow);
     }
}

SetOneShot(Number,OneShot)

 UBYTE Number;
 ULONG OneShot;

{
 if (!AllocationCheck(Number)) return;
 if (OneShot>=length[Number]) OneShot=0;
 oneshot[Number]=OneShot;
 Number_to_String(BufferShot[Number],oneshot[Number],5);
 OnlyRefresh(TempShotLength[Number],MyWindow);
} 

SetStart(Number,Start)

 UBYTE Number;
 ULONG Start;

{
 if (!AllocationCheck(Number)) return;
 if (Start>=end[Number]) Start=end[Number]-MaxiPart[currenty[Number]]/100;
 if (Start>=allocated[Number]) Start=startpos[Number];
 startpos[Number]=Start;
 length[Number]=end[Number]-startpos[Number];
 Number_to_String(BufferStart[Number],startpos[Number],5);
 OnlyRefresh(TempCount[Number],MyWindow);
 MaxiPart[5]=100*length[Number]/128;
 if (oneshot[Number]>length[Number])
     {
      oneshot[Number]=0;
      Number_to_String(BufferShot[Number],oneshot[Number],5);
      OnlyRefresh(TempShotLength[Number],MyWindow);
     }
}

SetPeriod(Number,Period)

 UBYTE Number;
 ULONG Period;

{
 if (Period<124 || Period>999)
    {
     Number_to_String(BufferPeriod[Number],period[Number],2);
     OnlyRefresh(TempPeriod[Number],MyWindow);
     return;
    }
 period[Number]=Period;
 samplingrate[Number]=3580000/Period;
 Number_to_String(BufferRate[Number],samplingrate[Number],4 );
 OnlyRefresh(TempRate[Number],MyWindow);
 Number_to_String(BufferPeriod[Number],period[Number],2);
 OnlyRefresh(TempPeriod[Number],MyWindow);
 CustomBase->aud[Number].ac_per=(UWORD)period[Number];
}

SetRate(Number,Rate)

 UBYTE Number;
 ULONG Rate;

{
 if (Rate>28870)
     {
      DisplayRequest("Value must be less than 28871");
      Number_to_String(BufferRate[Number],Rate,4);
      OnlyRefresh(TempRate[Number],MyWindow);
      return;
     }
 if (Rate<=3583)
     {
      DisplayRequest("Value must be greater than 3583");
      Number_to_String(BufferRate[Number],Rate,4);
      OnlyRefresh(TempLength[Number],MyWindow);
      return;
     }
 samplingrate[Number]=Rate;
 period[Number]=3580000/samplingrate[Number];
 Number_to_String(BufferPeriod[Number],period[Number],2);
 OnlyRefresh(TempPeriod[Number],MyWindow);
 Number_to_String(BufferRate[Number],samplingrate[Number],4 );
 OnlyRefresh(TempRate[Number],MyWindow);
 CustomBase->aud[Number].ac_per=(UWORD)period[Number];
}

RefreshOneShot(Number)

 UBYTE Number;

{
 current=currenty[Number];
 MaxiPart[0]=MaxiPart[1]=(100*allocated[Number])/128;
 MaxiPart[5]=(100*length[Number])/128;
 Divisor=PotiDiv[current];
 parapointer=parameter[current];
 SetValue = parapointer[Number];
 SetValue -= PotiStart[current];
 SetValue *=100;
 if (MaxiPart[current]) SetValue /= MaxiPart[current];
 else SetValue=0;
 SetValue=SetValue<<Divisor;
 if (SetValue>65535) SetValue=65535;
 OneShotInfo[Number].VertPot=(UWORD)(65535-SetValue);
 OnlyRefresh(TempOneShot[Number],MyWindow);
}

InitSoundPart(Number)

 UBYTE Number;

{
 UBYTE counter=0;
 struct SoundParts *CurrentSoundPart,*OneShotPart;
 ULONG OneShot,RepeatPart;

 hi=0;
 OneShot=oneshot[Number];
 RepeatPart=length[Number]-OneShot;
 FreeSoundPart(Number);
 IntCount[Number]=0;
 DisplayFreeMem();
 FirstSoundPart[Number]=CurrentSoundPart=OneShotPart=AllocMem(10,MEMF_PUBLIC);
 CurrentSoundPart->Location=(UBYTE *)(start[Number]+startpos[Number]);
 if (OneShot)
     {
      hi=(BYTE)(OneShot/131072);
      IntCount[Number]=hi+3;
      while (hi)
            {
             hi--;
             counter++;
             CurrentSoundPart->Length=65535;
             CurrentSoundPart->NextOne=AllocMem(10,MEMF_PUBLIC);
             CurrentSoundPart=CurrentSoundPart->NextOne;
             CurrentSoundPart->Location=(UBYTE *)(start[Number]+startpos[Number]+131072*counter);
            }
      CurrentSoundPart->Length=(UWORD)((OneShot % 131072)/2);
      if (CurrentSoundPart->Length==0) CurrentSoundPart->Length=2;
      CurrentSoundPart->NextOne=OneShotPart=AllocMem(10,MEMF_PUBLIC);
      CurrentSoundPart=OneShotPart;
     }
 counter=0;
 hi=(BYTE)(RepeatPart/131072);
 if (OneShot) IntCount[Number]+=(hi+1);
 else IntCount[Number]=hi+3;
 CurrentSoundPart->Location=(UBYTE *)(start[Number]+startpos[Number]+OneShot);
 while (hi)
        {
         hi--;
         counter++;
         CurrentSoundPart->Length=65535;
         CurrentSoundPart->NextOne=AllocMem(10,MEMF_PUBLIC);
         CurrentSoundPart=CurrentSoundPart->NextOne;
         CurrentSoundPart->Location=(UBYTE *)(start[Number]+startpos[Number]+131072*counter+OneShot);
        }
 CurrentSoundPart->Length=(UWORD)((RepeatPart % 131072)/2);
 if (CurrentSoundPart->Length==0) CurrentSoundPart->Length=2;
 CurrentSoundPart->NextOne=OneShotPart;
 IntVariables[Number].CurrentSoundPart=FirstSoundPart[Number];
}

FreeSoundPart(Channel)

 UBYTE Channel;

{
 struct SoundParts *CurrentSoundPart,*NextOne;
 BYTE count;

 count=IntCount[Channel]-2;
 if (!FirstSoundPart[Channel]) return;
 CurrentSoundPart=FirstSoundPart[Channel];
 do {
     NextOne=CurrentSoundPart->NextOne;
     FreeMem(CurrentSoundPart,sizeof(struct SoundParts));
     CurrentSoundPart=NextOne;
     count--;
    } while (count);
 FirstSoundPart[Channel]=0;
}

#asm
              public _IntHandler
_IntHandler:  move     d1,$9c(a0)
              and.w    #%0000011110000000,d1
              beq.s    exit
              move.l   #$dff0a0,a0
              clr.l    d0
              move.b   #4,d0
              asr.l    #7,d1
myloop:       sub.b    #1,d0
              btst     d0,d1
              beq.s    myloop
              asl.l    #4,d0
              move.l   8(a1,d0),a5
              move.l   12(a1,d0),a0
              add.w    #1,(a0)
              cmpm.w   (a0)+,(a5)+
              bne.s    continue
              move.l   12(a1,d0),a0
              move.w   #2,(a0)
              move.l   4(a1,d0),a5
              cmp.w    #0,(a5)
              bne.s    continue
              asl.l    #7,d1
              move.w   d1,$dff09a
              move.w   d1,$dff09c
              asr.l    #7,d1
again:        and.w    #%0000000000001111,d1
              move.w   d1,$dff096
              move.w   $dff002,d0
              and.w    #%0000000000001111,d0
              and.w    d1,d0
              bne.s    again
              rts
continue:     move.l   #$dff0a0,a0
              move.l   (a1,d0),a5
              move.w   (a5),4(a0,d0)
              move.l   2(a5),(a0,d0)
              move.l   6(a5),(a1,d0)
exit:         rts

#endasm
