git-svn-id: http://moon:8086/svn/software/trunk/libsrc/cmp@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
126 lines
3.2 KiB
C
Executable File
126 lines
3.2 KiB
C
Executable File
// --------------------------------------------------------------
|
|
// main.cpp
|
|
// Test Application
|
|
// 08.03.2003
|
|
// --------------------------------------------------------------
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <conio.h>
|
|
#include <math.h>
|
|
#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;
|
|
}
|
|
|