Я настроил свой AVAudioEngine по своему собственному методу, например так:
AVAudioSession* session = [AVAudioSession sharedInstance];
[session setPreferredSampleRate:[session sampleRate] error:nil];
[session setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
[session setActive:YES error:nil];
audioEngine_ = [[AVAudioEngine alloc] init];
//tap the outputNode to create the singleton
[audioEngine_ outputNode];
NSError* error;
[audioEngine_ startAndReturnError:&error];
Нет ошибки при запуске.У меня есть другой метод, чтобы прикрепить AVAudioUnitMIDIInstrument из AudioComponentDescription, которое я получил от Inter-App Audio.Мой метод подключения выглядит так:
-(void)connectInstrument:(AudioComponentDescription)desc {
instNode_ = nil;
instNode_ = [[AVAudioUnitMIDIInstrument alloc] initWithAudioComponentDescription:desc];
[audioEngine_ attachNode:instNode_];
//Crashes here
[audioEngine_ connect:instNode_ to:[audioEngine_ outputNode] format:nil];
[audioEngine_ startAndReturnError:nil];
NSLog(@"done connecting");
}
Сбой не дает мне никакой полезной информации.Я получаю это:
неверный режим 'kCFRunLoopCommonModes', предоставленный CFRunLoopRunSpecific - разрыв на _CFRunLoopError_RunCalledWithInvalidMode для отладки.Это сообщение будет появляться только один раз за выполнение.
* Завершение приложения из-за необработанного исключения 'NSRangeException', причина: '* - [__ NSArrayM objectAtIndexedSubscript:]: индекс 0 за пределами для пустого массива'
Если я выполню тест и попытаюсь создать новый узел микшера и подключить / подключить его, сбоя не будет.
У меня есть более важная информация
Если я сделаю это:
AVAudioFormat* instFormat = [instUnit_ outputFormatForBus:0];
Я получу ту же ошибку:
- [__ NSArrayM objectAtIndexedSubscript:]: индекс 0 за пределами для пустого массива
Это почти как если быне установлен AVAudioFormat для любых выходных шин и входных шин (я также проверил inputFormatForBus).Это странно, потому что если я сделаю:
AudioStreamBasicDescription f1;
UInt32 outsize = sizeof(f1);
AudioUnitGetProperty(instNode_.audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &f1, &outsize);
, то f1 - это действительное описание AudioStreamBasicDescription, показывающее стандартную частоту дискретизации 44,1 кГц, 32-битное с плавающей запятой, 2 канала.Таким образом, существует формат выходного потока, но он, кажется, не подключен ни к какой выходной шине экземпляра AVAudioUnitMIDIInstrument.
РЕДАКТИРОВАТЬ - Дополнительная информация Даже еслиЯ просто пытаюсь получить доступ к instUnite_.name я получаю NSRangeException.Мне интересно, если это проблема с тем, как я получаю описание компонента.Я пытаюсь использовать Inter-App Audio (я выполнил все необходимые права, возможности и настройку идентификатора приложения).Вот как я открываю компоненты Inter-App Audio:
NSMutableArray* units = [[NSMutableArray alloc] init];
AudioComponentDescription searchDesc = { kAudioUnitType_RemoteInstrument, 0, 0, 0, 0 };
NSArray* componentArray = [[AVAudioUnitComponentManager sharedAudioUnitComponentManager] componentsMatchingDescription:searchDesc];
for(AVAudioUnitComponent* component in componentArray) {
AudioComponentDescription description = component.audioComponentDescription;
InterAppAudioUnit* unit = [[InterAppAudioUnit alloc] init];
unit.componentDescription = description;
unit.icon = AudioComponentGetIcon(component.audioComponent, 44.0f);
unit.name = component.name;
unit.avComponent = component;
[units addObject:unit];
}
_units = units;
[self.tableView reloadData];
Это все в представленном UITableViewController.После нажатия на одну я просто выполняю:
[self connectInstrument:unit.componentDescription];
Если я вместо этого вручную создаю описание компонента для локального модуля, AVAudioUnit создается просто отлично и ничего не падает.