title: Natively buffering audio
body: <p>This probably is one of my own mistakes, but I can't seem to find what is wrong. After trying to improve performance of my application, I moved audio buffering from the Java layer to the native layer. Audio handling (recording/playing) is already done natively using the OpenSL ES API.</p>
  
  <p>Yet the native buffering is causing my application to crash whenever I start the application. I use a simple Queue implementation as my buffer, where the first node is the oldest data (FIFO).</p>
  
  <pre><code>struct bufferNode{
      struct bufferNode* next;
      jbyte* data;
  };
  
  struct bufferQueue{
      struct bufferNode* first;
      struct bufferNode* last;
      int size;
  };
  </code></pre>
  
  <p>The audio data is referred to by the jbyte* in the bufferNode. Access to the Queue is done via these two methods, and is synchronized with a mutex.</p>
  
  <pre><code>void enqueueInBuffer(struct bufferQueue* queue, jbyte* data){
      SLresult result;
      if(queue != NULL){
          if(data != NULL){
              result = pthread_mutex_lock(&amp;recMutex);
              if(result != 0){
                  decodeMutexResult(result);
                  logErr("EnqueueInBuffer", "Unable to acquire recording mutex");
              } else {
                  struct bufferNode* node = (struct bufferNode*)malloc(sizeof(struct bufferNode));
                  if(node == NULL){
                      logErr("EnqueueInBuffer", "Insufficient memory available to buffer new audio");
                  } else {
                      node-&gt;data = data;
                      if(queue-&gt;first == NULL){
                          queue-&gt;first = queue-&gt;last = node;
                      } else {
                          queue-&gt;last-&gt;next = node;
                          queue-&gt;last = node;
                      }
                      queue-&gt;size = queue-&gt;size + 1;
                      node-&gt;next = NULL;
                  }
              }
              result = pthread_mutex_unlock(&amp;recMutex);
              if(result != 0){
                  decodeMutexResult(result);
                  logErr("EnqueueInBuffer", "Unable to release recording mutex");
              }
          } else {
              logErr("EnqueueInBuffer", "Data is NULL");
          }
      } else {
          logErr("EnqueueInBuffer", "Queue is NULL");
      }
  }
  
  void dequeueFromBuffer(struct bufferQueue* queue, jbyte* returnData){
      SLresult result;
      result = pthread_mutex_lock(&amp;recMutex);
      if(result != 0){
          decodeMutexResult(result);
          logErr("DequeueFromBuffer", "Unable to acquire recording mutex");
      } else {
          if(queue-&gt;first == NULL){
              returnData = NULL;
          } else {
              returnData = queue-&gt;first-&gt;data;
              struct bufferNode* tmp = queue-&gt;first;
              if(queue-&gt;first == queue-&gt;last){
                  queue-&gt;first = queue-&gt;last = NULL;
              } else {
                  queue-&gt;first = queue-&gt;first-&gt;next;
              }
              free(tmp);
              queue-&gt;size = queue-&gt;size - 1;
          }
      }
      result = pthread_mutex_unlock(&amp;recMutex);
      if(result != 0){
          decodeMutexResult(result);
          logErr("DequeueFromBuffer", "Unable to release recording mutex");
      }
  }
  </code></pre>
  
  <ul>
  <li>Where the log and decode methods are selfdeclared utility methods. Log just logs the message to the logcat, while the decode methods "decode" any error number possible from the previous method call.</li>
  </ul>
  
  <p>Yet I keep getting an error when I try to enqueue audio data. Whenever I call the <code>enqueueInBuffer</code> method, I get a SIGSEGV native error, with code 1 (SEGV_MAPERR). Yet I can't seem to find what is causing the error. Both the Queue and the audio data exist when I try to make the <code>enqueueInBuffer</code> method call (which is done in an OpenSL ES Recorder callback, hence the synchronization).</p>
  
  <p>Is there something else going on what causes the segmentation fault? Probably I am responsible for it, but I can't seem to find the error.</p>