[Speex-dev] Encoding and decoding problem in speex 1.0.4

Jean-Marc Valin Jean-Marc.Valin at USherbrooke.ca
Wed Jan 5 22:06:10 PST 2005


Hi,

>From your code/explainations, I have only one question: How the hell do
you expect the speex_encode call to know how many samples you put in the
buffer? The answer is that there's no way to know. In narrowband mode,
Speex works on 160-sample frames. Please read the doc for more details.

	Jean-Marc

Le mercredi 05 janvier 2005 à 09:36 +0000, Vinod Vijayan a écrit :
> Hi,
>   I am using the speex 1.0.4 library from Windows.
>   I have posted my problem before but didn't get a solution. I am doing an
> VOIP project
>   in which i am recording sound and streaming it to the peer. I wanted to
> encode and decode
>   wav files that brought me to this site.
> 
>   I am recording sound in the following format:-
> 
>   m_WaveFormatEx.wFormatTag          = WAVE_FORMAT_PCM;
>   m_WaveFormatEx.nChannels           = 1;
>   m_WaveFormatEx.wBitsPerSample      = 8;
>   m_WaveFormatEx.cbSize              = 0;
>   m_WaveFormatEx.nSamplesPerSec      = 8000;
>   m_WaveFormatEx.nBlockAlign         = 1;
>   m_WaveFormatEx.nAvgBytesPerSec     = 8000;
> 
>   The recording is as follows :-
> 
>   When the buffer(size = 2000 bytes) gets filled with sound data a
> function with the body shown
>   below is called.
> 
>   LPWAVEHDR lpHdr = (LPWAVEHDR) lParam;
>   if(lpHdr->dwBytesRecorded==0 || lpHdr==NULL)
>     return ERROR_SUCCESS;
>   ::waveInUnprepareHeader(m_hRecord, lpHdr, sizeof(WAVEHDR));
> 
>   Here lpHdr->lpData contains the audio data in a character array.
> 
>   Now here I want to use Speex codec for encoding the data so the encoding
> function is
>   called (I am thankful to Tay YueWeng for the function).
> 
> 
>   char *encode(char *buffer, int &encodeSize)
>   {
>       char   *encodedBuffer = new char[RECBUFFER/2];            /*
> RECBUFFER = 2000 */
>       short   speexShort;
>       float  speexFloat[RECBUFFER/2];
>       void   *mEncode       = speex_encoder_init(&speex_nb_mode);
> 
>       /*Initialization of the structure that holds the bits*/
>       speex_bits_init(&mBits);
> 
>       // Convert the audio to a short then to a float buffer
>       int    halfBufferSize = RECBUFFER/2;
> 
>       for (int i = 0; i < halfBufferSize; 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,
> RECBUFFER/2);
> 
>       /*Destroy the encoder state*/
>       speex_encoder_destroy(mEncode);
>      /*Destroy the bit-stream struct*/
>       speex_bits_destroy(&mBits);
> 
>       // Return the encoded buffer
>       return encodedBuffer;
>   }
> 
>   Here i noticed that though my captured audio data is 2000 bytes the
> compressed form is
>   always 38 bytes. In the speexFloat array above i get values in the range
> -32767 to +32767.
>   Is it correct. Also after calling the 'speex_encode' function the first
> 160 values in the
>   input float array i.e. speexFloat is changed (why does it happen?Is
> anything abnormal).
> 
>   Further after calling the above function for testing I decode the
> returned encoded data
>   immediately by calling the decoding function shown bellow :-
> 
>   char *decode (char *buffer, int encodeSize)
>    {
>      char *decodedBuffer   = new char[RECBUFFER];
>      short speexShort;
>      float speexFloat[RECBUFFER/2];
>      // Decode the sound data into a float buffer
>      void  *mDecode        = speex_decoder_init(&speex_nb_mode);
> 
>      /*Initialization of the structure that holds the bits*/
>      speex_bits_init(&mBits);
> 
>      int    halfBufferSize = RECBUFFER/2;
>      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 < halfBufferSize; i++)
>       {
>          speexShort = speexFloat[i];
> 	 memcpy(&decodedBuffer[i*2], &speexShort, sizeof(short));
>       }
> 
>      /*Destroy the decoder state*/
>      speex_encoder_destroy(mDecode);
>      /*Destroy the bit-stream truct*/
>      speex_bits_destroy(&mBits);
> 
>      // Return the buffer
>     return decodedBuffer;
>   }
> 
>  After decoding using the above function only the first 160 values in the
> decodedBuffer array is
>  changed. i.e i encoded an 2000 byte audio data to get a 38 byte encoded
> audio data. On decoding
>  the 38 byte audio data i get an decompressed 160 byte data. I don't
> understand whats going
>  wrong. I checked all the messages posted in this newsgroup and did'nt
> find an answer so i am
>  posting this code hoping that it gets solved soon.  Thanks in advance.
> _______________________________________________
> Speex-dev mailing list
> Speex-dev at xiph.org
> http://lists.xiph.org/mailman/listinfo/speex-dev
> 
-- 
Jean-Marc Valin <Jean-Marc.Valin at USherbrooke.ca>
Université de Sherbrooke



More information about the Speex-dev mailing list