?? chmplay.cpp
字號(hào):
/*----------------------------------------------------------------------------
_ _ _
/\ | | | (_)
/ \ _ __ __| |_ __ ___ _ __ ___ ___ __| |_ __ _
/ /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
/ ____ \| | | | (_| | | | (_) | | | | | | __/ (_| | | (_| |
/_/ \_\_| |_|\__,_|_| \___/|_| |_| |_|\___|\__,_|_|\__,_|
The contents of this file are subject to the Andromedia Public
License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.andromedia.com/APL/
Software distributed under the License is distributed on an
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Pueblo client code, released November 4, 1998.
The Initial Developer of the Original Code is Andromedia Incorporated.
Portions created by Andromedia are Copyright (C) 1998 Andromedia
Incorporated. All Rights Reserved.
Andromedia Incorporated 415.365.6700
818 Mission Street - 2nd Floor 415.365.6701 fax
San Francisco, CA 94103
Contributor(s):
--------------------------------------------------------------------------
Chaco team: Dan Greening, Glenn Crocker, Jim Doubek,
Coyote Lussier, Pritham Shetty.
Wrote and designed original codebase.
------------------------------------------------------------------------------
Implementation of the ChMediaPlayer class. This class knows how to
load and play MIDI music files as well as Wave audio files.
----------------------------------------------------------------------------*/
// $Header: /home/cvs/chaco/modules/client/msw/ChSound/ChMPlay.cpp,v 1.29 1996/10/04 21:50:05 coyote Exp $
#include "headers.h"
// Set Toolvox target...
#if defined( CH_MSW )
#if defined( WIN32 )
#define VOXWARE_WIN32
#else // defined( WIN32 )
#define VOXWARE_WIN16
#endif // defined( WIN32 )
#else // defined( CH_MSW )
#error Voxware platform not defined!
#endif // defined( CH_MSW )
#if defined( CH_USE_VOXWARE )
#include <tnt.h> // Toolvox (Voxware) includes
#endif // defined( CH_USE_VOXWARE )
#include <ChCore.h>
#include "ChMPlay.h"
#include "ChSoundInfo.h"
/*----------------------------------------------------------------------------
Constants
----------------------------------------------------------------------------*/
#define WAVE_BUFFER_SECS 2
//#define WAVE_DEV_NAME "mciwave"
//#define MIDI_DEV_NAME "mciseq"
#define WAVE_DEV_NAME "audiowave"
#define MIDI_DEV_NAME "seqencer"
/*----------------------------------------------------------------------------
Forward declarations
----------------------------------------------------------------------------*/
#if 0
VOXAPI_CALLBACK VoxwareCallbackFunc( unsigned short wVox,
unsigned short wMessage,
LPVOXWARE_DATA lpVoxwareData );
#endif // defined( CH_USE_VOXWARE )
/*----------------------------------------------------------------------------
ChMediaPlayer public methods
----------------------------------------------------------------------------*/
ChMediaPlayer::ChMediaPlayer( DeviceType deviceType,
bool* pboolDeviceInUseFlag ) :
m_pMainInfo( 0 ),
m_pboolDeviceInUseFlag( pboolDeviceInUseFlag ),
m_boolExists( true ),
m_deviceType( deviceType ),
m_pMCIObject( 0 ),
m_boolLoopVolume( false ),
m_suVolume( 0xffff ),
m_pInfo( 0 )
{
ASSERT( pboolDeviceInUseFlag );
GetNotifyWnd()->Create();
GetNotifyWnd()->SetPlayer( this );
m_pInfo = new ChSoundInfo;
ASSERT( GetSoundInfo() );
m_pMixer = new ChMixer( deviceType );
m_boolExists = DeviceExists( deviceType );
}
ChMediaPlayer::~ChMediaPlayer()
{
if (IsDeviceOpen())
{
CloseDevice();
}
if (m_pMixer)
{
delete m_pMixer;
}
if (GetSoundInfo())
{
delete m_pInfo;
m_pInfo = 0;
}
GetNotifyWnd()->DestroyWindow();
}
bool ChMediaPlayer::Play( const ChSoundInfo* pInfo )
{
bool boolSuccess;
if (IsDeviceOpen())
{
CloseDevice();
}
OpenDevice();
boolSuccess = GetDevice()->OpenFile( pInfo->GetFilename() );
if (!boolSuccess)
{
CloseDevice();
}
else
{
PrepAndPlay( pInfo );
}
return boolSuccess;
}
void ChMediaPlayer::Stop()
{
if (!IsDeviceOpen())
{
return;
}
/* 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 );
// Stop the device
GetDevice()->Stop();
SetPlaying( false );
}
void ChMediaPlayer::SetVolume( chuint16 suVolume )
{
m_suVolume = suVolume;
if (IsPlaying())
{
GetMixer()->SetVolume( m_suVolume );
}
}
/*----------------------------------------------------------------------------
ChMediaPlayer protected methods
----------------------------------------------------------------------------*/
bool ChMediaPlayer::PrepAndPlay( const ChSoundInfo* pInfo )
{
ASSERT( pInfo );
*m_pInfo = *pInfo;
ASSERT( 0 != GetSoundInfo() );
SetEventInfo( GetSoundInfo()->GetEvents(), GetSoundInfo()->GetAction(),
GetSoundInfo()->GetMD5() );
if (GetSoundInfo()->IsVolumeValid())
{
SetLooping( GetSoundInfo()->IsLooping(), GetSoundInfo()->GetVolume() );
GetMixer()->SetVolume( GetSoundInfo()->GetVolume() );
}
else
{
SetLooping( GetSoundInfo()->IsLooping() );
GetMixer()->SetVolume( m_suVolume );
}
SetPlaying( true );
return DoPlay();
}
bool ChMediaPlayer::DoPlay()
{
GetDevice()->Play();
return true;
}
bool ChMediaPlayer::DeviceExists( DeviceType deviceType )
{
bool boolExists;
switch( deviceType )
{
case devMidi:
{
boolExists = 0 < midiOutGetNumDevs();
break;
}
case devWave:
case devSpeech:
{
boolExists = 0 < waveOutGetNumDevs();
break;
}
default:
{
TRACE( "ChMediaPlayer::DeviceExists: Unknown device.\n" );
boolExists = false;
break;
}
}
return boolExists;
}
void ChMediaPlayer::OpenDevice()
{
m_pMCIObject = new ChMCIObject( GetDeviceType(), GetNotifyWnd() );
ASSERT( 0 != m_pMCIObject );
}
void ChMediaPlayer::CloseDevice()
{
if (m_pMCIObject)
{
m_pMCIObject->Close();
delete m_pMCIObject;
m_pMCIObject = 0;
}
}
void ChMediaPlayer::OnPlayComplete()
{
if (IsLooping())
{
Play( GetSoundInfo() );
}
else
{
CloseDevice();
SetPlaying( false );
if (GetEvents() & soundEvtComplete)
{ // Send completion notification
GetMainInfo()->SendWorldCommand( GetMD5(), GetAction(),
PUEBLO_SOUND_COMPLETE );
}
GetMainInfo()->OnPlayComplete( GetDeviceType() );
}
}
/*----------------------------------------------------------------------------
ChMCIObject public methods
----------------------------------------------------------------------------*/
ChMCIObject::ChMCIObject( DeviceType deviceType, CWnd* pwndNotify ) :
m_deviceType( deviceType ),
m_pwndNotify( pwndNotify )
{
ClearDevice();
}
ChMCIObject::~ChMCIObject()
{
if (IsOpen())
{
Close();
}
ASSERT( !IsOpen() );
}
bool ChMCIObject::OpenFile( const string& strFilename )
{
chuint32 luResult;
DWORD dwOpenOptions = MCI_WAIT |
MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID |
MCI_OPEN_ELEMENT;
if (IsOpen())
{
Close();
}
ASSERT( !IsOpen() );
ClearDevice(); // Zero out the open structure
switch( GetDeviceType() )
{
case devMidi:
{
SetDeviceType( (const char*)MCI_DEVTYPE_SEQUENCER );
break;
}
case devWave:
{
SetDeviceType( (const char*)MCI_DEVTYPE_WAVEFORM_AUDIO );
dwOpenOptions |= MCI_WAVE_OPEN_BUFFER;
break;
}
default:
{
TRACE( "ChMCIObject::OpenFile: Unknown device. "
"Trying to make do.\n" );
SetDeviceType( 0 );
dwOpenOptions &= ~((DWORD)MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID );
break;
}
}
m_openParams.lpstrElementName = strFilename;
m_openParams.dwBufferSeconds = WAVE_BUFFER_SECS;
luResult = mciSendCommand( 0, MCI_OPEN, dwOpenOptions,
(chparam)(void*)&m_openParams );
if (luResult != 0)
{
MCIError( luResult );
ClearDevice(); // Zero out the open structure
return false;
}
/* Set the time format to
milliseconds */
MCI_SET_PARMS set;
set.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
luResult = mciSendCommand( GetDeviceID(), MCI_SET,
MCI_WAIT | MCI_SET_TIME_FORMAT,
(chparam)(void*)&set );
if (luResult != 0)
{
MCIError( luResult );
ClearDevice(); // Zero out the open structure
return false;
}
/* Attempt to cue the file so it
will play with no delay */
MCI_GENERIC_PARMS generic;
ChMemClearStruct( &generic );
luResult = mciSendCommand( GetDeviceID(), MCI_CUE, MCI_WAIT,
(chparam)(void*)&generic );
return true;
}
void ChMCIObject::Close()
{
MCI_GENERIC_PARMS generic;
chuint32 luResult;
if (!IsOpen())
{
return; // Already closed.
}
Stop(); // Just in case.
luResult = mciSendCommand( GetDeviceID(), MCI_CLOSE, MCI_WAIT,
(chparam)(void*)&generic );
if (luResult != 0)
{
MCIError( luResult );
}
ClearDevice(); // Zero out the open structure
}
void ChMCIObject::Play()
{
MCI_PLAY_PARMS play;
chuint32 luResult;
if (!IsOpen())
{
return; // Not open
}
mciSendCommand( GetDeviceID(), MCI_SEEK,
MCI_WAIT | MCI_SEEK_TO_START, 0 );
// Play music
play.dwCallback = (DWORD)m_pwndNotify->m_hWnd;
luResult = mciSendCommand( GetDeviceID(), MCI_PLAY, MCI_NOTIFY,
(chparam)(void*)&play );
if (luResult != 0)
{
MCIError( luResult );
}
}
void ChMCIObject::Stop()
{
chuint32 luResult;
if (!IsOpen())
{
return; // Not open
}
luResult = mciSendCommand( GetDeviceID(), MCI_STOP, MCI_WAIT, 0 );
if (luResult != 0)
{
MCIError( luResult );
}
}
chuint32 ChMCIObject::GetPosition()
{
if (!IsOpen())
{
return 0; // Not open
}
MCI_STATUS_PARMS status;
status.dwItem = MCI_STATUS_POSITION;
if (mciSendCommand( GetDeviceID(), MCI_STATUS,
MCI_WAIT | MCI_STATUS_ITEM,
(chparam)(void*)&status) != 0)
{
return 0; // Some error
}
return status.dwReturn;
}
/*----------------------------------------------------------------------------
ChMCIObject private methods
----------------------------------------------------------------------------*/
void ChMCIObject::MCIError( chuint32 luError )
{
char strBuffer[256];
strBuffer[0] = 0;
mciGetErrorString( luError, strBuffer, sizeof( strBuffer ) );
if (!strlen( strBuffer ))
{
strcpy( strBuffer, "Unknown error" );
}
TRACE( strBuffer );
TRACE( "\n" );
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -