我正在开发一个iOS应用程序,使用AVAudioEngine进行各种操作,包括将音频录制到文件中,使用音频单元对该音频应用效果,以及播放应用效果后的音频。我使用tap也将输出写入文件。完成后,它会在音频回放时实时写入文件。
是否可以设置一个AVAudioEngine图形,从文件中读取,使用音频单元处理声音,并输出到文件中,但速度比实时快(即,尽快地处理它)?这样做的用例是输出几分钟带有效果的音频,我肯定不想等待几分钟来进行处理。
编辑:这是我用来设置AVAudioEngine图形并播放声音文件的代码:
是否可以设置一个AVAudioEngine图形,从文件中读取,使用音频单元处理声音,并输出到文件中,但速度比实时快(即,尽快地处理它)?这样做的用例是输出几分钟带有效果的音频,我肯定不想等待几分钟来进行处理。
编辑:这是我用来设置AVAudioEngine图形并播放声音文件的代码:
AVAudioEngine* engine = [[AVAudioEngine alloc] init];
AVAudioPlayerNode* player = [[AVAudioPlayerNode alloc] init];
[engine attachNode:player];
self.player = player;
self.engine = engine;
if (!self.distortionEffect) {
self.distortionEffect = [[AVAudioUnitDistortion alloc] init];
[self.engine attachNode:self.distortionEffect];
[self.engine connect:self.player to:self.distortionEffect format:[self.distortionEffect outputFormatForBus:0]];
AVAudioMixerNode* mixer = [self.engine mainMixerNode];
[self.engine connect:self.distortionEffect to:mixer format:[mixer outputFormatForBus:0]];
}
[self.distortionEffect loadFactoryPreset:AVAudioUnitDistortionPresetDrumsBitBrush];
NSError* error;
if (![self.engine startAndReturnError:&error]) {
NSLog(@"error: %@", error);
} else {
NSURL* fileURL = [[NSBundle mainBundle] URLForResource:@"test2" withExtension:@"mp3"];
AVAudioFile* file = [[AVAudioFile alloc] initForReading:fileURL error:&error];
if (error) {
NSLog(@"error: %@", error);
} else {
[self.player scheduleFile:file atTime:nil completionHandler:nil];
[self.player play];
}
}
以上代码使用AVAudioUnitDistortionPresetDrumsBitBrush
失真预设,实时播放test2.mp3文件中的声音。
接着,在[self.player play]之后添加了以下代码:
[self.engine stop];
[self renderAudioAndWriteToFile];
我修改了Vladimir提供的renderAudioAndWriteToFile方法,使其不再在第一行分配新的AVAudioEngine,而是直接使用已经设置好的self.engine。
然而,在renderAudioAndWriteToFile中,它记录了“无法呈现音频单元”,因为AudioUnitRender返回kAudioUnitErr_Uninitialized
状态。
编辑2:我应该提到,我很乐意将我发布的AVAudioEngine代码转换为使用C API,如果这样做会使事情变得更加容易。但是,我希望这段代码能够产生与AVAudioEngine代码相同的输出(包括上面显示的工厂预设的使用)。