CoreAudio: Make it possible to set volume on of QAudioOutput

QAudioOutput::setVolume stopped working for CoreAudio when it was ported
to live in it's own plugin.  This was because it was not possible to set
the volume of QAudioOutput in iOS.  Now the functionality has been
restored and added for iOS as well.  For OS X we use the old method of
setting the volume property of the AudioUnit.  On iOS it is not possible
to set the volume on a per AudioUnit basis, so we now manually modify
the buffer contents (the same we do for QAudioInput already).

Task-number: QTBUG-36756
Change-Id: I42b5892fe5534217043fa55e7b5b9a4ce824050d
Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
This commit is contained in:
Andy Nichols
2014-03-02 18:44:52 +01:00
committed by The Qt Project
parent 1f5b5cb473
commit 775914ffb2

View File

@@ -52,6 +52,10 @@
# include <CoreServices/CoreServices.h> # include <CoreServices/CoreServices.h>
#endif #endif
#if defined(Q_OS_IOS)
# include <QtMultimedia/private/qaudiohelpers_p.h>
#endif
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
static const int DEFAULT_BUFFER_SIZE = 8 * 1024; static const int DEFAULT_BUFFER_SIZE = 8 * 1024;
@@ -430,13 +434,23 @@ QAudioFormat CoreAudioOutput::format() const
void CoreAudioOutput::setVolume(qreal volume) void CoreAudioOutput::setVolume(qreal volume)
{ {
const qreal normalizedVolume = qBound(qreal(0.0), volume, qreal(1.0)); const qreal normalizedVolume = qBound(qreal(0.0), volume, qreal(1.0));
m_cachedVolume = normalizedVolume;
if (!m_isOpen) { if (!m_isOpen) {
m_cachedVolume = normalizedVolume;
return; return;
} }
//TODO: actually set the output volume here #if defined(Q_OS_OSX)
//To set the output volume you need a handle to the mixer unit //on OS X the volume can be set directly on the AudioUnit
if (AudioUnitSetParameter(m_audioUnit,
kHALOutputParam_Volume,
kAudioUnitScope_Global,
0 /* bus */,
(float)normalizedVolume,
0) == noErr)
m_cachedVolume = normalizedVolume;
#else
m_cachedVolume = normalizedVolume;
#endif
} }
qreal CoreAudioOutput::volume() const qreal CoreAudioOutput::volume() const
@@ -497,6 +511,17 @@ OSStatus CoreAudioOutput::renderCallback(void *inRefCon, AudioUnitRenderActionFl
if (framesRead > 0) { if (framesRead > 0) {
ioData->mBuffers[0].mDataByteSize = framesRead * bytesPerFrame; ioData->mBuffers[0].mDataByteSize = framesRead * bytesPerFrame;
d->m_totalFrames += framesRead; d->m_totalFrames += framesRead;
#ifdef Q_OS_IOS
// on iOS we have to adjust the sound volume ourselves
if (!qFuzzyCompare(d->m_cachedVolume, qreal(1.0f))) {
QAudioHelperInternal::qMultiplySamples(d->m_cachedVolume,
d->m_audioFormat,
ioData->mBuffers[0].mData, /* input */
ioData->mBuffers[0].mData, /* output */
ioData->mBuffers[0].mDataByteSize);
}
#endif
} }
else { else {
ioData->mBuffers[0].mDataByteSize = 0; ioData->mBuffers[0].mDataByteSize = 0;