Exemple #1
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;
}
Exemple #2
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;
}