0

I'm reading an audio file into RAM using the following method by passing an MPMediaItem object. However, each time this is called, the beginning of the function is supposed to free the memory used for the previous audio file and it doesn't, i.e., Xcode shows the memory usage keeps increasing each time the function is called and eventually the OS runs out of memory.

Am I doing anything obviously wrong?

NOTE: the below function is the only place I am using my audioData ivar

Memory allocation summary in Instruments

The same audio file cached in memory by below function

void *audioData;

- (void)playItem:(MPMediaItem *)mediaItem
{
   if (audioData != NULL) {
       NSLog(@"audio data pointer not empty");
       free (audioData);
   }

   // open audio file
   AudioFileID audioFileID;
   NSURL *mediaItemURL = [mediaItem valueForProperty:MPMediaItemPropertyAssetURL];

   OSErr err;
   err = AudioFileOpenURL((__bridge CFURLRef)mediaItemURL,
                          kAudioFileReadPermission,
                          0,
                          &audioFileID);
   NSAssert(err == noErr, @"Couldn't open audio file...");

   // read audio file properties and malloc audioData property
   UInt32 audioDataPacketCount;
   UInt32 audioDataPacketCountSize = sizeof(audioDataPacketCount);
   err = AudioFileGetProperty(audioFileID,
                              kAudioFilePropertyAudioDataPacketCount,
                              &audioDataPacketCountSize,
                              &audioDataPacketCount);
   NSAssert(err == noErr, @"Couldn't read audio file properties...");

   UInt32 audioDataByteCount;
   UInt32 audioDataByteCountSize = sizeof(audioDataByteCount);
   err = AudioFileGetProperty(audioFileID,
                              kAudioFilePropertyAudioDataByteCount,
                              &audioDataByteCountSize,
                              &audioDataByteCount);
   NSAssert(err == noErr, @"Couldn't read audio file properties...");
   audioData = malloc(audioDataByteCount);

   // read audio file packets
   err = AudioFileReadPacketData(audioFileID,
                                 false,
                                 &audioDataByteCount,
                                 NULL,
                                 0,
                                 &audioDataPacketCount,
                                 audioData);
   NSAssert(err == noErr, @"Couldn't read audio file to memory...");

}

EDIT: I used the same code structure and read the audio file data using ExtAudioFileRead function instead and memory deallocates and gets reallocated as supposedly. It may be something to do with how I'm using the AudioFileReadPacketData function =/

JackyJohnson
  • 3,106
  • 3
  • 28
  • 35

1 Answers1

0

You need to call AudioFileClose before freeing the AudioFileID resources.

Otherwise AudioFile retains a reference to the audio data void pointer and memory cannot be freed.

if (audioData != NULL) {
   NSLog(@"audio data pointer not empty");
   AudioFileClose(audioFileID);  // <- missing call
   free (audioData);
}
JackyJohnson
  • 3,106
  • 3
  • 28
  • 35
liaogang
  • 508
  • 3
  • 16
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – skuntsel Sep 28 '14 at 08:00
  • I don't understand what you say , @skuntsel. Sorry , English is not my mother language. Can you make it simply? – liaogang Sep 28 '14 at 08:05
  • You might be right with the answer, but you should expand your answer so that people reading it would be able to find it containing all the aspects of the topic. As it currently stands it is like a game for the reader. – skuntsel Sep 28 '14 at 08:10