Daedelus
Daedelus

Reputation: 266

Connecting AVAudioMixerNode to AVAudioEngine

I use AVAudioMixerNode to change audio format. this entry helped me a lot. Below code gives me data i want. But i hear my own voice on phone's speaker. How can i prevent it?

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
    }
}

Upvotes: 5

Views: 2303

Answers (2)

Stefan Pintilie
Stefan Pintilie

Reputation: 705

I did it like this to change the frequency to 48000Hz / 16 bit per sample / 2 channels, and save it to wave file:

      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)")
      }

And the function block

 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)
           }
      }
 }

The stopEngine function is this, you should call it also when you want to stop the recording:

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

Upvotes: 0

Mark
Mark

Reputation: 352

You can hear your microphone recording through your speakers because your microphone is connected to downMixer, which is connected to engine.outputNode. You could probably just mute the output for the downMixer if you aren't using it with other inputs:

downMixer.outputVolume = 0.0

Upvotes: 4

Related Questions