| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | // 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.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-07 21:31:30 +08:00
										 |  |  |  | #ifndef INITGUID
 | 
					
						
							|  |  |  |  | #	define INITGUID		// MFAudioFormat_PCM, MF_MT_MAJOR_TYPE, MF_MT_SUBTYPE, MFMediaType_Audio
 | 
					
						
							|  |  |  |  | #endif
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | #include "Transcoder.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-11 17:24:11 +08:00
										 |  |  |  | #include "audio-modules.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-12 00:27:54 +08:00
										 |  |  |  | #include "../common/ComPtr.hpp"
 | 
					
						
							| 
									
										
										
										
											2019-01-22 10:23:12 +08:00
										 |  |  |  | #include "../core/logs.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-11 17:24:11 +08:00
										 |  |  |  | #include "../core/modules.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | namespace easy2d | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	Transcoder::Transcoder() | 
					
						
							|  |  |  |  | 		: wave_format_(nullptr) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	 | 
					
						
							|  |  |  |  | 	Transcoder::~Transcoder() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (wave_format_) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			::CoTaskMemFree(wave_format_); | 
					
						
							|  |  |  |  | 			wave_format_ = nullptr; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 	const WAVEFORMATEX* Transcoder::GetWaveFormatEx() const | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return wave_format_; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-07 23:54:19 +08:00
										 |  |  |  | 	HRESULT Transcoder::LoadMediaFile(String const& file_path, BYTE** wave_data, UINT32* wave_data_size) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		HRESULT hr = S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		ComPtr<IMFSourceReader> reader; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 21:58:01 +08:00
										 |  |  |  | 		hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromURL( | 
					
						
							| 
									
										
										
										
											2019-02-07 23:54:19 +08:00
										 |  |  |  | 			file_path.c_str(), | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			nullptr, | 
					
						
							|  |  |  |  | 			&reader | 
					
						
							|  |  |  |  | 		); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 			hr = ReadSource(reader.Get(), wave_data, wave_data_size); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 		return hr; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 	HRESULT Transcoder::LoadMediaResource(Resource const& res, BYTE** wave_data, UINT32* wave_data_size) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		HRESULT	hr = S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		ComPtr<IStream> stream; | 
					
						
							|  |  |  |  | 		ComPtr<IMFByteStream> byte_stream; | 
					
						
							|  |  |  |  | 		ComPtr<IMFSourceReader> reader; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-21 21:24:45 +08:00
										 |  |  |  | 		LPVOID buffer; | 
					
						
							|  |  |  |  | 		DWORD buffer_size; | 
					
						
							|  |  |  |  | 		if (!res.Load(buffer, buffer_size)) { return false; } | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 21:58:01 +08:00
										 |  |  |  | 		stream = modules::Shlwapi::Get().SHCreateMemStream( | 
					
						
							| 
									
										
										
										
											2019-01-21 21:24:45 +08:00
										 |  |  |  | 			static_cast<const BYTE*>(buffer), | 
					
						
							|  |  |  |  | 			static_cast<UINT>(buffer_size) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (stream == nullptr) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-02-07 21:31:30 +08:00
										 |  |  |  | 			E2D_ERROR_LOG(L"SHCreateMemStream failed"); | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			return E_OUTOFMEMORY; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-01-22 21:58:01 +08:00
										 |  |  |  | 			hr = modules::MediaFoundation::Get().MFCreateMFByteStreamOnStream(stream.Get(), &byte_stream); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-01-22 21:58:01 +08:00
										 |  |  |  | 			hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromByteStream( | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 				byte_stream.Get(), | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				nullptr, | 
					
						
							|  |  |  |  | 				&reader | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 			hr = ReadSource(reader.Get(), wave_data, wave_data_size); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 		return hr; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	HRESULT Transcoder::ReadSource(IMFSourceReader* reader, BYTE** wave_data, UINT32* wave_data_size) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		HRESULT hr = S_OK; | 
					
						
							|  |  |  |  | 		DWORD max_stream_size = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		ComPtr<IMFMediaType> partial_type; | 
					
						
							|  |  |  |  | 		ComPtr<IMFMediaType> uncompressed_type; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 21:58:01 +08:00
										 |  |  |  | 		hr = modules::MediaFoundation::Get().MFCreateMediaType(&partial_type); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			hr = partial_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			hr = partial_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// <20><><EFBFBD><EFBFBD> source reader <20><>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ú<EFBFBD><C3BA>ʵĽ<CAB5><C4BD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			hr = reader->SetCurrentMediaType( | 
					
						
							| 
									
										
										
										
											2019-02-03 00:16:53 +08:00
										 |  |  |  | 				(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				0, | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 				partial_type.Get() | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// <20><> IMFMediaType <20>л<EFBFBD>ȡ WAVEFORMAT <20>ṹ
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			hr = reader->GetCurrentMediaType( | 
					
						
							| 
									
										
										
										
											2019-02-03 00:16:53 +08:00
										 |  |  |  | 				(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				&uncompressed_type | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// ָ<><D6B8><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			hr = reader->SetStreamSelection( | 
					
						
							| 
									
										
										
										
											2019-02-03 00:16:53 +08:00
										 |  |  |  | 				(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				true | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// <20><>ȡ WAVEFORMAT <20><><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			UINT32 size = 0; | 
					
						
							| 
									
										
										
										
											2019-01-22 21:58:01 +08:00
										 |  |  |  | 			hr = modules::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType( | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 				uncompressed_type.Get(), | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				&wave_format_, | 
					
						
							|  |  |  |  | 				&size, | 
					
						
							| 
									
										
										
										
											2019-02-03 00:16:53 +08:00
										 |  |  |  | 				(DWORD)MFWaveFormatExConvertFlag_Normal | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>С
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			PROPVARIANT prop; | 
					
						
							|  |  |  |  | 			PropVariantInit(&prop); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			hr = reader->GetPresentationAttribute( | 
					
						
							| 
									
										
										
										
											2019-02-03 00:16:53 +08:00
										 |  |  |  | 				(DWORD)MF_SOURCE_READER_MEDIASOURCE, | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				MF_PD_DURATION, | 
					
						
							|  |  |  |  | 				&prop | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			LONGLONG duration = prop.uhVal.QuadPart; | 
					
						
							|  |  |  |  | 			max_stream_size = static_cast<DWORD>( | 
					
						
							|  |  |  |  | 				(duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1 | 
					
						
							| 
									
										
										
										
											2019-02-03 00:16:53 +08:00
										 |  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			PropVariantClear(&prop); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// <20><>ȡ<EFBFBD><C8A1>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			DWORD flags = 0; | 
					
						
							|  |  |  |  | 			DWORD position = 0; | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 			BYTE* data = new (std::nothrow) BYTE[max_stream_size]; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			ComPtr<IMFSample> sample; | 
					
						
							|  |  |  |  | 			ComPtr<IMFMediaBuffer> buffer; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (data == nullptr) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2019-02-07 21:31:30 +08:00
										 |  |  |  | 				E2D_ERROR_LOG(L"Low memory"); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				hr = E_OUTOFMEMORY; | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			else | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				while (true) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					hr = reader->ReadSample( | 
					
						
							| 
									
										
										
										
											2019-02-03 00:16:53 +08:00
										 |  |  |  | 						(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 						0, | 
					
						
							|  |  |  |  | 						nullptr, | 
					
						
							|  |  |  |  | 						&flags, | 
					
						
							|  |  |  |  | 						nullptr, | 
					
						
							|  |  |  |  | 						&sample | 
					
						
							|  |  |  |  | 					); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 					if (flags & MF_SOURCE_READERF_ENDOFSTREAM) { break; } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 					if (sample == nullptr) { continue; } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 					if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 					{ | 
					
						
							|  |  |  |  | 						hr = sample->ConvertToContiguousBuffer(&buffer); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 						if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 						{ | 
					
						
							|  |  |  |  | 							BYTE *audio_data = nullptr; | 
					
						
							|  |  |  |  | 							DWORD sample_buffer_length = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 							hr = buffer->Lock( | 
					
						
							|  |  |  |  | 								&audio_data, | 
					
						
							|  |  |  |  | 								nullptr, | 
					
						
							|  |  |  |  | 								&sample_buffer_length | 
					
						
							|  |  |  |  | 							); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 							if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 							{ | 
					
						
							|  |  |  |  | 								for (DWORD i = 0; i < sample_buffer_length; i++) | 
					
						
							|  |  |  |  | 								{ | 
					
						
							|  |  |  |  | 									data[position++] = audio_data[i]; | 
					
						
							|  |  |  |  | 								} | 
					
						
							|  |  |  |  | 								hr = buffer->Unlock(); | 
					
						
							|  |  |  |  | 							} | 
					
						
							|  |  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 						buffer = nullptr; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 					sample = nullptr; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 					if (FAILED(hr)) { break; } | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 				if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					*wave_data = data; | 
					
						
							|  |  |  |  | 					*wave_data_size = position; | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		return hr; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } |