2010-01-10 15 views
7

Tengo una aplicación para iPhone de nivel pequeño. Necesito cargar y liberar archivos de sonido para cada nivel. Todo funciona bien con mi openAL SoundManager, excepto cuando se lanzan sonidos.¿Cómo se elimina y libera completamente la memoria de un archivo de sonido OpenAL?

Al principio, cuando elimino un sonido, parece hacer lo que se supone que debe hacer: elimina el sonido y no puedo acceder a él nuevamente a menos que lo vuelva a cargar. PERO, cuando pruebo mis aplicaciones dealloc con 'Instruments', no muestra ninguna desasignación. No parece liberar la memoria. Entonces, cuando pasas de un nivel a otro, la memoria no tarda en agotarse y la aplicación se bloquea.

me sale este error en la consola:

Programa

recibe la señal: “0”. advertencia: check_safe_call: no se pudo restaurar la trama actual matar dejar de fumar

Así es como me carga los sonidos -

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

}

Y esta es la forma en que estoy tratando de eliminar/lanzamiento. Pero aún parece conservar la memoria del archivo de sonido -

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

}

Puede alguien pensar en distancia a eliminar por completo todo rastro de mi archivo de sonido (con la posibilidad de cargar de nuevo)?

¡Muchas gracias!

+0

Hola, Varias vistas pero todavía no hay respuestas? ... Si observa este código y no ve nada incorrecto en él, dígalo.Entonces podría llevarme a pensar que mi problema no está en que mis búferes no liberen memoria. Gracias – Jonathan

+0

alBufferDataStatic es un "cuchillo afilado" con un montón de advertencias ocultas. Recomiendo ver este video: http://youtu.be/6QQAzhwalPI – dontWatchMyProfile

Respuesta

5

Si alguien está interesado ... mi problema se resolvió cambiando el alBufferDataStaticProc a alBufferData. Luego agregue if(data) free(data); Vea a continuación.

Gracias por su ayuda.

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

¡funciona! ¡Gracias! – Ricibald

+0

En realidad, esto no funcionó para mí, pero me ayudó mucho a encontrar el problema. Todo lo que necesitaba hacer, usando el mismo ejemplo de Apple, era agregar 'if (device! = NULL) [selfdeardownOpenAL];' before '[self initOpenAL];' – cregox

0

no están familiarizados con las especialidades con OpenAL para iPhone, pero aquí es mi cálculo aproximado:

es el buffer todavía unido a una fuente de OpenAL, es decir, tiene que llamó alSourcei (..., AL_BUFFER, ...) o alSourceQueueBuffers entre la carga y la versión? Si ese es el caso, es posible que necesite ejecutar alSourcei (..., AL_BUFFER, NULL) o alSourceUnqueueBuffers antes de eliminar el búfer.

Intente comprobar errores OpenAL (alGetErrors) después de llamar a alDeleteBuffers.

2

Esta es una suma de lo que hice "para eliminar por completo todo rastro de mi archivo de sonido (con la posibilidad de cargar de nuevo)" usando el mismo apple example y algunos openAL documentation:

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

La principal adición aquí es if, que en mi caso agregué realmente en teardownOpenAL.

Cuestiones relacionadas