[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