Vinod Vijayan
2005-Jan-05 01:31 UTC
[Speex-dev] Encoding and decoding problem in speex 1.0.4
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.
Vinod Vijayan wrote:>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:- > >I don't know much about windows "Wave" stuff, but this doesn't look right:> 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; > > >You want 16 bits per sample, and 16000 bytes per second... -SteveK
Why not simply use PortAudio ?
Vinod Vijayan
2005-Jan-05 21:55 UTC
[Speex-dev] Encoding and decoding problem in speex 1.0.4
> I don't know much about windows "Wave" stuff, but this doesn't look right: > >> 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; >> >> >> > You want 16 bits per sample, and 16000 bytes per second... >I beg to differ. I used the same format for recording as above and saved it to a WAV file. Then I encoded the WAV file using the Speex command line encoder. I then decoded the generated speex file using the Speex command line decoder and found that the newly decoded sample and the original one was nearly the same. I repeat I had used the same wave format as above. How is this possible?
Jean-Marc Valin
2005-Jan-05 22:12 UTC
[Speex-dev] Encoding and decoding problem in speex 1.0.4
Hi,>From your code/explainations, I have only one question: How the hell doyou 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@xiph.org > http://lists.xiph.org/mailman/listinfo/speex-dev >-- Jean-Marc Valin <Jean-Marc.Valin@USherbrooke.ca> Universit? de Sherbrooke