title: Playing Audio on iOS from Socket connection
body: <p>Hope you can help me with this issue, I have seen a lot of questions related to this, but none of them really helps me to figure out what I am doing wrong here.</p>
  
  <p>So on Android I have an AudioRecord which is recording audio and sending the audio as byte array over a socket connection to clients. This part was super easy on Android and is working perfectly.</p>
  
  <p>When I started working with iOS I found out there is no easy way to go about this, so after 2 days of research and plugging and playing this is what I have got. Which still does not play any audio. It makes a noise when it starts but none of the audio being transferred over the socket is being played. I confirmed that the socket is receiving data by logging each element in the buffer array.</p>
  
  <p>Here is all the code I am using, a lot is reused from a bunch of sites, can't remember all the links. (BTW using AudioUnits)</p>
  
  <p>First up, audio processor:
  Play Callback</p>
  
  <pre><code>static OSStatus playbackCallback(void *inRefCon,
                                   AudioUnitRenderActionFlags *ioActionFlags,
                                   const AudioTimeStamp *inTimeStamp,
                                   UInt32 inBusNumber,
                                   UInt32 inNumberFrames,
                                   AudioBufferList *ioData) {
  
      /**
       This is the reference to the object who owns the callback.
       */
      AudioProcessor *audioProcessor = (__bridge AudioProcessor*) inRefCon;
  
      // iterate over incoming stream an copy to output stream
      for (int i=0; i &lt; ioData-&gt;mNumberBuffers; i++) {
          AudioBuffer buffer = ioData-&gt;mBuffers[i];
  
          // find minimum size
          UInt32 size = min(buffer.mDataByteSize, [audioProcessor audioBuffer].mDataByteSize);
  
          // copy buffer to audio buffer which gets played after function return
          memcpy(buffer.mData, [audioProcessor audioBuffer].mData, size);
  
          // set data size
          buffer.mDataByteSize = size;
      }
      return noErr;
  }
  </code></pre>
  
  <p>Audio processor initialize</p>
  
  <pre><code>-(void)initializeAudio
  {
      OSStatus status;
  
      // We define the audio component
      AudioComponentDescription desc;
      desc.componentType = kAudioUnitType_Output; // we want to ouput
      desc.componentSubType = kAudioUnitSubType_RemoteIO; // we want in and ouput
      desc.componentFlags = 0; // must be zero
      desc.componentFlagsMask = 0; // must be zero
      desc.componentManufacturer = kAudioUnitManufacturer_Apple; // select provider
  
      // find the AU component by description
      AudioComponent inputComponent = AudioComponentFindNext(NULL, &amp;desc);
  
      // create audio unit by component
      status = AudioComponentInstanceNew(inputComponent, &amp;audioUnit);
  
      [self hasError:status:__FILE__:__LINE__];
  
      // define that we want record io on the input bus
      UInt32 flag = 1;
  
  
      // define that we want play on io on the output bus
      status = AudioUnitSetProperty(audioUnit,
                                    kAudioOutputUnitProperty_EnableIO, // use io
                                    kAudioUnitScope_Output, // scope to output
                                    kOutputBus, // select output bus (0)
                                    &amp;flag, // set flag
                                    sizeof(flag));
      [self hasError:status:__FILE__:__LINE__];
  
      /*
       We need to specifie our format on which we want to work.
       We use Linear PCM cause its uncompressed and we work on raw data.
       for more informations check.
  
       We want 16 bits, 2 bytes per packet/frames at 44khz
       */
      AudioStreamBasicDescription audioFormat;
      audioFormat.mSampleRate         = SAMPLE_RATE;
      audioFormat.mFormatID           = kAudioFormatLinearPCM;
      audioFormat.mFormatFlags        = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
      audioFormat.mFramesPerPacket    = 1;
      audioFormat.mChannelsPerFrame   = 1;
      audioFormat.mBitsPerChannel     = 16;
      audioFormat.mBytesPerPacket     = 2;
      audioFormat.mBytesPerFrame      = 2;
  
      // set the format on the output stream
      status = AudioUnitSetProperty(audioUnit,
                                    kAudioUnitProperty_StreamFormat,
                                    kAudioUnitScope_Output,
                                    kInputBus,
                                    &amp;audioFormat,
                                    sizeof(audioFormat));
  
      [self hasError:status:__FILE__:__LINE__];
  
  
  
      /**
       We need to define a callback structure which holds
       a pointer to the recordingCallback and a reference to
       the audio processor object
       */
      AURenderCallbackStruct callbackStruct;
  
      /*
       We do the same on the output stream to hear what is coming
       from the input stream
       */
      callbackStruct.inputProc = playbackCallback;
      callbackStruct.inputProcRefCon = (__bridge void *)(self);
  
      // set playbackCallback as callback on our renderer for the output bus
      status = AudioUnitSetProperty(audioUnit,
                                    kAudioUnitProperty_SetRenderCallback,
                                    kAudioUnitScope_Global,
                                    kOutputBus,
                                    &amp;callbackStruct,
                                    sizeof(callbackStruct));
  
      [self hasError:status:__FILE__:__LINE__];
  
      // reset flag to 0
      flag = 0;
  
      /*
       we need to tell the audio unit to allocate the render buffer,
       that we can directly write into it.
       */
      status = AudioUnitSetProperty(audioUnit,
                                    kAudioUnitProperty_ShouldAllocateBuffer,
                                    kAudioUnitScope_Output,
                                    kInputBus,
                                    &amp;flag,
                                    sizeof(flag));
  
      /*
       we set the number of channels to mono and allocate our block size to
       1024 bytes.
       */
      audioBuffer.mNumberChannels = 1;
      audioBuffer.mDataByteSize = 512 * 2;
      audioBuffer.mData = malloc( 512 * 2 );
  
      // Initialize the Audio Unit and cross fingers =)
      status = AudioUnitInitialize(audioUnit);
      [self hasError:status:__FILE__:__LINE__];
  
      NSLog(@"Started");
  
  }
  </code></pre>
  
  <p>Start Playing </p>
  
  <pre><code>-(void)start;
  {
      // start the audio unit. You should hear something, hopefully &lt;img src="http://www.stefanpopp.de/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley"&gt;
      OSStatus status = AudioOutputUnitStart(audioUnit);
      [self hasError:status:__FILE__:__LINE__];
  }
  </code></pre>
  
  <p>Adding data to the buffer</p>
  
  <pre><code>-(void)processBuffer: (AudioBufferList*) audioBufferList
  {
      AudioBuffer sourceBuffer = audioBufferList-&gt;mBuffers[0];
  
      // we check here if the input data byte size has changed
      if (audioBuffer.mDataByteSize != sourceBuffer.mDataByteSize) {
          // clear old buffer
          free(audioBuffer.mData);
          // assing new byte size and allocate them on mData
          audioBuffer.mDataByteSize = sourceBuffer.mDataByteSize;
          audioBuffer.mData = malloc(sourceBuffer.mDataByteSize);
      }
      // loop over every packet
      // copy incoming audio data to the audio buffer
      memcpy(audioBuffer.mData, audioBufferList-&gt;mBuffers[0].mData, audioBufferList-&gt;mBuffers[0].mDataByteSize);
  }
  </code></pre>
  
  <p>Stream connection callback (Socket)</p>
  
  <pre><code>-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
  {
      if(eventCode == NSStreamEventHasBytesAvailable)
      {
          if(aStream == inputStream) {
              uint8_t buffer[1024];
              UInt32 len;
              while ([inputStream hasBytesAvailable]) {
                  len = (UInt32)[inputStream read:buffer maxLength:sizeof(buffer)];
                  if(len &gt; 0)
                  {
                      AudioBuffer abuffer;
  
                      abuffer.mDataByteSize = len; // sample size
                      abuffer.mNumberChannels = 1; // one channel
                      abuffer.mData = buffer;
  
                      int16_t audioBuffer[len];
  
                      for(int i = 0; i &lt;= len; i++)
                      {
                          audioBuffer[i] = MuLaw_Decode(buffer[i]);
                      }
  
                      AudioBufferList bufferList;
                      bufferList.mNumberBuffers = 1;
                      bufferList.mBuffers[0] = abuffer;
  
                      NSLog(@"%", bufferList.mBuffers[0]);
  
                      [audioProcessor processBuffer:&amp;bufferList];
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>The <a href="https://stackoverflow.com/a/11417011/831371">MuLaw_Decode</a></p>
  
  <pre><code>#define MULAW_BIAS 33
  int16_t MuLaw_Decode(uint8_t number)
  {
      uint8_t sign = 0, position = 0;
      int16_t decoded = 0;
      number =~ number;
      if(number&amp;0x80)
      {
          number&amp;=~(1&lt;&lt;7);
          sign = -1;
      }
      position= ((number &amp; 0xF0) &gt;&gt; 4) + 5;
      decoded = ((1&lt;&lt;position) | ((number&amp;0x0F) &lt;&lt; (position - 4)) |(1&lt;&lt;(position-5))) - MULAW_BIAS;
      return (sign == 0) ? decoded : (-(decoded));
  }
  </code></pre>
  
  <p>And the code that opens the connection and initialises the audio processor</p>
  
  <pre><code>CFReadStreamRef readStream;
  CFWriteStreamRef writeStream;
  
  
  
  CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"10.0.0.14", 6000, &amp;readStream, &amp;writeStream);
  
  
  inputStream = (__bridge_transfer NSInputStream *)readStream;
  outputStream = (__bridge_transfer NSOutputStream *)writeStream;
  
  [inputStream setDelegate:self];
  [outputStream setDelegate:self];
  
  [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  [inputStream open];
  [outputStream open];
  
  
  audioProcessor = [[AudioProcessor alloc] init];
  [audioProcessor start];
  [audioProcessor setGain:1];
  </code></pre>
  
  <p>I believe the issue in my code is with the socket connection callback, that I am not doing the right thing with the data.</p>