[Speex-dev] VoIP with wavefrom and speex

Peter Soxberger Peter.Soxberger at gmx.net
Tue Jan 20 02:37:22 PST 2009


Hi!

I'm totally new to audio programming. I managed to create a VoIP with waveform (PCM). The problem was the really high traffic, so I desided to use speex for compressing the data.

I'm recording with mono, 16bit/sample, 8000 samples per second. I tried to add the speex compression, but I always get a crash when I try to decode the data.

Here is my encode and decode function:

int audio_encode(char dest[],WAVEHDR *source,int srclen, int quality)
{
	SpeexBits bits;
	void *enc_state;
	float input[160];
	char output[200];
	unsigned int i,n=0;
	int compr_length = 0;
	unsigned short length;

	speex_bits_init(&bits);
	enc_state = speex_encoder_init(&speex_nb_mode);
	speex_encoder_ctl(enc_state,SPEEX_SET_QUALITY,&quality);
	while(1)
	{
		for(i=0;i<160;i++)
		{
			if(n>=srclen)
			{
				speex_bits_destroy(&bits);
				speex_encoder_destroy(enc_state);
				return compr_length;
			}
			input[i] = source->lpData[n];
			n++;
		}
		speex_bits_reset(&bits);
		speex_encode(enc_state,input, &bits);
		length = speex_bits_write(&bits, output, 200);
		compr_length = bwrite_data(dest,compr_length,length); //writes 2 Byte into dest
		memcpy(&dest[compr_length],output,length);
		compr_length += length;
	}
}

int audio_decode(WAVEHDR *dest, char *source, int srclen)
{
	SpeexBits bits;
	float output[160];
	void *dec_state;
	unsigned int i;
	unsigned int reading_pos = 0;
	unsigned short length;
	unsigned int writing_pos = 0;
	
	//Decodiern:
	speex_bits_init(&bits);
	dec_state = speex_decoder_init(&speex_nb_mode);
	while(reading_pos < srclen && writing_pos < 512)
	{
		length = bget_data(source,reading_pos,sizeof(short)); //get 2 Byte value from source
		reading_pos += 2+length;
		speex_bits_read_from(&bits,&source[reading_pos], length);
		speex_decode(dec_state, &bits, output);
		memcpy(&dest->lpData[writing_pos],output,160);
		writing_pos += 160;
	}
	speex_bits_destroy(&bits);
	speex_decoder_destroy(dec_state);
	return writing_pos;
}

The functions are called this way:

//Encoding
save_length = audio_encode(buffer,Hdr,Hdr->dwBytesRecorded,8);
//...
//Decode again:
save_length = audio_decode(Hdr,buffer,save_length);

Here are the waveform options:

waveform.nChannels = 1;
waveform.wFormatTag = WAVE_FORMAT_PCM;
waveform.wBitsPerSample = 16;
waveform.nSamplesPerSec = 8000;
waveform.nBlockAlign = (waveform.nChannels*waveform.wBitsPerSample)/8;
waveform.nAvgBytesPerSec = waveform.nSamplesPerSec*waveform.nBlockAlign;
waveform.cbSize = 0;


What am I doing wrong? Are there any examples for encoding a waveform pcm stream in realtime (I didn't found any)?

Thanks for your help,

Peter


-- 
Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger


More information about the Speex-dev mailing list