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
Apparently Analagous Threads
- Speex encoding/decoding producing garbled audio
- Decoding producing garbled sound
- Speex encoding/decoding producing garbled audio
- Integrating speex with VideoNet application: Constant background noise
- Integrating speex with VideoNet application: Constantbackground noise