@@ -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