cocos2dx win32下修改音量大小
来源:互联网 发布:xinnet域名管理 编辑:程序博客网 时间:2024/05/24 15:43
寫在前面,此方法不適合跨平台,純粹為實現win32平台下的音量修改。方法是用directshow,以前寫過一篇文章是說在遊戲中播放視頻的。
具體的方法如下:
1. 創建一個hidewindow,這也是simpleaudioengine的做法,用來處理directshow產生的事件
2. 初始化COM接口
3. 播放文件
4. 關閉接口
#define WIN32_LEAN_AND_MEAN#include <tchar.h>#include <stdio.h>#include <dshow.h>#include <atlbase.h>#include <strsafe.h>#include "CCDirector.h"#include "movieplay.h"#include <Windows.h>//// Globals//NS_CC_BEGINIGraphBuilder *pGB = NULL;IMediaControl *pMC = NULL;IVideoWindow *pVW = NULL;IMediaEventEx *pME = NULL;IBasicAudio *pBA = NULL;IMediaSeeking *pMS = NULL;IMediaPosition *pMP = NULL;BOOL g_bContinue=FALSE, g_bUserInterruptedPlayback=FALSE;static HWND g_sndHWND;static HINSTANCE s_hInstance;static HWND g_videoHWND;//// Function prototypes//#define RELEASE(i) {if (i) i->Release(); i = NULL;}HRESULT PlaySoundMedia(LPTSTR lpszSound,HWND hwnd);HRESULT GetInterfaces(HWND);void SoundHandleEvent();void CreateHideWindow();LRESULT WINAPI _SoundPlayProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
HRESULT GetInterfaces(HWND hwnd){HRESULT hr = S_OK;// Instantiate filter graph interfaceCoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGB);// Get interfaces to control playback & screensizepGB->QueryInterface(IID_IMediaControl, (void **)&pMC);pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW);pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS);pGB->QueryInterface(IID_IMediaPosition, (void **)&pMP);// Get interface to allow the app to wait for completion of playbackpGB->QueryInterface(IID_IMediaEventEx, (void **)&pME);// For audiopGB->QueryInterface(IID_IBasicAudio, (void **)&pBA);/*// Set windows positionpVW->put_Owner((OAHWND)hwnd);pVW->put_WindowStyle(WS_CLIPSIBLINGS | WS_CHILD);RECT grc;GetClientRect(hwnd, &grc);pVW->SetWindowPosition(grc.left, grc.top, grc.right, grc.bottom);*/return S_OK;// In case of failure, the helper macro jumps here}void CleanupInterfaces(){// Release the DirectShow interfaces//cocos2d::CCDirector::sharedDirector()->startAnimation();if (pME)pME->SetNotifyWindow(NULL,0,0);// Stop playback and exitif (pMC)pMC->Stop();RELEASE(pGB);RELEASE(pMC);RELEASE(pVW);RELEASE(pME);RELEASE(pMS);RELEASE(pBA);RELEASE(pMP);CoUninitialize();}
HRESULT GetInterfaces(HWND hwnd){HRESULT hr = S_OK;// Instantiate filter graph interfaceCoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGB);// Get interfaces to control playback & screensizepGB->QueryInterface(IID_IMediaControl, (void **)&pMC);pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW);pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS);pGB->QueryInterface(IID_IMediaPosition, (void **)&pMP);// Get interface to allow the app to wait for completion of playbackpGB->QueryInterface(IID_IMediaEventEx, (void **)&pME);// For audiopGB->QueryInterface(IID_IBasicAudio, (void **)&pBA);/*// Set windows positionpVW->put_Owner((OAHWND)hwnd);pVW->put_WindowStyle(WS_CLIPSIBLINGS | WS_CHILD);RECT grc;GetClientRect(hwnd, &grc);pVW->SetWindowPosition(grc.left, grc.top, grc.right, grc.bottom);*/return S_OK;// In case of failure, the helper macro jumps here}void CleanupInterfaces(){// Release the DirectShow interfaces//cocos2d::CCDirector::sharedDirector()->startAnimation();if (pME)pME->SetNotifyWindow(NULL,0,0);// Stop playback and exitif (pMC)pMC->Stop();RELEASE(pGB);RELEASE(pMC);RELEASE(pVW);RELEASE(pME);RELEASE(pMS);RELEASE(pBA);RELEASE(pMP);CoUninitialize();}
HRESULT PlaySoundFile(LPTSTR szSound, bool bLoop) {g_bContinue = bLoop;CreateHideWindow();CloseSound();if (!szSound)return E_POINTER;HRESULT hr;// Create the main hidden window to field keyboard input//if (!CreateHiddenWindow(hInstance, szMovie))//return E_FAIL;// Initialize COMif (FAILED(hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))return hr;// Get DirectShow interfacesif (FAILED(hr = GetInterfaces(g_sndHWND))){CoUninitialize();return hr;}pME->SetNotifyWindow((OAHWND)g_sndHWND,WM_SOUNDEVENT,0);// Play the movie / cutscenePlaySoundMedia(szSound,g_sndHWND);// If the user interrupted playback and there was no other error,// return S_FALSE.if ((hr == S_OK) && g_bUserInterruptedPlayback)hr = S_FALSE;// Release DirectShow interfaces//CleanupInterfaces();//CoUninitialize();return hr;}double GetSoundTime() {double duration;if (pMP)pMP->get_Duration(&duration);return duration;}void PauseSound() {pMC->Pause();}void StopSound() {pMC->Stop();}void ResumeSound() {pMC->Run();}void CloseSound() {if (pME)pME->SetNotifyWindow((OAHWND)NULL,0,0);// Stop playback and exitif (pMC)pMC->Stop();RELEASE(pGB);RELEASE(pMC);RELEASE(pVW);RELEASE(pME);RELEASE(pMS);RELEASE(pBA);RELEASE(pMP);CoUninitialize();}void GetSoundVolume(long g_lVolume) { pBA->get_Volume(&g_lVolume);}void SetSoundVolume(long lVol) {pBA->put_Volume(lVol);}void SetMuteVolume() {SetSoundVolume(-10000);}void SetFullVolume() {SetSoundVolume(0);}bool IsSoundPlaying() {bool result;long lEventCode;LONG_PTR lpParam1, lpParam2;HRESULT hr = pME->GetEvent(&lEventCode, &lpParam1, &lpParam2, 0);if (lEventCode == EC_ACTIVATE)if (lpParam1 == TRUE)result = TRUE;elseresult = FALSE;return result;}bool IsSoundStop() {return !IsSoundPlaying();}void SoundHandleEvent() {HRESULT hr = S_OK;//g_bContinue = TRUE;MSG msg;long lEventCode;LONG_PTR lpParam1, lpParam2;// Enter a loop of checking for events and sampling keyboard inputwhile (hr = pME->GetEvent(&lEventCode, &lpParam1, &lpParam2, 0),SUCCEEDED(hr)) {hr = pME->FreeEventParams(lEventCode, lpParam1, lpParam2);if (g_bContinue == TRUE) {if(EC_COMPLETE == lEventCode) {LONGLONG pos = 0;hr = pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning);pMC->Pause();pMC->Run();} else if (lEventCode == EC_WINDOW_DESTROYED || lEventCode == EC_USERABORT) {CloseSound();break;}} else {if (lEventCode == EC_COMPLETE || lEventCode == EC_WINDOW_DESTROYED || lEventCode == EC_USERABORT) {CloseSound();break;}}}}HRESULT PlaySoundMedia(LPTSTR lpszSound,HWND hwnd) {USES_CONVERSION;WCHAR wFileName[MAX_PATH];BOOL bSleep=TRUE;HRESULT hr = S_OK;if (!lpszSound)return E_POINTER;wcsncpy(wFileName, T2W(lpszSound), MAX_PATH-1);wFileName[MAX_PATH - 1] = 0;hr = pGB->RenderFile(wFileName, NULL);// Display first frame of the moviehr = pMC->Pause();// Start playbackhr = pMC->Run();}void CreateHideWindow() {if (! s_hInstance) {s_hInstance = GetModuleHandle( NULL ); // Grab An Instance For Our WindowWNDCLASS wc; // Windows Class Structure// Redraw On Size, And Own DC For Window.wc.style = 0; wc.lpfnWndProc = _SoundPlayProc; // WndProc Handles Messageswc.cbClsExtra = 0; // No Extra Window Datawc.cbWndExtra = 0; // No Extra Window Datawc.hInstance = s_hInstance; // Set The Instancewc.hIcon = 0; // Load The Default Iconwc.hCursor = LoadCursor( NULL, IDC_ARROW ); // Load The Arrow Pointerwc.hbrBackground = NULL; // No Background Required For GLwc.lpszMenuName = NULL; // We Don't Want A Menuwc.lpszClassName = TEXT("Sound Play"); // Set The Class Nameif (! RegisterClass(&wc)&& 1410 != GetLastError()){return;}}g_sndHWND = CreateWindowEx(WS_EX_APPWINDOW, // Extended Style For The WindowTEXT("Sound Play"), // Class NameNULL, // Window TitleWS_POPUPWINDOW,/*WS_OVERLAPPEDWINDOW*/ // Defined Window Style0, 0, // Window Position0, // Window Width0, // Window HeightNULL, // No Parent WindowNULL, // No Menus_hInstance, // InstanceNULL );if (g_sndHWND){;//SetWindowLong(g_sndHWND, GWL_USERDATA, (LONG)wc);}}LRESULT WINAPI _SoundPlayProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {switch(Msg) {case WM_SOUNDEVENT:SoundHandleEvent();break;}return DefWindowProc(hWnd, Msg, wParam, lParam);}NS_CC_END
注:通過directshow獲得的當前音量大小為0,即使重新改過了也是0。
下面看看一個效果,隨著場景的談出,也讓音樂同時談出。
void CastScene::onExitTransitionDidStart() {PVZDebugLog("CastScene Transition Exit");this->schedule(schedule_selector(CastScene::updateMusicFadeout),0.5f);}void CastScene::replaceWithMainScene() {// CCScene* scene = new CCScene();// CCLayer* pLayer = new MainMenuScene();// pLayer->autorelease();// scene->addChild(pLayer, 0);// For transition without effect, mustbe autorelease for eachlayer//CCSprite *pSpr = (CCSprite*)this->getChildByTag(LAYER_TAG::tagLabel);//this->removeChildByTag(LAYER_TAG::tagLabel);this->unschedule(schedule_selector(CastScene::updateKeyboardSelect));CCScene *s = new TransitionCastScenePage();CCLayer* pLayer = new CastScenePlaceholder();s->addChild(pLayer);CCScene* pScene = CCTransitionFade::create(3.0f,s);if (pScene) {//CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(true); CCDirector::sharedDirector()->replaceScene(pScene);}s->release();pLayer->release();}
void CastScene::updateMusicFadeout(float dt) {g_lVol -= 500;SetSoundVolume(g_lVol);//CocosDenshion::SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();}
g_lVol為此編譯單元中的全局變量,在init()中設置為0。
- cocos2dx win32下修改音量大小
- 修改win32平台下窗口大小,及屏幕适配
- cocos2dx 3.x Win32音量调节无效解决步骤详解
- Android 如何修改拨号按键音量大小
- 修改系统默认的音量大小
- 如何修改Android5.1系统音量大小
- windows下修改系统音量
- mtk 平台下网络通话音量大小。
- 修改cocos2dx,处理win32窗口事件
- cocos2dx win32修改鼠标指针图案
- Cocos2dx 3.1.1 之 修改屏幕大小
- COCOS2DX 安卓WIN32下配置手册
- Win32下-cocos2dx-3.0创建项目
- cocos2dx Win32下添加控制台输出
- Android4.4 系统默认各种音量大小值修改
- Android7.1修改系统默认多媒体音量大小
- mt6735 [Audio Common]如何修改拨号按键音量大小
- mt6735 [Audio Common]如何修改拨号按键音量大小
- UVA 1449
- Android不同系统版本依然能调用到正确的API方法Demo——Service调用startForeground举例
- D3DXMatrixScaling 函数
- android平台下使用点九PNG技术
- mysql在myeclipse中的应用
- cocos2dx win32下修改音量大小
- 网页嵌入百度搜索,谷歌搜索下拉选择直接搜索
- Android 4.0 拨号盘界面的分析(源码)
- 读书笔记——OpenGL超级宝典
- 折半查找的递归实现与qsort
- 利用gd库,生成一个图片 imagecreatetruecolor
- hdu 2199 Can you solve this equation?
- Java Web 之过滤器Filter详解
- Project:CC#4; Title:Youth