使用AVAudioEngine

时间:2016-05-16 15:36:01

标签: objective-c xcode7 avfoundation audio-recording avaudioengine

我目前正在尝试同时录制播放器节点和输入节点,但我遇到了一些困难。我可以让他们单独录制,并在某些时候设置我的代码记录两者。唯一的问题是,当我设法这样做时,来自输入节点的录制内容将通过扬声器播放,因为它的录音会产生回声,最终会产生太多无法承受的反馈。所以我试着按如下方式调整我的代码,所以输入节点不能通过扬声器播放,但我发现它很难。

我正在尝试按如下方式设置代码:

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]);
}];

但是它不会记录播放器。

请告诉我,有人知道该怎么做。

谢谢,

约书亚

0 个答案:

没有答案