From dd33d6c35768cdc34cce51070c76a13ad5e41ffe Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Thu, 2 Jun 2011 20:01:40 +0000 Subject: [PATCH] dahdi: Update the dahdi_ec_chunk interface to support preec streams. dahdi_ec_chunk is the function that saves the received audio and places a signed linear copy of it in the pre echocanceled buffer on the channel. By splitting the input and output of this function into two parameters, a driver that can provide separate pre and post ec streams can pass them independently to DAHDI, without worrying about DAHDI overwriting a stream that may have already been echocanceled by the hardware. Previously, the dahdi_ec_chunk interface took a received audio buffer and overwrote it after canceling the echo. Now the input and output from the function are broken up in order to support hardware echocans that have a different preechocan stream. Signed-off-by: Shaun Ruffell Acked-by: Tzafrir Cohen git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9941 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/dahdi-base.c | 59 ++++++++++++++++++-------------------- include/dahdi/kernel.h | 10 +++++-- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c index b91ec12..a6290f9 100644 --- a/drivers/dahdi/dahdi-base.c +++ b/drivers/dahdi/dahdi-base.c @@ -7730,8 +7730,22 @@ static void process_echocan_events(struct dahdi_chan *chan) } } -static void -__dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, const u8 *txchunk) +/** + * __dahdi_ec_chunk() - process echo for a single channel + * @ss: DAHDI channel + * @rxchunk: buffer to store audio with cancelled audio + * @preecchunk: chunk of audio on which to cancel echo + * @txchunk: reference chunk from the other direction + * + * The echo canceller function fixes received (from device to userspace) + * audio. In order to fix it it uses the transmitted audio as a + * reference. This call updates the echo canceller for a single chunk (8 + * bytes). + * + * Call with local interrupts disabled. + */ +void __dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, + const u8 *preecchunk, const u8 *txchunk) { short rxlin; int x; @@ -7740,7 +7754,7 @@ __dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, const u8 *txchunk) /* Save a copy of the audio before the echo can has its way with it */ for (x = 0; x < DAHDI_CHUNKSIZE; x++) /* We only ever really need to deal with signed linear - let's just convert it now */ - ss->readchunkpreec[x] = DAHDI_XLAW(rxchunk[x], ss); + ss->readchunkpreec[x] = DAHDI_XLAW(preecchunk[x], ss); } /* Perform echo cancellation on a chunk if necessary */ @@ -7751,7 +7765,7 @@ __dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, const u8 *txchunk) if (ss->ec_state->status.mode & __ECHO_MODE_MUTE) { /* Special stuff for training the echo can */ for (x=0;xec_state->status.mode == ECHO_MODE_PRETRAINING) { if (--ss->ec_state->status.pretrain_timer <= 0) { ss->ec_state->status.pretrain_timer = 0; @@ -7778,7 +7792,8 @@ __dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, const u8 *txchunk) short rxlins[DAHDI_CHUNKSIZE], txlins[DAHDI_CHUNKSIZE]; for (x = 0; x < DAHDI_CHUNKSIZE; x++) { - rxlins[x] = DAHDI_XLAW(rxchunk[x], ss); + rxlins[x] = DAHDI_XLAW(preecchunk[x], + ss); txlins[x] = DAHDI_XLAW(txchunk[x], ss); } ss->ec_state->ops->echocan_process(ss->ec_state, rxlins, txlins, DAHDI_CHUNKSIZE); @@ -7797,27 +7812,7 @@ __dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, const u8 *txchunk) #endif } } - -/** - * _dahdi_ec_chunk() - process echo for a single channel - * @ss: DAHDI channel - * @rxchunk: chunk of audio on which to cancel echo - * @txchunk: reference chunk from the other direction - * - * The echo canceller function fixes received (from device to userspace) - * audio. In order to fix it it uses the transmitted audio as a - * reference. This call updates the echo canceller for a single chunk (8 - * bytes). - * - * Call with local interrupts disabled. - */ -void _dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, const u8 *txchunk) -{ - spin_lock(&ss->lock); - __dahdi_ec_chunk(ss, rxchunk, txchunk); - spin_unlock(&ss->lock); -} -EXPORT_SYMBOL(_dahdi_ec_chunk); +EXPORT_SYMBOL(__dahdi_ec_chunk); /** * dahdi_ec_span() - process echo for all channels in a span. @@ -7831,11 +7826,13 @@ void _dahdi_ec_span(struct dahdi_span *span) { int x; for (x = 0; x < span->channels; x++) { - if (span->chans[x]->ec_current) { - spin_lock(&span->chans[x]->lock); - __dahdi_ec_chunk(span->chans[x], span->chans[x]->readchunk, span->chans[x]->writechunk); - spin_unlock(&span->chans[x]->lock); - } + struct dahdi_chan *const chan = span->chans[x]; + if (!chan->ec_current) + continue; + + spin_lock(&chan->lock); + _dahdi_ec_chunk(chan, chan->readchunk, chan->writechunk); + spin_unlock(&chan->lock); } } EXPORT_SYMBOL(_dahdi_ec_span); diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h index 56a75cf..41196e4 100644 --- a/include/dahdi/kernel.h +++ b/include/dahdi/kernel.h @@ -1158,8 +1158,14 @@ struct dahdi_tone *dahdi_mf_tone(const struct dahdi_chan *chan, char digit, int as possible. ECHO CANCELLATION IS NO LONGER AUTOMATICALLY DONE AT THE DAHDI LEVEL. dahdi_ec_chunk will not echo cancel if it should not be doing so. rxchunk is modified in-place */ -void _dahdi_ec_chunk(struct dahdi_chan *chan, unsigned char *rxchunk, - const unsigned char *txchunk); +void __dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, + const u8 *preecchunk, const u8 *txchunk); + +static inline void _dahdi_ec_chunk(struct dahdi_chan *chan, + u8 *rxchunk, const u8 *txchunk) +{ + __dahdi_ec_chunk(chan, rxchunk, rxchunk, txchunk); +} static inline void dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk)