diff options
author | Shaun Ruffell <sruffell@digium.com> | 2010-08-17 11:53:18 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2010-08-17 11:53:18 +0000 |
commit | fe514454e37522c96392d5d6c65e83f1257e5662 (patch) | |
tree | 7bd03ea3b5a9d5f820f1b284b91aebb819de5ca3 /drivers/dahdi/wctdm24xxp | |
parent | 3f5401d777a967f003c9edadb8686932065e884d (diff) |
wcte12xp, wctdm24xxp: Add compile time option CONFIG_VOICEBUS_ECREFERENCE.
Add compile time option to improve the reference signal provided to
software echo cancelers. The intent here is for this functionality to
become the default behavior but more testing and work on the edge cases
is needed. It's being brought in now as a compile time option since there
have been reports that it helps in some environments.
Instead of using two buffers, which means that at best we're two
milliseconds behind, use a circular buffer where audio data is written
on the transmit side and read on the receive path. In this way high
latency values will not interfere with the operation of software
echo cancelers. DAHDI-291. DAHDI-387.
This work was originally on:
http://svn.asterisk.org/svn/dahdi/linux/team/sruffell/improved_ecreference@9143
and includes a generic kfifo replacement by Matt Fredrickson.
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9144 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/wctdm24xxp')
-rw-r--r-- | drivers/dahdi/wctdm24xxp/base.c | 36 | ||||
-rw-r--r-- | drivers/dahdi/wctdm24xxp/wctdm24xxp.h | 3 |
2 files changed, 39 insertions, 0 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index 4a7f1fd..eefba37 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -943,6 +943,13 @@ static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char *writechun } } insert_tdm_data(wc, writechunk); +#ifdef CONFIG_VOICEBUS_ECREFERENCE + for (x = 0; x < wc->avchannels; ++x) { + __dahdi_fifo_put(wc->ec_reference[x], + wc->chans[x]->chan.writechunk, + DAHDI_CHUNKSIZE); + } +#endif } for (x = 0; x < DAHDI_CHUNKSIZE; x++) { @@ -1192,7 +1199,14 @@ static inline void wctdm_receiveprep(struct wctdm *wc, const u8 *readchunk) if (likely(wc->initialized)) { for (x = 0; x < wc->avchannels; x++) { struct dahdi_chan *c = &wc->chans[x]->chan; +#ifdef CONFIG_VOICEBUS_ECREFERENCE + unsigned char buffer[DAHDI_CHUNKSIZE]; + __dahdi_fifo_get(wc->ec_reference[x], buffer, + ARRAY_SIZE(buffer)); + dahdi_ec_chunk(c, c->readchunk, buffer); +#else dahdi_ec_chunk(c, c->readchunk, c->writechunk); +#endif } for (x = 0; x < MAX_SPANS; x++) { @@ -4317,6 +4331,12 @@ static void wctdm_back_out_gracefully(struct wctdm *wc) LIST_HEAD(local_list); voicebus_release(&wc->vb); +#ifdef CONFIG_VOICEBUS_ECREFERENCE + for (i = 0; i < ARRAY_SIZE(wc->ec_reference); ++i) { + if (wc->ec_reference[i]) + dahdi_fifo_free(wc->ec_reference[i]); + } +#endif for (i = 0; i < ARRAY_SIZE(wc->spans); ++i) { if (wc->spans[i] && wc->spans[i]->span.chans) @@ -4872,6 +4892,22 @@ __wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } up(&ifacelock); +#ifdef CONFIG_VOICEBUS_ECREFERENCE + for (i = 0; i < ARRAY_SIZE(wc->ec_reference); ++i) { + /* 256 is the smallest power of 2 that will contains the + * maximum possible amount of latency. */ + wc->ec_reference[i] = dahdi_fifo_alloc(256, GFP_KERNEL); + + if (IS_ERR(wc->ec_reference[i])) { + ret = PTR_ERR(wc->ec_reference[i]); + wc->ec_reference[i] = NULL; + wctdm_back_out_gracefully(wc); + return ret; + } + } +#endif + + wc->desc = (struct wctdm_desc *)ent->driver_data; /* This is to insure that the analog span is given lowest priority */ diff --git a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h index 1452850..ebacff1 100644 --- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h +++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h @@ -269,6 +269,9 @@ struct wctdm { struct wctdm_span *aspan; /* pointer to the spans[] holding the analog span */ struct wctdm_span *spans[MAX_SPANS]; struct wctdm_chan *chans[NUM_MODULES]; +#ifdef CONFIG_VOICEBUS_ECREFERENCE + struct dahdi_fifo *ec_reference[NUM_MODULES]; +#endif /* Only care about digital spans here */ /* int span_timing_prio[MAX_SPANS - 1]; */ |