summaryrefslogtreecommitdiffstats
path: root/src/multimedia/audio
diff options
context:
space:
mode:
authorLev Zelenskiy <lev.zelenskiy@nokia.com>2012-07-25 13:23:57 +1000
committerQt by Nokia <qt-info@nokia.com>2012-07-26 09:06:23 +0200
commit403eee4d871d389a54e9e3b41dca092d7eac9bac (patch)
treecad5f688981315e01d227485826edae2d4793dc2 /src/multimedia/audio
parent64dbf9d96874a2f6a77b6b525514e0995c358f65 (diff)
Volume control for QAudioInput windows backend.
Change-Id: I1245a38c68254fc48373a856dc44e8ad8142636e Reviewed-by: Ling Hu <ling.hu@nokia.com>
Diffstat (limited to 'src/multimedia/audio')
-rw-r--r--src/multimedia/audio/qaudioinput_win32_p.cpp108
-rw-r--r--src/multimedia/audio/qaudioinput_win32_p.h7
2 files changed, 115 insertions, 0 deletions
diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp
index 1ed68d256..a5e124c6e 100644
--- a/src/multimedia/audio/qaudioinput_win32_p.cpp
+++ b/src/multimedia/audio/qaudioinput_win32_p.cpp
@@ -72,11 +72,16 @@ QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device)
resuming = false;
finished = false;
waveBlockOffset = 0;
+
+ mixerID = 0;
+ memset(&mixerLineControls, 0, sizeof(mixerLineControls));
+ initMixer();
}
QAudioInputPrivate::~QAudioInputPrivate()
{
stop();
+ closeMixer();
}
void QT_WIN_CALLBACK QAudioInputPrivate::waveInProc( HWAVEIN hWaveIn, UINT uMsg,
@@ -163,6 +168,71 @@ QAudio::State QAudioInputPrivate::state() const
return deviceState;
}
+#ifndef DRVM_MAPPER_CONSOLEVOICECOM_GET
+ #ifndef DRVM_MAPPER
+ #define DRVM_MAPPER 0x2000
+ #endif
+ #ifndef DRVM_MAPPER_STATUS
+ #define DRVM_MAPPER_STATUS (DRVM_MAPPER+0)
+ #endif
+ #define DRVM_USER 0x4000
+ #define DRVM_MAPPER_RECONFIGURE (DRVM_MAPPER+1)
+ #define DRVM_MAPPER_PREFERRED_GET (DRVM_MAPPER+21)
+ #define DRVM_MAPPER_CONSOLEVOICECOM_GET (DRVM_MAPPER+23)
+#endif
+
+void QAudioInputPrivate::setVolume(qreal volume)
+{
+ for (DWORD i = 0; i < mixerLineControls.cControls; i++) {
+
+ MIXERCONTROLDETAILS controlDetails;
+ controlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ controlDetails.dwControlID = mixerLineControls.pamxctrl[i].dwControlID;
+ controlDetails.cChannels = 1;
+
+ if ((mixerLineControls.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_FADER) ||
+ (mixerLineControls.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)) {
+ MIXERCONTROLDETAILS_UNSIGNED controlDetailsUnsigned;
+ controlDetailsUnsigned.dwValue = qBound(DWORD(0), DWORD(65535.0 * volume + 0.5), DWORD(65535));
+ controlDetails.cMultipleItems = 0;
+ controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
+ controlDetails.paDetails = &controlDetailsUnsigned;
+ mixerSetControlDetails((HMIXEROBJ)mixerID, &controlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
+ }
+ }
+}
+
+qreal QAudioInputPrivate::volume() const
+{
+ DWORD volume = 0;
+ for (DWORD i = 0; i < mixerLineControls.cControls; i++) {
+ if ((mixerLineControls.pamxctrl[i].dwControlType != MIXERCONTROL_CONTROLTYPE_FADER) &&
+ (mixerLineControls.pamxctrl[i].dwControlType != MIXERCONTROL_CONTROLTYPE_VOLUME)) {
+ continue;
+ }
+
+ MIXERCONTROLDETAILS controlDetails;
+ controlDetails.cbStruct = sizeof(controlDetails);
+ controlDetails.dwControlID = mixerLineControls.pamxctrl[i].dwControlID;
+ controlDetails.cChannels = 1;
+ controlDetails.cMultipleItems = 0;
+ controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
+ MIXERCONTROLDETAILS_UNSIGNED detailsUnsigned;
+ controlDetails.paDetails = &detailsUnsigned;
+ memset(controlDetails.paDetails, 0, controlDetails.cbDetails);
+
+ MMRESULT result = mixerGetControlDetails((HMIXEROBJ)mixerID, &controlDetails, MIXER_GETCONTROLDETAILSF_VALUE);
+ if (result != MMSYSERR_NOERROR)
+ continue;
+ if (controlDetails.cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED))
+ continue;
+ volume = detailsUnsigned.dwValue;
+ break;
+ }
+
+ return volume / 65535.0;
+}
+
void QAudioInputPrivate::setFormat(const QAudioFormat& fmt)
{
if (deviceState == QAudio::StoppedState)
@@ -351,6 +421,44 @@ void QAudioInputPrivate::close()
}
}
+void QAudioInputPrivate::initMixer()
+{
+ QDataStream ds(&m_device, QIODevice::ReadOnly);
+ quint32 inputDevice;
+ ds >> inputDevice;
+
+ if (int(inputDevice) < 0)
+ return;
+
+ // Get the Mixer ID from the Sound Device ID
+ if (mixerGetID((HMIXEROBJ)inputDevice, &mixerID, MIXER_OBJECTF_WAVEIN) != MMSYSERR_NOERROR)
+ return;
+
+ // Get the Destination (Recording) Line Infomation
+ MIXERLINE mixerLine;
+ mixerLine.cbStruct = sizeof(MIXERLINE);
+ mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
+ if (mixerGetLineInfo((HMIXEROBJ)mixerID, &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR)
+ return;
+
+ // Set all the Destination (Recording) Line Controls
+ if (mixerLine.cControls > 0) {
+ mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS);
+ mixerLineControls.dwLineID = mixerLine.dwLineID;
+ mixerLineControls.cControls = mixerLine.cControls;
+ mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
+ mixerLineControls.pamxctrl = new MIXERCONTROL[mixerLineControls.cControls];
+ if (mixerGetLineControls((HMIXEROBJ)mixerID, &mixerLineControls, MIXER_GETLINECONTROLSF_ALL) != MMSYSERR_NOERROR)
+ closeMixer();
+ }
+}
+
+void QAudioInputPrivate::closeMixer()
+{
+ delete[] mixerLineControls.pamxctrl;
+ memset(&mixerLineControls, 0, sizeof(mixerLineControls));
+}
+
int QAudioInputPrivate::bytesReady() const
{
if(period_size == 0 || buffer_size == 0)
diff --git a/src/multimedia/audio/qaudioinput_win32_p.h b/src/multimedia/audio/qaudioinput_win32_p.h
index 1c9c7fab8..723433f02 100644
--- a/src/multimedia/audio/qaudioinput_win32_p.h
+++ b/src/multimedia/audio/qaudioinput_win32_p.h
@@ -114,6 +114,8 @@ public:
qint64 elapsedUSecs() const;
QAudio::Error error() const;
QAudio::State state() const;
+ void setVolume(qreal volume);
+ qreal volume() const;
QIODevice* audioSource;
QAudioFormat settings;
@@ -150,6 +152,11 @@ private:
bool open();
void close();
+ void initMixer();
+ void closeMixer();
+ UINT mixerID;
+ MIXERLINECONTROLS mixerLineControls;
+
private slots:
void feedback();
bool deviceReady();