[Home]

Summary:ASTERISK-03019: Speex with Xten phone is buggy (Zap dialed part hears silence)
Reporter:tony robin (tony robin)Labels:
Date Opened:2004-12-16 22:39:12.000-0600Date Closed:2011-06-07 14:10:16
Priority:MinorRegression?No
Status:Closed/CompleteComponents:Channels/chan_sip/CodecHandling
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:
Description:I am having a hard time trying to get Speex to work flawlessly with Asterisk and Xten phone.
I first compiled Speex 1.1.6 and then Asterisk. At the first dial, Asterisk core dumps.
I then compiled Speex 1.0.4 and then Asterisk. When the communication starts (Dial Zap), it seems to work but Asterisk produces a lot of warnings (see Additional info) and the dialed person doesn't hear any sound.
I tried to compile Speex with and without sse optimization but it doesn't resolve the bugs.

****** ADDITIONAL INFORMATION ******

$ uname -a
Linux PBX 2.6.8.1 #2 SMP Thu Oct 14 23:53:45 CEST 2004 i686 Intel(R) Xeon(TM) CPU 3.06GHz GenuineIntel GNU/Linux
$ emerge -V
Portage 2.0.51-r3 (default-linux/x86/2004.2, gcc-3.3.4, glibc-2.3.4.20041006-r0, 2.6.8.1 i686)
$ gcc --version
gcc (GCC) 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)
$ /lib/libc.so.6
GNU C Library 20041006 release version 2.3.4, by Roland McGrath et al.
$ asterisk -vr
IPBX*CLI> show version
Asterisk 1.0.2 built by root@PBX on a i686 running Linux
IPBX*CLI>
Dec 17 04:56:42 WARNING[262160]: chan_sip.c:2820 process_sdp: No compatible codecs!
Dec 17 04:56:44 WARNING[262160]: chan_sip.c:2820 process_sdp: No compatible codecs!
   -- Executing Dial("SIP/191-1405", "Zap/g1/999999999") in new stack
   -- Called g1/999999999
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:45 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:45 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:46 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:46 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:46 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:46 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:46 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:46 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:46 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:46 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:46 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:46 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Dec 17 04:56:46 WARNING[13893650]: codec_speex.c:166 speextolin_framein: Out of buffer space
Dec 17 04:56:46 WARNING[13893650]: chan_zap.c:4173 zt_write: Frame too large
Comments:By: Clod Patry (junky) 2004-12-16 22:46:56.000-0600

What's your config on this soft phone?
Which product of x-ten? X-Pro or X-lite? which version?

By: tony robin (tony robin) 2004-12-16 23:07:59.000-0600

X-PRO release 1103g build stamp 14162

Config : only SPX is selected (codecs tested with success : G711a iLBC).

Speex Magic Number: 110
Speex Quality: 9
Speex Complexity: 4

[HKEY_CURRENT_USER\Software\XtenNetworksInc\X-PRO]
"settings:TransmitSilence"=dword:00000001
"Speex:MagicNumber"=dword:0000006e
"Speex:Enabled"=dword:00000001

By: Brian West (bkw918) 2004-12-17 00:02:04.000-0600

you can work around this... also apply the .reg fix in the contrib folder.

bkw

By: tony robin (tony robin) 2004-12-17 01:57:32.000-0600

Registry fix already applied as you can see above.

What do you mean by "you can work around this..." ? That few people use Speex or that I am the first to report this bug ?

G711a consumes a lot of bandwidth and iLBC audio quality is poor. So Speex is the natural choice of my company.

By: Brian West (bkw918) 2004-12-17 10:03:38.000-0600

No but GSM and ilbc are both supported by that softphone and use the exact same bandwidth.  This is a known issue but ONLY with xlite because it seems they tack on a header and we dont need that.  

bkw

By: Brian West (bkw918) 2004-12-17 21:25:41.000-0600

Also if you have ilbc audio issues... then its a local issue... try turning off silence supression.  ilbc here sounds flawless.

bkw

By: Mark Spencer (markster) 2004-12-18 08:31:45.000-0600

Actually it may be the other way around.  Speex is a very difficult codec to support because it doesn't have any way to know the number of frames.  When running Speex over IAX2 we add a trailing flag which can say that's the end of the frame.  It may be possible in rtp.c to take the incoming speex, convert to bits, add the trailing piece and convert back, possibly -- I don't know for sure.  If not, we may just have to drop Speex support on RTP or someone else can try to come up with a solution.

By: Clod Patry (junky) 2004-12-21 00:34:04.000-0600

Tony Robin: any update here?
did you try with GSM?
What's your solution exactly?

By: stevekstevek (stevekstevek) 2004-12-21 18:43:59.000-0600

Interestingly, I'm working on a similar issue, and I just wrote a message describing the API I'd like to see for this.  I had talked about this with Jean-Marc earlier.

But, doesn't rtp send along something to let you know the number of samples?

Here's the message [sorry if the formatting is ugly]:
===========================================
[Me]

>This is something I've encountered in trying to make a particular
> asterisk application handle properly IAX2 frames which contain either
> 20ms of 40ms of speex data.  For a CBR case, where the bitrate is
> known, this is fairly easy to do, especially if the frames _do_ always
> end on byte boundaries.  For a VBR case, it is more difficult, because
> it doesn't look like there's a way to just parse the speex bitstream
> and break it up into the constituent 20ms frames.


[Jean Marc]
It would be possible, but unnecessarily messy.




Jean-Marc Valin wrote:

[me]

>>I looked at nb_celp.c, and it seems that it would be pretty messy.
>>I'd need to implement a lot of the actual codec just to be able to
>>determine the number of frames in a packet.
>>    
>>
>
>  
>
[Jean-Marc]

>No, it's one step above nb_celp.c, all you need to implement is 8
>functions (init, destroy, process and ctl, for both encode and decode).
>It can be done fairly easily. Look at modes.c perhaps. The only struct
>that needs to be filled is SpeexMode. Even then, I'm willing to add an
>even simpler layer if necessary.
>  
>

I'm revisiting this issue now.  It looks like it would help to have the ability to:

1) Take a look at some speex data, and return the number of samples it contains.  This would go here in asterisk, for example:

asterisk/channels/chan_iax2.c:
static int get_samples(struct ast_frame *f)
{
       int samples=0;
       switch(f->subclass) {
       case AST_FORMAT_SPEEX:
               samples = 160;  /* XXX Not necessarily true XXX */
               break;
       case AST_FORMAT_G723_1:
               samples = 240 /* XXX Not necessarily true XXX */;
               break;
       case AST_FORMAT_ILBC:
               samples = 240 * (f->datalen / 50);
               break;
       case AST_FORMAT_GSM:
               samples = 160 * (f->datalen / 33);
               break;
       case AST_FORMAT_G729A:
               samples = 160 * (f->datalen / 20);
               break;
[...]
}

In this case, though, chan_iax2.c doesn't necessarily know if the speex codec is loaded..

And later, it might also be useful to have an API which takes a bunch of SpeexBits, and gives the caller a way to split up the SpeexBits into separate 20ms frames.  [The first API could be a subset of this].

The main API would be:

int speex_decode_bits(SpeexBits *inBits, SpeexBits*outBits).

inBits is SpeexBits containing the bits we're interested in.
outBits may be NULL.  If not NULL, and inBits contains valid frames, they are written, one frame per call, to outBits.

it would return the same values as speex_decode(_int).


SpeexBits inBits, outBits;
void *state;

initialize:
   state = speex_decoder_init(&speex_nb_mode);


process:
   speex_bits_read_from(&inBits, inBuf, inlen);

   for(i=0; ;i+=160) {
      if(speex_decode_bits(&inBits,&outBits)) break;
     
       /* do something with outBits, if you want */
   }

   (i) now contains the number of samples contained in inBuf.


I think this is the simplest, most sensible API, no?

-SteveK
================================

By: stevekstevek (stevekstevek) 2004-12-23 10:16:01.000-0600

It seems that the draft RTP profile for speex,

http://www.speex.org/drafts/draft-herlein-speex-rtp-profile-02.txt

Is to just put the raw speex bits into the payload, and pad it with
  "a 0 followed by all ones
  (until the end of the octet).  This padding is only required for
  the last frame in the packet, and only to ensure the packet
  contents ends on an octet boundary."

If X-ten is adding a preceeding header, then they're not following the draft protocol.

By: twisted (twisted) 2005-01-09 22:27:36.000-0600

So what's happening here?  Is X-Ten breaking the "law" of speex?  Is this an issue which still needs to be addressed?  What's going on?

--housekeeping

By: twisted (twisted) 2005-01-28 19:58:49.000-0600

Final request for status

By: Olle Johansson (oej) 2005-02-13 13:30:30.000-0600

No activity, obviously no interest any more.

/Housekeeping