Question

I am working on an iOS project that needs to encode and decode Speex audio using a remoteIO audio unit as input / output.

The problem I am having is although speex doesn't print any errors, the audio I get is somewhat recognizable as voice but very distorted, sort of sounds like the gain was just cranked up in a robotic way.

Here are the encode and decode functions (Input to encode is 320 bytes of signed integers from the audio unit render function, Input to decode is 62 bytes of compressed data ):

#define AUDIO_QUALITY 10
#define FRAME_SIZE 160
#define COMP_FRAME_SIZE 62

char *encodeSpeexWithBuffer(spx_int16_t *buffer, int *insize) {
    SpeexBits bits;
    void *enc_state;



    char *outputBuffer = (char *)malloc(200);

    speex_bits_init(&bits);
    enc_state = speex_encoder_init(&speex_nb_mode);

    int quality = AUDIO_QUALITY;

    speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &quality);


    speex_bits_reset(&bits);

    speex_encode_int(enc_state, buffer, &bits);



    *insize = speex_bits_write(&bits, outputBuffer, 200);


    speex_bits_destroy(&bits);
    speex_encoder_destroy(enc_state);


    return outputBuffer;
}

short *decodeSpeexWithBuffer(char *buffer) {
    SpeexBits bits;
    void *dec_state;

    speex_bits_init(&bits);

    dec_state = speex_decoder_init(&speex_nb_mode);

    short *outTemp = (short *)malloc(FRAME_SIZE * 2);

    speex_bits_read_from(&bits, buffer, COMP_FRAME_SIZE);
    speex_decode_int(dec_state, &bits, outTemp);

    speex_decoder_destroy(dec_state);
    speex_bits_destroy(&bits);


    return outTemp;
}

And the audio unit format:

// Describe format
audioFormat.mSampleRate         = 8000.00;
audioFormat.mFormatID           = kAudioFormatLinearPCM;
audioFormat.mFormatFlags        =  kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket    = 1;
audioFormat.mChannelsPerFrame   = 1;
audioFormat.mBitsPerChannel     = 16;
audioFormat.mBytesPerPacket     = 2;
audioFormat.mBytesPerFrame      = 2;

No errors are reported anywhere and I have confirmed that the Audio Unit is processing at a sample rate of 8000

Was it helpful?

Solution

After a few days of going crazy over this I finally figured it out. The trick with Speex is that you must initialize a SpeexBit and encoder void* and use them throughout the entire session. Because I was recreating them for every piece of the encode it was causing strange sounding results.

Once I moved:

 speex_bits_init(&bits);
 enc_state = speex_encoder_init(&speex_nb_mode);

Out of the while loop everything worked great.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top