Esempio n. 1
0
void FormantFilter::filterout(REALTYPE *smp)
{
    int i, j;
    for(i = 0; i < SOUND_BUFFER_SIZE; i++) {
        inbuffer[i] = smp[i];
        smp[i]      = 0.0;
    }

    for(j = 0; j < numformants; j++) {
        for(i = 0; i < SOUND_BUFFER_SIZE; i++)
            tmpbuf[i] = inbuffer[i] * outgain;
        formant[j]->filterout(tmpbuf);

        if(ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j], currentformants[j].amp))
            for(i = 0; i < SOUND_BUFFER_SIZE; i++)
                smp[i] += tmpbuf[i]
                          * INTERPOLATE_AMPLITUDE(oldformantamp[j],
                                                  currentformants[j].amp,
                                                  i,
                                                  SOUND_BUFFER_SIZE);
        else
            for(i = 0; i < SOUND_BUFFER_SIZE; i++)
                smp[i] += tmpbuf[i] * currentformants[j].amp;
        oldformantamp[j] = currentformants[j].amp;
    }
}
Esempio n. 2
0
void
FormantFilter::filterout (float * smp)
{
  int i, j;
  for (i = 0; i < PERIOD; i++)
    {
      inbuffer[i] = smp[i];
      smp[i] = 0.0;
    };

  for (j = 0; j < numformants; j++)
    {
      for (i = 0; i < PERIOD; i++)
	tmpbuf[i] = inbuffer[i] * outgain;
      formant[j]->filterout (tmpbuf);

      if (ABOVE_AMPLITUDE_THRESHOLD
	  (oldformantamp[j], currentformants[j].amp))
	for (i = 0; i < PERIOD; i++)
	  smp[i] +=
	    tmpbuf[i] * INTERPOLATE_AMPLITUDE (oldformantamp[j],
					       currentformants[j].amp, i,
					       PERIOD);
      else
	for (i = 0; i < PERIOD; i++)
	  smp[i] += tmpbuf[i] * currentformants[j].amp;
      oldformantamp[j] = currentformants[j].amp;
    };
};
Esempio n. 3
0
void FormantFilter::filterout(float *smp)
{
    float inbuffer[buffersize];

    memcpy(inbuffer, smp, bufferbytes);
    memset(smp, 0, bufferbytes);

    for(int j = 0; j < numformants; ++j) {
        float tmpbuf[buffersize];
        for(int i = 0; i < buffersize; ++i)
            tmpbuf[i] = inbuffer[i] * outgain;
        formant[j]->filterout(tmpbuf);

        if(ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j], currentformants[j].amp))
            for(int i = 0; i < buffersize; ++i)
                smp[i] += tmpbuf[i]
                          * INTERPOLATE_AMPLITUDE(oldformantamp[j],
                                                  currentformants[j].amp,
                                                  i,
                                                  buffersize);
        else
            for(int i = 0; i < buffersize; ++i)
                smp[i] += tmpbuf[i] * currentformants[j].amp;
        oldformantamp[j] = currentformants[j].amp;
    }
}
Esempio n. 4
0
void FormantFilter::filterout(float *smp)
{
  int i;
  int j;

  for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
  {
    m_inbuffer[i] = smp[i];
    smp[i] = 0.0;
  }

  for (j = 0 ; j < m_numformants ; j++)
  {
    for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
    {
      m_tmpbuf[i] = m_inbuffer[i] * m_outgain;
    }

    m_formants[j].filterout(m_tmpbuf);

    if (ABOVE_AMPLITUDE_THRESHOLD(m_oldformantamp[j], m_currentformants[j].amplitude))
    {
      for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
      {
        smp[i] += m_tmpbuf[i] * INTERPOLATE_AMPLITUDE(m_oldformantamp[j], m_currentformants[j].amplitude, i, SOUND_BUFFER_SIZE);
      }
    }
    else
    {
      for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
      {
        smp[i] += m_tmpbuf[i] * m_currentformants[j].amplitude;
      }
    }

    m_oldformantamp[j] = m_currentformants[j].amplitude;
  }
}
Esempio n. 5
0
/*
 * Note Output
 */
int SUBnote::noteout(float *outl, float *outr)
{
    memcpy(outl, synth.denormalkillbuf, synth.bufferbytes);
    memcpy(outr, synth.denormalkillbuf, synth.bufferbytes);

    if(NoteEnabled == OFF)
        return 0;

    float tmprnd[synth.buffersize];
    float tmpsmp[synth.buffersize];
    //left channel
    for(int i = 0; i < synth.buffersize; ++i)
        tmprnd[i] = RND * 2.0f - 1.0f;
    for(int n = 0; n < numharmonics; ++n) {
        float rolloff = overtone_rolloff[n];
        memcpy(tmpsmp, tmprnd, synth.bufferbytes);
        for(int nph = 0; nph < numstages; ++nph)
            filter(lfilter[nph + n * numstages], tmpsmp);
        for(int i = 0; i < synth.buffersize; ++i)
            outl[i] += tmpsmp[i] * rolloff;
    }

    if(GlobalFilterL != NULL)
        GlobalFilterL->filterout(&outl[0]);

    //right channel
    if(stereo) {
        for(int i = 0; i < synth.buffersize; ++i)
            tmprnd[i] = RND * 2.0f - 1.0f;
        for(int n = 0; n < numharmonics; ++n) {
            float rolloff = overtone_rolloff[n];
            memcpy(tmpsmp, tmprnd, synth.bufferbytes);
            for(int nph = 0; nph < numstages; ++nph)
                filter(rfilter[nph + n * numstages], tmpsmp);
            for(int i = 0; i < synth.buffersize; ++i)
                outr[i] += tmpsmp[i] * rolloff;
        }
        if(GlobalFilterR != NULL)
            GlobalFilterR->filterout(&outr[0]);
    }
    else
        memcpy(outr, outl, synth.bufferbytes);

    if(firsttick != 0) {
        int n = 10;
        if(n > synth.buffersize)
            n = synth.buffersize;
        for(int i = 0; i < n; ++i) {
            float ampfadein = 0.5f - 0.5f * cosf(
                (float) i / (float) n * PI);
            outl[i] *= ampfadein;
            outr[i] *= ampfadein;
        }
        firsttick = 0;
    }

    if(ABOVE_AMPLITUDE_THRESHOLD(oldamplitude, newamplitude))
        // Amplitude interpolation
        for(int i = 0; i < synth.buffersize; ++i) {
            float tmpvol = INTERPOLATE_AMPLITUDE(oldamplitude,
                                                 newamplitude,
                                                 i,
                                                 synth.buffersize);
            outl[i] *= tmpvol * panning;
            outr[i] *= tmpvol * (1.0f - panning);
        }
    else
        for(int i = 0; i < synth.buffersize; ++i) {
            outl[i] *= newamplitude * panning;
            outr[i] *= newamplitude * (1.0f - panning);
        }

    oldamplitude = newamplitude;
    computecurrentparameters();

    // Apply legato-specific sound signal modifications
    legato.apply(*this, outl, outr);

    // Check if the note needs to be computed more
    if(AmpEnvelope->finished() != 0) {
        for(int i = 0; i < synth.buffersize; ++i) { //fade-out
            float tmp = 1.0f - (float)i / synth.buffersize_f;
            outl[i] *= tmp;
            outr[i] *= tmp;
        }
        KillNote();
    }
    return 1;
}
Esempio n. 6
0
int PADnote::noteout(float *outl, float *outr)
{
    computecurrentparameters();
    float *smps = pars->sample[nsample].smp;
    if(smps == NULL) {
        for(int i = 0; i < synth->buffersize; ++i) {
            outl[i] = 0.0f;
            outr[i] = 0.0f;
        }
        return 1;
    }
    float smpfreq = pars->sample[nsample].basefreq;


    float freqrap = realfreq / smpfreq;
    int   freqhi  = (int) (floor(freqrap));
    float freqlo  = freqrap - floor(freqrap);


    if(config.cfg.Interpolation)
        Compute_Cubic(outl, outr, freqhi, freqlo);
    else
        Compute_Linear(outl, outr, freqhi, freqlo);


    if(firsttime) {
        fadein(outl);
        fadein(outr);
        firsttime = false;
    }

    NoteGlobalPar.GlobalFilterL->filterout(outl);
    NoteGlobalPar.GlobalFilterR->filterout(outr);

    //Apply the punch
    if(NoteGlobalPar.Punch.Enabled != 0)
        for(int i = 0; i < synth->buffersize; ++i) {
            float punchamp = NoteGlobalPar.Punch.initialvalue
                             * NoteGlobalPar.Punch.t + 1.0f;
            outl[i] *= punchamp;
            outr[i] *= punchamp;
            NoteGlobalPar.Punch.t -= NoteGlobalPar.Punch.dt;
            if(NoteGlobalPar.Punch.t < 0.0f) {
                NoteGlobalPar.Punch.Enabled = 0;
                break;
            }
        }

    if(ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude, globalnewamplitude))
        // Amplitude Interpolation
        for(int i = 0; i < synth->buffersize; ++i) {
            float tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude,
                                                 globalnewamplitude,
                                                 i,
                                                 synth->buffersize);
            outl[i] *= tmpvol * NoteGlobalPar.Panning;
            outr[i] *= tmpvol * (1.0f - NoteGlobalPar.Panning);
        }
    else
        for(int i = 0; i < synth->buffersize; ++i) {
            outl[i] *= globalnewamplitude * NoteGlobalPar.Panning;
            outr[i] *= globalnewamplitude * (1.0f - NoteGlobalPar.Panning);
        }


    // Apply legato-specific sound signal modifications
    legato.apply(*this, outl, outr);

    // Check if the global amplitude is finished.
    // If it does, disable the note
    if(NoteGlobalPar.AmpEnvelope->finished() != 0) {
        for(int i = 0; i < synth->buffersize; ++i) { //fade-out
            float tmp = 1.0f - (float)i / synth->buffersize_f;
            outl[i] *= tmp;
            outr[i] *= tmp;
        }
        finished_ = 1;
    }

    return 1;
}
Esempio n. 7
0
/*
 * Note Output
 */
int SUBnote::noteout(REALTYPE *outl,REALTYPE *outr)
{
    int i;

    memcpy(outl, denormalkillbuf, SOUND_BUFFER_SIZE * sizeof(REALTYPE));
    memcpy(outr, denormalkillbuf, SOUND_BUFFER_SIZE * sizeof(REALTYPE));

    if (NoteEnabled==OFF) return(0);

    //left channel
    for (i=0;i<SOUND_BUFFER_SIZE;i++) tmprnd[i]=RND*2.0-1.0;
    for (int n=0;n<numharmonics;n++) {
        memcpy(tmpsmp, tmprnd, SOUND_BUFFER_SIZE * sizeof(REALTYPE));
        for (int nph=0;nph<numstages;nph++)
            filter(lfilter[nph+n*numstages],tmpsmp);
        for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=tmpsmp[i];
    };

    if (GlobalFilterL!=NULL) GlobalFilterL->filterout(&outl[0]);

    //right channel
    if (stereo!=0) {
        for (i=0;i<SOUND_BUFFER_SIZE;i++) tmprnd[i]=RND*2.0-1.0;
        for (int n=0;n<numharmonics;n++) {
            memcpy(tmpsmp, tmprnd, SOUND_BUFFER_SIZE * sizeof(REALTYPE));
            for (int nph=0;nph<numstages;nph++)
                filter(rfilter[nph+n*numstages],tmpsmp);
            for (i=0;i<SOUND_BUFFER_SIZE;i++) outr[i]+=tmpsmp[i];
        };
        if(GlobalFilterR != NULL)
            GlobalFilterR->filterout(&outr[0]);
    }
    else
        memcpy(outr, outl, SOUND_BUFFER_SIZE * sizeof(REALTYPE));

    if (firsttick!=0) {
        int n=10;
        if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE;
        for (i=0;i<n;i++) {
            REALTYPE ampfadein=0.5-0.5*cos((REALTYPE) i/(REALTYPE) n*PI);
            outl[i]*=ampfadein;
            outr[i]*=ampfadein;
        };
        firsttick=0;
    };

    if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude,newamplitude)) {
        // Amplitude interpolation
        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
            REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(oldamplitude
                                                  ,newamplitude,i,SOUND_BUFFER_SIZE);
            outl[i]*=tmpvol*panning;
            outr[i]*=tmpvol*(1.0-panning);
        };
    } else {
        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
            outl[i]*=newamplitude*panning;
            outr[i]*=newamplitude*(1.0-panning);
        };
    };

    oldamplitude=newamplitude;
    computecurrentparameters();

    // Apply legato-specific sound signal modifications
    if (Legato.silent) { // Silencer
        if (Legato.msg!=LM_FadeIn) {
            memset(outl, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE));
            memset(outr, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE));
		};
    };
    switch (Legato.msg) {
    case LM_CatchUp : // Continue the catch-up...
        if (Legato.decounter==-10) Legato.decounter=Legato.fade.length;
        for (i=0;i<SOUND_BUFFER_SIZE;i++) {//Yea, could be done without the loop...
            Legato.decounter--;
            if (Legato.decounter<1) {
                // Catching-up done, we can finally set
                // the note to the actual parameters.
                Legato.decounter=-10;
                Legato.msg=LM_ToNorm;
                SUBlegatonote(Legato.param.freq, Legato.param.vel, Legato.param.portamento, Legato.param.midinote, false);
                break;
            }
        }
        break;
    case LM_FadeIn : // Fade-in
        if (Legato.decounter==-10) Legato.decounter=Legato.fade.length;
        Legato.silent=false;
        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
            Legato.decounter--;
            if (Legato.decounter<1) {
                Legato.decounter=-10;
                Legato.msg=LM_Norm;
                break;
            }
            Legato.fade.m+=Legato.fade.step;
            outl[i]*=Legato.fade.m;
            outr[i]*=Legato.fade.m;
        }
        break;
    case LM_FadeOut : // Fade-out, then set the catch-up
        if (Legato.decounter==-10) Legato.decounter=Legato.fade.length;
        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
            Legato.decounter--;
            if (Legato.decounter<1) {
                for (int j=i;j<SOUND_BUFFER_SIZE;j++) {
                    outl[j]=0.0;
                    outr[j]=0.0;
                }
                Legato.decounter=-10;
                Legato.silent=true;
                // Fading-out done, now set the catch-up :
                Legato.decounter=Legato.fade.length;
                Legato.msg=LM_CatchUp;
                REALTYPE catchupfreq=Legato.param.freq*(Legato.param.freq/Legato.lastfreq);//This freq should make this now silent note to catch-up (or should I say resync ?) with the heard note for the same length it stayed at the previous freq during the fadeout.
                SUBlegatonote(catchupfreq, Legato.param.vel, Legato.param.portamento, Legato.param.midinote, false);
                break;
            }
            Legato.fade.m-=Legato.fade.step;
            outl[i]*=Legato.fade.m;
            outr[i]*=Legato.fade.m;
        }
        break;
    default :
        break;
    }

    // Check if the note needs to be computed more
    if (AmpEnvelope->finished()!=0) {
        for (i=0;i<SOUND_BUFFER_SIZE;i++) {//fade-out
            REALTYPE tmp=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE;
            outl[i]*=tmp;
            outr[i]*=tmp;
        };
        KillNote();
    };
    return(1);
};
Esempio n. 8
0
int PADnote::noteout(REALTYPE *outl, REALTYPE *outr)
{
    computecurrentparameters();
    REALTYPE *smps = pars->sample[nsample].smp;
    if(smps == NULL) {
        for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
            outl[i] = 0.0;
            outr[i] = 0.0;
        }
        return 1;
    }
    REALTYPE smpfreq = pars->sample[nsample].basefreq;


    REALTYPE freqrap = realfreq / smpfreq;
    int      freqhi  = (int) (floor(freqrap));
    REALTYPE freqlo  = freqrap - floor(freqrap);


    if(config.cfg.Interpolation)
        Compute_Cubic(outl, outr, freqhi, freqlo);
    else
        Compute_Linear(outl, outr, freqhi, freqlo);


    if(firsttime) {
        fadein(outl);
        fadein(outr);
        firsttime = false;
    }

    NoteGlobalPar.GlobalFilterL->filterout(outl);
    NoteGlobalPar.GlobalFilterR->filterout(outr);

    //Apply the punch
    if(NoteGlobalPar.Punch.Enabled != 0) {
        for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
            REALTYPE punchamp = NoteGlobalPar.Punch.initialvalue
                                * NoteGlobalPar.Punch.t + 1.0;
            outl[i] *= punchamp;
            outr[i] *= punchamp;
            NoteGlobalPar.Punch.t -= NoteGlobalPar.Punch.dt;
            if(NoteGlobalPar.Punch.t < 0.0) {
                NoteGlobalPar.Punch.Enabled = 0;
                break;
            }
        }
    }

    if(ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude, globalnewamplitude)) {
        // Amplitude Interpolation
        for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
            REALTYPE tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude,
                                                    globalnewamplitude,
                                                    i,
                                                    SOUND_BUFFER_SIZE);
            outl[i] *= tmpvol * NoteGlobalPar.Panning;
            outr[i] *= tmpvol * (1.0 - NoteGlobalPar.Panning);
        }
    }
    else {
        for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
            outl[i] *= globalnewamplitude * NoteGlobalPar.Panning;
            outr[i] *= globalnewamplitude * (1.0 - NoteGlobalPar.Panning);
        }
    }


    // Apply legato-specific sound signal modifications
    if(Legato.silent)    // Silencer
        if(Legato.msg != LM_FadeIn)
            for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
                outl[i] = 0.0;
                outr[i] = 0.0;
            }
    switch(Legato.msg) {
    case LM_CatchUp:  // Continue the catch-up...
        if(Legato.decounter == -10)
            Legato.decounter = Legato.fade.length;
        for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { //Yea, could be done without the loop...
            Legato.decounter--;
            if(Legato.decounter < 1) {
                // Catching-up done, we can finally set
                // the note to the actual parameters.
                Legato.decounter = -10;
                Legato.msg = LM_ToNorm;
                PADlegatonote(Legato.param.freq,
                              Legato.param.vel,
                              Legato.param.portamento,
                              Legato.param.midinote,
                              false);
                break;
            }
        }
        break;
    case LM_FadeIn:  // Fade-in
        if(Legato.decounter == -10)
            Legato.decounter = Legato.fade.length;
        Legato.silent = false;
        for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
            Legato.decounter--;
            if(Legato.decounter < 1) {
                Legato.decounter = -10;
                Legato.msg = LM_Norm;
                break;
            }
            Legato.fade.m += Legato.fade.step;
            outl[i] *= Legato.fade.m;
            outr[i] *= Legato.fade.m;
        }
        break;
    case LM_FadeOut:  // Fade-out, then set the catch-up
        if(Legato.decounter == -10)
            Legato.decounter = Legato.fade.length;
        for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
            Legato.decounter--;
            if(Legato.decounter < 1) {
                for(int j = i; j < SOUND_BUFFER_SIZE; j++) {
                    outl[j] = 0.0;
                    outr[j] = 0.0;
                }
                Legato.decounter = -10;
                Legato.silent    = true;
                // Fading-out done, now set the catch-up :
                Legato.decounter = Legato.fade.length;
                Legato.msg = LM_CatchUp;
                REALTYPE catchupfreq = Legato.param.freq
                                       * (Legato.param.freq / Legato.lastfreq);            //This freq should make this now silent note to catch-up (or should I say resync ?) with the heard note for the same length it stayed at the previous freq during the fadeout.
                PADlegatonote(catchupfreq,
                              Legato.param.vel,
                              Legato.param.portamento,
                              Legato.param.midinote,
                              false);
                break;
            }
            Legato.fade.m -= Legato.fade.step;
            outl[i] *= Legato.fade.m;
            outr[i] *= Legato.fade.m;
        }
        break;
    default:
        break;
    }


    // Check if the global amplitude is finished.
    // If it does, disable the note
    if(NoteGlobalPar.AmpEnvelope->finished() != 0) {
        for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out
            REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
            outl[i] *= tmp;
            outr[i] *= tmp;
        }
        finished_ = 1;
    }

    return 1;
}
Esempio n. 9
0
/*
 * Master audio out (the final sound)
 */
void Master::AudioOut(REALTYPE *outl,REALTYPE *outr){
    int i,npart,nefx;

/*    //test!!!!!!!!!!!!! se poate bloca aici (mutex)
    if (seq.play){
	int type,par1,par2,again,midichan;
	int ntrack=1;
//	    do{
		again=seq.getevent(ntrack,&midichan,&type,&par1,&par2);
		if (type>0) {
//		printf("aaa\n");	
	
	    	    if (type==1){//note_on or note_off
			if (par2!=0) NoteOn(midichan,par1,par2);
			    else NoteOff(midichan,par1);
	    	    };
		};
//	    } while (again);
    };
*/


//    printf("zzzz\n");


    //Swaps the Left channel with Right Channel (if it is asked for)
    if (swaplr!=0){
        REALTYPE *tmp=outl;
	outl=outr;
	outr=tmp;
    };
    
    //clean up the output samples 
    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
	outl[i]=0.0;
	outr[i]=0.0;
    };

    //Compute part samples and store them part[npart]->partoutl,partoutr
    for (npart=0;npart<NUM_MIDI_PARTS;npart++)
	if (part[npart]->Penabled!=0) part[npart]->ComputePartSmps();

    //Insertion effects 
    for (nefx=0;nefx<NUM_INS_EFX;nefx++){
	if (Pinsparts[nefx]>=0) {
	    int efxpart=Pinsparts[nefx];
	    if (part[efxpart]->Penabled!=0) 
		insefx[nefx]->out(part[efxpart]->partoutl,part[efxpart]->partoutr);
	};
    };
    
    
    //Apply the part volumes and pannings (after insertion effects)
    for (npart=0;npart<NUM_MIDI_PARTS;npart++){
	if (part[npart]->Penabled==0)  continue; 

	REALTYPE newvol_l=part[npart]->volume;
	REALTYPE newvol_r=part[npart]->volume;
	REALTYPE oldvol_l=part[npart]->oldvolumel;
	REALTYPE oldvol_r=part[npart]->oldvolumer;
	REALTYPE pan=part[npart]->panning;
	if (pan<0.5) newvol_l*=pan*2.0;
   	    else newvol_r*=(1.0-pan)*2.0;
	
	if (ABOVE_AMPLITUDE_THRESHOLD(oldvol_l,newvol_l)||
	    ABOVE_AMPLITUDE_THRESHOLD(oldvol_r,newvol_r)){//the volume or the panning has changed and needs interpolation
	    
	    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
		REALTYPE vol_l=INTERPOLATE_AMPLITUDE(oldvol_l,newvol_l,i,SOUND_BUFFER_SIZE);
		REALTYPE vol_r=INTERPOLATE_AMPLITUDE(oldvol_r,newvol_r,i,SOUND_BUFFER_SIZE);
		part[npart]->partoutl[i]*=vol_l;
	        part[npart]->partoutr[i]*=vol_r;
	    };
	    part[npart]->oldvolumel=newvol_l;
	    part[npart]->oldvolumer=newvol_r;

	} else {
	    for (i=0;i<SOUND_BUFFER_SIZE;i++) {//the volume did not changed
		part[npart]->partoutl[i]*=newvol_l;
	        part[npart]->partoutr[i]*=newvol_r;
	    };
	};
    };


    //System effects
    for (nefx=0;nefx<NUM_SYS_EFX;nefx++){
	if (sysefx[nefx]->geteffect()==0) continue;//the effect is disabled

    	//Clean up the samples used by the system effects
	for (i=0;i<SOUND_BUFFER_SIZE;i++) {
	    tmpmixl[i]=0.0;
	    tmpmixr[i]=0.0;
	};

	//Mix the channels according to the part settings about System Effect
	for (npart=0;npart<NUM_MIDI_PARTS;npart++){
	    //skip if the part has no output to effect	    
	    if (Psysefxvol[nefx][npart]==0) continue;

	    //skip if the part is disabled
	    if (part[npart]->Penabled==0) continue;

	    //the output volume of each part to system effect
	    REALTYPE vol=sysefxvol[nefx][npart];
	    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
		tmpmixl[i]+=part[npart]->partoutl[i]*vol;
		tmpmixr[i]+=part[npart]->partoutr[i]*vol;
	    };
	};
	
	// system effect send to next ones
	for (int nefxfrom=0;nefxfrom<nefx;nefxfrom++){
	    if (Psysefxsend[nefxfrom][nefx]!=0){
		REALTYPE v=sysefxsend[nefxfrom][nefx];
		for (i=0;i<SOUND_BUFFER_SIZE;i++) {
		    tmpmixl[i]+=sysefx[nefxfrom]->efxoutl[i]*v;
		    tmpmixr[i]+=sysefx[nefxfrom]->efxoutr[i]*v;
		};
	    };
	};

	sysefx[nefx]->out(tmpmixl,tmpmixr);
	
	//Add the System Effect to sound output
	REALTYPE outvol=sysefx[nefx]->sysefxgetvolume();
	for (i=0;i<SOUND_BUFFER_SIZE;i++) {
	    outl[i]+=tmpmixl[i]*outvol;
	    outr[i]+=tmpmixr[i]*outvol;
	};

    };

    //Mix all parts
    for (npart=0;npart<NUM_MIDI_PARTS;npart++){
	for (i=0;i<SOUND_BUFFER_SIZE;i++) {//the volume did not changed
    	    outl[i]+=part[npart]->partoutl[i];
	    outr[i]+=part[npart]->partoutr[i];
	};
    };
    
    //Insertion effects for Master Out
    for (nefx=0;nefx<NUM_INS_EFX;nefx++){
	if (Pinsparts[nefx] == -2) 
	    insefx[nefx]->out(outl,outr);
    };

    //Master Volume
    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
        outl[i]*=volume;
        outr[i]*=volume;
    };

    //Peak computation (for vumeters)
    vuoutpeakl=1e-12;vuoutpeakr=1e-12;
    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
        if (fabs(outl[i])>vuoutpeakl) vuoutpeakl=fabs(outl[i]);
        if (fabs(outr[i])>vuoutpeakr) vuoutpeakr=fabs(outr[i]);
    };
    if ((vuoutpeakl>1.0)||(vuoutpeakr>1.0)) vuclipped=1;
    if (vumaxoutpeakl<vuoutpeakl) vumaxoutpeakl=vuoutpeakl;
    if (vumaxoutpeakr<vuoutpeakr) vumaxoutpeakr=vuoutpeakr;

    //RMS Peak computation (for vumeters)
    vurmspeakl=1e-12;vurmspeakr=1e-12;
    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
        vurmspeakl+=outl[i]*outl[i];
        vurmspeakr+=outr[i]*outr[i];
    };
    vurmspeakl=sqrt(vurmspeakl/SOUND_BUFFER_SIZE);
    vurmspeakr=sqrt(vurmspeakr/SOUND_BUFFER_SIZE);
    
    //Part Peak computation (for Part vumeters or fake part vumeters)
    for (npart=0;npart<NUM_MIDI_PARTS;npart++){
	vuoutpeakpart[npart]=1.0e-12;
	if (part[npart]->Penabled!=0) {
    	    REALTYPE *outl=part[npart]->partoutl,
		     *outr=part[npart]->partoutr;
	    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
		REALTYPE tmp=fabs(outl[i]+outr[i]);
    		if (tmp>vuoutpeakpart[npart]) vuoutpeakpart[npart]=tmp;
	    };
	    vuoutpeakpart[npart]*=volume;
	} else {
	    if (fakepeakpart[npart]>1) fakepeakpart[npart]--;
	};
    };


    //Shutup if it is asked (with fade-out)
    if (shutup!=0){
	for (i=0;i<SOUND_BUFFER_SIZE;i++) {
	    REALTYPE tmp=(SOUND_BUFFER_SIZE-i)/(REALTYPE) SOUND_BUFFER_SIZE;
	    outl[i]*=tmp;
	    outr[i]*=tmp;
	};
	ShutUp();
    };

    //update the LFO's time
    LFOParams::time++;

    if (HDDRecorder.recording()) HDDRecorder.recordbuffer(outl,outr);
    dump.inctick();
};