Skip to content

Commit 80b6757

Browse files
committed
coreaudio3: very minor optimization
1 parent a3621b9 commit 80b6757

1 file changed

Lines changed: 49 additions & 32 deletions

File tree

audio/drivers/coreaudio3.m

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ @interface CoreAudio3 : NSObject {
181181
unsigned _hwRate;
182182
unsigned _lastInputRate;
183183
double _lastRateAdjust;
184+
float *_convBuffer;
185+
size_t _convBufferFrames;
184186
}
185187

186188
@property (nonatomic, readwrite) BOOL nonBlock;
@@ -288,6 +290,12 @@ - (instancetype)initWithRate:(NSUInteger)rate
288290

289291
_au = au;
290292

293+
/* Allocate converter output buffer (enough for 2048 output frames) */
294+
_convBufferFrames = 2048;
295+
_convBuffer = (float *)calloc(_convBufferFrames * 2, sizeof(float));
296+
if (!_convBuffer)
297+
return nil;
298+
291299
RARCH_LOG("[CoreAudio3] Using buffer size of %u bytes: (latency = %u ms, hw rate = %u Hz, %s).\n",
292300
(unsigned)self.bufferSizeInBytes, (unsigned)latency, _hwRate,
293301
_interleaved ? "interleaved" : "non-interleaved");
@@ -304,6 +312,11 @@ - (void)dealloc {
304312
AudioConverterDispose(_converter);
305313
_converter = NULL;
306314
}
315+
if (_convBuffer)
316+
{
317+
free(_convBuffer);
318+
_convBuffer = NULL;
319+
}
307320
}
308321

309322
- (unsigned)hardwareRate {
@@ -398,11 +411,7 @@ - (ssize_t)writeRawInt16:(const int16_t *)samples
398411
rateAdjust:(double)rateAdjust {
399412
OSStatus err;
400413
double effectiveRate;
401-
UInt32 outputFrames;
402-
float *outputBuffer;
403-
size_t outputSamples;
404-
ssize_t written;
405-
AudioBufferList outputBufferList;
414+
size_t framesWritten = 0;
406415
coreaudio3_converter_ctx_t ctx;
407416

408417
if (frames == 0)
@@ -461,41 +470,49 @@ - (ssize_t)writeRawInt16:(const int16_t *)samples
461470
_lastRateAdjust = rateAdjust;
462471
}
463472

464-
/* Calculate output size and allocate buffer */
465-
outputFrames = (UInt32)ceil((double)frames * _hwRate / effectiveRate) + 16;
466-
outputBuffer = (float *)malloc(outputFrames * 2 * sizeof(float));
467-
if (!outputBuffer)
468-
return -1;
469-
470-
/* Set up output buffer list for interleaved stereo */
471-
outputBufferList.mNumberBuffers = 1;
472-
outputBufferList.mBuffers[0].mNumberChannels = 2;
473-
outputBufferList.mBuffers[0].mDataByteSize = outputFrames * 2 * sizeof(float);
474-
outputBufferList.mBuffers[0].mData = outputBuffer;
475-
476473
/* Set up callback context */
477474
ctx.data = samples;
478475
ctx.frames_left = frames;
479476

480-
err = AudioConverterFillComplexBuffer(_converter,
481-
coreaudio3_converter_cb, &ctx,
482-
&outputFrames, &outputBufferList, NULL);
483-
484-
if (err != noErr && err != 1) /* 1 means end of input */
477+
/* Process in chunks that fit our pre-allocated buffer */
478+
while (ctx.frames_left > 0)
485479
{
486-
RARCH_ERR("[CoreAudio3]: AudioConverterFillComplexBuffer failed: %d\n", (int)err);
487-
free(outputBuffer);
488-
return -1;
489-
}
480+
UInt32 outputFrames = (UInt32)_convBufferFrames;
481+
AudioBufferList outputBufferList;
482+
size_t outputSamples;
483+
ssize_t written;
484+
485+
outputBufferList.mNumberBuffers = 1;
486+
outputBufferList.mBuffers[0].mNumberChannels = 2;
487+
outputBufferList.mBuffers[0].mDataByteSize = outputFrames * 8; /* stereo float */
488+
outputBufferList.mBuffers[0].mData = _convBuffer;
490489

491-
/* Write resampled float data to ring buffer */
492-
outputSamples = outputFrames * 2;
493-
written = [self writeFloat:outputBuffer samples:outputSamples];
490+
err = AudioConverterFillComplexBuffer(_converter,
491+
coreaudio3_converter_cb, &ctx,
492+
&outputFrames, &outputBufferList, NULL);
494493

495-
free(outputBuffer);
494+
if (err != noErr && err != 1) /* 1 means end of input */
495+
{
496+
RARCH_ERR("[CoreAudio3]: AudioConverterFillComplexBuffer failed: %d\n", (int)err);
497+
break;
498+
}
499+
500+
if (outputFrames == 0)
501+
break;
502+
503+
/* Write resampled float data to ring buffer */
504+
outputSamples = outputFrames * 2;
505+
written = [self writeFloat:_convBuffer samples:outputSamples];
506+
507+
if (written > 0)
508+
framesWritten += written / 2; /* count frames, not samples */
509+
510+
/* In nonblock mode, stop if we couldn't write everything */
511+
if (_nonBlock && ctx.frames_left > 0)
512+
break;
513+
}
496514

497-
/* Return input frames consumed */
498-
return (written > 0) ? (ssize_t)frames : written;
515+
return (ssize_t)framesWritten;
499516
}
500517

501518
@end

0 commit comments

Comments
 (0)