Fix some QAudioInput errors on OSX.

Default buffer size wasn't always calculated correctly, and the timer
used in push mode was sometimes incorrect.

Change-Id: Ic31b9d16e16e4c25a5ebfc302590829e179a96bf
Reviewed-by: Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com>
This commit is contained in:
Michael Goddard
2012-07-09 16:49:03 +10:00
committed by Qt by Nokia
parent f4e83a3a27
commit 8c12864361

View File

@@ -239,7 +239,9 @@ public:
{ {
m_maxPeriodSize = maxPeriodSize; m_maxPeriodSize = maxPeriodSize;
m_periodTime = m_maxPeriodSize / m_outputFormat.mBytesPerFrame * 1000 / m_outputFormat.mSampleRate; m_periodTime = m_maxPeriodSize / m_outputFormat.mBytesPerFrame * 1000 / m_outputFormat.mSampleRate;
m_buffer = new QAudioRingBuffer(bufferSize + (bufferSize % maxPeriodSize == 0 ? 0 : maxPeriodSize - (bufferSize % maxPeriodSize)));
m_buffer = new QAudioRingBuffer(bufferSize);
m_inputBufferList = new QAudioBufferList(m_inputFormat); m_inputBufferList = new QAudioBufferList(m_inputFormat);
m_flushTimer = new QTimer(this); m_flushTimer = new QTimer(this);
@@ -284,7 +286,7 @@ public:
const int available = m_buffer->free(); const int available = m_buffer->free();
while (err == noErr && !feeder.empty()) { while (err == noErr && !feeder.empty()) {
QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available); QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available - copied);
if (region.second == 0) if (region.second == 0)
break; break;
@@ -368,7 +370,9 @@ public:
void startFlushTimer() void startFlushTimer()
{ {
if (m_device != 0) { if (m_device != 0) {
m_flushTimer->start((m_buffer->size() - (m_maxPeriodSize * 2)) / m_maxPeriodSize * m_periodTime); // We use the period time for the timer, since that's
// around the buffer size (pre conversion >.>)
m_flushTimer->start(qMax(1, m_periodTime));
} }
} }
@@ -669,15 +673,37 @@ bool QAudioInputPrivate::open()
return false; return false;
} }
// Allocate buffer AudioValueRange bufferRange;
periodSizeBytes = numberOfFrames * streamFormat.mBytesPerFrame; size = sizeof(AudioValueRange);
if (internalBufferSize < periodSizeBytes * 2) if (AudioUnitGetProperty(audioUnit,
internalBufferSize = periodSizeBytes * 2; kAudioDevicePropertyBufferFrameSizeRange,
else kAudioUnitScope_Global,
internalBufferSize -= internalBufferSize % streamFormat.mBytesPerFrame; 0,
&bufferRange,
&size) != noErr) {
qWarning() << "QAudioInput: Failed to get audio period size range";
return false;
}
audioBuffer = new QtMultimediaInternal::QAudioInputBuffer(internalBufferSize, // See if the requested buffer size is permissible
UInt32 frames = qBound((UInt32)bufferRange.mMinimum, internalBufferSize / streamFormat.mBytesPerFrame, (UInt32)bufferRange.mMaximum);
// Set it back
if (AudioUnitSetProperty(audioUnit,
kAudioDevicePropertyBufferFrameSize,
kAudioUnitScope_Global,
0,
&frames,
sizeof(UInt32)) != noErr) {
qWarning() << "QAudioInput: Failed to set audio buffer size";
return false;
}
// Now allocate a few buffers to be safe.
periodSizeBytes = internalBufferSize = frames * streamFormat.mBytesPerFrame;
audioBuffer = new QtMultimediaInternal::QAudioInputBuffer(internalBufferSize * 4,
periodSizeBytes, periodSizeBytes,
deviceFormat, deviceFormat,
streamFormat, streamFormat,