Mikhail Dudarev
2013-Feb-12 14:13 UTC
[Speex-dev] Speexdec says: 'This doesn't look like a Speex file' (am I missing headers?)
Hello, guys! I'm a novice at programming, learning about the speex and its applications now. Specifically, my current goal is to encode microphone input on iOS device in real-time, saving result to a file frame-by-frame. So far, I've managed to: 1) compile speex static library (it works, at least for iPhone/iPad, but not on iOS simulator; this is fine for now); 2) encode pcm data from microphone into 'something' which resembles speex (in fact it expected to be speex file, but not actually; see below for details). To check validity of the result file, I use speexdec script, as following: ...$ speexdec encodingResultSpeexFile decodedSpeexFile This doesn't look like a Speex file So I assume that the file, which my program creates, is invalid for some reason. Is some particular kind of header required? What should it be (ogg, rtp or something else) and how should I add it? Could you guide me in right direction, please? --- To give you fuller picture, I'll attach single audio input buffer along with piece of the code to encode bytes from such buffers frame-by-frame: a) Audio input buffer (abridged a bit): CMSampleBuffer 0x6ead20 retainCount: 1 allocator: 0x33bdf213 invalid = NO ... formatDescription = <CMAudioFormatDescription 0x6e84b0 [0x3f7cd650]> { mediaType:'soun' mediaSubType:'lpcm' mediaSpecific: { ASBD: { mSampleRate: 44100.000000 mFormatID: 'lpcm' mFormatFlags: 0xc mBytesPerPacket: 2 mFramesPerPacket: 1 mBytesPerFrame: 2 mChannelsPerFrame: 1 mBitsPerChannel: 16 } ... } ... } sbufToTrackReadiness = 0x0 numSamples = 375 sampleTimingArray[1] = { {PTS = {82626949766094/1000000000 = 82626.950, rounded}, DTS = {INVALID}, duration = {1/44100 = 0.000}}, } sampleSizeArray[1] = { sampleSize = 2, } dataBuffer = 0x6e7a40 b) Actual data which is kept in aforementioned buffer (for the sake of completeness): 0f001400 0b000d00 04000a00 f7ff1300 0a000300 f9ff1c00 1b001c00 f9ffc0ff bfffadff b7ff86ff 7cff5fff 63ff67ff 84ffb5ff bbffd4ff e4ff1500 1c001000 04001400 39002500 27005000 44002000 e7ffe5ff c7ffd7ff bbffcbff d1ffc8ff c7ffc4ff e8fff6ff 2f003a00 5c005400 66006600 71006700 5e006000 4a003300 0a002300 4a004c00 47001c00 fbfff6ff 0a00b1ff 8dff85ff 9bff87ff 93ff7fff 84ff74ff 6fff75ff 91ffa2ff c1ff9aff 86ff7eff 7aff59ff 53ff6aff 71ffb3ff c5ffe1ff 0900faff e9fff3ff 1d003100 34001400 0600fcff d5ffecff 0d002200 60006500 6f006c00 61002b00 0700d8ff ccffcbff baff7aff 65ff61ff 94ffccff 0e002800 56006400 9800ad00 ea00c700 cb00ab00 af00bc00 ab00be00 a700ad00 76006d00 34003100 0c00e7ff c2ffcbff c6ffcdff acffadff a2ff88ff 86ff4aff 5eff19ff 3eff26ff 66ff8bff bcffe9ff d8ff3300 1e006a00 7600a700 7e009f00 b2000801 15011501 d100d900 92008f00 86007b00 62004900 6d006e00 52002f00 f0ff0000 b6ffebff 96ffb0ff 51ff76ff 45ff61ff 18ff2aff 12ff29ff 2fff70ff 6aff9fff b6ffdeff c3ffd9ff a8ffc0ff b7fffbff 00001e00 c4ffe4ff dbffe1ff d5ff0300 0e001c00 03000800 0b001f00 d9ff1a00 d7ffe3ff bdff0300 f6ff1b00 c9ffecff 06005e00 50009100 60005f00 05002000 ffff1200 dfffecff d9ff0100 ccfff3ff b2ffceff 9bffd4ff c5ffe2ff b1ffecff e0ff0000 e6fffbff e2ff1c00 11002a00 11003900 4c009800 8a00b100 63008800 66008d00 65008600 69006700 5e006200 74006f00 5f006700 62006700 4f007100 75007800 7a006f00 65005200 1f00d7ff caffb8ff aaffb4ff 9aff6eff 61ff6bff 5dff6cff 75ff75ff 77ff95ff adffd3ff d9ffd7ff f6ff0700 1a002f00 40001e00 1b000e00 1a001400 25002800 38002900 1d002000 0000e6ff effff2ff 0100dbff daffb9ff efffe6ff e4ffd5ff dbffb5ff 89ff8dff a6ffc1ff e3ffd5ff f7ff0500 0e00e9ff 0f001200 2f002c00 37004e00 46002500 d3ffbbff b0ff c) The code (here is the piece to deal with single input buffer, which example is give above; so it's same for all input buffers): int writtenBytesNumber; SpeexBits bits; int samplesPerFrame; int quality = 6; char compressedBits[200]; speex_bits_init(&bits); memset(compressedBits, 0, 200); void *encoderState = speex_encoder_init(&speex_wb_mode); // setting wideband mode speex_encoder_ctl(encoderState, SPEEX_GET_FRAME_SIZE, &samplesPerFrame); // 320 samples/frame speex_encoder_ctl(encoderState, SPEEX_SET_QUALITY, &quality); CMItemCount numberOfSamples = CMSampleBufferGetNumSamples(sampleBuffer); // 375 samples size_t sampleSize = CMSampleBufferGetSampleSize(sampleBuffer, 0); // 2 bytes CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sampleBuffer); // see attachment (b) above size_t blockBufferDataLength = CMBlockBufferGetDataLength(blockBufferRef); // 750 bytes NSMutableData *allSamplesMutableData = [NSMutableData dataWithLength:blockBufferDataLength]; CMBlockBufferCopyDataBytes(blockBufferRef, 0, blockBufferDataLength, allSamplesMutableData.mutableBytes); // copying bytes to object int nextSampleStartPosition = 0; for (int i = 0; i < numberOfSamples; i++) { NSData *singleSampleData = [NSData dataWithBytes:[[allSamplesMutableData subdataWithRange:NSMakeRange(nextSampleStartPosition, sampleSize)] bytes] length:sampleSize]; nextSampleStartPosition += sampleSize; [_intermediateSampleBuffer addObject:singleSampleData]; // we put samples here until it's enough for the frame if (_intermediateSampleBuffer.count == samplesPerFrame) { speex_bits_reset(&bits); short samplesArray[samplesPerFrame]; // c-array which will get samples from _intermediateSampleBuffer for (int j = 0; j < samplesPerFrame; j++) { samplesArray[j] = (short)[(NSData *)[_intermediateSampleBuffer objectAtIndex:j] bytes]; } [_intermediateSampleBuffer removeAllObjects]; // flushing _intermediateSampleBuffer to make it ready for next samples speex_encode_int(encoderState, samplesArray, &bits); writtenBytesNumber = speex_bits_write(&bits, compressedBits, samplesPerFrame); // usually 52 bytes for wideband and quality=6 fwrite(&writtenBytesNumber, sizeof(int), 1, _speexFile); // following the example in sampleenc.c we put size of compressedBits first fwrite(compressedBits, sizeof(char), writtenBytesNumber, _speexFile); // putting encoded bits themselves memset(compressedBits, 0, 200); } } speex_bits_destroy(&bits); speex_encoder_destroy(encoderState); p.s. I understand that code is far from optimal, but it's not final version. Though advice regarding code (if any) quality is also appreciated. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.xiph.org/pipermail/speex-dev/attachments/20130212/e4f264a8/attachment-0001.htm
Reasonably Related Threads
- Speexdec says: 'This doesn't look like a Speex file' (am I missing headers?)
- Speexdec says: 'This doesn't look like a Speex file' (am I missing headers?).
- Speexdec says: 'This doesn't look like a Speex file' (am I missing headers?).
- trying to write encoder - need help!
- openh323 conflict; can speex_encode take short?