title: Write 2 single channel files into 1 two channel file with separate left and right channels
body: <p>I am trying to write 2 single channel audio files to a single 2 channel file, where the first audio file goes to the left channel and the second one to the right channel.
  I used the AVAudioEngine class with the standard mixer, but this blends the 2 audio files and writes the same thing both in the left and right channel.
  Here is the code I use:</p>
  
  <pre><code>//
  //  ViewController.m
  //  StereoMixer
  //
  
  #import "ViewController.h"
  #import &lt;AVFoundation/AVFoundation.h&gt;
  
  extern void CheckError(NSError *error);
  
  @interface ViewController ()
  
  @property(nonatomic, strong) AVAudioEngine *engine;
  
  @end
  
  @implementation ViewController
  
  -(void)viewDidLoad {
      [super viewDidLoad];
  
      NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
  
      NSString *outputFile = [docsDir stringByAppendingPathComponent:@"output.caf"];
      NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
  
      [self mergeAudioFilePath1:[bundlePath stringByAppendingPathComponent:@"1.m4a"]
                 audioFilePath2:[bundlePath stringByAppendingPathComponent:@"2.m4a"]
             outputFilePath:outputFile];
  }
  
  -(void)mergeAudioFilePath1:(NSString *)audioFilePath1 audioFilePath2:(NSString *)audioFilePath2 outputFilePath:(NSString *)outputFilePath {
      _engine = [[AVAudioEngine alloc] init];
  
      AVAudioFormat *stereoFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:44100 channels:2];
  
      NSError *error = nil;
  
      AVAudioMixerNode *mainMixer = _engine.mainMixerNode;
  
      AVAudioFile *audioFile1 = [[AVAudioFile alloc] initForReading:[NSURL fileURLWithPath:audioFilePath1] error:&amp;error];
      CheckError(error);
      AVAudioFile *audioFile2 = [[AVAudioFile alloc] initForReading:[NSURL fileURLWithPath:audioFilePath2] error:&amp;error];
      CheckError(error);
  
      AVAudioPlayerNode *player1 = [[AVAudioPlayerNode alloc] init];
      AVAudioPlayerNode *player2 = [[AVAudioPlayerNode alloc] init];
  
      [_engine attachNode:player1];
      [_engine attachNode:player2];
  
      stereoFormat = [mainMixer outputFormatForBus:0];
      [_engine connect:player1 to:mainMixer fromBus:0 toBus:0 format:audioFile1.processingFormat];
      [_engine connect:player2 to:mainMixer fromBus:0 toBus:1 format:audioFile2.processingFormat];
      [_engine connect:mainMixer to:_engine.outputNode format:stereoFormat];
  
  
      [[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:&amp;error];
      AVAudioFile *outputFile = [[AVAudioFile alloc] initForWriting:[NSURL fileURLWithPath:outputFilePath]
                                                           settings:[_engine.inputNode inputFormatForBus:0].settings
                                                              error:&amp;error];
  
      CheckError(error);
  
      if (![_engine startAndReturnError:&amp;error]) {
          NSLog(@"Error in [engine startAndReturnError:&amp;error]");
      }
      [mainMixer installTapOnBus:0 bufferSize:4096 format:[mainMixer outputFormatForBus:0] block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) {
          NSError *error;
          BOOL success;
          NSLog(@"writing");
  
          if ((outputFile.length &lt; audioFile1.length) || (outputFile.length &lt; audioFile2.length)) {
              success = [outputFile writeFromBuffer:buffer error:&amp;error];
              NSAssert(success, @"error writing buffer data to file, %@", [error localizedDescription]);
              if (error) {
                  NSLog(@"writebuffererror =%@",error);
              }
          } else {
              [mainMixer removeTapOnBus:0];
              NSLog(@"done");
          }
  
      }];
  
      [player1 scheduleFile:audioFile1 atTime:nil completionHandler:nil];
      [player2 scheduleFile:audioFile2 atTime:nil completionHandler:nil];
  
      [player1 play];
      [player2 play];
  }
  
  @end
  
  void CheckError(NSError *error) {
      if (error == nil) return;
  //    NSLog(@"Error: %@", error);
      NSError *newError = [NSError errorWithDomain:NSOSStatusErrorDomain
                                           code:error.code
                                       userInfo:nil];
      NSLog(@"Error: %@", [newError description]);
  
  }
  </code></pre>
  
  <p>Any ideas?</p>