converting from interleaved to noninterleaved
converting from interleaved to noninterleaved
- Subject: converting from interleaved to noninterleaved
- From: daniel oberhoff <email@hidden>
- Date: Sun, 28 Sep 2003 00:33:38 +0200
hi folks!
i am having trouble with the audio converter api (also due to lack of
documentation...).
i want to convert sampledata (so far always loaded thru audiofile api)
into a noninterleaved, 32bit float format so i can easily render it to
my custom gl sampledata view. now whenever i encounter an interleaved 2
channel format my conversion method will just run forever. it seems as
though the proc i hand over to AudioConverterFillBuffer doesnt ever get
called in this case, because neither does the read pointer get
increased nor do printf's or NSLog's come out of it. when i first
convert it to a mono format i have no problem (i also get messages out
of my input proc then!). only when i tell the converter to deinterleave
channels. i would not like to move to complex buffers, as there seems
to be a lot of information wanted to be handled in the imput proc that
i dont know what to do with. if that would be the only solution i would
rather deinterleave by hand...
heres the relevant code, its from inside an NSObject called SampleData
which basically keeps the data and the format (an
AudioStreamBasicDescription) and supplies a bunch of useful methods.
everything from outside this code snippet should be self explamatory.
please cc any answers to me!
thanx
daniel
OSStatus SDACInputDataProc( AudioConverterRef inAudioConverter,
UInt32* ioDataSize,
void** outData,
void* inUserData) {
SDACprocessBuffer* buf = (SDACprocessBuffer*)inUserData;
*outData = &buf->data[buf->position];
if (buf->length - buf->position < 0)
return noErr + 1;
if (*ioDataSize > buf->length - buf->position)
*ioDataSize = buf->length - buf->position;
NSLog(@"[SDACInputDataProc] handed over %d bytes, buffer: %d/%d",
*ioDataSize, buf->position, buf->length);
buf->position += *ioDataSize;
return noErr;
}
static unsigned int _SDACstepsize = 1024; //conversion based on pull
model, pull buffers of this size!
+ (void) convertData:(NSData*)src inRange:(NSRange)sRange format:(const
AudioStreamBasicDescription*)srcFormat
toData:(NSMutableData*)dst toFormat:(const
AudioStreamBasicDescription*)dstFormat {
AudioConverterRef converter;
OSErr error;
SDACprocessBuffer inbuf, outbuf;
UInt32 ioDataSize;
unsigned inSize = sRange.length;
double estGrow = (double)dstFormat->mBytesPerFrame /
(double)srcFormat->mBytesPerFrame * (double)dstFormat->mSampleRate /
(double)srcFormat->mSampleRate;
unsigned estSize = inSize * (unsigned) ceil(estGrow);
error = AudioConverterNew(srcFormat, dstFormat, &converter);
if (error != noErr)
[NSException raise:@"SampleData conversion failure"
format:@"failed to allocate converter"];
[dst setLength:estSize];
inbuf.length = inSize;
inbuf.data = (Byte*)([src bytes] + (size_t)sRange.location);
inbuf.position = 0;
outbuf.length = estSize;
outbuf.data = [dst mutableBytes];
outbuf.position = 0;
while(inbuf.position < inbuf.length) {
ioDataSize = _SDACstepsize;
//resize if needed
if (outbuf.position + ioDataSize > outbuf.length) {
outbuf.length += MAX(outbuf.length >> 2, ioDataSize);
[dst setLength:outbuf.length];
}
AudioConverterFillBuffer(converter, SDACInputDataProc, &inbuf,
&ioDataSize, &outbuf.data[outbuf.position]);
outbuf.position += ioDataSize;
#if debug
NSLog(@"conv[%d/%d]: got %d bytes, total %d bytes, outbuf %d
bytes", inbuf.position, inbuf.length, ioDataSize, outbuf.position,
outbuf.length);
#endif
}
[dst setLength:outbuf.position];
AudioConverterDispose(converter);
}
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.