Avoid audio from iPhone speakers while recording audio from the same iPhone

49 Views Asked by At

I am working on an app where the app continuously records audio. In between it also plays audio which are fetched through our server's in wav format.

Everything is working fine. Audio is recording and Audio coming from server is also playing through speakers.

Issue: I don't want the mic to record the audio which is being played through speaker which is coming from server. I have tried several solutions but every time the audio from the server is played, it is recorded by the iPhone mic. Below is my implementation.

`In ViewDidLoad()

 self.recordingSession = AVAudioSession.sharedInstance()

do {
                try recordingSession.setCategory(AVAudioSession.Category.playAndRecord, mode: .videoRecording, options: .defaultToSpeaker)
                try recordingSession.setActive(true)
                recordingSession.requestRecordPermission() { [unowned self] allowed in
                    DispatchQueue.main.async {
                        if allowed {
                            self.startRecording()
                        } else {
                            // failed to record!
                        }
                    }
                }
            } catch {
                // failed to record!
   }

func startRecording() {
        fileName = getDocumentsDirectory().appendingPathComponent("recording.wav")

                let settings = [
                    AVFormatIDKey: Int(kAudioFormatLinearPCM),
                    AVSampleRateKey: 12000,
                    AVNumberOfChannelsKey: 1,
                    AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
                ] as [String : Any]

                do{

                    audioRecorder = try AVAudioRecorder(url: fileName, settings: settings)
                    audioRecorder.delegate = self


                    if(audioRecorder.record(forDuration: 3 )) {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
                            print("recording succesfull...")
                            if self.audioRecorder != nil {
                                self.audioRecorder.stop()
                                self.audioRecorder = nil
                            }
                        }
                    }

                }
                catch {
                    print ("failed...")
                }
    }

 func playSound(url: URL) {
      do {
          print("Play URL:", url)
          let data = try! Data(contentsOf: url)
          audioPlayer = try! AVAudioPlayer(data: data)
          audioPlayer.delegate = self
          audioPlayer.prepareToPlay()
          audioPlayer.volume = 1.0
          audioPlayer.play()
      } catch let error {
        print(error.localizedDescription)
      }
    }
1

There are 1 best solutions below

0
On

what you are searching is the echo cancellation technology , in IOS you should use AudioUnit(kAudioUnitSubType_VoiceProcessingIO) to split the speaker and mic