[Asterisk-Dev] Packet loss concealment for xLaw to Zaptel..

Steve Kann stevek at stevek.com
Wed Mar 16 16:57:20 MST 2005


One of the open issues remaining for the new jitterbuffer and PLC 
systems is that when a call is bridged between VoIP and zaptel, and the 
frames are not going through a translator, then PLC does not take place.

So, instead of having an interpolated frame used when a frame is lost, 
we get silence, and one of the principal benefits of this new system is 
lost.

There's lots of ways to address this.  Basically, to use Steve 
Underwood's PLC code in this situation, we need to go through slinear 
for audio sent to zaptel.

The simplest (if not most efficient) solution to this problem seemed to 
me to find some way to (if so configured), force all zaptel channels to 
linear mode.  In this way, asterisk will take things from xLaw to 
slinear and apply PLC, and zaptel in the kernel will take it back to xLaw.

I tried this little hack, though, and it worked when calls came _from_ 
zaptel, but didn't seem to work for calls going to zaptel:

====================
diff -u -w -r1.414 chan_zap.c
--- channels/chan_zap.c 5 Mar 2005 02:08:37 -0000 1.414
+++ channels/chan_zap.c 8 Mar 2005 22:08:24 -0000
@@ -630,7 +630,8 @@
 static const struct ast_channel_tech zap_tech = {
        .type = type,
        .description = tdesc,
- .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW,
+// .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW,
+ .capabilities = AST_FORMAT_SLINEAR,
        .requester = zt_request,
        .send_digit = zt_digit,
        .send_text = zt_sendtext,
@@ -4681,6 +4682,16 @@
                tmp->rawwriteformat = deflaw;
                tmp->writeformat = deflaw;
                i->subs[index].linear = 0;
+
+/* HACK */
+ tmp->nativeformats =
+ tmp->rawreadformat =
+ tmp->readformat =
+ tmp->rawwriteformat =
+ tmp->writeformat = AST_FORMAT_SLINEAR;
+ i->subs[index].linear = 1;
+/* /HACK */
+
                zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
                features = 0;
                if (i->busydetect && CANBUSYDETECT(i)) {
====================


However, this whole method would have the following effects, in this 
common case of using zaptel in the US on TE[14]xxP cards:

Incoming audio:
audio comes in via uLaw on TDM
zaptel in kernel translates uLaw to PCM
asterisk translates PCM back to uLaw
uLaw goes out via VoIP

Outgoing audio:
uLaw comes in via VoIP
asterisk translates uLaw to PCM [and does PLC if lost frames have been 
detected, etc]
zaptel in kernel translates PCM back to uLaw
uLaw goes out zaptel TDM

This is all not as efficient as it could be, but, on the other hand, 
uLaw <-> PCM translation is pretty cheap and it's lossless.

Ideally, what we'd do somehow, is basically, pass along the xLaw frames 
in the normal case, and keep a copy of them.

When we get an INTERP frame, we "seed" the PLC buffer, with the last 
frame we had, and then ask it to do plc_fillin for the missing frame.

After we do interpolation, we should send the next frame that we get 
through plc_rx as well, to "weave" in the new signal with the previously 
interpolated signal.

I started to try to implement that in zaptel, but I'm not sure all the 
extra code and complication from all this is actually worth it..   For 
my boxes, anyway, I'd be just as happy to figure out why my simple hack 
above didn't work.

Any thoughts?


 




More information about the asterisk-dev mailing list