[Speex-dev] Speex encoding/decoding producing garbled audio

Nathaniel Meyer nath_meyer at hotmail.com
Sun Sep 12 16:03:01 PDT 2004


I'm getting garbled playback with decoded fragments and I'm hoping someone 
here can point me in the right direction to correcting the problem.



Essentially I'm capturing audio from the microphone. I stream it over the 
net, but for testing purposes with this API I'm just grabbing the whole 
chunk and encoding / decoding it right away and then updating the sound 
buffer for playback. The playback sounds very scratchy with a bit of a buzz 
sound and some skipping; yet I can still make it out somewhat. At first I 
though maybe I was doing data conversion between bytes and shorts 
incorrectly, so I temporarily moved over to a short-based system. Still the 
problem persisted, so perhaps it could be a setting or two I'm missing? I 
posted my code below, demonstrating how I'm encoding and decoding the 
buffers. I can't see anything wrong with it, so I'm guessing my problem lies 
elsewhere. If anyone experienced a similar problem beforehand, it would be 
nice to know what I could be doing wrong. As far as the system itself, I can 
perfectly record audio at any channel setting, sample rate, or bit-rate and 
play it back fine.



- I'm using Speex version 1.1.6. I've also used 1.0.4 beforehand and 
experienced the same problem with it.



1) I initialize the bits, encoder, and decoder as normal (default settings 
seemed appropriate):

speex_bits_init(&mBits);

mEncode = speex_encoder_init(&speex_nb_mode);

mDecode = speex_decoder_init(&speex_nb_mode);



2) I record my audio at mono 8000Hz, 16bits per sample.



3) I encode frame-sized (320 bytes) fragments. Since I deal only with char 
data types, I convert to 2-byte short values first and then set the float 
buffer.

char *CSpeex::encode (char *buffer, int size, int &encodeSize)

{

      char *encodedBuffer = new char[160];

      short speexShort;

      float *speexFloat = new float[160];



      // Convert the audio to a short then to a float buffer

      for (int i = 0; i < 160; i++)

      {

            memcpy(&speexShort, &buffer[i*2], sizeof(short));

            speexFloat[i] = speexShort;

      }



      // Encode the sound data using the float buffer

      speex_bits_reset(&mBits);

      speex_encode(mEncode, speexFloat, &mBits);

      encodeSize = speex_bits_write(&mBits, encodedBuffer, 160);

      delete[] speexFloat;



      // Return the encoded buffer

      return encodedBuffer;

}



4) I immediately decode the encoded buffer. Encoded size is always 38 bytes 
for this sample set and expected decoded size is 320 bytes

char *CSpeex::decode (char *buffer, int encodeSize)

{

      char *decodedBuffer = new char[320];

      short speexShort;

      float *speexFloat = new float[160];



      // Decode the sound data into a float buffer

speex_bits_reset(&mBits);

      speex_bits_read_from(&mBits, buffer, encodeSize);

      speex_decode(mDecode, &mBits, speexFloat);



      // Convert from float to short to char

      for (int i = 0; i < 160; i++)

      {

            speexShort = speexFloat[i];

            memcpy(&decodedBuffer[i*2], &speexShort, sizeof(short));

      }

      delete[] speexFloat;



      // Return the buffer

      return decodedBuffer;

}





Hope no one minds the source post. I'm really stumped on this one, but the 
benefits of using Speex versus the bloat offered in the competitors are well 
worth the hassle. I'm looking forward to incorporating this into several 
games for VoIP support.





Thanks.


More information about the Speex-dev mailing list