AVAudioEngine 在连接节点上崩溃
AVAudioEngine crash on connect node
我已经用自己的方法设置了我的 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];
启动没有错误。我有另一种方法可以从我从 Inter-App Audio 乐器收到的 AudioComponentDescription 附加 AVAudioUnitMIDIInstrument。我的连接方法如下所示:
-(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");
}
崩溃没有给我任何有用的信息。我明白了:
提供给 CFRunLoopRunSpecific 的模式 'kCFRunLoopCommonModes' 无效 - 在 _CFRunLoopError_RunCalledWithInvalidMode 上中断以进行调试。此消息每次执行只会出现一次。
* 由于未捕获的异常 'NSRangeException' 而终止应用程序,原因:'* -[__NSArrayM objectAtIndexedSubscript:]:索引 0 超出空数组的范围'
如果我进行测试并尝试创建一个新的混音器节点并 attach/connect 它,不会发生崩溃。
我有更多相关信息
如果我这样做:
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.1khz 采样率、32 位浮点数、2 个通道。所以有一个输出流格式,但它似乎没有附加到 AVAudioUnitMIDIInstrument 实例的任何输出总线。
编辑 - 更多信息
即使我只是尝试访问 instUnite_.name,我也会得到 NSRangeException。我现在想知道这是否与我获取组件描述的方式有关。我正在尝试使用 Inter-App Audio(我已经完成了所有适当的权利、功能和应用程序 ID 设置)。这就是我发现 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 实例化得很好,没有任何崩溃。
我找到了答案。 AVAudioUnit 对象内部的 AUAudioUnit 对象在创建时没有输出总线。我不确定为什么。您可以通过这样做来修复它:
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];
我已经用自己的方法设置了我的 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];
启动没有错误。我有另一种方法可以从我从 Inter-App Audio 乐器收到的 AudioComponentDescription 附加 AVAudioUnitMIDIInstrument。我的连接方法如下所示:
-(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");
}
崩溃没有给我任何有用的信息。我明白了:
提供给 CFRunLoopRunSpecific 的模式 'kCFRunLoopCommonModes' 无效 - 在 _CFRunLoopError_RunCalledWithInvalidMode 上中断以进行调试。此消息每次执行只会出现一次。
* 由于未捕获的异常 'NSRangeException' 而终止应用程序,原因:'* -[__NSArrayM objectAtIndexedSubscript:]:索引 0 超出空数组的范围'
如果我进行测试并尝试创建一个新的混音器节点并 attach/connect 它,不会发生崩溃。
我有更多相关信息
如果我这样做:
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.1khz 采样率、32 位浮点数、2 个通道。所以有一个输出流格式,但它似乎没有附加到 AVAudioUnitMIDIInstrument 实例的任何输出总线。
编辑 - 更多信息 即使我只是尝试访问 instUnite_.name,我也会得到 NSRangeException。我现在想知道这是否与我获取组件描述的方式有关。我正在尝试使用 Inter-App Audio(我已经完成了所有适当的权利、功能和应用程序 ID 设置)。这就是我发现 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 实例化得很好,没有任何崩溃。
我找到了答案。 AVAudioUnit 对象内部的 AUAudioUnit 对象在创建时没有输出总线。我不确定为什么。您可以通过这样做来修复它:
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];