From 593fc92244fa8db6d0ea4d2c335eab90b8a7dee3 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 19 Jul 2014 07:44:42 +0000 Subject: [PATCH] Initial import git-svn-id: http://moon:8086/svn/software/trunk/libsrc/cmp@1 b431acfa-c32f-4a4a-93f1-934dc6c82436 --- cmp.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cmp.h | 47 ++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100755 cmp.c create mode 100755 cmp.h diff --git a/cmp.c b/cmp.c new file mode 100755 index 0000000..5259e27 --- /dev/null +++ b/cmp.c @@ -0,0 +1,125 @@ +// -------------------------------------------------------------- +// 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; +} + diff --git a/cmp.h b/cmp.h new file mode 100755 index 0000000..ecf0273 --- /dev/null +++ b/cmp.h @@ -0,0 +1,47 @@ +// -------------------------------------------------------------- +// main.cpp +// Test Application +// 08.03.2003 +// -------------------------------------------------------------- + +#include +#include +#include +#include +#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