[Speex-dev] Is Speex 1.0 and >=1.1 compatible?

Jean-Marc Valin jean-marc.valin at usherbrooke.ca
Sun Apr 11 06:52:54 PDT 2010


The main difference is not that much in the bit-stream but in the API. 
In earlier versions you had to append the terminator manually, whereas I 
modifed later versions to do it automatically in case programmers forgot 
(there was no reason not to do so).

	Jean-Marc

On 2010-04-11 05:23, Tobias wrote:
> On Saturday 10 April 2010 21.51.55 Jean-Marc Valin wrote:
>> All version after 1.0 are compatible with each other and with 1.0.
>
> Hi Jean-Marc and thanks for the quick reply.
>
> I have now looked at this further and got the idea to hard code the number of
> frames in the decoder temporarily as a test and voilà, it works! The problem
> seem to be some incompatibility in the termination handling. After processing
> exactly four frames the number of remaining bits can be anything from zero to
> seven which I guess is normal. However, if I use the while loop below,
> speex_decode will get called one more time (a total of five times) and that
> seem to mess up the decoder state. The decoded audio get sort of "bubbly".
>
> while ((speex_decode(dec_state,&bits, samples) == 0)&&
>            (speex_bits_remaining(&bits)>=  0)) {}
>
> As far as I can see, the termination handling is not compatible when encoding
> with, in this case, Speex ver 1.2rc1 and decoding with ver 1.0.5. Do you agree
> or have I done something wrong in my code?  The full code can be found here:
>
> http://svxlink.svn.sf.net/viewvc/svxlink/trunk/src/async/audio/AsyncAudioDecoderSpeex.cpp?view=markup
> http://svxlink.svn.sf.net/viewvc/svxlink/trunk/src/async/audio/AsyncAudioEncoderSpeex.cpp?view=markup
>
> I guess I could solve this problem by transmitting the frame count out-of-band
> but if Speex can handle it, it's better.
>
> Regards,
> Tobias
>
>
>>
>> 	Jean-Marc
>>
>> On 2010-04-10 15:44, Tobias wrote:
>>> Hi list,
>>>
>>> I'm trying to figure out how to do the most compatible implementation
>>> that will work with as many versions of Speex as possible. I am
>>> streaming multi frame Speex blocks over a TCP connection which works
>>> fine as long as the version of Speex is the same on both sides. When
>>> using a newer Speex (1.1.?) to encode and an older version to decode
>>> (1.0.5), it does not work.
>>>
>>> The encoder code look like this:
>>>
>>> int AudioEncoderSpeex::writeSamples(const float *samples, int count)
>>> {
>>>
>>>     for (int i=0; i<count; ++i)
>>>     {
>>>
>>>       sample_buf[buf_len++] = samples[i] * 32767.0;
>>>
>>>       if (buf_len == frame_size)
>>>       {
>>>
>>>         speex_encode(enc_state, sample_buf,&bits);
>>>         buf_len = 0;
>>>
>>>         if (++frame_cnt == 4) // Four frames per packet
>>>         {
>>>
>>>           speex_bits_insert_terminator(&bits);
>>>           int nbytes = speex_bits_nbytes(&bits);
>>>           char output_buf[nbytes];
>>>           nbytes = speex_bits_write(&bits, output_buf, nbytes);
>>>           writeEncodedSamples(output_buf, nbytes);
>>>           speex_bits_reset(&bits);
>>>           frame_cnt = 0;
>>>
>>>         }
>>>
>>>       }
>>>
>>>     }
>>>
>>>     return count;
>>>
>>> } /* AudioEncoderSpeex::writeSamples */
>>>
>>>
>>>
>>> The decoder have looked like this for quite a while:
>>>
>>> void AudioDecoderSpeex::writeEncodedSamples(void *buf, int size)
>>> {
>>>
>>>     char *ptr = (char *)buf;
>>>
>>>     speex_bits_read_from(&bits, ptr, size);
>>>     float samples[frame_size];
>>>
>>> #if SPEEX_MAJOR>   1 || (SPEEX_MAJOR == 1&&   SPEEX_MINOR>= 1)
>>>
>>>     while (speex_decode(dec_state,&bits, samples) == 0)
>>>
>>> #else
>>>
>>>     while ((speex_decode(dec_state,&bits, samples) == 0)&&
>>>
>>>            (speex_bits_remaining(&bits)>   0))
>>>
>>> #endif
>>>
>>>     {
>>>
>>>       for (int i=0; i<frame_size; ++i)
>>>       {
>>>
>>>         samples[i] = samples [i] / 32767.0;
>>>
>>>       }
>>>       sinkWriteSamples(samples, frame_size);
>>>
>>>     }
>>>
>>> } /* AudioDecoderSpeex::writeEncodedSamples */
>>>
>>>
>>> This have worked well when using the same version of Speex on both sides.
>>> When using 1.1 on the encoder and 1.0 on the decoder, the number of
>>> frames decoded varies between three and four even though four frames are
>>> always sent. The use of speex_bits_remaining is one I have found by
>>> Googling. I started to wonder if it's wrong now though. If I change the
>>> comparison to read
>>> "speex_bits_remaining(&bits)>= 0" I always get four frames decoded.
>>> However, it still does not sound correctly. The change from ">" to">="
>>> makes sense though. It should be OK for speex_decode to consume all bits
>>> so zero bits remaining should be OK (or?).
>>>
>>> The original question was if versions 1.0 and>= 1.1 is compatible. Can I
>>> make the code work in all cases or am I on a "mission impossible"?
>>>
>>> Regards,
>>> Tobias
> _______________________________________________
> Speex-dev mailing list
> Speex-dev at xiph.org
> http://lists.xiph.org/mailman/listinfo/speex-dev
>
>


More information about the Speex-dev mailing list