Knowledge Base Nr: 00170 volume.cpp - http://www.swe-kaiser.de
Downloads:
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
}