shithub: sox

Download patch

ref: 0aff9d901692e0252a5947ae63a2ed3f4ebd5259
parent: 5bff6d2f408ac3975819f7c5f450f6505eb229ae
author: cbagwell <cbagwell>
date: Sat Feb 19 15:22:59 EST 2011

Look for more than 1 buffer and warn user.  Attempt to fix
segfault occuring on some peoples boxes during playback.

--- a/src/coreaudio.c
+++ b/src/coreaudio.c
@@ -29,23 +29,34 @@
   sox_format_t *ft = (sox_format_t *)inClientData;
   priv_t *ac = (priv_t *)ft->priv;
   float *buf = outOutputData->mBuffers[0].mData;
-  int len;
+  unsigned int len;
+  unsigned int buf_num;
 
-  /* mDataByteSize may be non-zero even when mData is NULL, but that is 
-   * not an error.
-   */
-  if (buf == NULL)
-    return kAudioHardwareNoError;
+  pthread_mutex_lock(&ac->mutex);
 
+  for (buf_num = 0; buf_num <  outOutputData->mNumberBuffers; buf_num++)
+  {
+      /* TODO: Does more than 1 output buffer need to be handled? */
+      if (buf_num > 0)
+      {
+    	  outOutputData->mBuffers[buf_num].mDataByteSize = 0;
+	  continue;
+      }
 
-  pthread_mutex_lock(&ac->mutex);
+      buf = outOutputData->mBuffers[0].mData;
 
-  len = ac->buf_offset;
+      /* mDataByteSize may be non-zero even when mData is NULL, but that is
+       * not an error.
+       */
+      if (buf == NULL)
+	  continue;
 
-  memcpy(buf, ac->buffer, len);
-  outOutputData->mBuffers[0].mDataByteSize = len;
+      len = ac->buf_offset;
 
-  ac->buf_offset = 0;
+      memcpy(buf, ac->buffer, len);
+      outOutputData->mBuffers[buf_num].mDataByteSize = len;
+      ac->buf_offset = 0;
+  }
 
   pthread_mutex_unlock(&ac->mutex);
   pthread_cond_signal(&ac->cond);
@@ -63,26 +74,44 @@
 {
   sox_format_t *ft = (sox_format_t *)inClientData;
   priv_t *ac = (priv_t *)ft->priv;
-  float *buf = inInputData->mBuffers[0].mData;
-  size_t buflen = inInputData->mBuffers[0].mDataByteSize;
+  float *buf;
+  size_t buflen;
   float *destbuf = (float *)((unsigned char *)ac->buffer + ac->buf_offset);
   int i;
+  unsigned int buf_num;
 
-  /* mDataByteSize may be non-zero even when mData is NULL, but that is 
-   * not an error.
-   */
-  if (buf == NULL)
-    return kAudioHardwareNoError;
+  pthread_mutex_lock(&ac->mutex);
 
-  if (buflen > (ac->buf_size - ac->buf_offset))
-    buflen = ac->buf_size - ac->buf_offset;
+  for (buf_num = 0; buf_num <  inInputData->mNumberBuffers; buf_num++)
+  {
+      /* TODO: Does more than 1 input buffer need to be handled? */
+      if (buf_num > 0)
+      {
+	  lsx_warn("coreaudio: unhandled extra buffer.  Data discarded.");
+	  continue;
+      }
 
-  pthread_mutex_lock(&ac->mutex);
+      buf = inInputData->mBuffers[buf_num].mData;
+      buflen = inInputData->mBuffers[buf_num].mDataByteSize;
 
-  for (i = 0; i < (int)(buflen / sizeof(float)); i += 2) {
-    destbuf[i] = buf[i];
-    destbuf[i + 1] = buf[i + 1];
-    ac->buf_offset += sizeof(float) * 2;
+      /* mDataByteSize may be non-zero even when mData is NULL, but that is
+       * not an error.
+       */
+      if (buf == NULL)
+	  continue;
+
+      if (buflen > (ac->buf_size - ac->buf_offset))
+	  buflen = ac->buf_size - ac->buf_offset;
+
+      /* FIXME: Handle buffer overrun. */
+      if (buflen < ac->buf_size)
+	  lsx_warn("coreaudio: unhandled buffer overrun.  Data discarded.");
+
+      for (i = 0; i < (int)(buflen / sizeof(float)); i += 2) {
+	  destbuf[i] = buf[i];
+	  destbuf[i + 1] = buf[i + 1];
+	  ac->buf_offset += sizeof(float) * 2;
+      }
   }
 
   pthread_mutex_unlock(&ac->mutex);
@@ -171,7 +200,7 @@
 
   if (stream_desc.mChannelsPerFrame != ft->signal.channels)
   {
-    lsx_debug("audio device did not accept %d channels. Use %d channels instead.", (int)ft->signal.channels, 
+    lsx_debug("audio device did not accept %d channels. Use %d channels instead.", (int)ft->signal.channels,
               (int)stream_desc.mChannelsPerFrame);
     ft->signal.channels = stream_desc.mChannelsPerFrame;
   }
@@ -178,7 +207,7 @@
 
   if (stream_desc.mSampleRate != ft->signal.rate)
   {
-    lsx_debug("audio device did not accept %d sample rate. Use %d instead.", (int)ft->signal.rate, 
+    lsx_debug("audio device did not accept %d sample rate. Use %d instead.", (int)ft->signal.rate,
               (int)stream_desc.mSampleRate);
     ft->signal.rate = stream_desc.mSampleRate;
   }