プレイヤーノードのミキサーノードと入力ノードを使用してコードをセットアップしました。また、機能の中断や特定の変更に対処するように設定しました。
ただし、これらの変更には大きな問題があります。つまり、View Controller を閉じると、アプリのメモリが解放されなくなるだけでなく、playernode が引き続き再生されます。プレーヤー ノードでビューに戻り、停止を押しても機能しません。プレイヤーを再びアクティブにすることもでき、止められないプレイヤーと一緒にプレイします。
-(void)setupAudioOne
{
NSError *error;
BOOL success = NO;
[self initAVAudioSession];
_isSessionInterrupted = NO;
_isConfigChangePending = NO;
_player = [[AVAudioPlayerNode alloc] init];
_inputOne = [[AVAudioInputNode alloc] init];
_setReverb = [[AVAudioUnitReverb alloc] init];
NSURL *hiphopOneURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Hip Hop 1" ofType:@"caf"]];
AVAudioFile *hiphopOneFile = [[AVAudioFile alloc] initForReading:hiphopOneURL error:&error];
_playerLoopBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:[hiphopOneFile processingFormat] frameCapacity:(AVAudioFrameCount)[hiphopOneFile length]];
success = [hiphopOneFile readIntoBuffer:_playerLoopBuffer error:&error];
NSAssert(success, @"couldn't read buffer bitch, %@", [error localizedDescription]);
_isRecording = NO;
[self createEngineAndAttachNodes];
[self makeEngineConnections];
_setReverb.wetDryMix = 75;
[_setReverb loadFactoryPreset:AVAudioUnitReverbPresetMediumHall];
//get notifications from the engine if there's a hardware config change
[[NSNotificationCenter defaultCenter] addObserverForName:AVAudioEngineConfigurationChangeNotification object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
// if we've received this change rewire everything
_isConfigChangePending = YES;
if (!_isSessionInterrupted) {
NSLog(@"Received a %@ notification!", AVAudioEngineConfigurationChangeNotification);
NSLog(@"Re-wiring connections and starting once again");
[self makeEngineConnections];
[self startEngine];
}
else {
NSLog(@"Session is interrupted, deffering changes");
}
//post notification
if ([self.delegate respondsToSelector:@selector(engineConfigurationHasChanged)]) {
[self.delegate engineConfigurationHasChanged];
}
}];
[self startEngine];
}
問題の領域は、ハードウェア構成の変更がある場合にエンジンから通知を取得しようとするコードの下部にあります。このコードを削除すると、ビューが閉じられると、エンジンが使用しているすべてのメモリも削除されます。ただし、これは、誰かがヘッドフォンを接続すると、アプリがクラッシュすることも意味します。ご覧のコードが必要ですが、ビューが閉じられた場合にアプリが使用中のメモリを解放するようにコードを変更する必要があります。
何かアドバイス?