我目前正在尝试同时记录播放器节点和输入节点,但我遇到了一些困难。我可以让他们单独录制,并在某个时候将我的代码设置为录制两者。唯一的问题是,当我设法做到这一点时,来自输入节点的录制内容将通过扬声器播放,因为它的录制会产生回声,最终会产生难以承受的反馈。因此,我尝试按如下方式塑造我的代码,以便输入节点不会通过扬声器播放,但我发现它很难。
我正在尝试按如下方式设置我的代码:
Player Node Input Node (mic)
| |
| |
| |
v AVAudioConnectionPoint v
Main Mixer ----------------------->>Second Mixer
| |
| Node Tap
|
v
Output
我已经尝试了许多组合,但我不能把它们都放在这里,所以我会列出一些基本代码,并希望有人在这方面有一点专业知识。
首先我创建我的引擎并附加节点:
- (void)createEngineAndAttachNodes
{
_engine = [[AVAudioEngine alloc] init];
[_engine attachNode:_player];
_inputOne = _engine.inputNode;
_outputOne = _engine.outputNode;
}
然后我进行引擎连接(这是我需要知道哪里出错的地方。)
- (void)makeEngineConnections
{
_mainMixerOne = [_engine mainMixerNode];
_secondaryMixerOne = [_engine mainMixerNode];
_commonFormat = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatFloat32
sampleRate:44100 channels:2 interleaved:false];
AVAudioFormat *stereoFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:44100 channels:2];
[_engine connect:_player to:_mainMixerOne format:stereoFormat];
[_engine connect:_mainMixerOne to:_outputOne format:_commonFormat];
[_engine connect:_inputOne to:_secondaryMixerOne format:_commonFormat];
//Fan out mainMixer
NSArray<AVAudioConnectionPoint *> *destinationNodes = [NSArray arrayWithObjects:
[[AVAudioConnectionPoint alloc] initWithNode:_mainMixerOne bus:1], [[AVAudioConnectionPoint alloc]
initWithNode:_secondaryMixerOne bus:0], nil];
[_engine connect:_player toConnectionPoints:destinationNodes fromBus:0 format:_commonFormat];
}
每当我尝试将一个混音器直接连接到另一个混音器时,我都会收到错误消息:
thread 1 exc_bad_access code=2
最后,我尝试将这些都放在我的记录功能中。您看到的功能将记录播放器,但不会记录输入。
-(void)setupRecordOne
{
NSError *error;
if (!_mixerFileOne) _mixerFileOne = [NSURL URLWithString:[NSTemporaryDirectory() stringByAppendingString:@"mixerOutput.caf"]];
// AVAudioMixerNode *mainMixer = [_engine mainMixerNode];
AVAudioFile *mixerOutputFile = [[AVAudioFile alloc] initForWriting:_mixerFileOne
settings:_commonFormat.settings error:&error];
NSAssert(mixerOutputFile != nil, @"mixerOutputFile is nil, %@", [error localizedDescription]);
[self startEngine];
[_secondaryMixerOne installTapOnBus:0 bufferSize:4096
format:_commonFormat block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) {
NSError *error;
BOOL success = NO;
success = [mixerOutputFile writeFromBuffer:buffer error:&error];
NSAssert(success, @"error writing buffer data to file, %@", [error localizedDescription]);
}];
_isRecording = YES;
}
我可以记录输入的唯一方法是设置节点抽头,如下所示:
[self startEngine];
[_inputOne installTapOnBus:0 bufferSize:4096 format:_commonFormat
block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) {
NSError *error;
BOOL success = NO;
success = [mixerOutputFile writeFromBuffer:buffer error:&error];
NSAssert(success, @"error writing buffer data to file, %@", [error localizedDescription]);
}];
但随后它不会记录播放器。
请告诉我那里有人知道该怎么做。
谢谢,
约书亚