1、.h文件
#ifndef __NewAudioEngineDemo__NewAudioEngineDemo__ #define __NewAudioEngineDemo__NewAudioEngineDemo__ #include "cocos2d.h" #include "ui/CocosGUI.h" #include "VisibleRect.h" #include "audio/include/AudioEngine.h" USING_NS_CC; using namespace ui; class NewAudioEngineDemo : public Scene { public: CREATE_FUNC(NewAudioEngineDemo); virtual bool init(); }; class BaseTest : public Layer { public: CREATE_FUNC(BaseTest); virtual bool init(); virtual std::string title() const;//主标题 virtual std::string subtitle() const;//副标题 virtual void onExit() override; virtual void restartCallback(Ref* sender);//重新执行当前test virtual void nextCallback(Ref* sender);//下一个test virtual void backCallback(Ref* sender);//上一个test void menuCloseCallback(cocos2d::Ref* pSender);//关闭菜单回调函数 }; class AudioControlTest : public BaseTest { public: CREATE_FUNC(AudioControlTest); virtual ~AudioControlTest(); virtual bool init(); virtual void update(float dt); virtual std::string subtitle() const override; private: int _audioID; bool _loopEnabled; float _volume; float _duration; float _timeRatio; void* _playItem; void* _timeSlider; bool _updateTimeSlider; }; class PlaySimultaneouslyTest : public BaseTest { public: CREATE_FUNC(PlaySimultaneouslyTest); virtual ~PlaySimultaneouslyTest(); virtual bool init(); virtual std::string subtitle() const override; private: static const int TEST_COUNT = 10; std::string _files[TEST_COUNT]; void* _playItem; int _playingcount; }; class AudioProfileTest : public BaseTest { public: CREATE_FUNC(AudioProfileTest); virtual bool init(); virtual ~AudioProfileTest(); virtual std::string subtitle() const override; virtual void update(float dt); private: static const int FILE_COUNT = 2; std::string _files[FILE_COUNT]; cocos2d::experimental::AudioProfile _audioProfile; int _audioCount; Label* _showLabel; float _time; float _minDelay; void* _timeSlider; }; class InvalidAudioFileTest : public BaseTest { public: CREATE_FUNC(InvalidAudioFileTest); virtual bool init(); virtual ~InvalidAudioFileTest(); virtual std::string subtitle() const override; }; class LargeAudioFileTest : public BaseTest { public: CREATE_FUNC(LargeAudioFileTest); virtual bool init(); virtual ~LargeAudioFileTest(); virtual std::string subtitle() const override; }; #endif /* defined(__NewAudioEngineDemo__NewAudioEngineDemo__) */
2、.cpp文件
#include "NewAudioEngineDemo.h" #include "platform/CCPlatformConfig.h" #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 using namespace cocos2d::experimental; #define CL(__className__) [](){ return __className__::create();} static int sceneIdx = -1; static std::function<Layer*()> createFunctions[] = { CL(AudioControlTest),CL(PlaySimultaneouslyTest),CL(AudioProfileTest),CL(InvalidAudioFileTest),CL(LargeAudioFileTest)}; #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) static Layer* nextAction() { sceneIdx++; sceneIdx = sceneIdx % MAX_LAYER; auto layer = (createFunctions[sceneIdx])(); return layer; } static Layer* backAction() { sceneIdx--; int total = MAX_LAYER; if( sceneIdx < 0 ) sceneIdx += total; auto layer = (createFunctions[sceneIdx])(); return layer; } static Layer* restartAction() { auto layer = (createFunctions[sceneIdx])(); return layer; } //基类Layer bool BaseTest::init() { bool bRet = false; do{ CC_BREAK_IF(!Layer::init()); Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); ///////////////////////////// // 2. add a menu item with "X" image,which is clicked to quit the program // you may modify it. // add a "close" icon to exit the progress. it's an autorelease object auto closeItem = MenuItemImage::create( "CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(BaseTest::menuCloseCallback,this)); closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2,origin.y + visibleSize.height - closeItem->getContentSize().height/2)); // create menu,it's an autorelease object auto menu1 = Menu::create(closeItem,NULL); menu1->setPosition(Vec2::ZERO); this->addChild(menu1,1); std::string str = title(); const char * pTitle = str.c_str(); TTFConfig ttfConfig("fonts/tahoma.ttf",35); auto label = Label::createWithTTF(ttfConfig,pTitle); addChild(label,9999); label->setPosition( Vec2(VisibleRect::center().x,VisibleRect::top().y - 30) ); std::string strSubtitle = subtitle(); if( ! strSubtitle.empty() ) { ttfConfig.fontFilePath = "fonts/tahoma.ttf"; ttfConfig.fontSize = 30; auto l = Label::createWithTTF(ttfConfig,strSubtitle.c_str()); addChild(l,9999); l->setPosition( Vec2(VisibleRect::center().x,VisibleRect::top().y - 100) ); } auto item1 = MenuItemFont::create("backCallback",CC_CALLBACK_1(BaseTest::backCallback,this) ); auto item2 = MenuItemFont::create("restartCallback",CC_CALLBACK_1(BaseTest::restartCallback,this) ); auto item3 = MenuItemFont::create("nextCallback",CC_CALLBACK_1(BaseTest::nextCallback,this) ); auto menu = Menu::create(item1,item2,item3,NULL); menu->setPosition(Vec2::ZERO); item1->setPosition(Vec2(VisibleRect::center().x - item2->getContentSize().width*2,VisibleRect::bottom().y+item2->getContentSize().height/2)); item2->setPosition(Vec2(VisibleRect::center().x,VisibleRect::bottom().y+item2->getContentSize().height/2)); item3->setPosition(Vec2(VisibleRect::center().x + item2->getContentSize().width*2,VisibleRect::bottom().y+item2->getContentSize().height/2)); addChild(menu,9999); bRet = true; }while(0); return bRet; } void BaseTest::menuCloseCallback(Ref* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); return; #endif Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif } //重新执行当前test void BaseTest::restartCallback(cocos2d::Ref *sender) { auto s = new (std::nothrow) NewAudioEngineDemo(); s->addChild(restartAction()); Director::getInstance()->replaceScene(s); s->release(); } //下一个test void BaseTest::nextCallback(cocos2d::Ref *sender) { auto s = new (std::nothrow) NewAudioEngineDemo(); s->addChild(nextAction()); Director::getInstance()->replaceScene(s); s->release(); } //上一个test void BaseTest::backCallback(cocos2d::Ref *sender) { auto s = new (std::nothrow) NewAudioEngineDemo(); s->addChild(backAction()); Director::getInstance()->replaceScene(s); s->release(); } //onExit函数 void BaseTest::onExit() { AudioEngine::stopAll(); Layer::onExit(); } std::string BaseTest::title() const { return "NewAudioEngineDemo Test"; } std::string BaseTest::subtitle() const { return ""; } //封装按钮 class TextButton : public cocos2d::Label { public: //静态创建函数 static TextButton* create(const std::string& text,const std::function<void(TextButton*)>& onTriggered) { //如果非配内存失败,返回0 auto ret = new(std::nothrow) TextButton(); TTFConfig ttfconfig("fonts/arial.ttf",25); //创建成功,设置Label if(ret && ret->setTTFConfig(ttfconfig)) { //设置内容 ret->setString(text); //设置回调函数 ret->_onTriggered = onTriggered; ret->autorelease(); return ret; } delete ret; return nullptr; } //设置触摸响应 void setEnabled(bool enabled) { _enabled = enabled; //如果没有触摸 if(_enabled) { //设置Lable颜色为White this->setColor(Color3B::WHITE); }else{ //如果已经触摸,设置颜色Gray this->setColor(Color3B::GRAY); } } private: //构造函数,_enabled为true,_onTriggered为nullptr TextButton() :_enabled(true),_onTriggered(nullptr) { //注册监听事件 auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true);//事件禁止向下传递 //触摸事件类型 listener->onTouchBegan = CC_CALLBACK_2(TextButton::onTouchBegan,this); listener->onTouchEnded = CC_CALLBACK_2(TextButton::onTouchEnded,this); listener->onTouchCancelled = CC_CALLBACK_2(TextButton::onTouchCancelled,this); //加入事件 Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,this); } //判断是否在触摸范围内 bool touchHits(Touch* touch) { //将屏幕坐标转为节点坐标 auto hitPos = this->convertToNodeSpace(touch->getLocation()); //触摸点在节点坐标内,返回true,否则返回false if(hitPos.x >= 0 && hitPos.y >= 0 && hitPos.x <= _contentSize.width && hitPos.y <= _contentSize.height) { return true; } return false; } //触摸开始 bool onTouchBegan(Touch* touch,Event* event) { //调用touchHit函数,返回true,在节点上 auto hits = touchHits(touch); if(hits) { scaleButtonTo(0.95f);//执行按钮缩放 } return hits;//响应后面触摸事件 } //触摸结束 void onTouchEnded(Touch* touch,Event* event) { //如果没有触摸 if(_enabled) { //判断是否在节点上 auto hits = touchHits(touch); //如果在节点上,且响应事件不为nullptr if(hits && _onTriggered) { //调用响应事件 _onTriggered(this); } } //执行按钮缩放 scaleButtonTo(1); } //触摸取消 void onTouchCancelled(Touch* touch,Event* event) { scaleButtonTo(1); } //缩放操作 void scaleButtonTo(float scale) { auto action = ScaleTo::create(0.05f,scale); action->setTag(10000); stopActionByTag(10000); runAction(action); } //事件回调函数指针 std::function<void(TextButton*)> _onTriggered; bool _enabled;//是否触摸 }; //封装进度条类,拖动进度条响应事件 class SliderEx : public Slider { public: //触摸事件,按下,移动,抬起,取消 enum class TouchEvent { DOWN,MOVE,UP,CANCEL }; //定义函数函数指针 typedef std::function<void(SliderEx*,float,TouchEvent)> ccSliderExCallback; //静态创建函数 static SliderEx* create() { //std::nothrow分配内存失败返回0,必须包含头文件#include <new> auto ret = new(std::nothrow)SliderEx(); if(ret && ret->init()) { //初始化进度条 ret->_callback = nullptr; ret->loadBarTexture("sliderTrack.png"); ret->loadSlidBallTextures("sliderThumb.png","sliderThumb.png",""); ret->loadProgressBarTexture("sliderProgress.png"); ret->autorelease(); return ret; } //如果分配内存失败,删除ret并置空 CC_SAFE_DELETE(ret); return ret; } //设置回调函数 void setCallBack(const ccSliderExCallback& callback){ _callback = callback; } //设置进度比 void setRatio(float ratio) { if(ratio > 1.0f) { ratio = 1.0f; }else if(ratio < 0.0f) { ratio = 0.0f; } _ratio = ratio; _percent = 100* _ratio; //设置进度条光标的位置, float dis = _barLength * _ratio; _slidBallRenderer->setPosition(dis,_contentSize.height/2.0f); //设置进度条已走过的进度 if(_scale9Enabled) { //如果开启9宫格精灵,设置进度条已走过的进度比 _progressBarRenderer->setPreferredSize(Size(dis,_progressBarTextureSize.height)); }else{ //如果没有开启9宫格精灵 //首先获取进度条ProgressBar的精灵 auto spriteRenderer = _progressBarRenderer->getSprite(); //精灵不为空 if(nullptr != spriteRenderer) { //获取精灵的Rect Rect rect = spriteRenderer->getTextureRect(); rect.size.width = _progressBarTextureSize.width * _ratio;//设置获取精灵的Rect大小 spriteRenderer->setTextureRect(rect,spriteRenderer->isTextureRectRotated(),rect.size);//设置ProgressBar精灵的Rect } } } //触摸开始事件 virtual bool onTouchBegan(Touch* touch,Event* unusedEvent) override{ //进度条开始触摸 auto ret = Slider::onTouchBegan(touch,unusedEvent); //_callback不为空 if(ret && _callback){ _touchEvent = TouchEvent::DOWN; Vec2 nsp = convertToNodeSpace(_touchBeganPosition);//触摸点坐标转为节点坐标 _ratio = nsp.x / _barLength;//取得进度比,当前触摸位置除以进度条的长度 if(_ratio < 0.0f) { _ratio = 0.0f; }else if(_ratio > 1.0f) { _ratio = 1.0f; } _callback(this,_ratio,_touchEvent);//回调事件 } return ret; } //移动触摸 virtual void onTouchMoved(Touch* touch,Event* unusedEvent) override{ _touchEvent = TouchEvent::MOVE;//设置触摸类型 Slider::onTouchMoved(touch,unusedEvent);//Slider基类触摸 Vec2 nsp = convertToNodeSpace(_touchMovePosition);//触摸点坐标转为节点坐标 _ratio = nsp.x / _barLength; if(_ratio < 0.0f) { _ratio = 0.0f; }else if(_ratio > 1.0f) { _ratio = 1.0f; } if(_callback) { _callback(this,_touchEvent);//事件回调 } } //取消触摸 virtual void onTouchCancelled(Touch* touch,Event* unusedEvent) override { _touchEvent = TouchEvent::CANCEL; Slider::onTouchCancelled(touch,unusedEvent); if (_callback) { _callback(this,_touchEvent);//事件回调 } } private: TouchEvent _touchEvent;//触摸事件类型 float _ratio;//进度比 ccSliderExCallback _callback;//回调事件的指针函数 }; //基类Scene bool NewAudioEngineDemo::init() { bool bRet; do{ CC_BREAK_IF(!Scene::init()); //初始化AudioEngine CCASSERT(AudioEngine::lazyInit(),"Fail to initialize AudioEngine!"); //初始化sceneIdx sceneIdx = -1; //执行nextAction,执行第一个test auto layer = nextAction(); //加入NewAudioEngineDemo场景 addChild(layer); //切换场景 Director::getInstance()->replaceScene(this); bRet = true; }while(0); return bRet; } bool AudioControlTest::init() { bool bRet = false; do{ CC_BREAK_IF(!BaseTest::init()); _audioID = AudioEngine::INVAILD_AUDIO_ID; //是否循环 _loopEnabled = false; //音量大小 _volume = 1.0f; // _duration = AudioEngine::TIME_UNKNOWN; //更新间隔 _timeRatio = 0.0f; //更新进度条 _updateTimeSlider = true; //字体路径 std::string fontFilePath = "fonts/arial.ttf"; //当前Size auto layerSize = this->getContentSize(); //play按钮,第一个参数是按钮名称,第二个参数是回调函数,在触摸结束后响应 auto playItem = TextButton::create("play",[&](TextButton* button) { //判断ID是否为INVAILD_AUTIO_ID if(_audioID == AudioEngine::INVAILD_AUDIO_ID) { //播放音乐,第一个参数音乐文件路径,第二个参数,是否循环播放,第三个参数,音量,跟进去发现函数返回一个int值,值为0 _audioID = AudioEngine::play2d("background.mp3",_loopEnabled,_volume); log("_audioID = %d",_audioID);//打印0,即unordered_map的对象个数 log("INVAILD_AUDIO_ID = %d",AudioEngine::INVAILD_AUDIO_ID);//打印-1 //如果ID不等于AudioEngine::INVAILD_AUDIO_ID,执行以下代码 if(_audioID != AudioEngine::INVAILD_AUDIO_ID) { //设置按钮被按下,设置Lable字体颜色为灰色 button->setEnabled(false); //如果音乐播放完毕的回调函数 AudioEngine::setFinishCallback(_audioID,[&](int id,const std::string& filePath) { //重新恢复ID值为-1 _audioID = AudioEngine::INVAILD_AUDIO_ID; ((TextButton*)_playItem)->setEnabled(true);//设置按钮为非触摸状态,即没有被按下,按钮字体颜色为White _timeRatio = 0.0f;//更新时间间隔为0 ((SliderEx*)_timeSlider)->setRatio(_timeRatio);//设置进度比 }); } } }); _playItem = playItem;//将当前playItem赋值给_playItem,这一步在初始化时执行,先于触摸playItem前执行 playItem->setPosition(layerSize.width*0.3f,layerSize.height*0.7f); addChild(playItem); //停止按钮 auto stopItem = TextButton::create("stop",[&](TextButton* button){ if(_audioID != AudioEngine::INVAILD_AUDIO_ID) { AudioEngine::stop(_audioID); _audioID = AudioEngine::INVAILD_AUDIO_ID; ((TextButton*)_playItem)->setEnabled(true);//停止按钮按下,play按钮字体颜色变为White } }); stopItem->setPosition(layerSize.width*0.7f,layerSize.height*0.7f); addChild(stopItem); //暂停按钮 auto pauseItem = TextButton::create("pause",[&](TextButton* button){ if(_audioID != AudioEngine::INVAILD_AUDIO_ID) { AudioEngine::pause(_audioID); } }); pauseItem->setPosition(layerSize.width*0.3f,layerSize.height*0.6f); addChild(pauseItem); //恢复播放按钮 auto resumeItem = TextButton::create("resume",[&](TextButton* button){ if(_audioID != AudioEngine::INVAILD_AUDIO_ID) { AudioEngine::resume(_audioID); } }); resumeItem->setPosition(layerSize.width*0.7f,layerSize.height*0.6f); addChild(resumeItem); //是否循环播放 auto loopItem = TextButton::create("enable-loop",[&](TextButton* button){ _loopEnabled = !_loopEnabled;//取非,使_loopEnabled循环 if(_audioID != AudioEngine::INVAILD_AUDIO_ID) { AudioEngine::setLoop(_audioID,_loopEnabled);//设置是否循环 } //设置循环播放按钮字体内容 if(_loopEnabled) { button->setString("disable-loop"); }else{ button->setString("enable-loop"); } }); loopItem->setPosition(layerSize.width*0.3f,layerSize.height*0.5f); addChild(loopItem); //加载缓冲 auto uncacheItem = TextButton::create("uncache",[&](TextButton* button){ AudioEngine::uncache("background.mp3"); _audioID = AudioEngine::INVAILD_AUDIO_ID; ((TextButton*)_playItem)->setEnabled(true);//设置play按钮为非触摸状态 }); uncacheItem->setPosition(layerSize.width*0.7f,layerSize.height*0.5f); addChild(uncacheItem); //声音进度条 auto volumeSlider = SliderEx::create(); volumeSlider->setPercent(100); volumeSlider->setCallBack([&](SliderEx* sender,float ratio,SliderEx::TouchEvent event){ _volume = ratio;//获取音量值 if(_audioID != AudioEngine::INVAILD_AUDIO_ID) { //设置音量 AudioEngine::setVolume(_audioID,_volume); } }); volumeSlider->setPosition(Vec2(layerSize.width*0.5f,layerSize.height*0.35f)); addChild(volumeSlider); //时间进度条 auto timeSlider = SliderEx::create(); //参数引用类对象,参数传递在触摸事件中 timeSlider->setCallBack([&](SliderEx* sender,SliderEx::TouchEvent event){ switch (event) { case SliderEx::TouchEvent::MOVE: case SliderEx::TouchEvent::DOWN: _updateTimeSlider = false;//按钮和移动状态下,不更新时间进度条 break; case SliderEx::TouchEvent::UP://抬起 if(_audioID != AudioEngine::INVAILD_AUDIO_ID && _duration != AudioEngine::TIME_UNKNOWN) { //设置当前时间进度条的进度 AudioEngine::setCurrentTime(_audioID,_duration*ratio); } break; case SliderEx::TouchEvent::CANCEL: _updateTimeSlider = true;//取消动作,继续更新进度条 break; default: break; } }); timeSlider->setPosition(Vec2(layerSize.width*0.5f,layerSize.height*0.25f)); addChild(timeSlider); _timeSlider = timeSlider; //音量标签 auto volumeSliderPos = volumeSlider->getPosition(); auto sliderSize = volumeSlider->getContentSize(); auto volumeLabel = Label::createWithTTF("volume:",fontFilePath,20); volumeLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT); volumeLabel->setPosition(volumeSliderPos.x - sliderSize.width/2,volumeSliderPos.y); addChild(volumeLabel); //时间标签 auto timeSliderPos = timeSlider->getPosition(); auto timeLabel = Label::createWithTTF("time:",20); timeLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT); timeLabel->setPosition(timeSliderPos.x-sliderSize.width/2,timeSliderPos.y); addChild(timeLabel); //每0.1秒更新帧 this->schedule(CC_CALLBACK_1(AudioControlTest::update,this),0.1f,"update_key"); bRet = true; }while(0); return bRet; } void AudioControlTest::update(float dt) { //如果有音乐播放 if(_audioID != AudioEngine::INVAILD_AUDIO_ID) { //并且时间未知 if(_duration == AudioEngine::TIME_UNKNOWN) { //设置时间间隔 _duration = AudioEngine::getDuration(_audioID); } if(_duration != AudioEngine::TIME_UNKNOWN) { //如果时间间隔不为TIME_UNKNOWN,获取当前的播放时间 auto time = AudioEngine::getCurrentTime(_audioID); _timeRatio = time / _duration;//计算时间进度比 if(_updateTimeSlider)//如果更新进度条为true { ((SliderEx*)_timeSlider)->setRatio(_timeRatio);//设置时间进度条的进度 } } } } AudioControlTest::~AudioControlTest() { } std::string AudioControlTest::subtitle() const { return "audio control test"; } bool PlaySimultaneouslyTest::init() { bool bRet = false; do{ CC_BREAK_IF(!BaseTest::init()); char text[36]; int tmp = 81; //获取音乐文件 for(int index = 0; index < TEST_COUNT;++index) { sprintf(text,"FX0%d.mp3",tmp+index); _files[index] = text; } //统计正在播放数量 _playingcount = 0; //创建播放按钮,回调函数的参数button在TextButton的触摸事件中,传递的是this对象,即当前playItem对象 auto playItem = TextButton::create("play-simultaneously",[&](TextButton* button){ int audioId; _playingcount = 0; //设置按钮为触摸状态,即按下按钮 button->setEnabled(false); //获取当前时间,返回今天当前秒和微秒的值 auto startTime = utils::gettime(); for(int index = 0; index < TEST_COUNT; ++index) { //播放_files里的音乐 audioId = AudioEngine::play2d(_files[index]); if(audioId != AudioEngine::INVAILD_AUDIO_ID) { //正在播放增加1 _playingcount += 1; //播放完毕的回调函数 AudioEngine::setFinishCallback(audioId,const std::string& filePath){ //正在播放减1 _playingcount -= 1; //如果正在播放的数量小于等于-1,设置播放按钮为true,即未按下状态 if(_playingcount <= 0) { ((TextButton*)_playItem)->setEnabled(true); } }); }else//如果ID等于-1,则没有音乐文件播放,或播放音乐文件失败 { log("%s,%d,Fail to play File:%s",__FILE__,__LINE__,_files[index].c_str()); } } //打印播放的时长 log("diff time:%lf",utils::gettime() - startTime); }); //设置像素级坐标 playItem->setNormalizedPosition(Vec2(0.5f,0.5f)); this->addChild(playItem); _playItem = playItem; bRet = true; }while(0); return bRet; } PlaySimultaneouslyTest::~PlaySimultaneouslyTest() { } std::string PlaySimultaneouslyTest::subtitle() const { return "PlaySimultaneously Test"; } bool AudioProfileTest::init() { bool bRet = false; do{ CC_BREAK_IF(!BaseTest::init()); char text[30]; _files[0] = "background.mp3"; #if CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC _files[1] = "background.caf"; #else _files[1] = "background.ogg"; #endif std::string fontFilePath = "fonts/arial.ttf"; _minDelay = 1.0f;//两个声音的最小时间间隔 _time = 0.0f; _audioProfile.name = "AudioProfileTest";//name不可为空 _audioProfile.maxInstances = 3;//音乐文件数量 _audioProfile.minDelay = 1.0;//两个声音的最小时间间隔 Vec2 pos(0.5f,0.7f); for(int index = 0; index < FILE_COUNT; ++index) { sprintf(text,"play %s",_files[index].c_str()); auto playItem = TextButton::create(text,[&](TextButton* button){ int index = button->getTag(); //播放文件,参数1:文件路径,参数2:不循环播放,参数3:音量,参数4:AudioProfile对象,设置相关配置 auto id = AudioEngine::play2d(_files[index],false,1.0f,&_audioProfile); if(id != AudioEngine::INVAILD_AUDIO_ID) { _time = _minDelay; _audioCount += 1; char show[30]; sprintf(show,"audio count:%d",_audioCount); _showLabel->setString(show); //播放完毕回调事件 AudioEngine::setFinishCallback(id,const std::string& filePath){ _audioCount = -1; char show[30]; sprintf(show,_audioCount); _showLabel->setString(show); }); } }); playItem->setTag(index); playItem->setNormalizedPosition(pos); this->addChild(playItem); pos.y -= 0.15f; } Vec2 origin = Director::getInstance()->getVisibleOrigin(); Size winSize = Director::getInstance()->getVisibleSize(); auto profileInfoLabel = Label::createWithTTF("AudioProfile Info:\n max instance:3 \n minimum delay:1.0",20); profileInfoLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT); profileInfoLabel->setPosition(Vec2(origin.x,origin.y+winSize.height*0.65f)); addChild(profileInfoLabel); _audioCount = 0; //初始化_showLabel对象 _showLabel = Label::createWithTTF("audio count:0",20); _showLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT); _showLabel->setPosition(Vec2(origin.x,origin.y+winSize.height*0.5f)); addChild(_showLabel); //初始化timeSlider对象 auto timeSlider = SliderEx::create(); timeSlider->setEnabled(false); timeSlider->setNormalizedPosition(pos); addChild(timeSlider); _timeSlider = timeSlider; this->schedule(CC_CALLBACK_1(AudioProfileTest::update,0.05f,"update_key"); bRet = true; }while(0); return bRet; } void AudioProfileTest::update(float dt) { if(_time > 0.0f) { _time -= dt; //设置进度比 ((SliderEx*)_timeSlider)->setRatio(_time / _minDelay); } } AudioProfileTest::~AudioProfileTest() { } std::string AudioProfileTest::subtitle() const { return "AudioProfile test"; } bool InvalidAudioFileTest::init() { bool bRet = false; do{ CC_BREAK_IF(!BaseTest::init()); auto playItem = TextButton::create("play unsupported media type",[&](TextButton* button){ #if CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC AudioEngine::play2d("background.ogg"); #elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 AudioEngine::play2d("background.caf"); #endif }); playItem->setNormalizedPosition(Vec2(0.5f,0.6f)); this->addChild(playItem); //播放不存在的音乐文件,查看控制台 auto playItem2 = TextButton::create("play not-existent file",[&](TextButton* button){ AudioEngine::play2d("not-existent file.mp3"); }); playItem2->setNormalizedPosition(Vec2(0.5f,0.4f)); this->addChild(playItem2); bRet = true; }while(0); return bRet; } InvalidAudioFileTest::~InvalidAudioFileTest() { } std::string InvalidAudioFileTest::subtitle() const { return "InvalidAudioFile test"; } //播放比较大的音乐文件 bool LargeAudioFileTest::init() { bool bRet = false; do{ CC_BREAK_IF(!BaseTest::init()); auto playItem = TextButton::create("play large audio file",[&](TextButton* button){ AudioEngine::play2d("LuckyDay.mp3"); }); playItem->setNormalizedPosition(Vec2::ANCHOR_MIDDLE); this->addChild(playItem); bRet = true; }while(0); return bRet; } LargeAudioFileTest::~LargeAudioFileTest() { } std::string LargeAudioFileTest::subtitle() const { return "LargeAudioFile Test"; } #endif
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。