Knowledge Base Nr: 00170 volume.cpp - http://www.swe-kaiser.de

Downloads: C++-Klassen

Win32: Lautstärke systemweit einstellen, Mute und WAV-Dateien (im Hintergrund) abspielen

  
#include <mmsystem.h>

#if (1) //Englisch
#pragma comment(lib, "C:/Program Files/Microsoft Visual Studio/VC98/Lib/WINMM.LIB")
#else
#pragma comment(lib, "C:/Programme/Microsoft Visual Studio/VC98/Lib/WINMM.LIB")
#endif

class CSoundSupport
{
...
//lautstärke absolut setzen (0.0-1.0 entspricht 0-100%)
static int SetVolume(float fPercent);

//lautstärke relativ setzen in anzahl der kleinstmöglichen schritte (positiv oder negativ)
//bSetNormal=true ignoriert die nSteps und setzt die lautstärke auf den mittleren wert
static int SetVolumeWav(bool bSetNormal, int nSteps);
static int SetVolume(bool bSetNormal, int nSteps);

//lpszWAVfile = NULL stoppt wiedergabe - bWait wartet bis datei abgespielt ist - bRepeat wiederholt endlos
static int PlayWAV(const char* lpszWAVfile, bool bWait, bool bRepeat);

static int Mute(bool bOnOff);
};

int CSoundSupport::PlayWAV(const char* lpszWAVfile, bool bWait, bool bRepeat)
{
DWORD fdwSound = SND_FILENAME;

if (bWait)
fdwSound |= SND_SYNC;
else
fdwSound |= SND_ASYNC;

if (bRepeat)
fdwSound |= SND_LOOP;

BOOL bSucc = ::PlaySound(lpszWAVfile, NULL, fdwSound);

return bSucc ? 0 : -1; //ok
}


//lautstärke absolut setzen (0.0-1.0 entspricht 0-100%)
int CSoundSupport::SetVolume(float fPercent)
{
UINT nNumDevs = waveOutGetNumDevs();
ASSERT(nNumDevs > 0);
if (nNumDevs <= 0)
return -1;

DWORD dwVolume = 0;
HWAVEOUT hwo = 0;
MMRESULT mmr = 0;

//mmr = waveOutGetVolume(hwo, &dwVolume);

DWORD dwNewVolume = (DWORD)((float)0xffff * fPercent) & 0xffff;

dwVolume = ((dwNewVolume<<16)&0xffff0000) | dwNewVolume;
mmr = waveOutSetVolume(hwo, dwVolume);
if (mmr != MMSYSERR_NOERROR)
{
return -2;
}

return 0;
}

//lautstärke relativ setzen in anzahl der kleinstmöglichen schritte (positiv oder negativ)
//bSetNormal=true ignoriert die nSteps und setzt die lautstärke auf den mittleren wert
int CSoundSupport::SetVolumeWav(bool bSetNormal, int nSteps)
{
int nNumDev = mixerGetNumDevs();

TRACE("mixerGetNumDevs: <%d>\n", nNumDev);
ASSERT(nNumDev>0);
if (nNumDev<=0)
{
return -1;
}

MMRESULT mmr;

UINT uMxId = 0;

MIXERLINECONTROLS mxlc;
MIXERCONTROL mixctrl;
ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
mxlc.cControls = 1;
mxlc.dwControlID = 0;
mxlc.cbmxctrl = sizeof(MIXERCONTROL);
mxlc.pamxctrl = &mixctrl;

DWORD fdwControls = MIXER_OBJECTF_MIXER;

mmr = mixerGetLineControls((HMIXEROBJ)uMxId /*hmx*/, &mxlc, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -2;
}

TRACE("mixerGetLineControls: <%s> [%d..%d] steps : %d\n"
, mxlc.pamxctrl->szName
, mxlc.pamxctrl->Bounds.dwMinimum
, mxlc.pamxctrl->Bounds.dwMaximum
, mxlc.pamxctrl->Metrics.cSteps
);

MIXERCONTROLDETAILS mixdet;
MIXERCONTROLDETAILS_UNSIGNED det;
ZeroMemory(&mixdet, sizeof(MIXERCONTROLDETAILS));
mixdet.cbStruct = sizeof(MIXERCONTROLDETAILS);
mixdet.dwControlID = mxlc.pamxctrl->dwControlID;
mixdet.cChannels = 1;
mixdet.cMultipleItems = 0;
mixdet.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mixdet.paDetails = &det;

mmr = mixerGetControlDetails((HMIXEROBJ)uMxId, &mixdet, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -3;
}

if (bSetNormal)
{
det.dwValue = mxlc.pamxctrl->Bounds.dwMinimum +
((mxlc.pamxctrl->Bounds.dwMaximum - mxlc.pamxctrl->Bounds.dwMinimum) / 2);
}
else
{
if (nSteps > 0)
{
det.dwValue += (nSteps * mxlc.pamxctrl->Metrics.cSteps);
if (det.dwValue > mxlc.pamxctrl->Bounds.dwMaximum)
det.dwValue = mxlc.pamxctrl->Bounds.dwMaximum;
}
else
{
long nNewValue = det.dwValue + (nSteps * mxlc.pamxctrl->Metrics.cSteps);
if (nNewValue < (long)mxlc.pamxctrl->Bounds.dwMinimum) //'überschlag' verhindern!
det.dwValue = mxlc.pamxctrl->Bounds.dwMinimum;
else
det.dwValue = nNewValue;
}
}

mmr = mixerSetControlDetails((HMIXEROBJ)uMxId, &mixdet, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -4;
}

return 0; //ok
}

int CSoundSupport::Mute(bool bOnOff)
{
int nNumDev = mixerGetNumDevs();

TRACE("mixerGetNumDevs: <%d>\n", nNumDev);
ASSERT(nNumDev>0);
if (nNumDev<=0)
{
return -1;
}

//immer erster mixer
UINT uMxId = 0;

MMRESULT mmr;

MIXERLINE mxl;
ZeroMemory(&mxl, sizeof(MIXERLINE));
mxl.cbStruct = sizeof(MIXERLINE);
mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;

DWORD fdwControls = MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_COMPONENTTYPE;

mmr = mixerGetLineInfo((HMIXEROBJ)uMxId, &mxl, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -2;
}

MIXERLINECONTROLS mxlc;
MIXERCONTROL mixctrl;
ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
mxlc.cControls = 1;
mxlc.dwLineID = mxl.dwLineID;
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
mxlc.cbmxctrl = sizeof(MIXERCONTROL);
mxlc.pamxctrl = &mixctrl;

fdwControls = MIXER_OBJECTF_MIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE;

mmr = mixerGetLineControls((HMIXEROBJ)uMxId /*hmx*/, &mxlc, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -3;
}

TRACE("mixerGetLineControls: <%s> [%d..%d] steps : %d\n"
, mxlc.pamxctrl->szName
, mxlc.pamxctrl->Bounds.dwMinimum
, mxlc.pamxctrl->Bounds.dwMaximum
, mxlc.pamxctrl->Metrics.cSteps
);

MIXERCONTROLDETAILS mixdet;
MIXERCONTROLDETAILS_BOOLEAN det;
ZeroMemory(&mixdet, sizeof(MIXERCONTROLDETAILS));
mixdet.cbStruct = sizeof(MIXERCONTROLDETAILS);
mixdet.dwControlID = mxlc.pamxctrl->dwControlID;
mixdet.cChannels = 1;
mixdet.cMultipleItems = 0;
mixdet.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
mixdet.paDetails = &det;

/*///
fdwControls = MIXER_OBJECTF_MIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE;

mmr = mixerGetControlDetails((HMIXEROBJ)uMxId, &mixdet, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -3;
}
//*/

det.fValue = bOnOff ? 1L : 0L;
fdwControls = MIXER_OBJECTF_MIXER | MIXER_SETCONTROLDETAILSF_VALUE;

mmr = mixerSetControlDetails((HMIXEROBJ)uMxId, &mixdet, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -4;
}

return 0; //ok
}

int CSoundSupport::SetVolume(bool bSetNormal, int nSteps)
{
int nNumDev = mixerGetNumDevs();

TRACE("mixerGetNumDevs: <%d>\n", nNumDev);
ASSERT(nNumDev>0);
if (nNumDev<=0)
{
return -1;
}

MMRESULT mmr;

//immer erster mixer
UINT uMxId = 0;

MIXERLINE mxl;
ZeroMemory(&mxl, sizeof(MIXERLINE));
mxl.cbStruct = sizeof(MIXERLINE);
mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;

DWORD fdwControls = MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_COMPONENTTYPE;

mmr = mixerGetLineInfo((HMIXEROBJ)uMxId, &mxl, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -2;
}

MIXERLINECONTROLS mxlc;
MIXERCONTROL mixctrl;
ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
mxlc.cControls = 1;
mxlc.dwLineID = mxl.dwLineID;
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cbmxctrl = sizeof(MIXERCONTROL);
mxlc.pamxctrl = &mixctrl;

fdwControls = MIXER_OBJECTF_MIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE;

mmr = mixerGetLineControls((HMIXEROBJ)uMxId /*hmx*/, &mxlc, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -3;
}

MIXERCONTROLDETAILS mixdet;
MIXERCONTROLDETAILS_UNSIGNED det;
ZeroMemory(&mixdet, sizeof(MIXERCONTROLDETAILS));
mixdet.cbStruct = sizeof(MIXERCONTROLDETAILS);
mixdet.dwControlID = mxlc.pamxctrl->dwControlID;
mixdet.cChannels = 1;
mixdet.cMultipleItems = 0;
mixdet.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mixdet.paDetails = &det;

fdwControls = MIXER_OBJECTF_MIXER | MIXER_GETCONTROLDETAILSF_VALUE;

mmr = mixerGetControlDetails((HMIXEROBJ)uMxId, &mixdet, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -3;
}

if (bSetNormal)
{
det.dwValue = mxlc.pamxctrl->Bounds.dwMinimum +
((mxlc.pamxctrl->Bounds.dwMaximum - mxlc.pamxctrl->Bounds.dwMinimum) / 2);
}
else
{
if (nSteps > 0)
{
det.dwValue += (nSteps * mxlc.pamxctrl->Metrics.cSteps);
if (det.dwValue > mxlc.pamxctrl->Bounds.dwMaximum)
det.dwValue = mxlc.pamxctrl->Bounds.dwMaximum;
}
else
{
long nNewValue = det.dwValue + (nSteps * mxlc.pamxctrl->Metrics.cSteps);
if (nNewValue < (long)mxlc.pamxctrl->Bounds.dwMinimum) //'überschlag' verhindern!
det.dwValue = mxlc.pamxctrl->Bounds.dwMinimum;
else
det.dwValue = nNewValue;
}
}

fdwControls = MIXER_OBJECTF_MIXER | MIXER_SETCONTROLDETAILSF_VALUE;

mmr = mixerSetControlDetails((HMIXEROBJ)uMxId, &mixdet, fdwControls);
ASSERT(mmr == MMSYSERR_NOERROR);
if (mmr != MMSYSERR_NOERROR)
{
return -4;
}

return 0; //ok
}