2010-01-10 15 views
7

Tôi có một ứng dụng iPhone cấp độ nhỏ. Tôi cần tải và phát hành các tệp âm thanh cho từng cấp. Mọi thứ hoạt động tốt với SoundManager mở của tôi ngoại trừ phát hành âm thanh.Làm thế nào để bạn loại bỏ hoàn toàn và giải phóng bộ nhớ của một tệp âm thanh OpenAL?

Lúc đầu, khi tôi xóa một âm thanh, có vẻ như điều đó có nghĩa là phải làm gì - nó sẽ xóa âm thanh và tôi không thể truy cập lại âm thanh trừ khi tôi tải lại. NHƯNG, khi tôi kiểm tra các ứng dụng của mình bằng cách sử dụng ‘Instruments’, ứng dụng này không hiển thị bất kỳ thỏa thuận nào. Nó dường như không giải phóng bộ nhớ. Vì vậy, khi bạn di chuyển từ cấp này sang cấp khác, không mất nhiều thời gian để bộ nhớ hết và ứng dụng gặp sự cố.

tôi nhận được lỗi này trong giao diện điều khiển:

Chương trình đã nhận được tín hiệu: “0”. cảnh báo: check_safe_call: không thể khôi phục khung hiện giết bỏ

Đây là cách tôi tải âm thanh -

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

}

Và đây là cách tôi đang cố gắng để xóa/giải phóng. Nhưng nó vẫn có vẻ để giữ lại ký ức về các tập tin âm thanh -

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

}

bất cứ ai có thể nghĩ ra đi để hoàn toàn loại bỏ mọi dấu vết của tập tin âm thanh của tôi (với khả năng tải nó một lần nữa)?

Cảm ơn bạn rất nhiều!

+0

Xin chào, Một số chế độ xem nhưng chưa có câu trả lời? ... Nếu bạn nhìn vào mã này và không thể thấy bất kỳ điều gì sai, xin hãy nói như vậy.Sau đó, nó có thể khiến tôi nghĩ rằng vấn đề của tôi không phải là với bộ đệm của tôi không giải phóng bộ nhớ. Cảm ơn – Jonathan

+0

alBufferDataStatic là một "con dao sắc bén" với một loạt các cảnh báo ẩn. Tôi khuyên bạn nên xem video này: http://youtu.be/6QQAzhwalPI – dontWatchMyProfile

Trả lời

5

Nếu có ai quan tâm ... sự cố của tôi đã được giải quyết bằng cách thay đổi alBufferDataStaticProc thành alBufferData. Sau đó, thêm if(data) free(data); Xem bên dưới.

Cảm ơn sự giúp đỡ của bạn.

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

nó hoạt động! cảm ơn! – Ricibald

+0

Thực ra, điều này không hiệu quả đối với tôi, nhưng nó đã giúp ích rất nhiều trong việc tìm kiếm vấn đề. Tất cả những gì tôi cần làm, từ việc sử dụng cùng một ví dụ táo, đã thêm 'if (device! = NULL) [self teardownOpenAL];' before '[self initOpenAL];' – cregox

0

Không quen thuộc với các món ăn đặc với OpenAL dành cho iPhone, nhưng đây là rough đoán của tôi:

là bộ đệm vẫn gắn liền với một nguồn OpenAL, tức là có bạn gọi alSourcei (..., AL_BUFFER, ...) hoặc alSourceQueueBuffers giữa quá trình tải và bản phát hành? Nếu đó là trường hợp bạn có thể cần phải chạy alSourcei (..., AL_BUFFER, NULL) hoặc alSourceUnqueueBuffers trước khi xóa bộ đệm.

Thử kiểm tra lỗi OpenAL (alGetErrors) sau khi bạn đã gọi alDeleteBuffers.

2

Đây là một khoản tiền lên những gì tôi đã làm "để loại bỏ hoàn toàn mọi dấu vết của tập tin âm thanh của tôi (với khả năng tải nó một lần nữa)" sử dụng cùng một apple example và một số openAL documentation:

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

Ngoài ra chính ở đây là if, mà trong trường hợp của tôi, tôi thực sự được thêm vào teardownOpenAL.