Files
cmp/cmp.c
T
jens 593fc92244 Initial import
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/cmp@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
2014-07-19 07:44:42 +00:00

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;
}