summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-07-10 07:49:12 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-07-10 07:49:12 +0000
commitca6ee333c18fdc3b5ed68d9a44eb32bb23a09539 (patch)
tree9f95d047df6325d1283d8bfecdcda174f003f785
parente1e4fa86823223cd447bcb034db2a3845977e12c (diff)
PCM: A bugfix that was reintroduced in r4352:
After this change, the echo-canceler buffers were not cleared in some cases. As a result when one FXS is put ONHOOK, the other side could hear noise for a second or two until full disconnect is done. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@4407 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r--xpp/xbus-pcm.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/xpp/xbus-pcm.c b/xpp/xbus-pcm.c
index 644f1b9..ff4bee1 100644
--- a/xpp/xbus-pcm.c
+++ b/xpp/xbus-pcm.c
@@ -865,23 +865,30 @@ void generic_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
pcm = RPACKET_FIELD(pack, GLOBAL, PCM_READ, pcm);
pcm_mask = RPACKET_FIELD(pack, GLOBAL, PCM_READ, lines);
spin_lock_irqsave(&xpd->lock, flags);
- pcm_mute = xpd->mute_dtmf | xpd->silence_pcm;
+ /*
+ * Calculate the channels we want to mute
+ */
+ pcm_mute = ~xpd->wanted_pcm_mask;
+ pcm_mute |= xpd->mute_dtmf | xpd->silence_pcm;
if(!SPAN_REGISTERED(xpd))
goto out;
for (i = 0; i < xpd->channels; i++) {
volatile u_char *r = xpd->span.chans[i].readchunk;
bool got_data = IS_SET(pcm_mask, i);
- if(IS_SET(xpd->wanted_pcm_mask, i)) {
- /* Must fill zaptel buffers */
- if(got_data && !IS_SET(pcm_mute, i)) {
- /* We have and want real data */
- // memset((u_char *)r, 0x5A, ZT_CHUNKSIZE); // DEBUG
- // fill_beep((u_char *)r, 1, 1); // DEBUG: BEEP
- memcpy((u_char *)r, pcm, ZT_CHUNKSIZE);
- } else {
- /* Inject SILENCE */
- memset((u_char *)r, 0x7F, ZT_CHUNKSIZE);
+ if(got_data && !IS_SET(pcm_mute, i)) {
+ /* We have and want real data */
+ // memset((u_char *)r, 0x5A, ZT_CHUNKSIZE); // DEBUG
+ // fill_beep((u_char *)r, 1, 1); // DEBUG: BEEP
+ memcpy((u_char *)r, pcm, ZT_CHUNKSIZE);
+ } else if(IS_SET(xpd->wanted_pcm_mask | xpd->silence_pcm, i)) {
+ /* Inject SILENCE */
+ memset((u_char *)r, 0x7F, ZT_CHUNKSIZE);
+ if(IS_SET(xpd->silence_pcm, i)) {
+ /*
+ * This will clear the EC buffers until next tick
+ * So we don't have noise residues from the past.
+ */
memset(xpd->ec_chunk2[i], 0x7F, ZT_CHUNKSIZE);
memset(xpd->ec_chunk1[i], 0x7F, ZT_CHUNKSIZE);
}