📄 volumeinxxx.cpp
字号:
// VolumeInXXX.cpp : Module interface implementation.
// Developer : Alex Chmut
// Created : 8/11/98
#include "StdAfx.h"
#include "VolumeInXXX.h"
/////////////////////////////////////////////////////////////////////////////
// Defines
#define BAD_DWORD (DWORD)-1
#define WND_CLASS_NAME "Input Volume Msg Wnd Class"
#define WND_NAME "Input Volume Msg Wnd"
/////////////////////////////////////////////////////////////////////////////
// Globals
PCVolumeInXXX g_pThis = NULL;
////////////////////////////////////////////////////////////
//{{{ Audio specific functions
#define AUDFREQ 22050 // Frequency
#define AUDCHANNELS 1 // Number of channels
#define AUDBITSMPL 16 // Number of bits per sample
inline
void SetDeviceType( WAVEFORMATEX* pwfe )
{
memset( pwfe, 0, sizeof(WAVEFORMATEX) );
WORD nBlockAlign = (AUDCHANNELS*AUDBITSMPL)/8;
DWORD nSamplesPerSec = AUDFREQ;
pwfe->wFormatTag = WAVE_FORMAT_PCM;
pwfe->nChannels = AUDCHANNELS;
pwfe->nBlockAlign = nBlockAlign;
pwfe->nSamplesPerSec = nSamplesPerSec;
pwfe->wBitsPerSample = AUDBITSMPL;
pwfe->nAvgBytesPerSec = nSamplesPerSec*nBlockAlign;
}
//}}} Audio specific functions
/////////////////////////////////////////////////////////////////////////////
// Implementation
//////////////
CVolumeInXXX::CVolumeInXXX( UINT uLineIndex )
: m_bOK(false),
m_bInitialized(false),
m_bAvailable(false),
m_uMixerID(0L),
m_dwMixerHandle(0L),
m_hWnd(NULL),
m_uMicrophoneSourceLineIndex(BAD_DWORD),
m_dwMinimalVolume(BAD_DWORD),
m_dwMaximalVolume(BAD_DWORD),
m_pfUserSink(NULL),
m_dwUserValue(0L)
{
if ( m_bOK = Init() )
{
g_pThis = this;
if ( !Initialize( uLineIndex ) )
{
Done();
g_pThis = NULL;
}
}
}
//////////////
CVolumeInXXX::~CVolumeInXXX()
{
if ( m_bOK )
Done();
g_pThis = NULL;
}
//////////////
bool CVolumeInXXX::Init()
{
if ( !mixerGetNumDevs() )
return false;
// Getting Mixer ID
HWAVEIN hwaveIn;
MMRESULT mmResult;
WAVEFORMATEX WaveFmt;
SetDeviceType( &WaveFmt );
mmResult = waveInOpen( &hwaveIn, WAVE_MAPPER, &WaveFmt, 0L, 0L, CALLBACK_NULL );
if ( mmResult != MMSYSERR_NOERROR )
{
TRACE(".InputXxxVolume: FAILURE: Could not open WaveIn Mapper. mmResult=%d\n", mmResult );
return false;
} else {
mmResult = mixerGetID( (HMIXEROBJ)hwaveIn, &m_uMixerID, MIXER_OBJECTF_HWAVEIN );
waveInClose( hwaveIn );
if ( mmResult != MMSYSERR_NOERROR )
{
TRACE(".InputXxxVolume: FAILURE: WaveIn Mapper in Mixer is not available. mmResult=%d\n", mmResult );
return false;
}
}
// Exposing Window to Mixer
WNDCLASSEX wcx;
memset( &wcx, 0, sizeof(WNDCLASSEX) );
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.lpszClassName = WND_CLASS_NAME;
wcx.lpfnWndProc = (WNDPROC)MixerWndProc;
::RegisterClassEx(&wcx);
m_hWnd = CreateWindow( WND_CLASS_NAME,
WND_NAME,
WS_POPUP | WS_DISABLED,
0, 0, 0, 0,
NULL, NULL, NULL, NULL );
if ( !m_hWnd )
{
TRACE(".InputXxxVolume: FAILURE: Could not create internal window.\n" );
return false;
}
::ShowWindow(m_hWnd, SW_HIDE);
mmResult = mixerOpen( (LPHMIXER)&m_dwMixerHandle, m_uMixerID, (DWORD)m_hWnd, 0L, CALLBACK_WINDOW );
if ( mmResult != MMSYSERR_NOERROR )
{
TRACE(".InputXxxVolume: FAILURE: Could not open Mixer. mmResult=%d\n", mmResult );
::DestroyWindow( m_hWnd );
return false;
}
return true;
}
//////////////
void CVolumeInXXX::Done()
{
if ( mixerClose( (HMIXER)m_dwMixerHandle ) != MMSYSERR_NOERROR )
{
TRACE(".InputXxxVolume: WARNING: Could not close Mixer.\n" );
}
::DestroyWindow( m_hWnd );
m_bInitialized = false;
m_bOK = false;
}
//////////////
void CVolumeInXXX::OnControlChanged( DWORD dwControlID )
{
if ( m_dwVolumeControlID == dwControlID )
{
DWORD dwVolume = GetCurrentVolume();
if ( (dwVolume!=BAD_DWORD) && (m_pfUserSink) )
{
(*m_pfUserSink)( dwVolume, m_dwUserValue );
}
}
}
//////////////
bool CVolumeInXXX::Initialize( UINT uLineIndex )
{
MMRESULT mmResult;
if ( !m_bOK )
return false;
TRACE(".InputXxxVolume: Initializing for the Source Line (%d) ..\n", uLineIndex );
MIXERLINE MixerLine;
memset( &MixerLine, 0, sizeof(MIXERLINE) );
MixerLine.cbStruct = sizeof(MIXERLINE);
MixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
mmResult = mixerGetLineInfo( (HMIXEROBJ)m_dwMixerHandle, &MixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE );
if ( mmResult != MMSYSERR_NOERROR )
{
TRACE(".InputXxxVolume: FAILURE: Could not get WaveIn Destionation Line for the requested source while initilaizing. mmResult=%d\n", mmResult );
return false;
}
MIXERCONTROL Control;
memset( &Control, 0, sizeof(MIXERCONTROL) );
Control.cbStruct = sizeof(MIXERCONTROL);
MIXERLINECONTROLS LineControls;
memset( &LineControls, 0, sizeof(MIXERLINECONTROLS) );
LineControls.cbStruct = sizeof(MIXERLINECONTROLS);
MIXERLINE Line;
memset( &Line, 0, sizeof(MIXERLINE) );
Line.cbStruct = sizeof(MIXERLINE);
if ( ( uLineIndex < MixerLine.cConnections ) )
{
Line.dwDestination = MixerLine.dwDestination;
Line.dwSource = uLineIndex;
mmResult = mixerGetLineInfo( (HMIXEROBJ)m_dwMixerHandle, &Line, MIXER_GETLINEINFOF_SOURCE );
if ( mmResult != MMSYSERR_NOERROR )
{
TRACE(".InputXxxVolume: FAILURE: Could not get the requested Source Line while initilaizing. mmResult=%d\n", mmResult );
return false;
}
TRACE(".InputXxxVolume: \"%s\" Source Line adopted.\n", Line.szShortName );
LineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
LineControls.dwLineID = Line.dwLineID;
LineControls.cControls = 1;
LineControls.cbmxctrl = sizeof(MIXERCONTROL);
LineControls.pamxctrl = &Control;
mmResult = mixerGetLineControls( (HMIXEROBJ)m_dwMixerHandle, &LineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE );
if ( mmResult == MMSYSERR_NOERROR )
{
if ( !(Control.fdwControl & MIXERCONTROL_CONTROLF_DISABLED) )
{
m_bAvailable = true;
TRACE(".InputXxxVolume: \"%s\" Volume control for the Source Line adopted\n", Control.szShortName );
} else {
TRACE(".InputXxxVolume: WARNING: The Volume Control is disabled.\n" );
}
} else {
TRACE(".InputXxxVolume: WARNING: Could not get the requested Source Line Volume Control for the requested line while initilaizing. mmResult=%d\n", mmResult );
}
} else {
TRACE(".InputXxxVolume: FAILURE: Invalid Source Line index passed.\n" );
return false;
}
// Retrieving Microphone Source Line
for ( UINT uLine = 0; uLine < MixerLine.cConnections; uLine++ )
{
MIXERLINE MicrophoneLine;
memset( &MicrophoneLine, 0, sizeof(MIXERLINE) );
MicrophoneLine.cbStruct = sizeof(MIXERLINE);
MicrophoneLine.dwDestination = MixerLine.dwDestination;
MicrophoneLine.dwSource = uLine;
mmResult = mixerGetLineInfo( (HMIXEROBJ)m_dwMixerHandle, &MicrophoneLine, MIXER_GETLINEINFOF_SOURCE );
if ( mmResult == MMSYSERR_NOERROR )
{
if ( MicrophoneLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
{
m_uMicrophoneSourceLineIndex = MicrophoneLine.dwSource;
TRACE(".InputXxxVolume: Microphone Source Line \"%s\" has been found.\n", MicrophoneLine.szShortName );
break;
}
}
}
if ( m_uMicrophoneSourceLineIndex == BAD_DWORD )
{
TRACE(".InputXxxVolume: WARNING: Could not retrieve Microphone Source Line.\n" );
}
m_uSourceLineIndex = uLineIndex;
m_nChannelCount = Line.cChannels;
m_dwLineID = LineControls.dwLineID;
m_dwVolumeControlID = Control.dwControlID;
m_dwMinimalVolume = Control.Bounds.dwMinimum;
m_dwMaximalVolume = Control.Bounds.dwMaximum;
m_dwVolumeStep = Control.Metrics.cSteps;
m_bInitialized = true;
return true;
}
//////////////////////////////////////////////
bool CVolumeInXXX::GetMicrophoneSourceLineIndex( UINT* puLineIndex )
{
if ( !puLineIndex || !m_bInitialized || (m_uMicrophoneSourceLineIndex==BAD_DWORD) )
return false;
*puLineIndex = m_uMicrophoneSourceLineIndex;
return true;
}
//////////////////////////////////////////////
// IVolume interface
//////////////
bool CVolumeInXXX::IsAvailable()
{
return m_bAvailable;
}
//////////////
void CVolumeInXXX::Enable()
{
if ( !m_bInitialized )
return;
bool bAnyEnabled = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -