add: decode media resources with Media Foundation and playback with XAudio2.
This commit is contained in:
		
							parent
							
								
									80d1a87955
								
							
						
					
					
						commit
						a924eed280
					
				|  | @ -57,12 +57,11 @@ | ||||||
| #include <d2d1.h> | #include <d2d1.h> | ||||||
| #include <dwrite.h> | #include <dwrite.h> | ||||||
| #include <dinput.h> | #include <dinput.h> | ||||||
| #include <shlwapi.h> | #include <xaudio2.h> | ||||||
| #include <mfapi.h> | #include <mfapi.h> | ||||||
| #include <mfidl.h> | #include <mfidl.h> | ||||||
| #include <mferror.h> | #include <mfreadwrite.h> | ||||||
| #include <evr.h> | #include <shlwapi.h> | ||||||
| #include <mmdeviceapi.h> |  | ||||||
| 
 | 
 | ||||||
| // C++ RunTime Header Files
 | // C++ RunTime Header Files
 | ||||||
| #include <map> | #include <map> | ||||||
|  | @ -83,11 +82,10 @@ | ||||||
| #pragma comment(lib, "windowscodecs.lib") | #pragma comment(lib, "windowscodecs.lib") | ||||||
| #pragma comment(lib, "winmm.lib") | #pragma comment(lib, "winmm.lib") | ||||||
| #pragma comment(lib, "dinput8.lib") | #pragma comment(lib, "dinput8.lib") | ||||||
| #pragma comment(lib, "shlwapi") | #pragma comment(lib, "xaudio2.lib") | ||||||
| #pragma comment(lib, "mfplay.lib") |  | ||||||
| #pragma comment(lib, "mf.lib") |  | ||||||
| #pragma comment(lib, "mfplat.lib") | #pragma comment(lib, "mfplat.lib") | ||||||
| #pragma comment(lib, "mfuuid.lib") | #pragma comment(lib, "mfreadwrite.lib") | ||||||
|  | #pragma comment(lib, "shlwapi.lib") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #ifndef HINST_THISCOMPONENT | #ifndef HINST_THISCOMPONENT | ||||||
|  |  | ||||||
|  | @ -149,30 +149,21 @@ namespace e2d | ||||||
| 
 | 
 | ||||||
| 		~Audio(); | 		~Audio(); | ||||||
| 
 | 
 | ||||||
| 		// 获取音量
 | 		// 开启设备
 | ||||||
| 		float GetVolume(); | 		void Open(); | ||||||
| 
 | 
 | ||||||
| 		// 设置音量
 | 		// 关闭设备
 | ||||||
| 		void SetVolume( | 		void Close(); | ||||||
| 			float volume |  | ||||||
| 		); |  | ||||||
| 
 | 
 | ||||||
| 		// 是否静音
 | 		// 创建音源
 | ||||||
| 		bool GetMute(); | 		HRESULT CreateVoice( | ||||||
| 
 | 			IXAudio2SourceVoice ** voice, | ||||||
| 		// 设置静音
 | 			WAVEFORMATEX * wfx | ||||||
| 		void SetMute( |  | ||||||
| 			bool mute |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		LPWSTR					device_id;		// Device ID.
 | 		IXAudio2 * x_audio2_; | ||||||
| 		IMMDeviceEnumerator		*enum_;			// Audio device enumerator.
 | 		IXAudio2MasteringVoice*	mastering_voice_; | ||||||
| 		IMMDeviceCollection		*devices_;		// Audio device collection.
 |  | ||||||
| 		IMMDevice				*device_;		// An audio device.
 |  | ||||||
| 		IMFAttributes			*attributes_;	// Attribute store.
 |  | ||||||
| 		IMFMediaSink			*sink_;			// Streaming audio renderer (SAR)
 |  | ||||||
| 		IMFSimpleAudioVolume	*audio_volume; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										111
									
								
								core/e2dtool.h
								
								
								
								
							
							
						
						
									
										111
									
								
								core/e2dtool.h
								
								
								
								
							|  | @ -71,19 +71,10 @@ namespace e2d | ||||||
| 
 | 
 | ||||||
| 	// 音乐
 | 	// 音乐
 | ||||||
| 	class Music | 	class Music | ||||||
| 		: public IMFAsyncCallback |  | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		Music(); | 		Music(); | ||||||
| 
 | 
 | ||||||
| 		explicit Music( |  | ||||||
| 			const e2d::String& file_path	/* 音乐文件路径 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		explicit Music( |  | ||||||
| 			const Resource& res		/* 音乐资源 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		virtual ~Music(); | 		virtual ~Music(); | ||||||
| 
 | 
 | ||||||
| 		// 打开音乐文件
 | 		// 打开音乐文件
 | ||||||
|  | @ -104,6 +95,9 @@ namespace e2d | ||||||
| 		// 暂停
 | 		// 暂停
 | ||||||
| 		void Pause(); | 		void Pause(); | ||||||
| 
 | 
 | ||||||
|  | 		// 继续
 | ||||||
|  | 		void Resume(); | ||||||
|  | 
 | ||||||
| 		// 停止
 | 		// 停止
 | ||||||
| 		void Stop(); | 		void Stop(); | ||||||
| 
 | 
 | ||||||
|  | @ -113,99 +107,26 @@ namespace e2d | ||||||
| 		// 是否正在播放
 | 		// 是否正在播放
 | ||||||
| 		bool IsPlaying() const; | 		bool IsPlaying() const; | ||||||
| 
 | 
 | ||||||
| 		// 设置音量
 |  | ||||||
| 		bool SetVolume( |  | ||||||
| 			float volume	/* 范围: 0.0 ~ 1.0 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 获取音量
 | 		// 获取音量
 | ||||||
| 		float GetVolume() const; | 		float GetVolume() const; | ||||||
| 
 | 
 | ||||||
| 		// IUnknown methods
 | 		// 设置音量
 | ||||||
| 		STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override; | 		bool SetVolume( | ||||||
| 		STDMETHODIMP_(ULONG) AddRef() override; | 			float volume	/* 1.0 为原始音量 */ | ||||||
| 		STDMETHODIMP_(ULONG) Release() override; | 		); | ||||||
| 
 | 
 | ||||||
| 		// IMFAsyncCallback methods
 | 		// 获取 IXAudio2SourceVoice 对象
 | ||||||
| 		STDMETHODIMP  GetParameters(DWORD*, DWORD*) override; | 		IXAudio2SourceVoice * GetSourceVoice() const; | ||||||
| 		STDMETHODIMP  Invoke(IMFAsyncResult* pAsyncResult) override; |  | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		enum class State : int |  | ||||||
| 		{ |  | ||||||
| 			Closed = 0, |  | ||||||
| 			Loaded, |  | ||||||
| 			Started, |  | ||||||
| 			Paused, |  | ||||||
| 			Stopped, |  | ||||||
| 			Closing |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		E2D_DISABLE_COPY(Music); | 		E2D_DISABLE_COPY(Music); | ||||||
| 
 | 
 | ||||||
| 		// Media event handlers
 |  | ||||||
| 		HRESULT OnNewPresentation(IMFMediaEvent *pEvent); |  | ||||||
| 
 |  | ||||||
| 		HRESULT StartPlayback(); |  | ||||||
| 		HRESULT CreateMediaSource(PCWSTR sURL, IMFMediaSource **ppSource); |  | ||||||
| 		HRESULT HandleEvent(UINT_PTR pUnkPtr); |  | ||||||
| 
 |  | ||||||
| 		// Add a source node to a topology.
 |  | ||||||
| 		HRESULT AddSourceNode( |  | ||||||
| 			IMFTopology *pTopology,           // Topology.
 |  | ||||||
| 			IMFMediaSource *pSource,          // Media source.
 |  | ||||||
| 			IMFPresentationDescriptor *pPD,   // Presentation descriptor.
 |  | ||||||
| 			IMFStreamDescriptor *pSD,         // Stream descriptor.
 |  | ||||||
| 			IMFTopologyNode **ppNode         // Receives the node pointer.
 |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// Add an output node to a topology.
 |  | ||||||
| 		HRESULT AddOutputNode( |  | ||||||
| 			IMFTopology *pTopology,     // Topology.
 |  | ||||||
| 			IMFActivate *pActivate,     // Media sink activation object.
 |  | ||||||
| 			DWORD dwId,                 // Identifier of the stream sink.
 |  | ||||||
| 			IMFTopologyNode **ppNode   // Receives the node pointer.
 |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		HRESULT AddBranchToPartialTopology( |  | ||||||
| 			IMFTopology *pTopology,         // Topology.
 |  | ||||||
| 			IMFMediaSource *pSource,        // Media source.
 |  | ||||||
| 			IMFPresentationDescriptor *pPD, // Presentation descriptor.
 |  | ||||||
| 			DWORD iStream                  // Stream index.
 |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		//  Create a playback topology from a media source.
 |  | ||||||
| 		HRESULT CreatePlaybackTopology( |  | ||||||
| 			IMFMediaSource *pSource,          // Media source.
 |  | ||||||
| 			IMFPresentationDescriptor *pPD,   // Presentation descriptor.
 |  | ||||||
| 			IMFTopology **ppTopology          // Receives a pointer to the topology.
 |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		//  Create an activation object for a renderer, based on the stream media type.
 |  | ||||||
| 		HRESULT CreateMediaSinkActivate( |  | ||||||
| 			IMFStreamDescriptor *pSourceSD,     // Pointer to the stream descriptor.
 |  | ||||||
| 			IMFActivate **ppActivate |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		HRESULT GetSimpleAudioVolume( |  | ||||||
| 			IMFSimpleAudioVolume** ppAudioVolume |  | ||||||
| 		) const; |  | ||||||
| 
 |  | ||||||
| 		static LRESULT CALLBACK MediaProc( |  | ||||||
| 			HWND hWnd, |  | ||||||
| 			UINT Msg, |  | ||||||
| 			WPARAM wParam, |  | ||||||
| 			LPARAM lParam |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 	protected: | 	protected: | ||||||
| 		long					m_nRefCount; | 		bool					opened_; | ||||||
| 		int						m_nTimes; | 		bool					playing_; | ||||||
| 		IMFMediaSession *		m_pSession; | 		UINT32					size_; | ||||||
| 		IMFMediaSource          *m_pSource; | 		BYTE*					wave_data_; | ||||||
| 		HWND                    m_hwndEvent; | 		IXAudio2SourceVoice*	voice_; | ||||||
| 		State					m_state; |  | ||||||
| 		HANDLE                  m_hCloseEvent; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -280,11 +201,11 @@ namespace e2d | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 获取音量
 | 		// 获取音量
 | ||||||
| 		float GetVolume(); | 		float GetVolume() const; | ||||||
| 
 | 
 | ||||||
| 		// 设置音量
 | 		// 设置音量
 | ||||||
| 		void SetVolume( | 		void SetVolume( | ||||||
| 			float volume			/* 范围: 0.0 ~ 1.0 */ | 			float volume			/* 1.0 为原始音量 */ | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 暂停所有音乐
 | 		// 暂停所有音乐
 | ||||||
|  |  | ||||||
|  | @ -1,116 +0,0 @@ | ||||||
| // Copyright (c) 2016-2018 Easy2D - Nomango
 |  | ||||||
| // 
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 |  | ||||||
| // of this software and associated documentation files (the "Software"), to deal
 |  | ||||||
| // in the Software without restriction, including without limitation the rights
 |  | ||||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 |  | ||||||
| // copies of the Software, and to permit persons to whom the Software is
 |  | ||||||
| // furnished to do so, subject to the following conditions:
 |  | ||||||
| // 
 |  | ||||||
| // The above copyright notice and this permission notice shall be included in
 |  | ||||||
| // all copies or substantial portions of the Software.
 |  | ||||||
| // 
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 |  | ||||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 |  | ||||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 |  | ||||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 |  | ||||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 |  | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 |  | ||||||
| // THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| #include "..\e2dimpl.h" |  | ||||||
| 
 |  | ||||||
| e2d::MediaAsyncCallback::MediaAsyncCallback(HWND hwnd, IMFMediaSession * pSession, HANDLE hCloseEvent) |  | ||||||
| 	: m_pSession(pSession) |  | ||||||
| 	, m_hCloseEvent(hCloseEvent) |  | ||||||
| 	, m_hwnd(hwnd) |  | ||||||
| { |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| HRESULT e2d::MediaAsyncCallback::QueryInterface(REFIID riid, void** ppv) |  | ||||||
| { |  | ||||||
| 	static const QITAB qit[] = |  | ||||||
| 	{ |  | ||||||
| 		QITABENT(MediaAsyncCallback, IMFAsyncCallback), |  | ||||||
| 		{ 0 } |  | ||||||
| 	}; |  | ||||||
| 	return QISearch(this, qit, riid, ppv); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG e2d::MediaAsyncCallback::AddRef() |  | ||||||
| { |  | ||||||
| 	return InterlockedIncrement(&m_nRefCount); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG e2d::MediaAsyncCallback::Release() |  | ||||||
| { |  | ||||||
| 	ULONG uCount = InterlockedDecrement(&m_nRefCount); |  | ||||||
| 	if (uCount == 0) |  | ||||||
| 	{ |  | ||||||
| 		delete this; |  | ||||||
| 	} |  | ||||||
| 	return uCount; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| HRESULT e2d::MediaAsyncCallback::GetParameters(DWORD *, DWORD *) |  | ||||||
| { |  | ||||||
| 	// Implementation of this method is optional.
 |  | ||||||
| 	return E_NOTIMPL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| HRESULT e2d::MediaAsyncCallback::Invoke(IMFAsyncResult *pResult) |  | ||||||
| { |  | ||||||
| 	MediaEventType meType = MEUnknown;  // Event type
 |  | ||||||
| 
 |  | ||||||
| 	IMFMediaEvent *pEvent = NULL; |  | ||||||
| 
 |  | ||||||
| 	// Get the event from the event queue.
 |  | ||||||
| 	HRESULT hr = m_pSession->EndGetEvent(pResult, &pEvent); |  | ||||||
| 	if (FAILED(hr)) |  | ||||||
| 	{ |  | ||||||
| 		goto done; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Get the event type. 
 |  | ||||||
| 	hr = pEvent->GetType(&meType); |  | ||||||
| 	if (FAILED(hr)) |  | ||||||
| 	{ |  | ||||||
| 		goto done; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (meType == MESessionClosed) |  | ||||||
| 	{ |  | ||||||
| 		// The session was closed. 
 |  | ||||||
| 		// The application is waiting on the m_hCloseEvent event handle. 
 |  | ||||||
| 		SetEvent(m_hCloseEvent); |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		// For all other events, get the next event in the queue.
 |  | ||||||
| 		hr = m_pSession->BeginGetEvent(this, NULL); |  | ||||||
| 		if (FAILED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			goto done; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Check the application state. 
 |  | ||||||
| 
 |  | ||||||
| 	// If a call to IMFMediaSession::Close is pending, it means the 
 |  | ||||||
| 	// application is waiting on the m_hCloseEvent event and
 |  | ||||||
| 	// the application's message loop is blocked. 
 |  | ||||||
| 
 |  | ||||||
| 	// Otherwise, post a private window message to the application. 
 |  | ||||||
| 
 |  | ||||||
| 	//if (m_state != Closing)
 |  | ||||||
| 	{ |  | ||||||
| 		// Leave a reference count on the event.
 |  | ||||||
| 		pEvent->AddRef(); |  | ||||||
| 
 |  | ||||||
| 		::PostMessage(m_hwnd, WM_APP + 1, (WPARAM)pEvent, (LPARAM)meType); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| done: |  | ||||||
| 	SafeRelease(pEvent); |  | ||||||
| 	return S_OK; |  | ||||||
| } |  | ||||||
|  | @ -22,128 +22,46 @@ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| e2d::Audio::Audio() | e2d::Audio::Audio() | ||||||
| 	: enum_(nullptr) | 	: x_audio2_(nullptr) | ||||||
| 	, devices_(nullptr) | 	, mastering_voice_(nullptr) | ||||||
| 	, device_(nullptr) |  | ||||||
| 	, attributes_(nullptr) |  | ||||||
| 	, sink_(nullptr) |  | ||||||
| 	, device_id(nullptr) |  | ||||||
| 	, audio_volume(nullptr) |  | ||||||
| { | { | ||||||
| 	ThrowIfFailed( | 	ThrowIfFailed( | ||||||
| 		MFStartup(MF_VERSION) | 		MFStartup(MF_VERSION) | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	// Create the device enumerator.
 |  | ||||||
| 	ThrowIfFailed( | 	ThrowIfFailed( | ||||||
| 		CoCreateInstance( | 		XAudio2Create(&x_audio2_) | ||||||
| 			__uuidof(MMDeviceEnumerator), |  | ||||||
| 			NULL, |  | ||||||
| 			CLSCTX_ALL, |  | ||||||
| 			__uuidof(IMMDeviceEnumerator), |  | ||||||
| 			(void**)&enum_ |  | ||||||
| 		) |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	// Enumerate the rendering devices.
 |  | ||||||
| 	ThrowIfFailed( |  | ||||||
| 		enum_->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &devices_) |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	// Get ID of the first device in the list.
 |  | ||||||
| 	ThrowIfFailed( |  | ||||||
| 		devices_->Item(0, &device_) |  | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	ThrowIfFailed( | 	ThrowIfFailed( | ||||||
| 		device_->GetId(&device_id) | 		x_audio2_->CreateMasteringVoice(&mastering_voice_) | ||||||
| 	); | 	); | ||||||
| 
 |  | ||||||
| 	// Create an attribute store and set the device ID attribute.
 |  | ||||||
| 	ThrowIfFailed( |  | ||||||
| 		MFCreateAttributes(&attributes_, 2) |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	ThrowIfFailed( |  | ||||||
| 		attributes_->SetString( |  | ||||||
| 			MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, |  | ||||||
| 			device_id |  | ||||||
| 		) |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	// Create the audio renderer.
 |  | ||||||
| 	ThrowIfFailed( |  | ||||||
| 		MFCreateAudioRenderer(attributes_, &sink_) |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	IMFGetService* service = NULL; |  | ||||||
| 
 |  | ||||||
| 	ThrowIfFailed( |  | ||||||
| 		sink_->QueryInterface(IID_IMFGetService, (void **)&service) |  | ||||||
| 	); |  | ||||||
| 	 |  | ||||||
| 	ThrowIfFailed( |  | ||||||
| 		service->GetService(MR_POLICY_VOLUME_SERVICE, IID_PPV_ARGS(&audio_volume)) |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	SafeRelease(service); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Audio::~Audio() | e2d::Audio::~Audio() | ||||||
| { | { | ||||||
| 	SafeRelease(enum_); | 	if (mastering_voice_) | ||||||
| 	SafeRelease(devices_); | 	{ | ||||||
| 	SafeRelease(device_); | 		mastering_voice_->DestroyVoice(); | ||||||
| 	SafeRelease(attributes_); | 		mastering_voice_ = nullptr; | ||||||
| 	SafeRelease(audio_volume); | 	} | ||||||
| 	SafeRelease(sink_); | 
 | ||||||
| 	CoTaskMemFree(device_id); | 	SafeRelease(x_audio2_); | ||||||
| 
 | 
 | ||||||
| 	MFShutdown(); | 	MFShutdown(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float e2d::Audio::GetVolume() | HRESULT e2d::Audio::CreateVoice(IXAudio2SourceVoice ** voice, WAVEFORMATEX * wfx) | ||||||
| { | { | ||||||
| 	float volume = 0.f; | 	return x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO); | ||||||
| 	if (audio_volume) |  | ||||||
| 	{ |  | ||||||
| 		HRESULT hr = audio_volume->GetMasterVolume(&volume); |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			return volume; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return 0.f; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Audio::SetVolume(float volume) | void e2d::Audio::Open() | ||||||
| { | { | ||||||
| 	if (audio_volume) | 	x_audio2_->StartEngine(); | ||||||
| 	{ |  | ||||||
| 		volume = std::min(std::max(volume, 0.f), 1.f); |  | ||||||
| 		HRESULT hr = audio_volume->SetMasterVolume(volume); |  | ||||||
| 		printf("ºÇºÇ%#X\n", hr); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool e2d::Audio::GetMute() | void e2d::Audio::Close() | ||||||
| { | { | ||||||
| 	BOOL mute = FALSE; | 	x_audio2_->StopEngine(); | ||||||
| 	if (audio_volume) |  | ||||||
| 	{ |  | ||||||
| 		HRESULT hr = audio_volume->GetMute(&mute); |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			return mute ? true : false; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return FALSE; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void e2d::Audio::SetMute(bool mute) |  | ||||||
| { |  | ||||||
| 	if (audio_volume) |  | ||||||
| 	{ |  | ||||||
| 		audio_volume->SetMute(mute ? TRUE : FALSE); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										1202
									
								
								core/tools/Music.cpp
								
								
								
								
							
							
						
						
									
										1202
									
								
								core/tools/Music.cpp
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -68,7 +68,7 @@ void e2d::Player::Resume(const String & file_path) | ||||||
| 
 | 
 | ||||||
| 	size_t hash = file_path.GetHash(); | 	size_t hash = file_path.GetHash(); | ||||||
| 	if (musics_.end() != musics_.find(hash)) | 	if (musics_.end() != musics_.find(hash)) | ||||||
| 		musics_[hash]->Play(); | 		musics_[hash]->Resume(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Player::Stop(const String & file_path) | void e2d::Player::Stop(const String & file_path) | ||||||
|  | @ -137,7 +137,7 @@ void e2d::Player::Pause(const Resource& res) | ||||||
| void e2d::Player::Resume(const Resource& res) | void e2d::Player::Resume(const Resource& res) | ||||||
| { | { | ||||||
| 	if (musics_.end() != musics_.find(res.id)) | 	if (musics_.end() != musics_.find(res.id)) | ||||||
| 		musics_[res.id]->Play(); | 		musics_[res.id]->Resume(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Player::Stop(const Resource& res) | void e2d::Player::Stop(const Resource& res) | ||||||
|  | @ -153,14 +153,14 @@ bool e2d::Player::IsPlaying(const Resource& res) | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float e2d::Player::GetVolume() | float e2d::Player::GetVolume() const | ||||||
| { | { | ||||||
| 	return volume_; | 	return volume_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Player::SetVolume(float volume) | void e2d::Player::SetVolume(float volume) | ||||||
| { | { | ||||||
| 	volume_ = std::min(std::max(volume, 0.f), 1.f); | 	volume_ = std::min(std::max(volume, -224.f), 224.f); | ||||||
| 	for (const auto& pair : musics_) | 	for (const auto& pair : musics_) | ||||||
| 	{ | 	{ | ||||||
| 		pair.second->SetVolume(volume_); | 		pair.second->SetVolume(volume_); | ||||||
|  | @ -179,7 +179,7 @@ void e2d::Player::ResumeAll() | ||||||
| { | { | ||||||
| 	for (const auto& pair : musics_) | 	for (const auto& pair : musics_) | ||||||
| 	{ | 	{ | ||||||
| 		pair.second->Play(); | 		pair.second->Resume(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -45,7 +45,6 @@ | ||||||
|     <ClCompile Include="..\..\core\events\KeyEvent.cpp" /> |     <ClCompile Include="..\..\core\events\KeyEvent.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\events\MouseEvent.cpp" /> |     <ClCompile Include="..\..\core\events\MouseEvent.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\impl\TextRenderer.cpp" /> |     <ClCompile Include="..\..\core\impl\TextRenderer.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\impl\VoiceCallback.cpp" /> |  | ||||||
|     <ClCompile Include="..\..\core\modules\Audio.cpp" /> |     <ClCompile Include="..\..\core\modules\Audio.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\modules\Device.cpp" /> |     <ClCompile Include="..\..\core\modules\Device.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\modules\Game.cpp" /> |     <ClCompile Include="..\..\core\modules\Game.cpp" /> | ||||||
|  |  | ||||||
|  | @ -141,9 +141,6 @@ | ||||||
|     <ClCompile Include="..\..\core\impl\TextRenderer.cpp"> |     <ClCompile Include="..\..\core\impl\TextRenderer.cpp"> | ||||||
|       <Filter>impl</Filter> |       <Filter>impl</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\..\core\impl\VoiceCallback.cpp"> |  | ||||||
|       <Filter>impl</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\..\core\events\KeyEvent.cpp"> |     <ClCompile Include="..\..\core\events\KeyEvent.cpp"> | ||||||
|       <Filter>events</Filter> |       <Filter>events</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |  | ||||||
|  | @ -189,7 +189,6 @@ | ||||||
|     <ClCompile Include="..\..\core\events\KeyEvent.cpp" /> |     <ClCompile Include="..\..\core\events\KeyEvent.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\events\MouseEvent.cpp" /> |     <ClCompile Include="..\..\core\events\MouseEvent.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\impl\TextRenderer.cpp" /> |     <ClCompile Include="..\..\core\impl\TextRenderer.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\impl\VoiceCallback.cpp" /> |  | ||||||
|     <ClCompile Include="..\..\core\modules\Audio.cpp" /> |     <ClCompile Include="..\..\core\modules\Audio.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\modules\Device.cpp" /> |     <ClCompile Include="..\..\core\modules\Device.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\modules\Game.cpp" /> |     <ClCompile Include="..\..\core\modules\Game.cpp" /> | ||||||
|  |  | ||||||
|  | @ -141,9 +141,6 @@ | ||||||
|     <ClCompile Include="..\..\core\impl\TextRenderer.cpp"> |     <ClCompile Include="..\..\core\impl\TextRenderer.cpp"> | ||||||
|       <Filter>impl</Filter> |       <Filter>impl</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\..\core\impl\VoiceCallback.cpp"> |  | ||||||
|       <Filter>impl</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\..\core\events\KeyEvent.cpp"> |     <ClCompile Include="..\..\core\events\KeyEvent.cpp"> | ||||||
|       <Filter>events</Filter> |       <Filter>events</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |  | ||||||
|  | @ -101,7 +101,7 @@ | ||||||
|       <Optimization>Disabled</Optimization> |       <Optimization>Disabled</Optimization> | ||||||
|       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||||
|       <SDLCheck>false</SDLCheck> |       <SDLCheck>false</SDLCheck> | ||||||
|       <DebugInformationFormat>None</DebugInformationFormat> |       <DebugInformationFormat>EditAndContinue</DebugInformationFormat> | ||||||
|       <MinimalRebuild>false</MinimalRebuild> |       <MinimalRebuild>false</MinimalRebuild> | ||||||
|       <TreatWarningAsError>true</TreatWarningAsError> |       <TreatWarningAsError>true</TreatWarningAsError> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  | @ -222,7 +222,6 @@ | ||||||
|     <ClCompile Include="..\..\core\events\KeyEvent.cpp" /> |     <ClCompile Include="..\..\core\events\KeyEvent.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\events\MouseEvent.cpp" /> |     <ClCompile Include="..\..\core\events\MouseEvent.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\impl\TextRenderer.cpp" /> |     <ClCompile Include="..\..\core\impl\TextRenderer.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\impl\MediaAsyncCallback.cpp" /> |  | ||||||
|     <ClCompile Include="..\..\core\modules\Audio.cpp" /> |     <ClCompile Include="..\..\core\modules\Audio.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\modules\Device.cpp" /> |     <ClCompile Include="..\..\core\modules\Device.cpp" /> | ||||||
|     <ClCompile Include="..\..\core\modules\Game.cpp" /> |     <ClCompile Include="..\..\core\modules\Game.cpp" /> | ||||||
|  |  | ||||||
|  | @ -216,9 +216,6 @@ | ||||||
|     <ClCompile Include="..\..\core\modules\Device.cpp"> |     <ClCompile Include="..\..\core\modules\Device.cpp"> | ||||||
|       <Filter>modules</Filter> |       <Filter>modules</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\..\core\impl\MediaAsyncCallback.cpp"> |  | ||||||
|       <Filter>impl</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="..\..\core\easy2d.h" /> |     <ClInclude Include="..\..\core\easy2d.h" /> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue