Сбой AVAudioEngine на соединительном узле - PullRequest
0 голосов
/ 16 октября 2018

Я настроил свой 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 создается просто отлично и ничего не падает.

1 Ответ

0 голосов
/ 17 октября 2018

Я нашел ответ.Объект AUAudioUnit внутри объекта AVAudioUnit не имеет выходных шин при создании.Я не уверен почему.Вы можете исправить это, выполнив это:

AUAudioUnit* auInst = instUnit_.AUAudioUnit;
NSMutableArray<AUAudioUnitBus*>* busArray = [[NSMutableArray alloc] init];
AVAudioFormat* outFormat = [[self->audioEngine_ outputNode] outputFormatForBus:0];
AUAudioUnitBus* bus = [[AUAudioUnitBus alloc] initWithFormat:outFormat error:&err];
[busArrays addObject:bus];
[[auInst outputBusses] replaceBusses:busArray];
...