kstenerud/ObjectAL-for-iPhone — Issue #20: infinite loop while loading file
Author: bartekhugo
Created: 2011-12-06 13:18:37+00:00
State: open

well i dont know too much about all this stuff but i was getting an infinite loop while loading some audio files (most of them was working ok). so traced it and find out that when ExtAudioFileRead(fileHandle, &numFramesRead, &bufferList) returns in numFramesRead 0 it indicates that end-of-file was reached. so ive added a simple break for it and it seems to be working for me, i just wanted to share it and get an opinion about it
here's the whole method

- (void*) audioDataWithStartFrame:(SInt64) startFrame
numFrames:(SInt64) numFrames
bufferSize:(UInt32*) bufferSize
{
@synchronized(self)
{
if(nil == fileHandle)
{
OAL_LOG_ERROR(@"Attempted to read from closed file. Returning nil (url = %@)", url);
return nil;
}

OSStatus error;
UInt32 numFramesRead;
AudioBufferList bufferList;
UInt32 bufferOffset = 0;

// < 0 means read to the end of the file.
if(numFrames < 0)
{
numFrames = totalFrames - startFrame;
}

// Allocate some memory to hold the data
UInt32 streamSizeInBytes = (UInt32)(streamDescription.mBytesPerFrame * numFrames);
void* streamData = malloc(streamSizeInBytes);
if(nil == streamData)
{
OAL_LOG_ERROR(@"Could not allocate %d bytes for audio buffer from file (url = %@)",
streamSizeInBytes,
url);
goto onFail;
}

if(noErr != (error = ExtAudioFileSeek(fileHandle, startFrame)))
{
REPORT_EXTAUDIO_CALL(error, @"Could not seek to %ll in file (url = %@)",
startFrame,
url);
goto onFail;
}

bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = streamDescription.mChannelsPerFrame;
for(UInt32 framesToRead = (UInt32) numFrames; framesToRead > 0; framesToRead -= numFramesRead)
{
bufferList.mBuffers[0].mDataByteSize = streamDescription.mBytesPerFrame * framesToRead;
bufferList.mBuffers[0].mData = streamData + bufferOffset;

numFramesRead = framesToRead;
if(noErr != (error = ExtAudioFileRead(fileHandle, &numFramesRead, &bufferList)))
{
REPORT_EXTAUDIO_CALL(error, @"Could not read audio data in file (url = %@)",
url);
goto onFail;
}
if (numFramesRead == 0)
break;

bufferOffset += streamDescription.mBytesPerFrame * numFramesRead;
}

if(nil != bufferSize)
{
*bufferSize = streamSizeInBytes;
}

return streamData;

onFail:
if(nil != streamData)
{
free(streamData);
}
return nil;
}
}