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:
parent
76df5ab26b
commit
dd33d6c357
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user