<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
<br>
[sorry for the loss of proper attributions, this is from two messages]:<br>
<br>
[Me]<br>
<pre wrap="">&gt;This is something I've encountered in trying to make a particular
<span class="moz-txt-citetags">&gt; </span>asterisk application handle properly IAX2 frames which contain either
<span class="moz-txt-citetags">&gt; </span>20ms of 40ms of speex data.  For a CBR case, where the bitrate is
<span class="moz-txt-citetags">&gt; </span>known, this is fairly easy to do, especially if the frames <span
 class="moz-txt-underscore"><span class="moz-txt-tag">_</span>do<span
 class="moz-txt-tag">_</span></span> always
<span class="moz-txt-citetags">&gt; </span>end on byte boundaries.  For a VBR case, it is more difficult, because
<span class="moz-txt-citetags">&gt; </span>it doesn't look like there's a way to just parse the speex bitstream
<span class="moz-txt-citetags">&gt; </span>and break it up into the constituent 20ms frames.
</pre>
<pre wrap=""><!---->
[Jean Marc]
It would be possible, but unnecessarily messy. 

</pre>
<br>
<br>
Jean-Marc Valin wrote:<br>
<br>
[me]<br>
<blockquote cite="mid1100710393.3788.42.camel@localhost" type="cite">
  <blockquote type="cite">
    <pre wrap="">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.
    </pre>
  </blockquote>
  <pre wrap=""><!---->
  </pre>
</blockquote>
[Jean-Marc]<br>
<blockquote cite="mid1100710393.3788.42.camel@localhost" type="cite">
  <pre wrap="">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.
  </pre>
</blockquote>
<br>
I'm revisiting this issue now.&nbsp; It looks like it would help to have the
ability to:<br>
<br>
1) Take a look at some speex data, and return the number of samples it
contains.&nbsp; This would go here in asterisk, for example:<br>
<br>
asterisk/channels/chan_iax2.c:<br>
static int get_samples(struct ast_frame *f)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int samples=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(f-&gt;subclass) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case AST_FORMAT_SPEEX:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; samples = 160;&nbsp; /* XXX Not necessarily true XXX */<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case AST_FORMAT_G723_1:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; samples = 240 /* XXX Not necessarily true XXX */;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case AST_FORMAT_ILBC:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; samples = 240 * (f-&gt;datalen / 50);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case AST_FORMAT_GSM:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; samples = 160 * (f-&gt;datalen / 33);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case AST_FORMAT_G729A:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; samples = 160 * (f-&gt;datalen / 20);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>
[...]<br>
}<br>
<br>
In this case, though, chan_iax2.c doesn't necessarily know if the speex
codec is loaded..<br>
<br>
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.&nbsp; [The first API could be a subset of this].<br>
<br>
The main API would be: <br>
<br>
int speex_decode_bits(SpeexBits *inBits, SpeexBits*outBits).&nbsp; <br>
<br>
inBits is SpeexBits containing the bits we're interested in.<br>
outBits may be NULL.&nbsp; If not NULL, and inBits contains valid frames,
they are written, one frame per call, to outBits.<br>
<br>
it would return the same values as speex_decode(_int).<br>
<br>
<br>
SpeexBits inBits, outBits;<br>
void *state;<br>
<br>
initialize:<br>
&nbsp;&nbsp;&nbsp; state = speex_decoder_init(&amp;speex_nb_mode);<br>
<br>
<br>
process:<br>
&nbsp;&nbsp;&nbsp; speex_bits_read_from(&amp;inBits, inBuf, inlen);<br>
<br>
&nbsp;&nbsp;&nbsp; for(i=0; ;i+=160) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; if(speex_decode_bits(&amp;inBits,&amp;outBits)) break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* do something with outBits, if you want */<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; (i) now contains the number of samples contained in inBuf.<br>
<br>
<br>
I think this is the simplest, most sensible API, no?<br>
<br>
-SteveK<br>
<br>
<br>
</body>
</html>