PopCap 播放声音

 

 

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;

}

//////////////////////////////////////////////////////////////////

 

(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值