-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathicmp_process.c
119 lines (115 loc) · 4.12 KB
/
icmp_process.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// icmp_process.c - instantaneous-compression processing functions
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "chapro.h"
/***********************************************************/
FUNC(void)
cha_icmp_process(CHA_PTR cp, float *x, float *y, int cs)
{
float *Lcs, *Lcm, *Lce, *Lmx, *Gcs, *Gcm, *Gce, *Gmx;
float *Gmn, *Lfb, *Gsup, *Gpre, *gsup, *ginc, *zdr, *zdi;
float Lsup = 0, rnge, head;
float agtf, lrpk;
int *dsm, *dso;
int i, k, kr, ki, nc, dsmx, id, kd, dsmo, dsi, im, cm, jm;
static float eps = 1e-20f;
// compression
nc = CHA_IVAR[_nc];
cm = CHA_IVAR[_cm];
lrpk = (float) CHA_DVAR[_lrpk];
dsm = (int *) cp[_dsm];
dso = (int *) cp[_dso];
Lcs = (float *) cp[_Lcs];
Lcm = (float *) cp[_Lcm];
Lce = (float *) cp[_Lce];
Lmx = (float *) cp[_Lmx];
Gcs = (float *) cp[_Gcs];
Gcm = (float *) cp[_Gcm];
Gce = (float *) cp[_Gce];
Gmx = (float *) cp[_Gmx];
Gmn = (float *) cp[_Gmn];
Lfb = (float *) cp[_Lfb];
Gsup = (float *) cp[_Gsup];
Gpre = (float *) cp[_Gpre];
gsup = (float *) cp[_gsup];
ginc = (float *) cp[_ginc];
zdr = (float *) cp[_zdr];
zdi = zdr + dsm[0] * nc;
for (i = 0; i < cs; i++) {
dsmx = dsm[0];
dsmo = dsmx - 1;
dsi = (dsmx > 1);
/* loop over filterbank channel */
#pragma omp parallel for
for (k = 0; k < nc; k++) {
/* apply down-sample delay */
for (id = dsmo; id > 0; id--) {
kd = k * dsmx + id;
zdr[kd] = zdr[kd - 1];
zdi[kd] = zdi[kd - 1];
}
kd = k * dsmx;
/* retrieve input */
kr = (i + k * cs) * 2;
ki = kr + 1;
zdr[kd] = x[kr];
zdi[kd] = x[ki];
im = dsi ? ((i - dso[k]) % dsm[k]) : 0;
if (im == 0) { /* calculate channel levels ?? */
agtf = (float) _hypot(zdr[kd], zdi[kd]);
if (agtf < eps) {
agtf = eps;
}
Lfb[k] = db2(agtf / lrpk);
}
}
/* loop over suppressor channel */
#pragma omp parallel for
for (k = 0; k < nc; k++) {
im = dsi ? ((i - dso[k]) % dsm[k]) : 0;
if (im == 0) { /* calculate channel gains ?? */
if (cm) { /* compress mode */
Lsup = Lfb[k];
}
/* calculate compressive gain */
if (Lsup <= Lcs[k]) {
Gsup[k] = Gcs[k];
} else if (Lsup <= Lcm[k]) {
rnge = (Lcm[k] - Lsup) / (Lcm[k] - Lcs[k]);
Gsup[k] = Gcm[k] + (Gcs[k] - Gcm[k]) * rnge;
} else if (Lsup <= Lce[k]) {
rnge = (Lce[k] - Lsup) / (Lce[k] - Lcm[k]);
Gsup[k] = Gce[k] + (Gcm[k] - Gce[k]) * rnge;
} else {
Gsup[k] = Gce[k];
}
head = Lmx[k] - Lfb[k];
if (Gsup[k] > head) {
Gsup[k] = head;
} else if (Gsup[k] > Gmx[k]) {
Gsup[k] = Gmx[k];
} else if (Gsup[k] < Gmn[k]) {
Gsup[k] = Gmn[k];
}
}
/* apply compressive gain to filterbank outputs */
jm = dsi ? (im + 1) % dsm[k] : 0;
if (jm == 0) { /* next time-step calculates gain */
gsup[k] = undb2(Gsup[k]);
Gpre[k] = Gsup[k];
} else { /* interpolate gain */
if (im == 0) {
ginc[k] = undb2((Gsup[k] - Gpre[k]) / dsm[k]);
}
gsup[k] *= ginc[k];
}
/* store outputs */
kd = k * dsmx + dsmo;
kr = (i + k * cs) * 2;
ki = kr + 1;
y[kr] = gsup[k] * zdr[kd];
y[ki] = gsup[k] * zdi[kd];
}
}
}