[Speex-dev] Newbie problem with encoding
Bob Cowdery
bob at bobcowdery.plus.com
Sun Jan 2 13:03:54 PST 2011
Hi all,
I'm new to speex and there are quite a number of things I am stuggling
with. Any help much appreciated.
-bob-
Environment:
Ubuntu 10.04
Speex 1.2 rc-1
GNU C compiler
IDE Code::Blocks
My application is actually 'D' but I've written a 'C' wrapper following
the examples on speex.org.
I have raw data which is in float format with a nominal block size of
512 samples interleaved left and right giving a 1024 raw data block.
The sampling rate is 48KHz.
I scale and convert this buffer to short[1024].
I have put the relevant code below with comments about what works and
what does not. Anything with a number in front is a question.
This is just test code to get things working:
int lib_speex_init() {
int quality = 5;
int rate = 16000;
int err;
// Setup for coding
enc_state = NULL;
speex_bits_init(&bits);
enc_state = speex_encoder_init(&speex_wb_mode);
speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &quality);
speex_encoder_ctl(enc_state, SPEEX_SET_SAMPLING_RATE, &rate);
// Set up a resampler to resample to 16K which is wideband mode
resampler = speex_resampler_init(2, 48000, 16000, quality, &err);
return 0;
}
int lib_speex_resample(short* in, unsigned int* in_length, short* out,
unsigned int* out_length) {
// Resample the input frame to 16KHz
if(enc_state == NULL) return -100;
return speex_resampler_process_interleaved_int(resampler, in,
in_length, out, out_length);
}
So far this seems to do the right thing.
1. The resampled size is alternately two blocks of 341 and one block of
342. I guess 1024/3 isn't integral so the size varies.
int lib_speex_get_frame_sz() {
// Get the expected frame size
int sz;
if(enc_state == NULL) return -100;
speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &sz);
return sz;
}
This returns 320 as the expected frame size.
1. I assume this is the block size I have to call the encoder with.
int lib_speex_encode(short *samples, char*encoded_bytes) {
// Encode the data
int bytes_written;
if(enc_state == NULL) return -100;
speex_bits_reset(&bits);
speex_encode_stereo_int(samples,320, &bits);
bytes_written = speex_bits_write(&bits, encoded_bytes, 1024);
return bytes_written;
}
This goes wrong.
1. Is speex_encode_stereo_int() the right thing to call with interleaved
samples. I note it has a different signature to speex_encode_int().
2. How big should I make the bytes buffer to accommodate the block.
3. speex_bits_write() only writes 3 bytes (returns a count of 3). These
are always more the same values except the 50 varies 50-53 [116, -50,
-65, 0 ...]. All the remainder are 0. The input data (output from the
resampler) is correct (i.e it's not zeros).
More information about the Speex-dev
mailing list