title: Dynamically reconnecting AVAudioEngine nodes without stopping sound
body: <p>I'm trying to dynamically modify a graph of nodes in attached to an <code>AVAudioEngine</code>, but the graph outputs silence after every reconnection. </p>
  
  <p>In  the below sample, I'd like to dynamically connect <code>player</code> to <code>engine.mainMixerNode</code>, but whenever I call <code>toggleBypass</code> I get silence. </p>
  
  <p>Is it possible to carry out this rewiring without pausing playback of the <code>AVAudioPlayerNode</code>? </p>
  
  <pre class="lang-swift prettyprint-override"><code>class Sample: UIViewController {
  
      let engine = AVAudioEngine()
      let player = AVAudioPlayerNode()
      let effectNode = AVAudioUnitDelay()
  
      @objc func toggleBypass() {
          if effectNode.numberOfInputs == 0 {
              engine.connect(player, to: effectNode, format: file.processingFormat)
              engine.connect(effectNode, to: engine.mainMixerNode, format: file.processingFormat)
          } else {
              engine.connect(player, to: engine.mainMixerNode, format: file.processingFormat)
          }
      }
  
      override func viewDidLoad() {
          super.viewDidLoad()
  
          view.backgroundColor = .red
  
          view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(toggleBypass)))
  
          try! AVAudioSession.sharedInstance().setCategory(.playback)
          try! AVAudioSession.sharedInstance().setPreferredIOBufferDuration(0.005)
          try! AVAudioSession.sharedInstance().setActive(true, options: [])
  
          do {
  
              engine.attach(player)
              engine.attach(effectNode)
  
              engine.connect(player, to: effectNode, format: file.processingFormat)
              engine.connect(effectNode, to: engine.mainMixerNode, format: file.processingFormat)
  
              player.scheduleBuffer(buffer, at: nil, options: .loops, completionHandler: nil)
  
              engine.prepare()
  
              try engine.start()
  
              player.play()
  
          } catch {
              assertionFailure(String(describing: error))
          }
      }
  
      lazy var file: AVAudioFile = {
          let fileURL = Bundle.main.url(forResource: "beber", withExtension: "mp3")!
          return try! AVAudioFile(forReading: fileURL)
      }()
  
      lazy var buffer: AVAudioPCMBuffer = {
          let buffer = AVAudioPCMBuffer(pcmFormat: file.processingFormat, frameCapacity: UInt32(file.length))!
          try! file.read(into: buffer)
          return buffer
      }()
  
  }
  </code></pre>
  
  <p>(Yes, I know I can update the effect's <code>bypass</code> property, but I'm interested knowing what the steps are to dynamically rewire a graph)</p>