summaryrefslogtreecommitdiff
path: root/sec.h
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-10-24 22:58:44 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-10-24 22:58:44 +0000
commit0eae84ac580869ffb545c9891645143ee5f870df (patch)
tree266f015032d7387a58da7b2f15b1ed2a3f5a693a /sec.h
parenta4e2770c246e360b27c2a5dd45c3f50f8df6bf7f (diff)
Version 0.3.2 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@121 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'sec.h')
-rwxr-xr-xsec.h77
1 files changed, 38 insertions, 39 deletions
diff --git a/sec.h b/sec.h
index 0140c15..95a7551 100755
--- a/sec.h
+++ b/sec.h
@@ -6,6 +6,7 @@
* any relevant standards (e.g. G.164/5/7/8). One day....
*
* Written by Steve Underwood <steveu@coppice.org>
+ * Various optimizations and improvements by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001 Steve Underwood
*
@@ -53,6 +54,8 @@
#define FREE(a) free(a)
#endif
+#include "arith.h"
+
#ifndef NULL
#define NULL 0
#endif
@@ -63,6 +66,8 @@
#define TRUE (!FALSE)
#endif
+#define USE_SHORTS
+
#define NONUPDATE_DWELL_TIME 600 /* 600 samples, or 75ms */
typedef struct
@@ -76,6 +81,7 @@ typedef struct
int16_t *tx_history; /* Last N tx samples */
int32_t *fir_taps; /* Echo FIR taps */
+ int16_t *fir_taps_short; /* Echo FIR taps, shorts instead of ints */
int curr_pos;
@@ -98,14 +104,18 @@ static echo_can_state_t *echo_can_create(int len, int adaption_mode);
static void echo_can_free(echo_can_state_t *ec);
static int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx);
-/* Original parameters :
+/* Original parameters :
#define MIN_TX_POWER_FOR_ADAPTION 256
#define MIN_RX_POWER_FOR_ADAPTION 128
*/
-/* Better ones found by Jim */
+#define MIN_TX_POWER_FOR_ADAPTION 256
+#define MIN_RX_POWER_FOR_ADAPTION 64
+
+/* Better ones found by Jim
#define MIN_TX_POWER_FOR_ADAPTION 128
#define MIN_RX_POWER_FOR_ADAPTION 64
+*/
static inline echo_can_state_t *echo_can_create(int len, int adaption_mode)
{
@@ -113,19 +123,20 @@ static inline echo_can_state_t *echo_can_create(int len, int adaption_mode)
void *ptr;
ptr = ec = (echo_can_state_t *) MALLOC(sizeof(*ec) + len * sizeof(int32_t) +
- len * sizeof(int16_t));
+ len * 3 * sizeof(int16_t));
if (ec == NULL)
return NULL;
- memset(ec, 0, sizeof(*ec) + len * sizeof(int32_t) + len * sizeof(int16_t));
+ memset(ec, 0, sizeof(*ec) + len * sizeof(int32_t) + len * 3 * sizeof(int16_t));
ec->taps = len;
ec->tap_mask = len - 1;
- ec->fir_taps = (int32_t *) (ptr + sizeof(*ec));
- ec->tx_history = (int16_t *) (ptr + sizeof(*ec) + len * sizeof(int32_t));
+ ec->tx_history = (int16_t *) (ptr + sizeof(*ec) );
+ ec->fir_taps = (int32_t *) (ptr + sizeof(*ec) + len * 2 * sizeof(int16_t));
+ ec->fir_taps_short = (int16_t *) (ptr + sizeof(*ec) + len * sizeof(int32_t) + len * 2 * sizeof(int16_t));
ec->rx_power_threshold = 10000000;
ec->use_suppressor = FALSE;
/* Non-linear processor - a fancy way to say "zap small signals, to avoid
accumulating noise". */
- ec->use_nlp = FALSE;
+ ec->use_nlp = TRUE;
return ec;
}
/*- End of function --------------------------------------------------------*/
@@ -138,15 +149,12 @@ static inline void echo_can_free(echo_can_state_t *ec)
static inline int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
{
- int offset;
- int limit;
int32_t echo_value;
int clean_rx;
int nsuppr;
- int i;
- int correction;
ec->tx_history[ec->curr_pos] = tx;
+ ec->tx_history[ec->curr_pos + ec->taps] = tx;
/* Evaluate the echo - i.e. apply the FIR filter */
/* Assume the gain of the FIR does not exceed unity. Exceeding unity
@@ -162,14 +170,11 @@ static inline int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t
/* 16 bit coeffs for the LMS give lousy results (maths good, actual sound
bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems
best */
- offset = ec->curr_pos;
- limit = ec->taps - offset;
- echo_value = 0;
- for (i = 0; i < limit; i++)
- echo_value += (ec->fir_taps[i] >> 16)*ec->tx_history[i + offset];
- offset = ec->taps - ec->curr_pos;
- for ( ; i < ec->taps; i++)
- echo_value += (ec->fir_taps[i] >> 16)*ec->tx_history[i - offset];
+#ifdef USE_SHORTS
+ echo_value = CONVOLVE2(ec->fir_taps_short, ec->tx_history + ec->curr_pos, ec->taps);
+#else
+ echo_value = CONVOLVE(ec->fir_taps, ec->tx_history + ec->curr_pos, ec->taps);
+#endif
echo_value >>= 16;
/* And the answer is..... */
@@ -193,34 +198,28 @@ static inline int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t
{
/* This is a really crude piece of decision logic, but it does OK
for now. */
- if (ec->tx_power > 2*ec->rx_power)
+ if (ec->tx_power > ec->rx_power << 1)
{
/* There is no far-end speech detected */
if (ec->nonupdate_dwell == 0)
{
/* ... and we are not in the dwell time from previous speech. */
//nsuppr = saturate((clean_rx << 16)/ec->tx_power);
- nsuppr = clean_rx >> 3;
+ nsuppr = (clean_rx << 16) / ec->tx_power;
+ nsuppr >>= 4;
+ if (nsuppr > 512)
+ nsuppr = 512;
+ if (nsuppr < -512)
+ nsuppr = -512;
/* Update the FIR taps */
- offset = ec->curr_pos;
- limit = ec->taps - offset;
ec->latest_correction = 0;
- for (i = 0; i < limit; i++)
- {
- correction = ec->tx_history[i + offset]*nsuppr;
- ec->fir_taps[i] += correction;
- //ec->latest_correction += abs(correction);
- }
- offset = ec->taps - ec->curr_pos;
- for ( ; i < ec->taps; i++)
- {
- correction = ec->tx_history[i - offset]*nsuppr;
- ec->fir_taps[i] += correction;
- //ec->latest_correction += abs(correction);
- }
- }
- else
+#ifdef USE_SHORTS
+ UPDATE2(ec->fir_taps, ec->fir_taps_short, ec->tx_history + ec->curr_pos, nsuppr, ec->taps);
+#else
+ UPDATE(ec->fir_taps, ec->fir_taps_short, ec->tx_history + ec->curr_pos, nsuppr, ec->taps);
+#endif
+ } else
{
ec->latest_correction = -3;
}
@@ -263,7 +262,7 @@ static inline int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t
clean_rx = 0;
/* Roll around the rolling buffer */
- ec->curr_pos = (ec->curr_pos + 1) & ec->tap_mask;
+ ec->curr_pos = (ec->curr_pos - 1) & ec->tap_mask;
return clean_rx;
}