⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chmplay.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:


#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 + -