Initial import
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/cmp@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
@@ -0,0 +1,125 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
// main.cpp
|
||||||
|
// Test Application
|
||||||
|
// 08.03.2003
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "radio.h"
|
||||||
|
|
||||||
|
#define EPSILON (20*log10(1 << 16))
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _scmp_curve_t
|
||||||
|
{
|
||||||
|
double kth, kc;
|
||||||
|
} cmp_curve_t;
|
||||||
|
|
||||||
|
typedef struct _scmp_t
|
||||||
|
{
|
||||||
|
long rms_size;
|
||||||
|
long dly_size;
|
||||||
|
long fs;
|
||||||
|
rbuf_t dly;
|
||||||
|
sl_var_t var;
|
||||||
|
double vca_gain_target, vca_gain, vca_gain_db;
|
||||||
|
double det_gain, det_gain_db;
|
||||||
|
double det_ar, det_br;
|
||||||
|
double det_af, det_bf;
|
||||||
|
double vca_ar, vca_br;
|
||||||
|
double vca_af, vca_bf;
|
||||||
|
int do_compress;
|
||||||
|
int peak_mode;
|
||||||
|
} cmp_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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);
|
||||||
|
double cmp_process(cmp_t *pObj, double xi, cmp_curve_t *pCurve, int curve_len, int mode);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
Reference in New Issue
Block a user