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

Tobias blomman at ludd.ltu.se
Sat Apr 10 12:44:09 PDT 2010


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


More information about the Speex-dev mailing list