 +    return;
 +  }
 +
-+  NSLog(@"Finish input initialization.");
++  RTCLog(@"Finish input initialization.");
 +  _isInputInited = YES;
 +  _waitsInputInit = NO;
 +  if (_inputInitCompletionHandler != nil) {

   OSStatus result = noErr;
   AudioStreamBasicDescription format = GetFormat(sample_rate);
   UInt32 size = sizeof(format);
@@ -315,6 +323,11 @@ static OSStatus GetAGCState(AudioUnit audio_unit, UInt32* enabled) {
   RTC_DCHECK_GE(state_, kUninitialized);
   RTCLog(@"Starting audio unit.");
 
+  /*
+  RTCAudioSession *session = [RTCAudioSession sharedInstance];
+  [session startVoiceProcessingAudioUnit: this];
+  */
+
   OSStatus result = AudioOutputUnitStart(vpio_unit_);
   if (result != noErr) {
     RTCLogError(@"Failed to start audio unit. Error=%ld", (long)result);
@@ -322,7 +335,9 @@ static OSStatus GetAGCState(AudioUnit audio_unit, UInt32* enabled) {
   } else {
     RTCLog(@"Started audio unit");
   }
+
   state_ = kStarted;
+
   return true;
 }
 
@@ -330,6 +345,9 @@ static OSStatus GetAGCState(AudioUnit audio_unit, UInt32* enabled) {
   RTC_DCHECK_GE(state_, kUninitialized);
   RTCLog(@"Stopping audio unit.");
 

+  // Specify the callback to be called by the I/O thread to us when input audio
+  // is available. The recorded samples can then be obtained by calling the
+  // AudioUnitRender() method.
+  AURenderCallbackStruct input_callback;
+  input_callback.inputProc = _vpAudioUnit->OnDeliverRecordedData;
+  input_callback.inputProcRefCon = _vpAudioUnit;
