📄 chmplay.cpp
字号:
#if defined( CH_USE_VOXWARE )
/*----------------------------------------------------------------------------
ChVoxwarePlayer public methods
----------------------------------------------------------------------------*/
ChSpeechPlayer::ChSpeechPlayer( DeviceType deviceType,
bool* pboolDeviceInUseFlag ) :
ChMediaPlayer( deviceType, pboolDeviceInUseFlag )
{
ASSERT( devSpeech == deviceType );
}
ChSpeechPlayer::~ChSpeechPlayer()
{
}
bool ChSpeechPlayer::Play( const ChSoundInfo* pInfo )
{
return PrepAndPlay( pInfo );
}
void ChSpeechPlayer::Stop()
{
MSG msg;
bool boolQuitMessage = false;
/* Set the event flags to zero
so that no notification
occurs (since this object
is being explicitly stopped) */
SetEventInfo( 0 );
// Turn off looping!
SetLooping( false );
SetStopped();
#if 0
/* We need to spin a message loop
to wait until the speech stops
playing... */
while (IsPlaying() && !boolQuitMessage)
{
if (::PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
{
if (WM_QUIT == msg.message)
{
boolQuitMessage = true;
::PostQuitMessage( msg.wParam );
}
else
{
::DispatchMessage( &msg );
}
}
}
#endif // 0
}
/*----------------------------------------------------------------------------
ChSpeechPlayer protected methods
----------------------------------------------------------------------------*/
bool ChSpeechPlayer::DoPlay()
{
const char* pstrFilename = GetSoundInfo()->GetFilename();
SetStopped( false );
ChTNT::PlayVoxFile( pstrFilename );
return true;
}
#if 0
/*----------------------------------------------------------------------------
Voxware callback function
----------------------------------------------------------------------------*/
VOXAPI_CALLBACK VoxwareCallbackFunc( unsigned short wVox,
unsigned short wMessage,
LPVOXWARE_DATA lpVoxwareData )
{
ChSpeechPlayer* pPlayer = (ChSpeechPlayer*)lpVoxwareData->dwUserData;
bool boolStopped = false;
switch( wMessage )
{
case VOXWARE_STARTPLAY:
{
TRACE( "ToolVox: Start play!\n" );
break;
}
case VOXWARE_ENDPLAY:
{
TRACE( "ToolVox: End play!\n" );
pPlayer->GetNotifyWnd()->PostMessage( MSG_ON_VOX_COMPLETE );
break;
}
case VOXWARE_GETINFO:
{
break;
}
case VOXWARE_PLAYBACKERROR:
{
TRACE( "ToolVox: Playback error\n" );
break;
}
default:
{
break;
}
}
#if defined( CH_DEBUG )
{
if (pPlayer->IsStopped())
{
TRACE( "ToolVox: STOPPED!\n" );
}
}
#endif // defined( CH_DEBUG )
return pPlayer->IsStopped();
}
#endif // 0
#endif // defined( CH_USE_VOXWARE )
/*----------------------------------------------------------------------------
ChMixer class
----------------------------------------------------------------------------*/
ChMixer::ChMixer( DeviceType deviceType ) :
m_deviceType( deviceType )
{
#if defined( CH_ARCH_32 )
{
m_boolUseMixerAPI = false;
m_hWinMMLib = LoadLibrary( TEXT( "winmm.dll" ) );
if (m_hWinMMLib)
{ /* Get the address of all the
procs used but not available
under Win32s */
pprocMixerOpen = (pprocTypeMixerOpen)
GetProcAddress( m_hWinMMLib, "mixerOpen" );
pprocMixerClose = (pprocTypeMixerClose)
GetProcAddress( m_hWinMMLib, "mixerClose" );
pprocMixerSetControlDetails = (pprocTypeMixerSetControlDetails)
GetProcAddress( m_hWinMMLib, "mixerSetControlDetails" );
pprocMixerGetNumDevs = (pprocTypeMixerGetNumDevs)
GetProcAddress( m_hWinMMLib, "mixerGetNumDevs" );
pprocMixerGetDevCaps = (pprocTypeMixerGetDevCaps)
GetProcAddress( m_hWinMMLib, "mixerGetDevCaps" );
pprocMixerGetLineInfo = (pprocTypeMixerGetLineInfo)
GetProcAddress( m_hWinMMLib, "mixerGetLineInfo" );
pprocMixerGetLineControls = (pprocTypeMixerGetLineControls)
GetProcAddress( m_hWinMMLib, "mixerGetLineControls" );
if (pprocMixerOpen && pprocMixerClose &&
pprocMixerSetControlDetails && pprocMixerGetNumDevs &&
pprocMixerGetLineInfo && pprocMixerGetLineControls)
{
m_boolUseMixerAPI = true;
}
}
if (m_boolUseMixerAPI)
{
MMRESULT mmr;
switch( deviceType )
{
case devMidi:
{
m_dwTargetComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
break;
}
case devWave:
case devSpeech:
{
m_dwTargetComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
break;
}
default:
{
ASSERT( false );
break;
}
}
mmr = GetMixerControl();
if (MMSYSERR_NOERROR == mmr)
{
m_boolValid = true;
// Init the details structures
ChMemClearStruct( &m_mixerControlDetails );
memset( &m_uMixerControlDetails, 0x00,
sizeof( m_uMixerControlDetails ) );
m_mixerControlDetails.cbStruct = sizeof( m_mixerControlDetails );
m_mixerControlDetails.dwControlID = m_mixerControl.dwControlID;
m_mixerControlDetails.cChannels = m_uiChannels;
m_mixerControlDetails.cbDetails = sizeof( MIXERCONTROLDETAILS_UNSIGNED );
m_mixerControlDetails.paDetails = &m_uMixerControlDetails[0];
}
else
{
m_boolValid = false;
}
}
}
#endif // CH_ARCH_32
}
ChMixer::~ChMixer()
{
/* The following 'if' statement may
not be necessary, but we were
getting some hangs on
mixerClose on NT 3.51 */
#if defined( CH_ARCH_32 )
{
if (m_boolUseMixerAPI)
{
if (ChCore::GetClientInfo()->GetPlatform() != osWinNT)
{
if (m_boolValid && (0 != m_hMixer) )
{
pprocMixerClose( m_hMixer );
}
}
FreeLibrary( m_hWinMMLib );
}
}
#endif // CH_ARCH_32
}
bool ChMixer::SetVolume( chuint16 suNewVolume )
{
#if defined( CH_ARCH_32 )
if ( m_boolUseMixerAPI )
{
return MixerSetVolume( suNewVolume );
}
else
#endif
{
return WaveSetVolume( suNewVolume );
}
}
#if defined( CH_ARCH_32 )
bool ChMixer::MixerSetVolume( chuint16 suNewVolume )
{
MMRESULT mmr;
int iChannel;
DWORD dwNewVolume( suNewVolume );
/* Make sure the mixer could be
opened */
if (!m_boolValid)
{
return false;
}
// Make sure the mixer is open
ASSERT( 0 != m_hMixer );
// Pin the volume
if (dwNewVolume < m_mixerControl.Bounds.dwMinimum)
{
dwNewVolume = m_mixerControl.Bounds.dwMinimum;
}
else if (dwNewVolume > m_mixerControl.Bounds.dwMaximum)
{
dwNewVolume = m_mixerControl.Bounds.dwMaximum;
}
// Set the volume for all channels
for (iChannel = 0; iChannel < (int)m_uiChannels; iChannel++)
{
m_uMixerControlDetails[iChannel].dwValue = dwNewVolume;
}
mmr = pprocMixerSetControlDetails( (HMIXEROBJ)m_hMixer, &m_mixerControlDetails,
MIXER_SETCONTROLDETAILSF_VALUE );
return MMSYSERR_NOERROR == mmr;
}
#endif // defined( CH_ARCH_32 )
/*----------------------------------------------------------------------------
ChMixer protected methods
----------------------------------------------------------------------------*/
#if defined( CH_ARCH_32 )
MMRESULT ChMixer::GetMixerControl()
{
MMRESULT mmr;
UINT uiSource;
UINT uiDest;
UINT uiMixerID;
MIXERCAPS mixerCaps;
UINT uiSrcLines;
MIXERLINE mixerLine;
BOOL boolFoundLine;
MIXERLINECONTROLS mixerLineControls;
if ((MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER != m_dwTargetComponentType) &&
(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT != m_dwTargetComponentType))
{
return MMSYSERR_INVALPARAM;
}
/* Check to ensure that we have
a mixer */
if (0 == pprocMixerGetNumDevs())
{
return MMSYSERR_NODRIVER;
}
// Take the first mixer.
uiMixerID = 0;
mmr = pprocMixerOpen( &m_hMixer, uiMixerID, 0, 0, 0 );
if (MMSYSERR_NOERROR != mmr)
{
return mmr;
}
mmr = pprocMixerGetDevCaps( (UINT)m_hMixer, &mixerCaps, sizeof( mixerCaps ) );
if (MMSYSERR_NOERROR != mmr)
{
pprocMixerClose( m_hMixer );
m_hMixer = 0;
return mmr;
}
mixerLine.dwComponentType = 0;
boolFoundLine = false;
/* Search the mixer device lines
for the correct line */
for (uiDest = 0; (uiDest < mixerCaps.cDestinations) && !boolFoundLine;
uiDest++)
{
ChMemClearStruct( &mixerLine );
mixerLine.cbStruct = sizeof( mixerLine );
mixerLine.dwDestination = uiDest;
mmr = pprocMixerGetLineInfo( (HMIXEROBJ)m_hMixer, &mixerLine,
MIXER_GETLINEINFOF_DESTINATION );
if (MMSYSERR_NOERROR != mmr)
{
pprocMixerClose( m_hMixer );
m_hMixer = 0;
return mmr;
}
if (MIXERLINE_COMPONENTTYPE_DST_SPEAKERS == mixerLine.dwComponentType)
{
/* This is an audio line intended
to drive speakers. This is
usually the output line of an
audio card. */
if (mixerLine.cChannels > maxChannels)
{
/* There are too many channels
to handle. More than 5?
Argh! */
pprocMixerClose( m_hMixer );
m_hMixer = 0;
return MMSYSERR_NOMEM;
}
// Save the number of channels
m_uiChannels = mixerLine.cChannels;
if (m_uiChannels > maxChannels)
{ // Pin the number of channels
m_uiChannels = maxChannels;
}
uiSrcLines = mixerLine.cConnections;
/* Search for the line that matches
the component we want to control */
for (uiSource = 0; uiSource < uiSrcLines; uiSource++)
{
ChMemClearStruct( &mixerLine );
mixerLine.cbStruct = sizeof( mixerLine );
mixerLine.dwDestination = uiDest;
mixerLine.dwSource = uiSource;
mmr = pprocMixerGetLineInfo( (HMIXEROBJ)m_hMixer, &mixerLine,
MIXER_GETLINEINFOF_SOURCE );
if (MMSYSERR_NOERROR != mmr)
{
pprocMixerClose( m_hMixer );
m_hMixer = 0;
return mmr;
}
if (mixerLine.dwComponentType == m_dwTargetComponentType)
{
/* Yay! This is the line
connecting our device to the
speakers. */
boolFoundLine = TRUE;
break;
}
}
}
}
if (!boolFoundLine)
{
pprocMixerClose( m_hMixer );
m_hMixer = 0;
return MMSYSERR_NOTSUPPORTED;
}
// Init the MIXERCONTROL struct
ChMemClearStruct( &mixerLineControls );
mixerLineControls.cbStruct = sizeof( mixerLineControls );
mixerLineControls.dwLineID = mixerLine.dwLineID;
mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
mixerLineControls.cbmxctrl = sizeof( MIXERCONTROL );
mixerLineControls.pamxctrl = &m_mixerControl;
mmr = pprocMixerGetLineControls( (HMIXEROBJ)m_hMixer, &mixerLineControls,
MIXER_GETLINECONTROLSF_ONEBYTYPE );
if (MMSYSERR_NOERROR != mmr)
{
pprocMixerClose( m_hMixer );
m_hMixer = 0;
return mmr;
}
return MMSYSERR_NOERROR;
}
#endif // defined( CH_ARCH_32 )
bool ChMixer::WaveSetVolume( chuint16 suNewVolume )
{
int iCount;
switch( m_deviceType )
{
case devMidi:
{
if (iCount = midiOutGetNumDevs())
{
for (int iDev = 0; iDev < iCount; iDev++)
{
midiOutSetVolume( (HMIDIOUT)iDev, MAKELONG( suNewVolume, suNewVolume ));
}
}
break;
}
case devWave:
case devSpeech:
{
if (iCount = waveOutGetNumDevs())
{
for (int iDev = 0; iDev < iCount; iDev++)
{
waveOutSetVolume( (HWAVEOUT)iDev, MAKELONG( suNewVolume, suNewVolume ));
}
}
break;
}
default:
{
break;
}
}
return true;
}
// Local Variables: ***
// tab-width:4 ***
// End: ***
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -