[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