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 <sruffell@digium.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9941 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
Shaun Ruffell 2011-06-02 20:01:40 +00:00
parent 76df5ab26b
commit dd33d6c357
2 changed files with 36 additions and 33 deletions

View File

@ -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;x<DAHDI_CHUNKSIZE;x++) {
rxlin = DAHDI_XLAW(rxchunk[x], ss);
rxlin = DAHDI_XLAW(preecchunk[x], ss);
if (ss->ec_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);

View File

@ -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)