annotate intercom/aec.cpp @ 2:13be24d74cd2

import intercom-0.4.1
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 09:57:52 +0200
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
1 /* aec.cpp
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
2 *
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
3 * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005).
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
4 * All Rights Reserved.
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
5 *
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
6 * Acoustic Echo Cancellation NLMS-pw algorithm
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
7 *
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
8 * Version 0.3 filter created with www.dsptutor.freeuk.com
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
9 * Version 0.3.1 Allow change of stability parameter delta
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
10 * Version 0.4 Leaky Normalized LMS - pre whitening algorithm
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
11 */
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
12
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
13 #include <stdio.h>
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
14 #include <stdlib.h>
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
15 #include <math.h>
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
16 #include <string.h>
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
17 #include <unistd.h>
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
18
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
19 #include "oss.h"
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
20 #include "aec.h"
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
21 #include "intercomd.h"
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
22
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
23 #include "tcp.h"
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
24
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
25 /* Vector Dot Product */
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
26 REAL dotp(REAL a[], REAL b[])
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
27 {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
28 REAL sum0 = 0.0, sum1 = 0.0;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
29 int j;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
30
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
31 for (j = 0; j < NLMS_LEN; j += 2) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
32 // optimize: partial loop unrolling
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
33 sum0 += a[j] * b[j];
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
34 sum1 += a[j + 1] * b[j + 1];
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
35 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
36 return sum0 + sum1;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
37 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
38
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
39
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
40 AEC::AEC()
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
41 {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
42 hangover = 0;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
43 memset(x, 0, sizeof(x));
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
44 memset(xf, 0, sizeof(xf));
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
45 memset(w, 0, sizeof(w));
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
46 j = NLMS_EXT;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
47 delta = 0.0f;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
48 setambient(NoiseFloor);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
49 dfast = dslow = M75dB_PCM;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
50 xfast = xslow = M80dB_PCM;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
51 gain = 1.0f;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
52 Fx.init(2000.0f/RATE);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
53 Fe.init(2000.0f/RATE);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
54
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
55 aes_y2 = M0dB;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
56
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
57 fdwdisplay = -1;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
58 dumpcnt = 0;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
59 memset(ws, 0, sizeof(ws));
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
60 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
61
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
62 // Adrian soft decision DTD
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
63 // (Dual Average Near-End to Far-End signal Ratio DTD)
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
64 // This algorithm uses exponential smoothing with differnt
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
65 // ageing parameters to get fast and slow near-end and far-end
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
66 // signal averages. The ratio of NFRs term
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
67 // (dfast / xfast) / (dslow / xslow) is used to compute the stepsize
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
68 // A ratio value of 2.5 is mapped to stepsize 0, a ratio of 0 is
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
69 // mapped to 1.0 with a limited linear function.
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
70 inline float AEC::dtd(REAL d, REAL x)
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
71 {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
72 float stepsize;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
73
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
74 // fast near-end and far-end average
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
75 dfast += ALPHAFAST * (fabsf(d) - dfast);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
76 xfast += ALPHAFAST * (fabsf(x) - xfast);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
77
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
78 // slow near-end and far-end average
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
79 dslow += ALPHASLOW * (fabsf(d) - dslow);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
80 xslow += ALPHASLOW * (fabsf(x) - xslow);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
81
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
82 if (xfast < M70dB_PCM) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
83 return 0.0; // no Spk signal
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
84 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
85
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
86 if (dfast < M70dB_PCM) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
87 return 0.0; // no Mic signal
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
88 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
89
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
90 // ratio of NFRs
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
91 float ratio = (dfast * xslow) / (dslow * xfast);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
92
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
93 // begrenzte lineare Kennlinie
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
94 const float M = (STEPY2 - STEPY1) / (STEPX2 - STEPX1);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
95 if (ratio < STEPX1) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
96 stepsize = STEPY1;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
97 } else if (ratio > STEPX2) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
98 stepsize = STEPY2;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
99 } else {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
100 // Punktrichtungsform einer Geraden
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
101 stepsize = M * (ratio - STEPX1) + STEPY1;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
102 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
103
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
104 return stepsize;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
105 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
106
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
107
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
108 inline void AEC::leaky()
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
109 // The xfast signal is used to charge the hangover timer to Thold.
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
110 // When hangover expires (no Spk signal for some time) the vector w
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
111 // is erased. This is my implementation of Leaky NLMS.
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
112 {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
113 if (xfast >= M70dB_PCM) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
114 // vector w is valid for hangover Thold time
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
115 hangover = Thold;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
116 } else {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
117 if (hangover > 1) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
118 --hangover;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
119 } else if (1 == hangover) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
120 --hangover;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
121 // My Leaky NLMS is to erase vector w when hangover expires
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
122 memset(w, 0, sizeof(w));
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
123 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
124 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
125 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
126
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
127
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
128 void AEC::openwdisplay() {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
129 // open TCP connection to program wdisplay.tcl
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
130 fdwdisplay = socket_async("127.0.0.1", 50999);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
131 };
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
132
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
133
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
134 inline REAL AEC::nlms_pw(REAL d, REAL x_, float stepsize)
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
135 {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
136 x[j] = x_;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
137 xf[j] = Fx.highpass(x_); // pre-whitening of x
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
138
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
139 // calculate error value
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
140 // (mic signal - estimated mic signal from spk signal)
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
141 REAL e = d;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
142 if (hangover > 0) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
143 e -= dotp(w, x + j);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
144 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
145 REAL ef = Fe.highpass(e); // pre-whitening of e
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
146
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
147 // optimize: iterative dotp(xf, xf)
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
148 dotp_xf_xf += (xf[j] * xf[j] - xf[j + NLMS_LEN - 1] * xf[j + NLMS_LEN - 1]);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
149
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
150 if (stepsize > 0.0) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
151 // calculate variable step size
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
152 REAL mikro_ef = stepsize * ef / dotp_xf_xf;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
153
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
154 // update tap weights (filter learning)
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
155 int i;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
156 for (i = 0; i < NLMS_LEN; i += 2) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
157 // optimize: partial loop unrolling
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
158 w[i] += mikro_ef * xf[i + j];
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
159 w[i + 1] += mikro_ef * xf[i + j + 1];
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
160 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
161 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
162
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
163 if (--j < 0) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
164 // optimize: decrease number of memory copies
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
165 j = NLMS_EXT;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
166 memmove(x + j + 1, x, (NLMS_LEN - 1) * sizeof(REAL));
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
167 memmove(xf + j + 1, xf, (NLMS_LEN - 1) * sizeof(REAL));
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
168 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
169
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
170 // Saturation
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
171 if (e > MAXPCM) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
172 return MAXPCM;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
173 } else if (e < -MAXPCM) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
174 return -MAXPCM;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
175 } else {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
176 return e;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
177 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
178 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
179
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
180
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
181 int AEC::doAEC(int d_, int x_)
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
182 {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
183 REAL d = (REAL) d_;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
184 REAL x = (REAL) x_;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
185
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
186 // Mic Highpass Filter - to remove DC
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
187 d = acMic.highpass(d);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
188
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
189 // Mic Highpass Filter - cut-off below 300Hz
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
190 d = cutoff.highpass(d);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
191
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
192 // Amplify, for e.g. Soundcards with -6dB max. volume
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
193 d *= gain;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
194
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
195 // Spk Highpass Filter - to remove DC
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
196 x = acSpk.highpass(x);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
197
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
198 // Double Talk Detector
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
199 stepsize = dtd(d, x);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
200
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
201 // Leaky (ageing of vector w)
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
202 leaky();
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
203
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
204 // Acoustic Echo Cancellation
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
205 d = nlms_pw(d, x, stepsize);
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
206
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
207 if (fdwdisplay >= 0) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
208 if (++dumpcnt >= (WIDEB*8000/10)) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
209 // wdisplay creates 10 dumps per seconds = large CPU load!
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
210 dumpcnt = 0;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
211 write(fdwdisplay, ws, DUMP_LEN*sizeof(float));
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
212 // we don't check return value. This is not production quality!!!
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
213 memset(ws, 0, sizeof(ws));
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
214 } else {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
215 int i;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
216 for (i = 0; i < DUMP_LEN; i += 2) {
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
217 // optimize: partial loop unrolling
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
218 ws[i] += w[i];
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
219 ws[i + 1] += w[i + 1];
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
220 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
221 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
222 }
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
223
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
224 return (int) d;
13be24d74cd2 import intercom-0.4.1
Peter Meerwald <pmeerw@cosy.sbg.ac.at>
parents:
diff changeset
225 }

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.