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 | ae6e3004f82f0173072ab10069722c80106aea36 (patch) | |
tree | 7bd03ea3b5a9d5f820f1b284b91aebb819de5ca3 /drivers/dahdi/wcte12xp | |
parent | 1e89ab194b9cdcfb36454fbeba81d31f52317d3b (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/wcte12xp')
-rw-r--r-- | drivers/dahdi/wcte12xp/base.c | 54 | ||||
-rw-r--r-- | drivers/dahdi/wcte12xp/wcte12xp.h | 8 |
2 files changed, 57 insertions, 5 deletions
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c index 03f40ae..46cd955 100644 --- a/drivers/dahdi/wcte12xp/base.c +++ b/drivers/dahdi/wcte12xp/base.c @@ -710,6 +710,13 @@ static void free_wc(struct t1 *wc) if (wc->wq) destroy_workqueue(wc->wq); +#ifdef CONFIG_VOICEBUS_ECREFERENCE + for (x = 0; x < ARRAY_SIZE(wc->ec_reference); ++x) { + if (wc->ec_reference[x]) + dahdi_fifo_free(wc->ec_reference[x]); + } +#endif + kfree(wc); } @@ -952,16 +959,20 @@ static void set_span_devicetype(struct t1 *wc) static int t1xxp_startup(struct dahdi_span *span) { struct t1 *wc = container_of(span, struct t1, span); - int i; +#ifndef CONFIG_VOICEBUS_ECREFERENCE + unsigned int i; +#endif check_and_load_vpm(wc); set_span_devicetype(wc); +#ifndef CONFIG_VOICEBUS_ECREFERENCE /* initialize the start value for the entire chunk of last ec buffer */ for (i = 0; i < span->channels; i++) { memset(wc->ec_chunk1[i], DAHDI_LIN2X(0, span->chans[i]), DAHDI_CHUNKSIZE); memset(wc->ec_chunk2[i], DAHDI_LIN2X(0, span->chans[i]), DAHDI_CHUNKSIZE); } +#endif /* Reset framer with proper parameters and start */ t1xxp_framer_start(wc, span); @@ -1901,6 +1912,13 @@ static inline void t1_transmitprep(struct t1 *wc, u8 *writechunk) dahdi_transmit(&wc->span); } +#ifdef CONFIG_VOICEBUS_ECREFERENCE + for (chan = 0; chan < wc->span.channels; chan++) { + __dahdi_fifo_put(wc->ec_reference[chan], + wc->chans[chan]->writechunk, DAHDI_CHUNKSIZE); + } +#endif + for (x = 0; x < DAHDI_CHUNKSIZE; x++) { if (likely(test_bit(INITIALIZED, &wc->bit_flags))) { for (chan = 0; chan < wc->span.channels; chan++) @@ -1924,6 +1942,8 @@ static inline void t1_transmitprep(struct t1 *wc, u8 *writechunk) } writechunk += (EFRAME_SIZE + EFRAME_GAP); } + + } /** @@ -1978,11 +1998,23 @@ static inline void t1_receiveprep(struct t1 *wc, const u8* readchunk) /* echo cancel */ if (likely(test_bit(INITIALIZED, &wc->bit_flags))) { +#ifdef CONFIG_VOICEBUS_ECREFERENCE + unsigned char buffer[DAHDI_CHUNKSIZE]; + for (x = 0; x < wc->span.channels; x++) { + __dahdi_fifo_get(wc->ec_reference[x], buffer, + ARRAY_SIZE(buffer)); + dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, + buffer); + } +#else for (x = 0; x < wc->span.channels; x++) { dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->ec_chunk2[x]); - memcpy(wc->ec_chunk2[x],wc->ec_chunk1[x],DAHDI_CHUNKSIZE); - memcpy(wc->ec_chunk1[x],wc->chans[x]->writechunk,DAHDI_CHUNKSIZE); + memcpy(wc->ec_chunk2[x], wc->ec_chunk1[x], + DAHDI_CHUNKSIZE); + memcpy(wc->ec_chunk1[x], wc->chans[x]->writechunk, + DAHDI_CHUNKSIZE); } +#endif dahdi_receive(&wc->span); } } @@ -2263,6 +2295,22 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi INIT_WORK(&wc->vpm_check_work, vpm_check_func); # endif +#ifdef CONFIG_VOICEBUS_ECREFERENCE + for (x = 0; x < ARRAY_SIZE(wc->ec_reference); ++x) { + /* 256 is used here since it is the largest power of two that + * will contain 8 * VOICBUS_DEFAULT_LATENCY */ + wc->ec_reference[x] = dahdi_fifo_alloc(256, GFP_KERNEL); + + if (IS_ERR(wc->ec_reference[x])) { + res = PTR_ERR(wc->ec_reference[x]); + wc->ec_reference[x] = NULL; + free_wc(wc); + return res; + } + + } +#endif /* CONFIG_VOICEBUS_ECREFERENCE */ + snprintf(wc->name, sizeof(wc->name)-1, "wcte12xp%d", index); pci_set_drvdata(pdev, wc); wc->vb.ops = &voicebus_operations; diff --git a/drivers/dahdi/wcte12xp/wcte12xp.h b/drivers/dahdi/wcte12xp/wcte12xp.h index 5994fa2..8c04afe 100644 --- a/drivers/dahdi/wcte12xp/wcte12xp.h +++ b/drivers/dahdi/wcte12xp/wcte12xp.h @@ -116,11 +116,15 @@ struct t1 { unsigned long bit_flags; unsigned long alarmtimer; unsigned char ledstate; - unsigned char ec_chunk1[32][DAHDI_CHUNKSIZE]; - unsigned char ec_chunk2[32][DAHDI_CHUNKSIZE]; struct dahdi_span span; /* Span */ struct dahdi_chan *chans[32]; /* Channels */ struct dahdi_echocan_state *ec[32]; /* Echocan state for channels */ +#ifdef CONFIG_VOICEBUS_ECREFERENCE + struct dahdi_fifo *ec_reference[32]; +#else + unsigned char ec_chunk1[32][DAHDI_CHUNKSIZE]; + unsigned char ec_chunk2[32][DAHDI_CHUNKSIZE]; +#endif unsigned long ctlreg; struct voicebus vb; atomic_t txints; |