Пример #1
0
/*
 * Envelope Output (dB)
 */
float Envelope::envout_dB()
{
    float out;
    if(linearenvelope != 0)
        return envout();

    if((currentpoint == 1) && (!keyreleased || (forcedrelase == 0))) { //first point is always lineary interpolated
        float v1 = dB2rap(envval[0]);
        float v2 = dB2rap(envval[1]);
        out = v1 + (v2 - v1) * t;

        t += inct;
        if(t >= 1.0f) {
            t    = 0.0f;
            inct = envdt[2];
            currentpoint++;
            out = v2;
        }

        if(out > 0.001f)
            envoutval = rap2dB(out);
        else
            envoutval = MIN_ENVELOPE_DB;
    }
    else
        out = dB2rap(envout());

    return out;
}
Пример #2
0
float EQ::getfreqresponse(float freq)
{
    float resp = 1.0f;
    for(int i = 0; i < MAX_EQ_BANDS; ++i) {
        if(filter[i].Ptype == 0)
            continue;
        resp *= filter[i].l->H(freq);
    }
    return rap2dB(resp * outvolume);
}
Пример #3
0
void
out_smb (holharm_t * s, float *smpsl, float *smpsr,
	 unsigned long sample_count)
{

  int i;
  float elratiol, elratior;
  float i_sum = 1e-12;
  float temp_sum, val_i_sum;
  float tmp;


  for (i = 0; i < sample_count; i++)
    {
      s->outil[i] = smpsl[i];
      s->outir[i] = smpsr[i];
      tmp = fabsf (smpsr[i] + smpsl[i]);
      if (tmp > i_sum)
	i_sum = tmp;

    }

  temp_sum = CLAMP (rap2dB (i_sum), -48.0, 15.0);
  val_i_sum = .6 * s->val_sum + .4 * temp_sum;
  s->val_sum = val_i_sum;


  if (*(s->PSELECT) == 1)
    {
      elratiol = s->ratiol;
      elratior = s->ratior;
    }
  else
    {
      elratiol = powf (2, *(s->intervall) / 12.0);
      elratior = powf (2, *(s->intervalr) / 12.0);
    }


  smbPitchShiftL (s, elratiol, sample_count, 2048, s->hq,
		  (float) s->SAMPLE_RATE, s->outil, s->outol);
  smbPitchShiftR (s, elratior, sample_count, 2048, s->hq,
		  (float) s->SAMPLE_RATE, s->outir, s->outor);


}
Пример #4
0
void FormantFilterGraph::draw() {
  int maxdB=30;
int ox=x(),oy=y(),lx=w(),ly=h(),i,oiy;
REALTYPE freqx;

fl_color(FL_BLACK);
fl_rectf(ox,oy,lx,ly);


//draw the lines
fl_color(FL_GRAY);

fl_line_style(FL_SOLID);
//fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2);

freqx=pars->getfreqpos(1000.0);
if ((freqx>0.0)&&(freqx<1.0))
   fl_line(ox+(int) (freqx*lx),oy,
    ox+(int) (freqx*lx),oy+ly);

for (i=1;i<10;i++){
   if(i==1){
     draw_freq_line(i*100.0,0);
     draw_freq_line(i*1000.0,0);
   }else 
    if (i==5){
      draw_freq_line(i*100.0,2);
      draw_freq_line(i*1000.0,2);
    }else{
      draw_freq_line(i*100.0,1);
      draw_freq_line(i*1000.0,1);
    };
};

draw_freq_line(10000.0,0);
draw_freq_line(20000.0,1);

fl_line_style(FL_DOT);
int GY=10;if (ly<GY*3) GY=-1;
for (i=1;i<GY;i++){
   int tmp=(int)(ly/(REALTYPE)GY*i);
   fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp);
};

fl_color(FL_YELLOW);
fl_font(FL_HELVETICA,10);
if (*nformant<pars->Pnumformants){
   draw_freq_line(pars->getformantfreq(pars->Pvowels[*nvowel].formants[*nformant].freq),2);

//show some information (like current formant frequency,amplitude)
   char tmpstr[20];

   snprintf(tmpstr,20,"%.2f kHz",pars->getformantfreq(pars->Pvowels[*nvowel].formants[*nformant].freq)*0.001);
   fl_draw(tmpstr,ox+1,oy+1,40,12,FL_ALIGN_LEFT,NULL,0);

   snprintf(tmpstr,20,"%d dB",(int)( rap2dB(1e-9 + pars->getformantamp(pars->Pvowels[*nvowel].formants[*nformant].amp)) + pars->getgain() ));
   fl_draw(tmpstr,ox+1,oy+15,40,12,FL_ALIGN_LEFT,NULL,0);

};

//draw the data

fl_color(FL_RED);
fl_line_style(FL_SOLID);

pars->formantfilterH(*nvowel,lx,graphpoints);

oiy=(int) ((graphpoints[0]/maxdB+1.0)*ly/2.0);
for (i=1;i<lx;i++){
   int iy=(int) ((graphpoints[i]/maxdB+1.0)*ly/2.0);
   if ((iy>=0)&&(oiy>=0)&&(iy<ly)&&(oiy<lx))
      fl_line(ox+i-1,oy+ly-oiy,ox+i,oy+ly-iy);
   oiy=iy;
};
}
Пример #5
0
/*
 * Get the freq. response of the formant filter
 */
void FilterParams::formantfilterH(int nvowel, int nfreqs, REALTYPE *freqs)
{
    REALTYPE c[3], d[3];
    REALTYPE filter_freq, filter_q, filter_amp;
    REALTYPE omega, sn, cs, alpha;

    for(int i = 0; i < nfreqs; i++)
        freqs[i] = 0.0;

    //for each formant...
    for(int nformant = 0; nformant < Pnumformants; nformant++) {
        //compute formant parameters(frequency,amplitude,etc.)
        filter_freq = getformantfreq(Pvowels[nvowel].formants[nformant].freq);
        filter_q    = getformantq(Pvowels[nvowel].formants[nformant].q) * getq();
        if(Pstages > 0)
            filter_q =
                (filter_q > 1.0 ? POW(filter_q, 1.0 / (Pstages + 1)) : filter_q);

        filter_amp = getformantamp(Pvowels[nvowel].formants[nformant].amp);


        if(filter_freq <= (SAMPLE_RATE / 2 - 100.0)) {
            omega = 2 * PI * filter_freq / SAMPLE_RATE;
            sn    = sin(omega);
            cs    = cos(omega);
            alpha = sn / (2 * filter_q);
            REALTYPE tmp = 1 + alpha;
            c[0]  = alpha / tmp *sqrt(filter_q + 1);
            c[1]  = 0;
            c[2]  = -alpha / tmp *sqrt(filter_q + 1);
            d[1]  = -2 * cs / tmp * (-1);
            d[2]  = (1 - alpha) / tmp * (-1);
        }
        else
            continue;


        for(int i = 0; i < nfreqs; i++) {
            REALTYPE freq = getfreqx(i / (REALTYPE) nfreqs);
            if(freq > SAMPLE_RATE / 2) {
                for(int tmp = i; tmp < nfreqs; tmp++)
                    freqs[tmp] = 0.0;
                break;
            }
            REALTYPE fr = freq / SAMPLE_RATE * PI * 2.0;
            REALTYPE x  = c[0], y = 0.0;
            for(int n = 1; n < 3; n++) {
                x += cos(n * fr) * c[n];
                y -= sin(n * fr) * c[n];
            }
            REALTYPE h = x * x + y * y;
            x = 1.0;
            y = 0.0;
            for(int n = 1; n < 3; n++) {
                x -= cos(n * fr) * d[n];
                y += sin(n * fr) * d[n];
            }
            h = h / (x * x + y * y);

            freqs[i] += POW(h, (Pstages + 1.0) / 2.0) * filter_amp;
        }
    }
    for(int i = 0; i < nfreqs; i++) {
        if(freqs[i] > 0.000000001)
            freqs[i] = rap2dB(freqs[i]) + getgain();
        else
            freqs[i] = -90.0;
    }
}
Пример #6
0
void
Compressor::out (float *efxoutl, float *efxoutr)
{

    int i;


    for (i = 0; i < PERIOD; i++) {
        float rdelta = 0.0f;
        float ldelta = 0.0f;
//Right Channel

        if(peak) {
            if (rtimer > hold) {
                rpeak *= 0.9998f;   //The magic number corresponds to ~0.1s based on T/(RC + T),
                rtimer--;
            }
            if (ltimer > hold) {
                lpeak *= 0.9998f;	//leaky peak detector.
                ltimer --;  //keeps the timer from eventually exceeding max int & rolling over
            }
            ltimer++;
            rtimer++;
            if(rpeak<fabs(efxoutr[i])) {
                rpeak = fabs(efxoutr[i]);
                rtimer = 0;
            }
            if(lpeak<fabs(efxoutl[i])) {
                lpeak = fabs(efxoutl[i]);
                ltimer = 0;
            }

            if(lpeak>20.0f) lpeak = 20.0f;
            if(rpeak>20.0f) rpeak = 20.0f; //keeps limiter from getting locked up when signal levels go way out of bounds (like hundreds)

        } else {
            rpeak = efxoutr[i];
            lpeak = efxoutl[i];
        }

        if(stereo) {
            rdelta = fabsf (rpeak);
            if(rvolume < 0.9f) {
                attr = att;
                relr = rel;
            } else if (rvolume < 1.0f) {
                attr = att + ((1.0f - att)*(rvolume - 0.9f)*10.0f);	//dynamically change attack time for limiting mode
                relr = rel/(1.0f + (rvolume - 0.9f)*9.0f);  //release time gets longer when signal is above limiting
            } else {
                attr = 1.0f;
                relr = rel*0.1f;
            }

            if (rdelta > rvolume)
                rvolume = attr * rdelta + (1.0f - attr)*rvolume;
            else
                rvolume = relr * rdelta + (1.0f - relr)*rvolume;


            rvolume_db = rap2dB (rvolume);
            if (rvolume_db < thres_db) {
                rgain = outlevel;
            } else if (rvolume_db < thres_mx) {
                //Dynamic ratio that depends on volume.  As can be seen, ratio starts
                //at something negligibly larger than 1 once volume exceeds thres, and increases toward selected
                // ratio by the time it has reached thres_mx.  --Transmogrifox

                eratio = 1.0f + (kratio-1.0f)*(rvolume_db-thres_db)* coeff_knee;
                rgain =   outlevel*dB2rap(thres_db + (rvolume_db-thres_db)/eratio - rvolume_db);
            } else {
                rgain = outlevel*dB2rap(thres_db + coeff_kk + (rvolume_db-thres_mx)*coeff_ratio - rvolume_db);
                limit = 1;
            }

            if ( rgain < MIN_GAIN) rgain = MIN_GAIN;
            rgain_t = .4f * rgain + .6f * rgain_old;
        };

//Left Channel
        if(stereo)  {
            ldelta = fabsf (lpeak);
        } else  {
            ldelta = 0.5f*(fabsf (lpeak) + fabsf (rpeak));
        };  //It's not as efficient to check twice, but it's small expense worth code clarity

        if(lvolume < 0.9f) {
            attl = att;
            rell = rel;
        } else if (lvolume < 1.0f) {
            attl = att + ((1.0f - att)*(lvolume - 0.9f)*10.0f);	//dynamically change attack time for limiting mode
            rell = rel/(1.0f + (lvolume - 0.9f)*9.0f);  //release time gets longer when signal is above limiting
        } else {
            attl = 1.0f;
            rell = rel*0.1f;
        }

        if (ldelta > lvolume)
            lvolume = attl * ldelta + (1.0f - attl)*lvolume;
        else
            lvolume = rell*ldelta + (1.0f - rell)*lvolume;

        lvolume_db = rap2dB (lvolume);

        if (lvolume_db < thres_db) {
            lgain = outlevel;
        } else if (lvolume_db < thres_mx) { //knee region
            eratio = 1.0f + (kratio-1.0f)*(lvolume_db-thres_db)* coeff_knee;
            lgain =   outlevel*dB2rap(thres_db + (lvolume_db-thres_db)/eratio - lvolume_db);
        } else {
            lgain = outlevel*dB2rap(thres_db + coeff_kk + (lvolume_db-thres_mx)*coeff_ratio - lvolume_db);
            limit = 1;
        }


        if ( lgain < MIN_GAIN) lgain = MIN_GAIN;
        lgain_t = .4f * lgain + .6f * lgain_old;

        if (stereo) {
            efxoutl[i] *= lgain_t;
            efxoutr[i] *= rgain_t;
            rgain_old = rgain;
            lgain_old = lgain;
        } else {
            efxoutl[i] *= lgain_t;
            efxoutr[i] *= lgain_t;
            lgain_old = lgain;
        }

        if(peak) {
            if(efxoutl[i]>0.999f) {            //output hard limiting
                efxoutl[i] = 0.999f;
                clipping = 1;
            }
            if(efxoutl[i]<-0.999f) {
                efxoutl[i] = -0.999f;
                clipping = 1;
            }
            if(efxoutr[i]>0.999f) {
                efxoutr[i] = 0.999f;
                clipping = 1;
            }
            if(efxoutr[i]<-0.999f) {
                efxoutr[i] = -0.999f;
                clipping = 1;
            }
            //highly probably there is a more elegant way to do that, but what the hey...
        }
    }

}
Пример #7
0
/*
 * Effect output
 */
void
Vocoder::out (float * smpsl, float * smpsr)
{
  int i, j;

  float tempgain;
  float maxgain=0.0f;
  float auxtemp, tmpgain;
   
   
   if(DS_state != 0)
   {
     A_Resample->mono_out(auxresampled,tmpaux,PERIOD,u_up,nPERIOD);
   }
   else
   memcpy(tmpaux,auxresampled,sizeof(float)*nPERIOD);


   for (i = 0; i<nPERIOD; i++)    //apply compression to auxresampled
   {
   auxtemp = input * tmpaux[i];
   if(fabs(auxtemp > compeak)) compeak = fabs(auxtemp);   //First do peak detection on the signal
   compeak *= prls;
   compenv = cbeta * oldcompenv + calpha * compeak;       //Next average into envelope follower
   oldcompenv = compenv;
   
   if(compenv > cpthresh)                                //if envelope of signal exceeds thresh, then compress
   {
   compg = cpthresh + cpthresh*(compenv - cpthresh)/compenv; 
   cpthresh = cthresh + cratio*(compg - cpthresh);   //cpthresh changes dynamically
   tmpgain = compg/compenv;
   }
   else
   {
   tmpgain = 1.0f;
   }


   
   if(compenv < cpthresh) cpthresh = compenv;
   if(cpthresh < cthresh) cpthresh = cthresh;
   
   tmpaux[i] = auxtemp * tmpgain;   

   tmpaux[i]=vlp->filterout_s(tmpaux[i]);
   tmpaux[i]=vhp->filterout_s(tmpaux[i]);

   };


      //End compression
      
   auxtemp = 0.0f;

   if(DS_state != 0)
   {
     U_Resample->out(smpsl,smpsr,tsmpsl,tsmpsr,PERIOD,u_up);
   }
  else
  {
   memcpy(tsmpsl,smpsl,sizeof(float)*nPERIOD);
   memcpy(tsmpsr,smpsr,sizeof(float)*nPERIOD);
  } 


   memset(tmpl,0,sizeof(float)*nPERIOD);
   memset(tmpr,0,sizeof(float)*nPERIOD);    



    for (j = 0; j < VOC_BANDS; j++)
    {

      for (i = 0; i<nPERIOD; i++)
       { 
       auxtemp = tmpaux[i];
       
       if(filterbank[j].speak < gate) filterbank[j].speak = 0.0f;  //gate 
       if(auxtemp>maxgain) maxgain = auxtemp; //vu meter level.    
           
       auxtemp = filterbank[j].aux->filterout_s(auxtemp);       
       if(fabs(auxtemp) > filterbank[j].speak) filterbank[j].speak = fabs(auxtemp);  //Leaky Peak detector
 
       filterbank[j].speak*=prls;

       filterbank[j].gain = beta * filterbank[j].oldgain + alpha * filterbank[j].speak;   
       filterbank[j].oldgain = filterbank[j].gain; 

       
       tempgain = (1.0f-ringworm)*filterbank[j].oldgain+ringworm*auxtemp; 

       tmpl[i] +=filterbank[j].l->filterout_s(tsmpsl[i])*tempgain;
       tmpr[i] +=filterbank[j].r->filterout_s(tsmpsr[i])*tempgain;   

       };
       
 
   };

   
       for (i = 0; i<nPERIOD; i++)
       { 
       tmpl[i]*=lpanning*level;
       tmpr[i]*=rpanning*level;       
       };


    if(DS_state != 0)
   {
     D_Resample->out(tmpl,tmpr,efxoutl,efxoutr,nPERIOD,u_down);
   }
   else
   {   
     memcpy(efxoutl,tmpl,sizeof(float)*nPERIOD);
     memcpy(efxoutr,tmpr,sizeof(float)*nPERIOD);
   }

      vulevel = (float)CLAMP(rap2dB(maxgain), -48.0, 15.0); 



};