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;
}