現在、プレイヤー ノードと入力ノードを同時に記録しようとしていますが、問題が発生しています。それらを個別に記録させることができ、ある時点で両方を記録するようにコードを設定しました。唯一の問題は、これを行うと、入力ノードから録音されたコンテンツがスピーカーから再生され、その録音がエコーを作成し、最終的に耐えられないほどのフィードバックを作成することです。そのため、入力ノードがスピーカーから再生されないように、次のようにコードを整形しようとしましたが、難しいと感じています。
次のようにコードを設定しようとしています。
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]);
}];
しかし、それはプレーヤーを記録しません。
何をすべきかを知っている人がいると教えてください。
ありがとう、
ジョシュア