// -------------------------------------------------------------- // main.cpp // Test Application // 08.03.2003 // -------------------------------------------------------------- #include #include #include #include #include "radio.h" #include "cmp.h" // -------------------------------------------------------------- void cmp_init(cmp_t *pObj, long fs, double rms_sec, double lookahead_sec, double det_attack_sec, double det_release_sec, double vca_attack_sec, double vca_release_sec) { pObj->rms_size = (long)(rms_sec*fs); pObj->dly_size = (long)(lookahead_sec*fs); if (pObj->dly_size <= 0) pObj->dly_size = 1; pObj->fs = fs; pObj->vca_gain = 1; pObj->vca_gain_db = 0; pObj->vca_gain_target = 1; pObj->det_gain = 0; pObj->det_gain_db = 0; pObj->peak_mode = 0; pObj->det_ar = 4.0/(det_attack_sec*pObj->fs); pObj->det_af = 4.0/(det_release_sec*pObj->fs); pObj->det_br = 1 - pObj->det_ar; pObj->det_bf = 1 - pObj->det_af; pObj->vca_ar = 4.0/(vca_attack_sec*pObj->fs); pObj->vca_af = 4.0/(vca_release_sec*pObj->fs); pObj->vca_br = 1 - pObj->vca_ar; pObj->vca_bf = 1 - pObj->vca_af; SlidingVarInit(&pObj->var, pObj->rms_size, fs/20); RBufInit(&pObj->dly, pObj->dly_size); } double cmp_process(cmp_t *pObj, double xi, cmp_curve_t *pCurve, int curve_len, int mode) { int k; double px, py, x, y; double x0, x1; double y0, y1; RBufPut(&pObj->dly, xi); x = RBufGetAfter(&pObj->dly, pObj->dly_size-1); px = sqrt(SlidingVarProcess(&pObj->var, xi)); if (px > pObj->det_gain) pObj->det_gain = pObj->det_ar*px + pObj->det_br*pObj->det_gain; else pObj->det_gain = pObj->det_af*px + pObj->det_bf*pObj->det_gain; if (pObj->peak_mode) pObj->det_gain = fabs(x); pObj->det_gain_db = 20*log10(pObj->det_gain); k=0; while(k < (curve_len-1)) { pObj->do_compress = 1; if (pObj->det_gain == 0) { pObj->vca_gain_target = 1; break; } if (pObj->det_gain_db <= pCurve[k+1].kth) { x0 = pCurve[k].kth; x1 = pCurve[k+1].kth; y0 = pCurve[k].kc; y1 = pCurve[k+1].kc; py = y0 + (pObj->det_gain_db - x0)*(y1-y0)/(x1-x0); pObj->vca_gain_target = pow(10, 0.05*py); // if (py > 0) // pObj->do_compress = 0; break; } else { k++; } } if (pObj->do_compress) { if (pObj->vca_gain > pObj->vca_gain_target) pObj->vca_gain = pObj->vca_ar*pObj->vca_gain_target + pObj->vca_br*pObj->vca_gain; else pObj->vca_gain = pObj->vca_af*pObj->vca_gain_target + pObj->vca_bf*pObj->vca_gain; } else { if (pObj->vca_gain < pObj->vca_gain_target) pObj->vca_gain = pObj->vca_ar*pObj->vca_gain_target + pObj->vca_br*pObj->vca_gain; else pObj->vca_gain = pObj->vca_af*pObj->vca_gain_target + pObj->vca_bf*pObj->vca_gain; } pObj->vca_gain_db = 20*log10(pObj->vca_gain); if (mode == 0) y = x; if (mode == 1) { if (pObj->peak_mode) y = 0.5*x*pObj->vca_gain_target; else y = x*pObj->vca_gain; } if (mode == 2) y = pObj->det_gain*sqrt(12.0)*(0.5-(double)rand()/RAND_MAX); if (mode == 3) y = 0.01*pObj->vca_gain_db; if (mode == 4) y = 0.01*(pObj->det_gain_db+pObj->vca_gain_db); return y; }