add: CallDebug( audioctrl, 5 );
context: MixGeneric ( REG(a0, struct Hook *Hook),              REG(a1, void *dst),              REG(a2, struct AHIPrivAudioCtrl *audioctrl) )#elsevoidMixGeneric ( struct Hook *Hook,              void *dst,              struct AHIPrivAudioCtrl *audioctrl )#endif{  struct AHIChannelData	*cd;  void                  *dstptr;  LONG                   samplesleft;  /* Clear the buffer */  memset(dst, 0, audioctrl->ahiac_BuffSizeNow);  /* Mix the samples */  audioctrl->ahiac_WetOrDry = AHIEDM_WET;  cd = audioctrl->ahiac_WetList;  while(TRUE)  {    while(cd != NULL) // .nextchannel    {      samplesleft = audioctrl->ac.ahiac_BuffSamples;      dstptr      = dst;      while(TRUE) // .contchannel      {        /* Call Sound Hook */        if(cd->cd_EOS)        {          cd->cd_EOS = FALSE;          if(audioctrl->ac.ahiac_SoundFunc != NULL)          {#if defined( VERSIONPOWERUP )            audioctrl->ahiac_ChannelNo = cd->cd_ChannelNo;            CallSoundHook( audioctrl );#else            CallHookPkt( audioctrl->ac.ahiac_SoundFunc,                         audioctrl,                         &cd->cd_ChannelNo);#endif          }        }        if(cd->cd_FreqOK && cd->cd_SoundOK)        {          if(cd->cd_AddRoutine == NULL)          {            break;  // Panic! Should never happen.          }          if(samplesleft >= cd->cd_Samples)          {            samplesleft -= cd->cd_Samples;            /* Call AddRoutine (cd->cd_Samples) */            CallAddRoutine(cd->cd_Samples, &dstptr, cd, audioctrl);            /* Linear interpol. stuff */            cd->cd_LastSampleL = cd->cd_TempLastSampleL;            cd->cd_LastSampleR = cd->cd_TempLastSampleR;            /* Give AHIST_INPUT special treatment! */            if(cd->cd_Type & AHIST_INPUT)            {              // Screw it... I doesn't work anyway.              continue; // .contchannel            }            /*            ** Offset always points OUTSIDE the sample after this            ** call.  Ie, if we read a sample at offset (Offset.I)            ** now, it does not belong to the sample just played.            ** This is true for both backward and forward mixing.            */            /* What we do now is to calculate how much futher we have               advanced. */              cd->cd_Offset -= cd->cd_LastOffset;            /*            ** Offset should now be added to the NEXT Offset. Offset            ** is positive of the sample was mixed forwards, and            ** negative if the sample was mixed backwards.  There is            ** one catch, however.  If the direction is about to            ** change now, Offset should instead be SUBTRACTED.            ** Let's check:            */            if( (cd->cd_Type ^ cd->cd_NextType) & AHIST_BW )            {              cd->cd_Offset = -cd->cd_Offset;            }            cd->cd_Offset += cd->cd_NextOffset;            cd->cd_FirstOffsetI = cd->cd_Offset >> 32;            /*            ** But what if the next sample is so short that we just            ** passed it!?  Here is the nice part.  CalcSamples            ** checks this, and sets cd_Samples to 0 in that case.            ** And the add routines doesn't do anything when asked to            ** mix 0 samples.  Assume we have passed a sample with 4            ** samples, and the next one is only 3.  CalcSamples            ** returns 0.  The (ADDFUNC) call above does not do            ** anything at all, OffsetI is still 4.  Now we subtract            ** LastOffsetI, which is 3.  Result:  We have passed the            ** sample with 1.  And guess what?  That's in range.            */            /* Now, let's copy the rest of the cd_Next#? stuff... */            cd->cd_FreqOK        = cd->cd_NextFreqOK;            cd->cd_SoundOK       = cd->cd_NextSoundOK;            cd->cd_Add           = cd->cd_NextAdd;            cd->cd_DataStart     = cd->cd_NextDataStart;            cd->cd_LastOffset    = cd->cd_NextLastOffset;            cd->cd_ScaleLeft     = cd->cd_NextScaleLeft;            cd->cd_ScaleRight    = cd->cd_NextScaleRight;            cd->cd_AddRoutine    = cd->cd_NextAddRoutine;            cd->cd_VolumeLeft    = cd->cd_NextVolumeLeft;            cd->cd_VolumeRight   = cd->cd_NextVolumeRight;            cd->cd_Type          = cd->cd_NextType;            cd->cd_Samples = CalcSamples( cd->cd_Add,                                          cd->cd_Type,                                          cd->cd_LastOffset,                                          cd->cd_Offset );            cd->cd_EOS = TRUE;      // signal End-Of-Sample            continue;               // .contchannel (same channel, new sound)          }          else          {            // .wont_reach_end            cd->cd_Samples -= samplesleft;                      /*** Call AddRoutine (samplesleft) ***/            CallAddRoutine(samplesleft, &dstptr, cd, audioctrl);          }        } // FreqOK && SoundOK        break; // .contchannel      } // while(TRUE)      cd = cd->cd_Succ;    } // while(cd)    if(audioctrl->ahiac_WetOrDry == AHIEDM_WET)    {      audioctrl->ahiac_WetOrDry = AHIEDM_DRY;      /*** AHIET_DSPECHO ***/      if(audioctrl->ahiac_EffDSPEchoStruct != NULL)      {        audioctrl->ahiac_EffDSPEchoStruct->ahiecho_Code(            audioctrl->ahiac_EffDSPEchoStruct, dst, audioctrl);      }      cd = audioctrl->ahiac_DryList;      if(audioctrl->ac.ahiac_Flags & AHIACF_POSTPROC)      {        /*** AHIET_MASTERVOLUME ***/        DoMasterVolume(dst, audioctrl);        /*        ** When AHIACB_POSTPROC is set, the dry data shall be placed        ** immediate after the wet data. This is done by modifying the        ** dst pointer        */        dst = (char *) dst + audioctrl->ac.ahiac_BuffSamples *                              AHI_SampleFrameSize(audioctrl->ac.ahiac_BuffType);      }      continue; /* while(TRUE) */    }    else    {      break; /* while(TRUE) */    }  } // while(TRUE)  /*** AHIET_MASTERVOLUME ***/  DoMasterVolume(dst, audioctrl);#if !defined( VERSIONPOWERUP )  // This is handled in m68k code, in order to minimize cache flushes.  /*** AHIET_OUTPUTBUFFER ***/  DoOutputBuffer(dst, audioctrl);  /*** AHIET_CHANNELINFO ***/  DoChannelInfo(audioctrl);#endif /* !defined( VERSIONPOWERUP ) */  return;}