0

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

T.Leavy
  • 504
  • 5
  • 16
  • :Hi am working on AudioUnit.i can't get desired bytes like (160 bytes) from Audiounit,it always gives power of 2. is it possible to get 320 bytes from Audiounit recording callback?if so please give some idea – Vasu Ashok Jul 27 '12 at 06:50
  • That is correct. Audio unit only gives you powers of 2 samples. You must buffer the audio data and then extract data from the buffer in 320 byte chunks when available – T.Leavy Aug 11 '12 at 06:31

1 Answers1

0

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.

T.Leavy
  • 504
  • 5
  • 16