Ios 将AvaudioExerNode连接到AVAudioEngine

Ios 将AvaudioExerNode连接到AVAudioEngine,ios,swift,pcm,avaudioengine,Ios,Swift,Pcm,Avaudioengine,我使用AVAudioMixerNode更改音频格式。这对我帮助很大。下面的代码提供了我想要的数据。但我在电话的扬声器里听到了我自己的声音。我怎样才能预防它 func startAudioEngine() { engine = AVAudioEngine() guard let engine = engine, let input = engine.inputNode else { // @TODO: error out return }

我使用AVAudioMixerNode更改音频格式。这对我帮助很大。下面的代码提供了我想要的数据。但我在电话的扬声器里听到了我自己的声音。我怎样才能预防它

func startAudioEngine()
{
    engine = AVAudioEngine()

    guard let engine = engine, let input = engine.inputNode else {
        // @TODO: error out
        return
    }

    let downMixer = AVAudioMixerNode()
    //I think you the engine's I/O nodes are already attached to itself by default, so we attach only the downMixer here:
    engine.attach(downMixer)

    //You can tap the downMixer to intercept the audio and do something with it:
    downMixer.installTap(onBus: 0, bufferSize: 2048, format: downMixer.outputFormat(forBus: 0), block:  //originally 1024
        { (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in

            //i get audio data here
        }
    )

    //let's get the input audio format right as it is
    let format = input.inputFormat(forBus: 0)
    //I initialize a 16KHz format I need:
    let format16KHzMono = AVAudioFormat.init(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 11025.0, channels: 1, interleaved: true)

    //connect the nodes inside the engine:
    //INPUT NODE --format-> downMixer --16Kformat--> mainMixer
    //as you can see I m downsampling the default 44khz we get in the input to the 16Khz I want
    engine.connect(input, to: downMixer, format: format)//use default input format
    engine.connect(downMixer, to: engine.outputNode, format: format16KHzMono)//use new audio format

    engine.prepare()

    do {
        try engine.start()
    } catch {
        // @TODO: error out
    }
}

您可以通过扬声器听到麦克风录音,因为您的麦克风已连接到
下混音器
,该下混音器已连接到
引擎。输出节点
。如果您没有将
下混音器的输出与其他输入一起使用,则可以将其静音:

downMixer.outputVolume=0.0

我这样做是为了将频率更改为每采样/2个通道48000Hz/16位,并将其保存到wave文件:

      let outputAudioFileFormat = [AVFormatIDKey: Int(kAudioFormatLinearPCM), AVSampleRateKey: 48000, AVNumberOfChannelsKey: 2, AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue]
      let audioRecordingFormat : AVAudioFormat = AVAudioFormat.init(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 48000, channels: 2, interleaved: true)!

      do{
           try file = AVAudioFile(forWriting: url, settings: outputAudioFileFormat, commonFormat: .pcmFormatInt16, interleaved: true)

           let recordingSession = AVAudioSession.sharedInstance()

           try recordingSession.setPreferredInput(input)
           try recordingSession.setPreferredSampleRate(audioRecordingFormat.sampleRate)

           engine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: audioRecordingFormat, block: self.bufferAvailable)
           engine.connect(engine.inputNode, to: engine.outputNode, format: audioRecordingFormat) //configure graph
      }
      catch
      {
           debugPrint("Could not initialize the audio file: \(error)")
      }
和功能块

 func bufferAvailable(buffer: AVAudioPCMBuffer, time: AVAudioTime)
 {
      do
      {
           try self.file?.write(from: buffer)

           if self.onBufferAvailable != nil {
                DispatchQueue.main.async {
                     self.onBufferAvailable!(buffer) // outside function used for analyzing and displaying a wave meter
                }
           }
      }
      catch{
           self.stopEngine()

           DispatchQueue.main.async {
                self.onRecordEnd(false)
           }
      }
 }
stopEngine函数是这样的,当您想要停止录制时,也应该调用它:

 private func stopEngine()
 {
      self.engine.inputNode.removeTap(onBus: 0)
      self.engine.stop()
 }