[Speex-dev] Any tips for speeding up encoding on iPhone?

Alex Bumbu alex.bumbu at gmail.com
Thu Jun 2 09:25:32 PDT 2011


Hi,


I'm trying to use Speex for real time encoding in an iPhone project but I'm
having latency problems. I appreciate any tips you may provide for speeding
things up.


The recording callback is providing 1024 samples (mono, frequency: 44100 Hz,
of type short) every 23 ms (1024.0 / 44100.0). I'm saving the samples in a
buffer and use them in the encoding thread (set for mode: wide band - 16
Khz), but for every frame of 320 samples it takes ~40 ms, so soon the buffer
runs out of space and it'll start missing samples.

I've tried lowering the quality and setting the recorder frequency to 16 Khz
but didn't worked.

Is there any way to optimize the encoding so it can keep up with the
recording?


Below you can find the code I'm using. Maybe you notice some obvious
problems.


- (void)initSpeexEncoder {

    speex_bits_init(&speexBits);

    speexEncoderState = speex_encoder_init(&speex_wb_mode);



    // get the frame size (expressed in samples)

    speexFrameSize = 0;

    speex_encoder_ctl(speexEncoderState, SPEEX_GET_FRAME_SIZE, &
speexFrameSize);



    // set quality parameter that controls the quality vs bit-rate tradeoff

    UInt8 speexEncodingQuality = 10; // values from 0 to 10 (inclusively)

    speex_encoder_ctl(speexEncoderState, SPEEX_SET_QUALITY,
&speexEncodingQuality);



    // alloc the buffer

    _compressedSpeexBufferSize = 1024;

    _compressedSpeexBuffer = malloc(_compressedSpeexBufferSize);

}


- (void)freeSpeexEncoder {

    speex_bits_destroy(&speexBits);

    speex_encoder_destroy(speexEncoderState);



    free(_compressedSpeexBuffer);

    _compressedSpeexBufferSize = 0;

}


- (void)encodeThread {

    // alloc buffer to hold the specified amount of short type samples

    short *input = malloc(speexFrameSize * sizeof(short));



    while (recording) {

        // proceed only if we have enough samples for a frame

        if (_toCompressBuffer.size >= speexFrameSize * sizeof(short)) {


            // fill frame with samples

            //memcpy(input, _toCompressBuffer.data, speexFrameSize *
sizeof(short));



            // process one frame at a time

            NSLog(@"Start encode");

            speex_bits_reset(&speexBits);

            //speex_encode_int(speexEncoderState, input, &speexBits);

            speex_encode_int(speexEncoderState, _toCompressBuffer.data, &
speexBits); // without using extra buffer

            UInt16 nbBytes = speex_bits_write(&speexBits,
_compressedSpeexBuffer, _compressedSpeexBufferSize);

NSLog(@"Ended encode");



            static int processedBytes = 0;

            processedBytes += speexFrameSize * sizeof(short);

            NSLog(@"Processed bytes: %d", processedBytes);



            if (nbBytes) {

                // write to file

                // first write the header (2 bytes)

                // the header must contain the number of compressed bytes
for a frame

                static bool once = NO;

                if (!once) {

                    [file writeData: [NSData dataWithBytesNoCopy: &nbBytes
length: sizeof(nbBytes)]];

                    once = YES;

                }



                // write encoded data

                [file writeData: [NSData dataWithBytesNoCopy:
_compressedSpeexBuffer length: nbBytes]];



                // remove from buffer -- one frame

                [_toCompressBuffer removeFirstBytes: speexFrameSize * sizeof
(short)];

                NSLog(@"Stop encode frame");

            }



        }

    }



    free(input);

}


Thanks,

Alex Bumbu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/speex-dev/attachments/20110602/0c64cb64/attachment.htm 


More information about the Speex-dev mailing list