2010-01-10 4 views
7

J'ai une petite application pour iPhone. J'ai besoin de charger et de libérer des fichiers audio pour chaque niveau. Tout fonctionne correctement avec mon openAL SoundManager sauf la libération de sons. Au début, quand je supprime un son, il semble faire ce qu'il est censé faire - il supprime le son et je ne peux pas y accéder à nouveau, sauf si je le recharger. MAIS, quand je teste mes applications dealloc avec 'Instruments' il ne montre aucune désaffectation. Cela ne semble pas libérer la mémoire. Ainsi, lorsque vous passez d'un niveau à un autre, il ne faut pas longtemps pour que la mémoire soit épuisée et que l'application plante.Comment supprimer et libérer complètement la mémoire d'un fichier son OpenAL?

Je reçois cette erreur console:

Programme signal reçu: « 0 ». Avertissement: check_safe_call: ne pouvait pas restaurer cadre actuel tuer quit

Voici comment je charge les sons -

- (void)loadSoundWithKey:(NSString*)aSoundKey fileName:(NSString*)aFileName fileExt:(NSString*)aFileExt { 
// Check to make sure that a sound with the same key does not already exist 
NSNumber *numVal = [soundLibrary objectForKey:aSoundKey]; 
// If the key is found log it and finish 
if(numVal != nil) { 
    NSLog(@"WARNING - SoundManager: Sound key '%@' already exists.", aSoundKey); 
    return; 
} 
    NSUInteger bufferID; 
// Generate a buffer within OpenAL for this sound 
alGenBuffers(1, &bufferID); 
// Set up the variables which are going to be used to hold the format 
// size and frequency of the sound file we are loading 
ALenum error = AL_NO_ERROR; 
ALenum format; 
ALsizei size; 
ALsizei freq; 
ALvoid *data; 
NSBundle *bundle = [NSBundle mainBundle]; 
// Get the audio data from the file which has been passed in 
CFURLRef fileURL = (CFURLRef)[[NSURL fileURLWithPath:[bundle pathForResource:aFileName ofType:aFileExt]] retain]; 
if (fileURL) 
{ 
    data = MyGetOpenALAudioData(fileURL, &size, &format, &freq); 
    CFRelease(fileURL); 
    if((error = alGetError()) != AL_NO_ERROR) { 
     NSLog(@"ERROR - SoundManager: Error loading sound: %x\n", error); 
     exit(1); 
    } 
    // Use the static buffer data API 
    alBufferDataStaticProc(bufferID, format, data, size, freq); 
    if((error = alGetError()) != AL_NO_ERROR) { 
     NSLog(@"ERROR - SoundManager: Error attaching audio to buffer: %x\n", error); 
    }  
} 
else 
{ 
    NSLog(@"ERROR - SoundManager: Could not find file '%@.%@'", aFileName, aFileExt); 
    data = NULL; 
} 

// Place the buffer ID into the sound library against |aSoundKey| 
[soundLibrary setObject:[NSNumber numberWithUnsignedInt:bufferID] forKey:aSoundKey]; 
if(DEBUG) NSLog(@"INFO - SoundManager: Loaded sound with key '%@' into buffer '%d'", aSoundKey, bufferID); 

}

Et voilà comment je suis en train de supprimer/Libération. Mais il semble encore conserver la mémoire du fichier sonore -

- (void)removeSoundWithKey:(NSString*)aSoundKey { 
// Find the buffer which has been linked to the sound key provided 
NSNumber *numVal = [soundLibrary objectForKey:aSoundKey]; 
// If the key is not found log it and finish 
if(numVal == nil) { 
    NSLog(@"WARNING - SoundManager: No sound with key '%@' was found so cannot be removed", aSoundKey); 
    return; 
}  
// Get the buffer number form the sound library so that the sound buffer can be released 
NSUInteger bufferID = [numVal unsignedIntValue]; 
alDeleteBuffers(1, &bufferID); 
[soundLibrary removeObjectForKey:aSoundKey]; 
if(DEBUG) NSLog(@"INFO - SoundManager: Removed sound with key '%@'", aSoundKey); 

}

Quelqu'un peut-il penser à l'écart pour éliminer complètement toute trace de mon fichier son (avec la possibilité de le charger à nouveau)?

Merci beaucoup!

+0

Bonjour, Plusieurs vues mais pas encore de réponses? ... Si vous regardez ce code et que vous ne voyez rien de mal, dites le.Cela pourrait alors me faire penser que mon problème n'est pas que mes tampons ne libèrent pas de mémoire. Merci – Jonathan

+0

alBufferDataStatic est un "couteau tranchant" avec un tas de mises en garde cachées. Je recommande de regarder cette vidéo: http://youtu.be/6QQAzhwalPI – dontWatchMyProfile

Répondre

5

Si quelqu'un est intéressé ... mon problème a été résolu en changeant le alBufferDataStaticProc en alBufferData. Puis ajouter if(data) free(data); Voir ci-dessous.

Merci pour votre aide.

alBufferData(bufferID, format, data, size, freq); 
    if((error = alGetError()) != AL_NO_ERROR) { 
     NSLog(@"ERROR - SoundManager: Error attaching audio to buffer: %x\n", error); 
    } 
    if (data) 
     free(data); 
}else{ 
    NSLog(@"ERROR - SoundManager: Could not find file '%@.%@'", fileName, fileType); 
    data = NULL; 
+0

ça marche! Merci! – Ricibald

+0

En fait, cela n'a pas fonctionné pour moi, mais cela a beaucoup aidé à trouver le problème. Tout ce que j'avais besoin de faire, en utilisant le même exemple de pomme, était d'ajouter 'if (device! = NULL) [self teardownOpenAL];' avant '[self initOpenAL];' – cregox

0

Vous n'êtes pas familier avec les spécialités avec OpenAL pour iPhone, mais voici mon estimation approximative:

Est-ce le tampon toujours attaché à une source OpenAL, à savoir avez-vous appelé alSourcei (..., AL_BUFFER, ...) ou alSourceQueueBuffers entre le chargement et la libération? Si tel est le cas, vous devrez peut-être exécuter alSourcei (..., AL_BUFFER, NULL) ou alSourceUnqueueBuffers avant de supprimer le tampon.

Essayez de rechercher les erreurs OpenAL (alGetErrors) après avoir appelé alDeleteBuffers.

2

C'est une somme jusqu'à ce que je l'ai fait « pour enlever complètement toute trace de mon fichier son (avec la possibilité de le charger à nouveau) » en utilisant la même apple example et certains openAL documentation:

if (device != NULL) 
    [self teardownOpenAL]; 
[self initOpenAL]; 
alSourcePlay(source); 

L'addition principale ici est que if, qui dans mon cas j'ai effectivement ajouté teardownOpenAL.

Questions connexes