0

When I try to swap between AudioKit players, I have different types of problems. I'll add the code, but I'll try to simplify it.

Let's say, I have five players and one recorder for those players, I'm recording player1 once and player2 once, if I'm trying to swap between them, the swap succeeds. If I'm recording player1 twice and player2 twice, the swap succeeds, but if I'm recording player1 twice and player2 once, during the swap it says that player1 doesn't exist(nil) - Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value.

Another problem: I've recorded player1 twice, player2 twice and player3 and player4 once, I'm trying to swap between player3 and player4 but it says that player3 or player4 doesn't exist(nil) - Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value. Only if player1 and player2 recorded once, or player3 and player4 recorded twice, it succeeds.

Last problem: I've recorded player1 once and player2 once, I want to swap player1 with empty player3, it succeeds. When I try to swap between player2 and player1(that is now supposed to be empty), it says player1 doesn't exist(nil) - Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value, When player1 now is supposed to be swapped with the recording on player2.

Help me figure out why it's so frustrating. here's the code:

@objc func startStopClipRecording1(button: UIButton, event: UIEvent) {

    switch self.state {
       case .readyToRecord :

           if self.recorded1 == true{
           while multiPlayers.contains(player1) {
               if let itemToRemoveIndex = multiPlayers.firstIndex(of: player1) {
                   multiPlayers.remove(at: itemToRemoveIndex)
               }
           }
        }

           self.plot?.node = self.mic
           self.state = .recording

    _ = AVAudioTime(hostTime: UInt64(event.timestamp * secondsToTicks))

           guard let lastRenderHostTime = mainMixer.avAudioNode.lastRenderTime?.hostTime else { fatalError("Engine not running!") }

           let audioSession = AKSettings.session
           let bufferDurationTicks = UInt64(audioSession.ioBufferDuration * secondsToTicks)
           let outputLatencyTicks = UInt64(audioSession.outputLatency * secondsToTicks)
           let inputLatencyTicks = UInt64(audioSession.inputLatency * secondsToTicks)

           let nextRenderHostTime = lastRenderHostTime + bufferDurationTicks

           let renderAfterNextHostTime = nextRenderHostTime + bufferDurationTicks

           let startTimeHost = renderAfterNextHostTime + outputLatencyTicks

           let playbackStartTime = AVAudioTime(hostTime: startTimeHost - outputLatencyTicks)

           let recordingStartTime = AVAudioTime(hostTime: startTimeHost + inputLatencyTicks)

           metronome.beatTime = 0
           directRecorder?.currentTime = 0

        var bars = 30 / (4 * (60 / metronome.tempo))
        bars.round(.towardZero)
        let durationClipRec = bars * (4 * (60 / metronome.tempo))

           try? directRecorder?.recordClip(time: 0, duration: durationClipRec, tap: nil) { result in
               switch result {
               case .error(let error):
                   AKLog(error)
                   return
               case .clip(let clip):
                   AKLog("direct.duration \(clip.duration)")
                   AKLog("direct.StartTime \(clip.startTime)")

                   do {
                    let urlInDocs = FileManager.docs.appendingPathComponent(self.filename1).appendingPathExtension(clip.url.pathExtension)

                    if FileManager.default.fileExists(atPath: urlInDocs.path){
                        FileManager.emtpyDocumentsDirectory()
                    }

                       try FileManager.default.moveItem(at: clip.url, to: urlInDocs)

                    self.url1 = urlInDocs

                    self.clip1 = clip

                       AKLog("Direct saved at " + urlInDocs.path)
                   } catch {
                       AKLog(error)
                   }
               }
           }


           let todoDelay = 0.001

        if self.recordedButNot1 == true{


                   multiPlayers.forEach { player in
                       player.play(at: playbackStartTime) }
            metronome.play(at: recordingStartTime + todoDelay)
            directRecorder?.start(at: recordingStartTime)
            recTimer1 = Timer.scheduledTimer(timeInterval: 30.2, target:self, selector:#selector(recAction1), userInfo:nil, repeats:false)
        }else{
           metronome.play(at: recordingStartTime + todoDelay)
           directRecorder?.start(at: recordingStartTime)
            recTimer1 = Timer.scheduledTimer(timeInterval: 30.2, target:self, selector:#selector(recAction1), userInfo:nil, repeats:false)
        }

        case .recording :

            directRecorder?.stopRecording()
            directRecorder?.stop()

        recordAction1()
          }

}

@objc func recAction1(){
    recordAction1()
}

func recordAction1(){

    self.addPlayer1(withFileURL: url1)

                          self.instButton1.isHidden = false
              swapMButton.isUserInteractionEnabled = true

                          self.plot?.node = nil

                               self.recorded1 = true
                               self.firstRecordDuration = true

                               self.recordedButNot2 = true
                               self.recordedButNot3 = true
                               self.recordedButNot4 = true
                               self.recordedButNot5 = true

                          self.metronome.stop()

                                    self.setupUIForPlaying()
                                    self.setupUIForRecording1()              


    recTimer1.invalidate()
}

    private func addPlayer1(withFileURL url: URL) {
       player1 = AKPlayer(url: url)
       player1.buffering = .always
       player1.prepare()
    player1.pan = 0
       self.multiPlayers.append(self.player1)
       self.mainMixer.connect(input: self.player1)
   }

func swap(_ str1: inout URL, _ str2: inout URL) {
      (str1, str2) = (str2, str1)
    }

func swapPlayers(AKplayer: AKPlayer, urlString: URL, timeLabel1: UITextField, timeLabel2: UITextField, 
textField1: UITextField, textField2: UITextField, playerName1: String, playerName2: String, 
instrument1: InstrumentButton, instrument2: InstrumentButton, isPlayer2Recorded: Bool, button1: 
UIImageView, button2: UIImageView, maskLayer: CAShapeLayer, view: UIView){

    while self.multiPlayers.contains(AKplayer) {
                   if let itemToRemoveIndex = self.multiPlayers.firstIndex(of: AKplayer) {
                       self.multiPlayers.remove(at: itemToRemoveIndex)
                   }
               }

    if playerName1 == self.recordingName1{

        fileName = filename1
        clip6 = clip1
    }
    if playerName1 == self.recordingName2{

        fileName = filename2
        clip6 = clip2
    }
    if playerName1 == self.recordingName3{

       fileName = filename3
        clip6 = clip3
    }
    if playerName1 == self.recordingName4{

       fileName = filename4
        clip6 = clip4
    }
    if playerName1 == self.recordingName5{

        fileName = filename5
        clip6 = clip5
    }

    let myLayer = plot!.waveformLayer!
    myLayer.path = maskLayer.path
    view.layer.addSublayer(myLayer)
    self.plot?.clear()


               instTextField6.text = textField1.text
               recordingTimeLabel6.text = timeLabel1.text

               if isPlayer2Recorded == true{

                if playerName2 == self.recordingName1{
                    AKplayer2 = player1
                }
                if playerName2 == self.recordingName2{
                    AKplayer2 = player2
                }
                if playerName2 == self.recordingName3{
                    AKplayer2 = player3
                }
                if playerName2 == self.recordingName4{
                    AKplayer2 = player4
                }
                if playerName2 == self.recordingName5{
                    AKplayer2 = player5
                }
                textField1.text = textField2.text
                textField2.text = instTextField6.text

                selectedInstrumentToImage(button: instrument1, textField: textField1)
                selectedInstrumentToImage(button: instrument2, textField: textField2)

                timeLabel1.text = timeLabel2.text
                timeLabel2.text = recordingTimeLabel6.text

                   while self.multiPlayers.contains(AKplayer2) {
                       if let itemToRemoveIndex = self.multiPlayers.firstIndex(of: AKplayer2) {
                           self.multiPlayers.remove(at: itemToRemoveIndex)

                       }
                }
                       if playerName1 == self.recordingName1{
                           if playerName2 == self.recordingName2{
                            print(url1!)
                            print(url2!)
                            swap(&url1, &url2)
                            print(url1!)
                            print(url2!)
                            addPlayer1(withFileURL: url1)
                            addPlayer2(withFileURL: url2)
                           }
                           if playerName2 == self.recordingName3{
                               self.url1 = self.url3
                               self.url3 = self.url6
                            addPlayer1(withFileURL: url1)
                            addPlayer3(withFileURL: url3)
                           }
                           if playerName2 == self.recordingName4{
                               self.url1 = self.url4
                               self.url4 = self.url6
                            addPlayer1(withFileURL: url1)
                            addPlayer4(withFileURL: url4)
                           }
                           if playerName2 == self.recordingName5{
                               self.url1 = self.url5
                               self.url5 = self.url6
                            addPlayer1(withFileURL: url1)
                            addPlayer5(withFileURL: url5)
                           }
                       }

                       if playerName1 == self.recordingName2{
                           if playerName2 == self.recordingName1{
                               self.url2 = self.url1
                               self.url1 = self.url6
                            addPlayer2(withFileURL: url2)
                            addPlayer1(withFileURL: url1)
                           }
                           if playerName2 == self.recordingName3{
                               self.url2 = self.url3
                               self.url3 = self.url6
                            addPlayer2(withFileURL: url2)
                            addPlayer3(withFileURL: url3)
                           }
                           if playerName2 == self.recordingName4{
                               self.url2 = self.url4
                               self.url4 = self.url6
                            addPlayer2(withFileURL: url2)
                            addPlayer4(withFileURL: url4)
                           }
                           if playerName2 == self.recordingName5{
                               self.url2 = self.url5
                               self.url5 = self.url6
                            addPlayer2(withFileURL: url2)
                            addPlayer5(withFileURL: url5)
                           }
                       }

                       if playerName1 == self.recordingName3{
                           if playerName2 == self.recordingName1{
                               self.url3 = self.url1
                               self.url1 = self.url6
                            addPlayer3(withFileURL: url3)
                            addPlayer1(withFileURL: url1)
                           }
                           if playerName2 == self.recordingName2{
                               self.url3 = self.url2
                               self.url2 = self.url6
                            addPlayer3(withFileURL: url3)
                            addPlayer2(withFileURL: url2)
                           }
                           if playerName2 == self.recordingName4{
                               self.url3 = self.url4
                               self.url4 = self.url6
                            addPlayer3(withFileURL: url3)
                            addPlayer4(withFileURL: url4)
                           }
                           if playerName2 == self.recordingName5{
                               self.url3 = self.url5
                               self.url5 = self.url6
                            addPlayer3(withFileURL: url3)
                            addPlayer5(withFileURL: url5)
                           }
                       }

                       if playerName1 == self.recordingName4{
                           if playerName2 == self.recordingName1{
                               self.url4 = self.url1
                               self.url1 = self.url6
                            addPlayer4(withFileURL: url4)
                            addPlayer1(withFileURL: url1)
                           }
                           if playerName2 == self.recordingName2{
                               self.url4 = self.url2
                               self.url2 = self.url6
                            addPlayer4(withFileURL: url4)
                            addPlayer2(withFileURL: url2)
                           }
                           if playerName2 == self.recordingName3{
                               self.url4 = self.url3
                               self.url3 = self.url6
                            addPlayer4(withFileURL: url4)
                            addPlayer3(withFileURL: url3)
                           }
                           if playerName2 == self.recordingName5{
                               self.url4 = self.url5
                               self.url5 = self.url6
                            addPlayer4(withFileURL: url4)
                            addPlayer5(withFileURL: url5)
                           }
                       }

                       if playerName1 == self.recordingName5{
                           if playerName2 == self.recordingName1{
                               self.url5 = self.url1
                               self.url1 = self.url6
                            addPlayer5(withFileURL: url5)
                            addPlayer1(withFileURL: url1)
                           }
                           if playerName2 == self.recordingName2{
                               self.url5 = self.url2
                               self.url2 = self.url6
                            addPlayer5(withFileURL: url5)
                            addPlayer2(withFileURL: url2)
                           }
                           if playerName2 == self.recordingName3{
                               self.url5 = self.url3
                               self.url3 = self.url6
                            addPlayer5(withFileURL: url5)
                            addPlayer3(withFileURL: url3)
                           }
                           if playerName2 == self.recordingName4{
                               self.url5 = self.url4
                               self.url4 = self.url6
                            addPlayer5(withFileURL: url5)
                            addPlayer4(withFileURL: url4)
                           }
                       }

               }else{


                button1.isUserInteractionEnabled = false
                button2.isUserInteractionEnabled = true

                textField1.text = ""
                textField2.text = instTextField6.text

                selectedInstrumentToImage(button: instrument1, textField: textField1)
                selectedInstrumentToImage(button: instrument2, textField: textField2)

                timeLabel1.text = timeLabel2.text
                timeLabel2.text = recordingTimeLabel6.text


                   if playerName1 == self.recordingName1{

                    recorded1 = false
                    reverb1.outputNode.removeTap(onBus: 0)
                    delay1.outputNode.removeTap(onBus: 0)
                    player1.outputNode.removeTap(onBus: 0)
                    player1 = nil
                    delaySlider1.isEnabled = false
                    reverbSlider1.isEnabled = false
                    volumeSlider1.isEnabled = false
                    soloButton1.isEnabled = false
                    muteButton1.isEnabled = false

                       if playerName2 == self.recordingName2{
                           self.url1 = nil
                           self.clip1 = nil
                           self.url2 = self.url6
                        addPlayer2(withFileURL: url2)
                        recorded2 = true
                       }
                       if playerName2 == self.recordingName3{
                           self.url1 = nil
                           self.clip1 = nil
                           self.url3 = self.url6
                        addPlayer3(withFileURL: url3)
                        recorded3 = true
                       }
                       if playerName2 == self.recordingName4{
                           self.url1 = nil
                           self.clip1 = nil
                           self.url4 = self.url6
                        addPlayer4(withFileURL: url4)
                         recorded4 = true
                       }
                       if playerName2 == self.recordingName5{
                           self.url1 = nil
                           self.clip1 = nil
                           self.url5 = self.url6
                        addPlayer5(withFileURL: url5)
                        recorded5 = true
                       }
                   }

                   if playerName1 == self.recordingName2{

                    recorded2 = false
                    reverb2.outputNode.removeTap(onBus: 0)
                    delay2.outputNode.removeTap(onBus: 0)
                    player2.outputNode.removeTap(onBus: 0)
                    player2 = nil
                    delaySlider2.isEnabled = false
                    reverbSlider2.isEnabled = false
                    volumeSlider2.isEnabled = false
                    soloButton2.isEnabled = false
                    muteButton2.isEnabled = false

                       if playerName2 == self.recordingName1{
                           self.url2 = nil
                           self.clip2 = nil
                           self.url1 = self.url6
                        addPlayer1(withFileURL: url1)
                        recorded1 = true
                       }
                       if playerName2 == self.recordingName3{
                           self.url2 = nil
                           self.clip2 = nil
                           self.url3 = self.url6
                        addPlayer3(withFileURL: url3)
                         recorded3 = true
                       }
                       if playerName2 == self.recordingName4{
                           self.url2 = nil
                           self.clip2 = nil
                           self.url4 = self.url6
                        addPlayer4(withFileURL: url4)
                        recorded4 = true
                       }
                       if playerName2 == self.recordingName5{
                           self.url2 = nil
                           self.clip2 = nil
                           self.url5 = self.url6
                        addPlayer5(withFileURL: url5)
                        recorded5 = true
                       }
                   }

                   if playerName1 == self.recordingName3{

                    recorded3 = false
                    reverb3.outputNode.removeTap(onBus: 0)
                    delay3.outputNode.removeTap(onBus: 0)
                    player3.outputNode.removeTap(onBus: 0)
                    player3 = nil
                    delaySlider3.isEnabled = false
                    reverbSlider3.isEnabled = false
                    volumeSlider3.isEnabled = false
                    soloButton3.isEnabled = false
                    muteButton3.isEnabled = false

                       if playerName2 == self.recordingName1{
                           self.url3 = nil
                           self.clip3 = nil
                           self.url1 = self.url6
                        addPlayer1(withFileURL: url1)
                        recorded1 = true
                       }
                       if playerName2 == self.recordingName2{
                           self.url3 = nil
                           self.clip3 = nil
                           self.url2 = self.url6
                        addPlayer2(withFileURL: url2)
                        recorded2 = true
                       }
                       if playerName2 == self.recordingName4{
                           self.url3 = nil
                           self.clip3 = nil
                           self.url4 = self.url6
                        addPlayer4(withFileURL: url4)
                        recorded4 = true
                       }
                       if playerName2 == self.recordingName5{
                           self.url3 = nil
                           self.clip3 = nil
                           self.url5 = self.url6
                        addPlayer5(withFileURL: url5)
                        recorded5 = true
                       }
                   }

                   if playerName1 == self.recordingName4{

                    recorded4 = false
                    reverb4.outputNode.removeTap(onBus: 0)
                    delay4.outputNode.removeTap(onBus: 0)
                    player4.outputNode.removeTap(onBus: 0)
                    player4 = nil
                    delaySlider4.isEnabled = false
                    reverbSlider4.isEnabled = false
                    volumeSlider4.isEnabled = false
                    soloButton4.isEnabled = false
                    muteButton4.isEnabled = false

                       if playerName2 == self.recordingName1{
                           self.url4 = nil
                           self.clip4 = nil
                           self.url1 = self.url6
                        addPlayer1(withFileURL: url1)
                        recorded1 = true
                       }
                       if playerName2 == self.recordingName2{
                           self.url4 = nil
                           self.clip4 = nil
                           self.url2 = self.url6
                        addPlayer2(withFileURL: url2)
                        recorded2 = true
                       }
                       if playerName2 == self.recordingName3{
                           self.url4 = nil
                           self.clip4 = nil
                           self.url3 = self.url6
                        addPlayer3(withFileURL: url3)
                         recorded3 = true
                       }
                       if playerName2 == self.recordingName5{
                           self.url4 = nil
                           self.clip4 = nil
                           self.url5 = self.url6
                        addPlayer5(withFileURL: url5)
                        recorded5 = true
                       }
                   }

                   if playerName1 == self.recordingName5{

                    recorded5 = false
                    reverb5.outputNode.removeTap(onBus: 0)
                    delay5.outputNode.removeTap(onBus: 0)
                    player5.outputNode.removeTap(onBus: 0)
                    player5 = nil
                    delaySlider5.isEnabled = false
                    reverbSlider5.isEnabled = false
                    volumeSlider5.isEnabled = false
                    soloButton5.isEnabled = false
                    muteButton5.isEnabled = false

                       if playerName2 == self.recordingName1{
                           self.url5 = nil
                           self.clip5 = nil
                           self.url1 = self.url6
                        addPlayer1(withFileURL: url1)
                        recorded1 = true
                       }
                       if playerName2 == self.recordingName2{
                           self.url5 = nil
                           self.clip5 = nil
                           self.url2 = self.url6
                        addPlayer2(withFileURL: url2)
                        recorded2 = true
                       }
                       if playerName2 == self.recordingName3{
                           self.url5 = nil
                           self.clip5 = nil
                           self.url3 = self.url6
                        addPlayer3(withFileURL: url3)
                         recorded3 = true
                       }
                       if playerName2 == self.recordingName4{
                           self.url5 = nil
                           self.clip5 = nil
                           self.url4 = self.url6
                        addPlayer4(withFileURL: url4)
                        recorded4 = true
                       }
                   }
                let urlInDocs = FileManager.docs.appendingPathComponent(self.fileName!).appendingPathExtension(clip6!.url.pathExtension)

                if FileManager.default.fileExists(atPath: urlInDocs.path){
                    FileManager.emtpyDocumentsDirectory()
                }

               }

}
aminography
  • 21,986
  • 13
  • 70
  • 74
Kurteran
  • 33
  • 4

1 Answers1

0

I've found the solution:

instead of:

FileManager.emtpyDocumentsDirectory()

in startStopClipRecording function, which I've found out it deletes all of the files, I had to do a specific code for the URL:

if FileManager.default.fileExists(atPath: urlInDocs.path){
                              do {
                                  try FileManager.default.removeItem(at: urlInDocs)
                                 print("File deleted", urlInDocs)
                              } catch let error as NSError {
                                  print("Error: \(error.domain)")
                              }
                          }
Kurteran
  • 33
  • 4