I simply cannot figure out this issue. The audio from the code below is playing extremely fast and choppy. There's one other issue on SO that is similar, but it is for variable bitrate and not applicable.
Some possible answers on other sites (directly set number of frames per packet) no longer work and give a aq -50 error code.
This is from a synthesizer codebase, source audio is 8:24 Linear PCM at 44,100 Hz, non-interleaved. Setting the frames (4096) to the sample rate (44100Hz) seems to fix the choppiness, but the audio generation backend cannot keep up, so it stalls every packet.
Any solutions? For the life of me, I cannot figure out what's causing this to run so fast.
static const int kNumBuffers = 3;
typedef struct CoreAudio_audiodriver
{
A2_audiodriver ad;
AudioQueueRef queue;
AudioQueueBufferRef buffer[kNumBuffers];
AudioStreamBasicDescription desc;
} CoreAudio_audiodriver;
/* CoreAudio render thread callback */
static void coreaudio_process(void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
{
A2_audiodriver *driver = (A2_audiodriver *)inUserData;
CoreAudio_audiodriver * cad = (CoreAudio_audiodriver *)inUserData;
A2_config * config = driver->driver.config;
int c, i;
int frames = 4096 /* samples */;
if( driver->Process )
{
driver->Process(driver, 4096 /* samples */); // loads 4096 samples into internal buffers
}
/* copy and interleave internal buffers to queue */
for ( i = 0; i < frames; i++ )
{
for ( c = 0; c < 2 /* channels */; c++ )
{
((int32_t *)inBuffer->mAudioData)[i + c] = driver->buffers[c][i];
}
}
inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity;
AudioQueueEnqueueBuffer(cad->queue, inBuffer, 0, NULL);
}
static int coreaudiod_Open(A2_driver *driver)
{
CoreAudio_audiodriver * drv = (CoreAudio_audiodriver *)driver;
A2_config * config = drv->ad.driver.config;
AudioStreamBasicDescription * desc = &drv->desc;
OSStatus err;
int c, i;
/* set up stream description */
desc->mSampleRate = (Float64)config->samplerate;
desc->mFormatID = kAudioFormatLinearPCM;
desc->mFormatFlags = kAudioFormatFlagIsSignedInteger;
desc->mFramesPerPacket = 1;
desc->mChannelsPerFrame = 2 /* channels */;
/* packet -> frame -> channel -> data */
desc->mBytesPerFrame = desc->mChannelsPerFrame * sizeof(int32_t);
desc->mBytesPerPacket = desc->mBytesPerFrame * desc->mFramesPerPacket;
desc->mBitsPerChannel = 24; /* 8:24 PCM */
/* set up queue */
err = AudioQueueNewOutput(
desc, // data format
coreaudio_process, // callback
driver, // data passed to callback
NULL, // internal run loop
kCFRunLoopCommonModes, // kCFRunLoopCommonMode
0, // reserved by Apple
&drv->queue // queue output
);
for ( i = 0; i < kNumBuffers; i++ )
{
/* internal buffer */
err = AudioQueueAllocateBuffer(
drv->queue,
desc->mBytesPerPacket * 4096 /* samples */,
&drv->buffer[i]
);
/* start callback polling */
drv->buffer[i]->mAudioDataByteSize = drv->buffer[i]->mAudioDataBytesCapacity;
err = AudioQueueEnqueueBuffer(drv->queue, drv->buffer[i], 0, NULL);
}
err = AudioQueueStart(drv->queue, NULL);
return 1;
}