Debug 目录下新建properties 目录,加入sound_res.xml 文件
//////////////////////////////////////////////////////////////////////////
// sound_res.xml
<?xml version="1.0" encoding="utf-8"?>
<SoundRes>
<MusicSeg>
<!-- background music-->
<Music id="SND_BACK_1" path="data/music/back1.ogg" />
</MusicSeg>
</SoundRes>
//////////////////////////////////////////////////////////////////////////
Debug 目录下加入文件和文件夹 data/music/back1.ogg
Debug 目录下加入audiere.dll
下载xx http://download.youkuaiyun.com/source/2315672,解压为extendLib 放在解决方案目录下,
新建如下文件并加入到解决方案:
//////////////////////////////////////////////////////////////////////////
// AudiereManager.h
/*
AudiereManager is a simple class to pack Audiere library , i just donot
want you to know what's OutputStreamPtr in Audiere, so i write this class.
Author : Kevin Lynx
Date : 1/29/2007
History : 1/29/2007 First version.
2/6/2007 add a setAllVolume function to set system volume
2/6/2007 make it can mix the same sound at the same time..cool
*/
#ifndef AUDIERE_MANAGER_H
#define AUDIERE_MANAGER_H
#include <algorithm>
#include <vector>
#include "../../extendLib/audiere.h"
using std::vector;
using namespace audiere;
typedef unsigned long HSOUND;
class AudiereManager
{
protected:
AudiereManager();
~AudiereManager();
public:
enum
{
LOAD_FAILED = -1,
MAX_SAMPLE_COU = 20
};
static AudiereManager *GetInstance(); //can be called many times
static void Release(); //can be called only one time
/*
interfaces
*/
/*
Name : load
Desc : load a music or sound ( ogg, it, xm, mod, wav, mp3.etc )
Param:
file : the music/sound file
bStream: if true, the file will be loaded as a stream
if you will load a music file, you 'd better set it true
load a sound , you can set it false
IMPORTANT : if you load a music , you 'd better make stream to be true
if a sound, make it false .
Return:the sound/music's id
*/
HSOUND load( const char *file, bool bStream = true );
/*
Name : play
Desc : play a sound/music specified by id
Param:
id : the sound/music id, if the id is not valid, then it willnot play it
bLoop: if true, the sound/ music will be loop
Return:none
*/
void play( HSOUND id, bool bLoop = false );
void stop( HSOUND id );
bool isPlaying( HSOUND id );
void reset( HSOUND id );
/*
Name : setVolume
Desc : set the sound/music specified by the id to volume
Param:
id : see play
volume: 0.0f -- 1.0f,
*/
void setVolume( HSOUND id, float volume );
float getVolume( HSOUND id );
/*
Name : setPan
Desc : set the soound/music specified by the id 's pan
Param:
id : see play
pan: 0.0f -- 1.0f , if the value is 0.0f, you can only
heard the sound from your left pc speaker, if 1.0f,
you can only heard the sound from the right pc speaker
*/
void setPan( HSOUND id, float pan );
float getPan( HSOUND id );
/*
Name : setPitchShift
Desc : in fact, i think it should be called 'setPlaySpeed"
Param:
id: see play
shift: 0.0f -- 1.0f, if 1.0f , the sound will be played
at a normal speed, otherwise it will slower, it bigger
than 1.0f, the speed will be faster
*/
void setPitchShift( HSOUND id, float shift );
float getPitchShift( HSOUND id );
bool isSeekable( HSOUND id );
int getLength( HSOUND id );
void setPosition( HSOUND id, int position );
int getPosition( HSOUND id );
void setAllVolume( float volume );
private:
AudioDevicePtr m_device;
private:
typedef vector<OutputStreamPtr> tStreams;
typedef vector<tStreams> tSounds;
tSounds m_soundContainer;
private:
static AudiereManager *m_Instance;
};
#endif
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// AudiereManager.cpp
/*
AudiereManager is a simple class to pack Audiere library , i just donot
want you to know what's OutputStreamPtr in Audiere, so i write this class.
Author : Kevin Lynx
Date : 1/29/2007
History : 1/29/2007 First version.
2/6/2007 add a setAllVolume function to set system volume
*/
#include "AudiereManager.h"
//#pragma comment( lib, "audiere.lib" )
//#pragma comment( lib, "../extendLib/audiere.lib" )
AudiereManager *AudiereManager::m_Instance = NULL;
AudiereManager::AudiereManager()
{
m_soundContainer.clear();
//get device
m_device = OpenDevice();
}
AudiereManager::~AudiereManager()
{
for( tSounds::iterator i = m_soundContainer.begin();
i != m_soundContainer.end();
++ i )
{
for( tStreams::iterator j = (*i).begin(); j != (*i).end(); ++j )
{
(*j) = NULL;
}
}
m_soundContainer.clear();
}
AudiereManager *AudiereManager::GetInstance()
{
if( m_Instance == NULL )
{
m_Instance = new AudiereManager();
}
return m_Instance;
}
void AudiereManager::Release()
{
if( m_Instance != NULL )
{
delete m_Instance;
m_Instance = NULL;
}
}
HSOUND AudiereManager::load( const char *file, bool bStream )
{
SampleSourcePtr sample = OpenSampleSource( file );
if( sample == NULL )
return LOAD_FAILED;
//create many sounds by sample
tStreams streamContainer;
OutputStreamPtr stream;
if( bStream )
{
//music doesnot need to make many samples
stream = OpenSound( m_device, sample, true );
streamContainer.push_back( stream );
//
m_soundContainer.push_back( streamContainer );
}
else
{
//sounds.
for( int i = 0; i < MAX_SAMPLE_COU; ++ i )
{
stream = OpenSound( m_device, sample, false );
streamContainer.push_back( stream );
}
//
m_soundContainer.push_back( streamContainer );
}
return HSOUND(m_soundContainer.size() - 1);
}
void AudiereManager::play( HSOUND id, bool bLoop )
{
if( id < 0 ||
id >= m_soundContainer.size() )
return ;
for( tStreams::iterator i = m_soundContainer.at( id ).begin();
i != m_soundContainer.at( id ).end();
++ i )
{
if( !(*i)->isPlaying() )
{
//if it's not playing, we can use it, otherwise, if we use a playing sound,
//it will do nothing
(*i)->play();
if( bLoop )
{
(*i)->setRepeat( true );
}
return ; //find ok,so return
}
}
}
void AudiereManager::stop( HSOUND id )
{
for( tStreams::iterator i = m_soundContainer.at( id ).begin();
i != m_soundContainer.at( id ).end();
++ i )
{
(*i)->stop();
}
}
bool AudiereManager::isPlaying( HSOUND id )
{
for( tStreams::iterator i = m_soundContainer.at( id ).begin();
i != m_soundContainer.at( id ).end();
++ i )
{
if( (*i)->isPlaying() )
return true;
}
return false;
}
void AudiereManager::reset( HSOUND id )
{
for( tStreams::iterator i = m_soundContainer.at( id ).begin();
i != m_soundContainer.at( id ).end();
++ i )
{
(*i)->reset();
}
}
void AudiereManager::setVolume( HSOUND id, float volume )
{
for( tStreams::iterator i = m_soundContainer.at( id ).begin();
i != m_soundContainer.at( id ).end();
++ i )
{
(*i)->setVolume( volume );
}
}
float AudiereManager::getVolume( HSOUND id )
{
return m_soundContainer.at( id ).at( 0 )->getVolume();
}
void AudiereManager::setPan( HSOUND id, float pan )
{
for( tStreams::iterator i = m_soundContainer.at( id ).begin();
i != m_soundContainer.at( id ).end();
++ i )
{
(*i)->setPan( pan );
}
}
float AudiereManager::getPan( HSOUND id )
{
return m_soundContainer.at( id ).at( 0 )->getPan();
}
void AudiereManager::setPitchShift( HSOUND id, float shift )
{
for( tStreams::iterator i = m_soundContainer.at( id ).begin();
i != m_soundContainer.at( id ).end();
++ i )
{
(*i)->setPitchShift( shift );
}
}
float AudiereManager::getPitchShift( HSOUND id )
{
return m_soundContainer.at( id ).at( 0 )->getPitchShift();
}
bool AudiereManager::isSeekable( HSOUND id )
{
return m_soundContainer.at( id ).at( 0 )->isSeekable();
}
int AudiereManager::getLength( HSOUND id )
{
return m_soundContainer.at( id ).at( 0 )->getLength();
}
int AudiereManager::getPosition( HSOUND id )
{
return m_soundContainer.at( id ).at( 0 )->getPosition();
}
void AudiereManager::setPosition( HSOUND id, int position )
{
for( tStreams::iterator i = m_soundContainer.at( id ).begin();
i != m_soundContainer.at( id ).end();
++ i )
{
(*i)->setPosition( position );
}
}
void AudiereManager::setAllVolume( float volume )
{
for( tSounds::iterator i = m_soundContainer.begin();
i != m_soundContainer.end();
++ i )
{
for( tStreams::iterator j = (*i).begin();
j != (*i).end();
++j )
{
(*j)->setVolume( volume );
}
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// SoundMgr.h
/*
Space Demon Made By Kevin Lynx
File : SoundMgr.h
Desc : manage the sound in this game...including manage the sound resources
maybe it can used in other projects...
Date : 2007.2.6
*/
#ifndef SOUND_MGR_H
#define SOUND_MGR_H
#include <string>
#include <map>
#include "./audiereMgr/AudiereManager.h"
class SoundMgr
{
public:
enum
{
NO_SOUND = -1
};
public:
/*
Name : Load
Desc : load all sounds specified in xml file
Param :
xmlFile : the sound/music resources description file
*/
bool Load( const char *xmlFile );
/*
Name : GetIdByStringId
Desc : return the sound id managed by audiereManager(i wrote)
Param:
strId : the string id describe in xml file
*/
HSOUND GetIdByStringId( std::string strId );
HSOUND GetIdByStringId( const char *strId );
/*
Name : SetSysSndVolume
Desc : set all the sounds' volume
Param:
volume : 0--1
*/
void SetSysSndVolume( float volume );
public:
static SoundMgr *GetInstance();
static void Release();
public:
AudiereManager *mSndPlayer;
private:
typedef std::map<std::string, HSOUND> tSounds;
private:
tSounds mSounds;
static SoundMgr *mInstance;
private:
SoundMgr();
~SoundMgr();
};
#endif
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// SoundMgr.cpp
/*
Space Demon Made By Kevin Lynx
File : SoundMgr.cpp
Desc : manage the sounds in this game
Date : 2007.2.6
*/
#include "SoundMgr.h"
#include <Debug.h>
#include "../extendLib/tinyxml.h"
SoundMgr *SoundMgr::mInstance = NULL;
SoundMgr::SoundMgr()
{
mSounds.clear();
mSndPlayer = mSndPlayer = AudiereManager::GetInstance();
}
SoundMgr::~SoundMgr()
{
AudiereManager::Release();
}
bool SoundMgr::Load( const char *xmlFile )
{
bool bLoadOK = true;
//get the instance of audiere manager
if( mSndPlayer == NULL )
return false;
TiXmlDocument *xmlDoc = new TiXmlDocument();
if( !xmlDoc->LoadFile( xmlFile ) )
{
return false;
}
TiXmlElement *rootElem = xmlDoc->RootElement();
TiXmlElement *musicElem = rootElem->FirstChildElement()->FirstChildElement() ;
//TiXmlElement *sndElem = rootElem->FirstChildElement()->NextSiblingElement()->FirstChildElement() ;
HSOUND sndId;
std::string strId;
//load all musics
while( musicElem != NULL )
{
sndId = mSndPlayer->load( musicElem->Attribute( "path" ) );
if( sndId == AudiereManager::LOAD_FAILED )
{
//SexyTraceFmt( "Load Sound %s FAILED", sndElem->Attribute( "path" ) );
bLoadOK = false;
}
else
{
//construct the map
mSounds.insert( tSounds::value_type( std::string( musicElem->Attribute( "id" ) ), sndId ) );
//set default volume if there has
double volume;
if( musicElem->Attribute( "defaultVol", &volume ) )
{
mSndPlayer->setVolume( sndId, volume );
}
}
musicElem = musicElem->NextSiblingElement();
}
//load all sounds
//while( sndElem != NULL )
//{
// sndId = mSndPlayer->load( sndElem->Attribute( "path" ), false );
// if( sndId == AudiereManager::LOAD_FAILED )
// {
// SexyTraceFmt( "Load Sound %s FAILED", sndElem->Attribute( "path" ) );
// bLoadOK = false;
// }
// else
// {
// mSounds.insert( tSounds::value_type( std::string( sndElem->Attribute( "id" ) ), sndId ) );
// //set default volume if there has
// double volume;
// if( sndElem->Attribute( "defaultVol", &volume ) )
// {
// mSndPlayer->setVolume( sndId, volume );
// }
// }
// sndElem = sndElem->NextSiblingElement();
//}
//
xmlDoc->Clear();
delete xmlDoc;
return bLoadOK;
}
HSOUND SoundMgr::GetIdByStringId( std::string strId )
{
tSounds::iterator i = mSounds.find( strId );
if( i == mSounds.end() )
return NO_SOUND;
else
return (*i).second ;
}
HSOUND SoundMgr::GetIdByStringId( const char *strId )
{
SexyTraceFmt( "GetIdByStringId : %s/n", strId );
if( strId == NULL )
return NO_SOUND;
else
return GetIdByStringId( std::string( strId ) );
}
void SoundMgr::SetSysSndVolume( float volume )
{
if( volume >= 0.0f &&
volume <= 1.0f )
{
mSndPlayer->setAllVolume( volume );
}
}
SoundMgr *SoundMgr::GetInstance()
{
if( mInstance == NULL )
{
mInstance = new SoundMgr();
}
return mInstance;
}
void SoundMgr::Release()
{
if( mInstance != NULL )
{
delete mInstance;
mInstance = NULL;
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// main.cpp
// 播放声音
#include <SexyAppBase.h>
#include <WidgetManager.h>
#include <ResourceManager.h>
#include <Widget.h>
#include <DDImage.h>
#include "SoundMgr.h"
#define ASSERT(value) if (!(value)) { _asm{int 3};}
using namespace Sexy;
#pragma comment( lib, "winmm.lib" )
#pragma comment( lib, "wsock32.lib" )
#ifdef _DEBUG
#pragma comment( lib, "SexyAppFramework_D.lib" )
#else
#pragma comment( lib, "SexyAppFramework.lib" )
#endif
#pragma comment( lib, "./extendLib/tinyxml.lib" )
#pragma comment( lib, "./extendLib/audiere.lib" )
const char *musicName = "SND_BACK_1";
int mSndId;
class CApp : public SexyAppBase
{
public:
CApp();
~CApp();
virtual void Init();
virtual void LoadingThreadProc();
virtual void LoadingThreadCompleted();
};
CApp::CApp()
{
mWidth = 550;
mHeight = 650;
mTitle = "APP";
mNoSoundNeeded = true;
mAutoEnable3D = true;
}
CApp::~CApp()
{
}
void CApp::Init()
{
SexyAppBase::Init();
}
void CApp::LoadingThreadProc()
{
//load all sounds
SoundMgr::GetInstance()->Load( "properties/sound_res.xml" );
mSndId = SoundMgr::GetInstance()->GetIdByStringId( musicName );
ASSERT( mSndId != SoundMgr::NO_SOUND );
}
void CApp::LoadingThreadCompleted()
{
SexyAppBase::LoadingThreadCompleted();
//begin to play background music
SoundMgr::GetInstance()->mSndPlayer->setPosition( mSndId, 0 );
SoundMgr::GetInstance()->mSndPlayer->play( mSndId, true );
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
gHInstance = hInstance;
CApp *app = new CApp();
app->Init();
app->Start();
delete app;
return 0;
}
//////////////////////////////////////////////////////////////////