Volume control for QAudioInput windows backend.
Change-Id: I1245a38c68254fc48373a856dc44e8ad8142636e Reviewed-by: Ling Hu <ling.hu@nokia.com>
This commit is contained in:
committed by
Qt by Nokia
parent
64dbf9d968
commit
403eee4d87
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user