2010-01-10 3 views
7

Ich habe eine kleine Ebene iPhone App. Ich muss Sound-Dateien für jede Ebene laden und freigeben. Alles funktioniert gut mit meinem openAL SoundManager, außer dem Freigeben von Sounds.Wie können Sie den Speicher einer OpenAL-Sounddatei vollständig entfernen und freigeben?

Zuerst, wenn ich einen Ton entferne, scheint es zu tun, was es tun soll - es entfernt den Ton und ich kann nicht wieder darauf zugreifen, wenn ich es neu lade. ABER, wenn ich meine apps deallocs mit "Instrumenten" teste, zeigt es keine Freigabe. Es scheint nicht die Erinnerung frei zu machen. Wenn Sie also von Level zu Level gehen, dauert es nicht lange, bis der Speicher ausgeht und die App abstürzt.

ich diesen Fehler in der Konsole:

Programmsignal empfangen: „0“. Warnung: check_safe_call: nicht aktuellen Frame wiederherstellen könnte töten

beenden

Dies ist, wie ich die Klänge laden -

- (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); 

}

Und das ist, wie ich zu entfernen versuchen/Freisetzung. Aber es scheint immer noch die Erinnerung an die Tondatei zu behalten -

- (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); 

}

jemand denken kann, entfernt vollständig jede Spur meiner Sounddatei zu entfernen (mit der Möglichkeit, es wieder zu laden)?

Vielen Dank!

+0

Hallo, Mehrere Ansichten, aber noch keine Antworten? ... Wenn Sie sich diesen Code anschauen und nichts falsch sehen können, sagen Sie es bitte.Dann könnte es mich dazu bringen, zu denken, dass mein Problem nicht darin besteht, dass meine Pufferspeicher nicht freigegeben werden. Danke – Jonathan

+0

alBufferDataStatic ist ein "scharfes Messer" mit einer Reihe versteckter Vorbehalte. Ich empfehle dieses Video zu sehen: http://youtu.be/6QQAzhwalPI – dontWatchMyProfile

Antwort

5

Wenn jemand interessiert ist ... wurde mein Problem gelöst, indem Sie die alBufferDataStaticProc zu alBufferData ändern. Dann hinzufügen if(data) free(data); Siehe unten.

Danke für Ihre Hilfe.

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

es funktioniert! Vielen Dank! – Ricibald

+0

Eigentlich funktionierte das nicht für mich, aber es half sehr, das Problem zu finden. Alles, was ich tun musste, um das gleiche Apple-Beispiel zu verwenden, war das Hinzufügen von 'if (device! = NULL) [self teardownOpenAL]; 'vor' [self initOpenAL]; ' – cregox

0

nicht vertraut mit den Spezialitäten mit OpenAL für iPhone, aber hier ist meine grobe Schätzung:

Ist der Puffer an eine OpenAL Quelle angeschlossen noch, also haben Sie alSourcei genannt (..., AL_BUFFER, ...) oder alSourceQueueBuffers zwischen dem Laden und dem Release? Wenn dies der Fall ist, müssen Sie möglicherweise alSourcei (..., AL_BUFFER, NULL) oder alSourceUnqueueBuffers ausführen, bevor Sie den Puffer löschen.

Versuchen Sie nach dem Aufruf von alDeleteBuffers nach OpenAL-Fehlern (alGetErrors) zu suchen.

2

Dies ist eine Summe aus, was ich tat „vollständig jede Spur von meiner Sounddatei (mit der Möglichkeit, wieder zu laden) zu entfernen“ die gleiche apple example verwenden und einige openAL documentation:

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

Die wichtigste Ergänzung hier ist, dass if, die in meinem Fall tatsächlich in teardownOpenAL hinzugefügt.

Verwandte Themen