diff options
author | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2003-02-02 17:52:04 +0000 |
---|---|---|
committer | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2003-02-02 17:52:04 +0000 |
commit | 3faeb827e8158f98a5ad9c3fc4006d29ee33de11 (patch) | |
tree | 38a67692067e47e04fe2ef836a2b2cc18fb4b0e1 | |
parent | eafd604d74acd879c8ee1208115d4abf8100228b (diff) |
Version 0.4.0 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@146 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-x | Makefile | 12 | ||||
-rwxr-xr-x | mec3.h | 212 | ||||
-rwxr-xr-x | zaptel.h | 26 |
3 files changed, 244 insertions, 6 deletions
@@ -35,12 +35,18 @@ KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char # #KFLAGS+=-DCONFIG_ZAPTEL_MMX # -# Pick your echo canceller: MARK, STEVE, or STEVE2 :) +# Pick your echo canceller: MARK2, MARK3, STEVE, or STEVE2 :) # #KFLAGS+=-DECHO_CAN_STEVE #KFLAGS+=-DECHO_CAN_STEVE2 #KFLAGS+=-DECHO_CAN_MARK KFLAGS+=-DECHO_CAN_MARK2 +#KFLAGS+=-DECHO_CAN_MARK3 +# +# Uncomment for aggressive residual echo supression under +# MARK2 echo canceller +# +#KFLAGS+=-DAGGRESSIVE_SUPPRESSOR # # Uncomment -DCONFIG_ZAPATA_NET to enable SyncPPP, CiscoHDLC, and Frame Relay # support. @@ -82,12 +88,12 @@ all: $(MODULES) ztcfg torisatool makefw ztmonitor ztspeed $(ZTTOOL) devel: tor2ee -tests: patgen pattest patlooptest hdlcstress hdlctest +tests: patgen pattest patlooptest hdlcstress hdlctest hdlcgen hdlcverify tor2.o: tor2.c tor2-hw.h tor.h tor2fw.h zaptel.h gcc $(KFLAGS) -c tor2.c -zaptel.o: zaptel.c zaptel.h digits.h arith.h sec.h mec.h sec-2.h +zaptel.o: zaptel.c zaptel.h digits.h arith.h sec.h mec.h sec-2.h mec2.h mec3.h gcc $(KFLAGS) -c zaptel.c torisa.o: torisa.c zaptel.h torisa.h @@ -0,0 +1,212 @@ +/* + * Mark's Third Echo Canceller + * + * Copyright (C) 2003, Digium, Inc. + * + * This program is free software and may be used + * and distributed under the terms of the GNU General Public + * License, incorporated herein by reference. + * + * Dedicated to the crew of the Columbia, STS-107 for their + * bravery and courageous sacrifice for science. + * + */ + +#ifndef _MARK3_ECHO_H +#define _MARK3_ECHO_H + + + +#ifdef __KERNEL__ +#include <linux/kernel.h> +#include <linux/slab.h> +#define MALLOC(a) kmalloc((a), GFP_KERNEL) +#define FREE(a) kfree(a) +#include <math.h> +#else +#include <stdlib.h> +#include <unistd.h> +#include <stdint.h> +#include <string.h> +#include <math.h> +#define MALLOC(a) malloc(a) +#define FREE(a) free(a) +#endif + + + +#define STEP_SIZE 0.4 /* Convergence rate */ + +#define SIGMA_P 0.01 /* Minimum adjustment */ +#define SIGMA_REF_PWR 0.01 /* Keep denominator from being 0 */ + +#define MIN_TX_ENERGY 256.0/32767.0 /* Must have at least this much reference */ +#define MIN_RX_ENERGY 32.0/32767.0 /* Must have at least this much receive energy */ + +#define MAX_ATTENUATION 64.0 /* Maximum amount of loss we care about */ +#define MAX_BETA 0.1 + +#define SUPPR_ATTENUATION 16.0 /* Amount of loss at which we suppress audio */ + +#define HANG_TIME 600 /* Hangover time */ + +#define NTAPS 128 /* Number of echo can taps */ + +#define BACKUP 256 /* Backup every this number of samples */ + +typedef struct { + float buf[NTAPS * 2]; + float max; + int maxexp; +} cbuf_f; + +typedef struct { + float a[NTAPS]; /* Coefficients */ + float b[NTAPS]; /* Coefficients */ + float c[NTAPS]; /* Coefficients */ + cbuf_f ref; /* Reference excitation */ + cbuf_f sig; /* Signal (echo + near end + noise) */ + cbuf_f e; /* Error */ + float refpwr; /* Reference power */ + int taps; /* Number of taps */ + int hcntr; /* Hangtime counter */ + int pos; /* Position in curcular buffers */ + int backup; /* Backup timer */ +} echo_can_state_t; + +static inline void echo_can_free(echo_can_state_t *ec) +{ + FREE(ec); +} + +static inline void buf_add(cbuf_f *b, float sample, int pos, int taps) +{ + /* Store and keep track of maxima */ + int x; + b->buf[pos] = sample; + b->buf[pos + taps] = sample; + if (sample > b->max) { + b->max = sample; + b->maxexp = taps; + } else { + b->maxexp--; + if (!b->maxexp) { + b->max = 0; + for (x=0;x<taps;x++) + if (b->max < fabs(b->buf[pos + x])) { + b->max = fabs(b->buf[pos + x]); + b->maxexp = x + 1; + } + } + } +} + +static inline short echo_can_update(echo_can_state_t *ec, short iref, short isig) +{ + int x; + float ref; + float sig; + float u; + float refpwr; + float beta; /* Factor */ + float se; /* Simulated echo */ + /* Convert to floats about 1.0 */ + ref = (iref/32767.0); + sig = (isig/32767.0); + +#if 0 + printf("start: %d, finish: %d\n", ec->start, ec->finish); +#endif + + if (!ec->backup) { + /* Backup coefficients periodically */ + ec->backup = BACKUP; + memcpy(ec->c,ec->b,sizeof(ec->c)); + memcpy(ec->b,ec->a,sizeof(ec->b)); + } else + ec->backup--; + /* Remove old samples from reference power calculation */ + ec->refpwr -= (ec->ref.buf[ec->pos] * ec->ref.buf[ec->pos]); + + /* Store signal and reference */ + buf_add(&ec->ref, ref, ec->pos, ec->taps); + buf_add(&ec->sig, sig, ec->pos, ec->taps); + + /* Add new reference power */ + ec->refpwr += (ec->ref.buf[ec->pos] * ec->ref.buf[ec->pos]); + + + /* Calculate simulated echo */ + se = 0.0; + for (x=0;x<ec->taps;x++) + se += ec->a[x] * ec->ref.buf[ec->pos + x]; + + u = sig - se; + if (ec->hcntr) + ec->hcntr--; + + /* Store error */ + buf_add(&ec->e, sig, ec->pos, ec->taps); + if ((ec->ref.max > MIN_TX_ENERGY) && + (ec->sig.max > MIN_RX_ENERGY) && + (ec->e.max * MAX_ATTENUATION > ec->ref.max)) { + /* We have sufficient energy */ + if (ec->sig.max * 2.0 < ec->ref.max) { + /* No double talk */ + if (!ec->hcntr) { + if (ec->refpwr < SIGMA_REF_PWR) + refpwr = SIGMA_REF_PWR; + else + refpwr = ec->refpwr; + beta = STEP_SIZE * u / refpwr; + if (beta > MAX_BETA) + beta = MAX_BETA; + if (beta < -MAX_BETA) + beta = -MAX_BETA; + /* Update coefficients */ + for (x=0;x<ec->taps;x++) { + ec->a[x] += beta * ec->ref.buf[ec->pos + x]; + } + } + } else { + if (!ec->hcntr) { + /* Our double talk detector is turning on for the first time. Revert + our coefficients, since we're probably well into the double talk by now */ + memcpy(ec->a, ec->c, sizeof(ec->a)); + } + /* Reset hang-time counter, and prevent backups */ + ec->hcntr = HANG_TIME; + ec->backup = BACKUP; + } + } +#ifndef NO_ECHO_SUPPRESSOR + if (ec->e.max * SUPPR_ATTENUATION < ec->ref.max) { + /* Suppress residual echo */ + u *= u; + } +#endif + ec->pos--; + if (ec->pos < 0) + ec->pos = ec->taps-1; + u *= 32767.0; + if (u < -32768.0) + u = -32768.0; + if (u > 32767.0) + u = 32767.0; + return (short)(u); +} + +static inline echo_can_state_t *echo_can_create(int taps, int adaption_mode) +{ + echo_can_state_t *ec; + taps = NTAPS; + ec = MALLOC(sizeof(echo_can_state_t)); + if (ec) { + memset(ec, 0, sizeof(ec)); + ec->taps = taps; + ec->pos = ec->taps-1; + } + return ec; +} + +#endif @@ -89,7 +89,7 @@ #define ZT_SIG_HDLCFCS ((1 << 9) | ZT_SIG_HDLCRAW) /* HDLC with FCS calculation */ #define ZT_SIG_HDLCNET ((1 << 10) | ZT_SIG_HDLCFCS) /* HDLC Network */ #define ZT_SIG_SLAVE (1 << 11) /* Slave to another channel */ -#define ZT_SIG_CAS (1 << 12) /* Just get bits */ +#define ZT_SIG_CAS (1 << 15) /* Just get bits */ #define ZT_ABIT 8 #define ZT_BBIT 4 @@ -129,8 +129,10 @@ #include "sec-2.h" #elif defined(ECHO_CAN_MARK) #include "mec.h" -#else +#elif defined(ECHO_CAN_MARK2) #include "mec2.h" +#else +#include "mec3.h" #endif #endif @@ -168,6 +170,7 @@ int alarms; /* alarms status */ int txlevel; /* what TX level is set to */ int rxlevel; /* current RX level */ int bpvcount; /* current BPV count */ +int irqmisses; /* current IRQ misses */ int syncsrc; /* span # of current sync source, or 0 for free run */ int numchans; /* number of configured channels on this span */ int totalchans; /* total number of channels on the span */ @@ -671,6 +674,12 @@ struct zt_tone_def { /* Structure for zone programming */ /* Ret Value for bits changing on a CAS / User channel */ #define ZT_EVENT_BITSCHANGED 13 +/* Ret value for the beginning of a pulse coming on its way */ +#define ZT_EVENT_PULSE_START 14 + +#define ZT_EVENT_PULSEDIGIT (1 << 16) /* This is OR'd with the digit received */ +#define ZT_EVENT_DTMFDIGIT (1 << 17) /* Ditto for DTMF */ + /* Flag Value for IOMUX, read avail */ #define ZT_IOMUX_READ 1 @@ -735,6 +744,10 @@ struct zt_tone_def { /* Structure for zone programming */ #define ZT_DEFAULT_RXFLASHTIME 1250 /* 1250ms longest rx flash */ #define ZT_DEFAULT_DEBOUNCETIME 600 /* 600ms of FXS GS signalling debounce */ +#define ZT_MINPULSETIME (15 * 8) /* 15 ms minimum */ +#define ZT_MAXPULSETIME (150 * 8) /* 150 ms maximum */ +#define ZT_PULSETIMEOUT ((ZT_MAXPULSETIME / 8) + 50) + #define ZT_LOOPCODE_TIME 10000 /* send loop codes for 10 secs */ #define ZT_ALARMSETTLE_TIME 5000 /* allow alarms to settle for 5 secs */ #define ZT_AFTERSTART_TIME 500 /* 500ms after start */ @@ -838,7 +851,7 @@ struct zt_chan { int eventinidx; /* out index in event buf (circular) */ int eventoutidx; /* in index in event buf (circular) */ - u_char eventbuf[ZT_MAX_EVENTSIZE]; /* event circ. buffer */ + unsigned int eventbuf[ZT_MAX_EVENTSIZE]; /* event circ. buffer */ wait_queue_head_t eventbufq; /* event wait queue */ wait_queue_head_t txstateq; /* waiting on the tx state to change */ @@ -920,7 +933,12 @@ struct zt_chan { /* RING debounce timer */ int ringdebtimer; + /* PULSE digit receiver stuff */ + int pulsecount; + int pulsetimer; + /* RBS timers */ + int itimerset; /* what the itimer was set to last */ int itimer; int otimer; @@ -1014,6 +1032,8 @@ struct zt_span { int maintstat; /* Maintenance state */ wait_queue_head_t maintq; /* Maintenance queue */ int mainttimer; /* Maintenance timer */ + + int irqmisses; /* Interrupt misses */ struct zt_chan *chans; /* Member channel structures */ |