Я пытаюсь передать файл на iphone с помощью OpenAL. Большая часть этого кода основана на превосходном учебнике Бена Бриттена ; однако я попытался сохранить данные в пользовательском классе в словаре, а не в словаре в словаре.
Я настроил пользовательский класс для хранения информации о файле, который я буду передавать в потоковом режиме. Здесь содержится NSString с именем fileName, которая содержит местоположение моего файла. Именно эта переменная меняет свое значение при извлечении. Пользовательский класс определяется так:
@interface DBuffer : NSObject {
NSString *fileName ;
UInt32 fileSize ;
UInt32 bufferSize ;
UInt32 bufferIndex ;
ALenum bufferFormat ;
ALsizei bufferFreq ;
BOOL bufferLoops ;
}
@property (nonatomic, retain) NSString *fileName ; *<-----;
@property (nonatomic, assign) UInt32 fileSize ;
@property (nonatomic, assign) UInt32 bufferSize ;
@property (nonatomic, assign) UInt32 bufferIndex ;
@property (nonatomic, assign) ALenum bufferFormat ;
@property (nonatomic, assign) ALsizei bufferFreq ;
@property (nonatomic, assign) BOOL bufferLoops ;
-(void)dealloc ;
@end
@implementation DBuffer
@synthesize fileName ;
@synthesize fileSize ;
@synthesize bufferSize ;
@synthesize bufferIndex ;
@synthesize bufferFormat ;
@synthesize bufferFreq ;
@synthesize bufferLoops ;
-(void)dealloc
{
[fileName release];
[super dealloc];
}
@end
Каждый звук хранится в словаре так:
-(void)loadFiles
{
NSMutableDictionary* tempLibrary = [[NSMutableDictionary alloc] init];
NSString* fileName = [[NSBundle mainBundle] pathForResource:@"b2" ofType:@"caf"];
[tempLibrary setObject:[self initializeStreamFromFile: fileName format:AL_FORMAT_STEREO16 freq:44100 ] forKey: @"101" ];
[fileName release];
NSString* fileName2 = [[NSBundle mainBundle] pathForResource:@"a5" ofType:@"caf"];
[tempLibrary setObject:[self initializeStreamFromFile: fileName2 format:AL_FORMAT_STEREO16 freq:44100 ] forKey: @"102" ];
[fileName2 release];
self.soundLibrary = tempLibrary;
[tempLibrary release];
NSLog(@"load files: tempLibrary %@<%x>", tempLibrary, &*tempLibrary);
NSLog(@"load files: soundLibrary %@<%x>", soundLibrary, &*soundLibrary);
NSLog(@"load files: soundLibrary retaincount %d", [soundLibrary retainCount]);
NSLog(@"load files: tempLibrary retaincount %d", [tempLibrary retainCount]);
DBuffer *retrieve = [soundLibrary objectForKey:@"101"];
NSLog(@"retrieve: %@",retrieve.fileName);
NSLog(@"retrieve retaincount: %d",[retrieve.fileName retainCount]);
}
Он вызывает initializeStreamFromFile, который определен ниже. После того, как он возвращает и добавляет классы в словарь, я делаю проверку, чтобы попытаться извлечь имя файла из словаря с помощью метода экземпляра loadFiles, и он работает нормально, возвращая:
"Получить: / Пользователи / Дэвид / Библиотека / Поддержка приложений / iPhone
Simulator / 4,2 / Применения / 7DA24283-8D58-49B8-BBeB-48B08D921367 / OpenALRefine.app / b2.caf "
Какой правильный адрес, такой же, как в журнале в точке инициализации, показанной ниже, и
"восстановить остаток: 2"
// this queues up the specified file for streaming
-(DBuffer*)initializeStreamFromFile:(NSString*)fileName format:(ALenum)format freq:(ALsizei)freq
{
// first, open the file
AudioFileID fileID = [self openAudioFile:fileName];
// find out how big the actual audio data is
UInt32 fileSize = [self audioFileSize:fileID];
UInt32 bufferSize = kOPENAL_STREAMING_BUFFER_SIZE;
UInt32 bufferIndex = 0;
DBuffer* DBufferID = [[[DBuffer alloc] init] autorelease];
DBufferID.fileName = fileName ;
DBufferID.fileSize = fileSize ;
DBufferID.bufferSize = bufferSize ;
DBufferID.bufferIndex = bufferIndex ;
DBufferID.bufferFormat = format ;
DBufferID.bufferFreq = freq ;
NSLog(@"DBufferID initialised %@<%x>", DBufferID, &*DBufferID);
//output of this is: "DBufferID initialised <DBuffer: 0x533a5f0><533a5f0>"
NSLog(@"DBufferID.fileName initialised %@<%x>", DBufferID.fileName, &*DBufferID.fileName);
//output of this is: "DBufferID.fileName initialised /Users/david/Library/Application Support/iPhone Simulator/4.2/Applications/7DA24283-8D58-49B8-BBEB-48B08D921367/OpenALRefine.app/b2.caf<55453a0>"
NSLog(@"DBufferID.fileName retaincount %d", [DBufferID.fileName retainCount]);
//output of this is: "DBufferID.fileName retaincount 3"
AudioFileClose(fileID);
return DBufferID;
}
Хорошо, пока все хорошо. В перо у меня есть простой интерфейс с кнопкой воспроизведения, прикрепленной к методу playStream. Я пытаюсь запустить тот же код в начале метода, например так:
- (NSUInteger)playStream:(NSString*)soundKey gain:(ALfloat)gain pitch:(ALfloat)pitch loops:(BOOL)loops
{
NSLog(@"PlayStream activiated");
ALenum err = alGetError(); // clear error code
NSLog(@"soundLibrary retaincount %d", [soundLibrary retainCount]);
DBuffer *retrieve = [soundLibrary objectForKey:@"101"];
NSLog(@"retrieve initialised %@<%x>", retrieve, &*retrieve);
NSLog(@"retrieve.fileName initialised %@<%x>", retrieve.fileName, &*retrieve.fileName);
Тем не менее, результаты от последнего к NSLogs:
"восстановить инициализированный <533a5f0>"
Пока все хорошо, тот же адрес памяти, который был отправлен в словарь. Однако при печати значение retrieve.fileName возвращает случайную строку, например, так:
"Инициализированный retrieve.fileName hu.lproj <55453a0>»
Вы заметите, что адрес памяти не изменился по сравнению с указанным в методе initializeStreamFromFile, напечатанном выше. Значение этой переменной выглядит случайным, другие значения, которые она возвратила:
»
«/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/System/Library/PrivateFrameworks/WebKit.framework"
и т. Д. Или просто "EXC_BAD_ACCESS"
Я относительно новичок в цели C, но я предполагаю, что это явно связано с плохим управлением памятью. Я читал на Apple pdfs по управлению памятью, чтобы попытаться исправить, но безрезультатно. Любые идеи будут оценены.