diff --git a/cocos/audio/winrt/Audio.cpp b/cocos/audio/winrt/Audio.cpp index 76b3e10bcf..feaf711a18 100644 --- a/cocos/audio/winrt/Audio.cpp +++ b/cocos/audio/winrt/Audio.cpp @@ -1,47 +1,30 @@ -//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF -//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO -//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A -//// PARTICULAR PURPOSE. -//// -//// Copyright (c) Microsoft Corporation. All rights reserved +/* +* cocos2d-x http://www.cocos2d-x.org +* +* Copyright (c) 2010-2011 - cocos2d-x community +* +* Portions Copyright (c) Microsoft Open Technologies, Inc. +* All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and limitations under the License. +*/ -#include "pch.h" #include "Audio.h" #include "MediaStreamer.h" +//#include "CCCommon.h" -static std::wstring CCUtf8ToUnicode(const char * pszUtf8Str, unsigned len/* = -1*/) -{ - std::wstring ret; - do - { - if (! pszUtf8Str) break; - // get UTF8 string length - if (-1 == len) - { - len = strlen(pszUtf8Str); - } - if (len <= 0) break; - - // get UTF16 string length - int wLen = MultiByteToWideChar(CP_UTF8, 0, pszUtf8Str, len, 0, 0); - if (0 == wLen || 0xFFFD == wLen) break; - - // convert string - wchar_t * pwszStr = new wchar_t[wLen + 1]; - if (! pwszStr) break; - pwszStr[wLen] = 0; - MultiByteToWideChar(CP_UTF8, 0, pszUtf8Str, len, pwszStr, wLen + 1); - ret = pwszStr; - if(pwszStr) { delete[] (pwszStr);}; - } while (0); - return ret; -} - -static inline void ThrowIfFailed(HRESULT hr) +inline void ThrowIfFailed(HRESULT hr) { if (FAILED(hr)) { - // Set a breakpoint on this line to catch DirectX API errors + // Set a breakpoint on this line to catch DX API errors. throw Platform::Exception::CreateException(hr); } } @@ -55,14 +38,14 @@ void AudioEngineCallbacks::Initialize(Audio *audio) // to be closed down and restarted. The error code is given in error. void _stdcall AudioEngineCallbacks::OnCriticalError(HRESULT Error) { + UNUSED_PARAM(Error); m_audio->SetEngineExperiencedCriticalError(); }; Audio::Audio() : m_backgroundID(0), - m_soundEffctVolume(1.0), + m_soundEffctVolume(1.0f), m_backgroundMusicVolume(1.0f) - { } @@ -220,8 +203,10 @@ void Audio::StopBackgroundMusic(bool bReleaseData) StopSoundEffect(m_backgroundID); - if (bReleaseData) + if (bReleaseData){ UnloadSoundEffect(m_backgroundID); + RemoveFromList(m_backgroundID); + } } void Audio::PauseBackgroundMusic() @@ -328,9 +313,6 @@ void Audio::PlaySoundEffect(unsigned int sound) m_soundEffects[sound].m_soundEffectSourceVoice->SubmitSourceBuffer(&m_soundEffects[sound].m_audioBuffer) ); - XAUDIO2_BUFFER buf = {0}; - XAUDIO2_VOICE_STATE state = {0}; - if (m_engineExperiencedCriticalError) { // If there's an error, then we'll recreate the engine on the next render pass return; @@ -426,7 +408,8 @@ void Audio::PauseAllSoundEffects() EffectList::iterator iter; for (iter = m_soundEffects.begin(); iter != m_soundEffects.end(); iter++) { - PauseSoundEffect(iter->first); + if (iter->first != m_backgroundID) + PauseSoundEffect(iter->first); } } @@ -439,11 +422,12 @@ void Audio::ResumeAllSoundEffects() EffectList::iterator iter; for (iter = m_soundEffects.begin(); iter != m_soundEffects.end(); iter++) { - ResumeSoundEffect(iter->first); + if (iter->first != m_backgroundID) + ResumeSoundEffect(iter->first); } } -void Audio::StopAllSoundEffects() +void Audio::StopAllSoundEffects(bool bReleaseData) { if (m_engineExperiencedCriticalError) { return; @@ -452,8 +436,27 @@ void Audio::StopAllSoundEffects() EffectList::iterator iter; for (iter = m_soundEffects.begin(); iter != m_soundEffects.end(); iter++) { - StopSoundEffect(iter->first); + if (iter->first != m_backgroundID){ + StopSoundEffect(iter->first); + if (bReleaseData) + { + UnloadSoundEffect(iter->first); + } + } } + if (bReleaseData) + { + for (iter = m_soundEffects.begin(); iter != m_soundEffects.end();) + { + if (iter->first != m_backgroundID){ + m_soundEffects.erase(iter++); + } + else + { + iter++; + } + } + } } bool Audio::IsSoundEffectStarted(unsigned int sound) @@ -464,39 +467,66 @@ bool Audio::IsSoundEffectStarted(unsigned int sound) return m_soundEffects[sound].m_soundEffectStarted; } +std::wstring CCUtf8ToUnicode(const char * pszUtf8Str) +{ + std::wstring ret; + do + { + if (! pszUtf8Str) break; + size_t len = strlen(pszUtf8Str); + if (len <= 0) break; + ++len; + wchar_t * pwszStr = new wchar_t[len]; + if (! pwszStr) break; + pwszStr[len - 1] = 0; + MultiByteToWideChar(CP_UTF8, 0, pszUtf8Str, len, pwszStr, len); + ret = pwszStr; + + if(pwszStr) { + delete[] (pwszStr); + (pwszStr) = 0; + } + + + } while (0); + return ret; +} + +std::string CCUnicodeToUtf8(const wchar_t* pwszStr) +{ + std::string ret; + do + { + if(! pwszStr) break; + size_t len = wcslen(pwszStr); + if (len <= 0) break; + + char * pszUtf8Str = new char[len*3 + 1]; + WideCharToMultiByte(CP_UTF8, 0, pwszStr, len+1, pszUtf8Str, len*3 + 1, 0, 0); + ret = pszUtf8Str; + + if(pszUtf8Str) { + delete[] (pszUtf8Str); + (pszUtf8Str) = 0; + } + }while(0); + + return ret; +} + void Audio::PreloadSoundEffect(const char* pszFilePath, bool isMusic) { - if (m_engineExperiencedCriticalError) { return; } int sound = Hash(pszFilePath); - if (m_soundEffects.end() != m_soundEffects.find(sound)) - { - return; - } - MediaStreamer mediaStreamer; - mediaStreamer.Initialize(CCUtf8ToUnicode(pszFilePath, -1).c_str()); + mediaStreamer.Initialize(CCUtf8ToUnicode(pszFilePath).c_str()); m_soundEffects[sound].m_soundID = sound; uint32 bufferLength = mediaStreamer.GetMaxStreamLengthInBytes(); - - if (m_soundEffects.find(sound) != m_soundEffects.end()) - { - if (m_soundEffects[sound].m_soundEffectBufferData) - { - delete[] m_soundEffects[sound].m_soundEffectBufferData; - m_soundEffects[sound].m_soundEffectBufferData = NULL; - } - } - else - { - m_soundEffects[sound].m_soundEffectBufferData = NULL; - } - m_soundEffects[sound].m_soundEffectBufferData = new byte[bufferLength]; mediaStreamer.ReadAll(m_soundEffects[sound].m_soundEffectBufferData, bufferLength, &m_soundEffects[sound].m_soundEffectBufferLength); @@ -549,6 +579,8 @@ void Audio::UnloadSoundEffect(const char* pszFilePath) int sound = Hash(pszFilePath); UnloadSoundEffect(sound); + + RemoveFromList(sound); } void Audio::UnloadSoundEffect(unsigned int sound) @@ -562,15 +594,18 @@ void Audio::UnloadSoundEffect(unsigned int sound) m_soundEffects[sound].m_soundEffectSourceVoice->DestroyVoice(); - if (m_soundEffects[sound].m_soundEffectBufferData) - { - delete[] m_soundEffects[sound].m_soundEffectBufferData; - m_soundEffects[sound].m_soundEffectBufferData = NULL; - } + if(m_soundEffects[sound].m_soundEffectBufferData) + delete [] m_soundEffects[sound].m_soundEffectBufferData; + m_soundEffects[sound].m_soundEffectBufferData = nullptr; m_soundEffects[sound].m_soundEffectSourceVoice = nullptr; - m_soundEffects[sound].m_soundEffectStarted = false;// - ZeroMemory(&m_soundEffects[sound].m_audioBuffer, sizeof(m_soundEffects[sound].m_audioBuffer)); + m_soundEffects[sound].m_soundEffectStarted = false; + ZeroMemory(&m_soundEffects[sound].m_audioBuffer, sizeof(m_soundEffects[sound].m_audioBuffer)); +} +void Audio::RemoveFromList( unsigned int sound ) +{ m_soundEffects.erase(sound); } + + diff --git a/cocos/audio/winrt/Audio.h b/cocos/audio/winrt/Audio.h index ae58dc7402..a00b9a2ef7 100644 --- a/cocos/audio/winrt/Audio.h +++ b/cocos/audio/winrt/Audio.h @@ -5,14 +5,25 @@ //// //// Copyright (c) Microsoft Corporation. All rights reserved +// For licensing information relating to this distribution please see Third Party Notices file. + #pragma once -#include "pch.h" +#include +#include +#include +#include +#include + +#define XAUDIO2_HELPER_FUNCTIONS 1 +#include #include static const int STREAMING_BUFFER_SIZE = 65536; static const int MAX_BUFFER_COUNT = 3; +#define UNUSED_PARAM(unusedparam) (void)unusedparam + struct SoundEffectData { unsigned int m_soundID; @@ -85,10 +96,11 @@ private: StreamingVoiceContext m_voiceContext; typedef std::map EffectList; - EffectList m_soundEffects; + typedef std::pair Effect; + EffectList m_soundEffects; - unsigned int m_backgroundID; - std::string m_backgroundFile; + unsigned int m_backgroundID; + std::string m_backgroundFile; bool m_backgroundLoop; float m_soundEffctVolume; @@ -144,9 +156,12 @@ public: void PauseAllSoundEffects(); void ResumeAllSoundEffects(); - void StopAllSoundEffects(); + void StopAllSoundEffects(bool bReleaseData); void PreloadSoundEffect(const char* pszFilePath, bool isMusic = false); void UnloadSoundEffect(const char* pszFilePath); void UnloadSoundEffect(unsigned int sound); + +private: + void RemoveFromList(unsigned int sound); }; diff --git a/cocos/audio/winrt/MediaStreamer.cpp b/cocos/audio/winrt/MediaStreamer.cpp index f6f985bf5b..fc6287cd04 100644 --- a/cocos/audio/winrt/MediaStreamer.cpp +++ b/cocos/audio/winrt/MediaStreamer.cpp @@ -1,49 +1,126 @@ -//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF -//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO -//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A -//// PARTICULAR PURPOSE. -//// -//// Copyright (c) Microsoft Corporation. All rights reserved +/* +* cocos2d-x http://www.cocos2d-x.org +* +* Copyright (c) 2010-2011 - cocos2d-x community +* +* Portions Copyright (c) Microsoft Open Technologies, Inc. +* All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and limitations under the License. +*/ -#include "pch.h" #include "MediaStreamer.h" -using namespace Windows::ApplicationModel; +#include +#include +#include -static inline void ThrowIfFailed(HRESULT hr) +#include +#include + +using namespace Microsoft::WRL; +using namespace Windows::Storage; +using namespace Windows::Storage::FileProperties; +using namespace Windows::Storage::Streams; +using namespace Windows::Foundation; +using namespace Windows::ApplicationModel; +using namespace Concurrency; + +#ifndef MAKEFOURCC + #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((uint32)(byte)(ch0) | ((uint32)(byte)(ch1) << 8) | \ + ((uint32)(byte)(ch2) << 16) | ((uint32)(byte)(ch3) << 24 )) +#endif /* defined(MAKEFOURCC) */ + +inline void ThrowIfFailed(HRESULT hr) { if (FAILED(hr)) { - // Set a breakpoint on this line to catch DirectX API errors + // Set a breakpoint on this line to catch DX API errors. throw Platform::Exception::CreateException(hr); } } - -MediaStreamer::MediaStreamer() +MediaStreamer::MediaStreamer() : + m_offset(0) { - m_reader = nullptr; - m_audioType = nullptr; ZeroMemory(&m_waveFormat, sizeof(m_waveFormat)); - - m_installedLocation = Package::Current->InstalledLocation; - m_installedLocationPath = Platform::String::Concat(m_installedLocation->Path, "\\Assets\\Resources\\"); + m_location = Package::Current->InstalledLocation; + m_locationPath = Platform::String::Concat(m_location->Path, "\\Assets\\Resources\\"); } MediaStreamer::~MediaStreamer() { } +Platform::Array^ MediaStreamer::ReadData( + _In_ Platform::String^ filename + ) +{ + CREATEFILE2_EXTENDED_PARAMETERS extendedParams = {0}; + extendedParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); + extendedParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; + extendedParams.dwFileFlags = FILE_FLAG_SEQUENTIAL_SCAN; + extendedParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; + extendedParams.lpSecurityAttributes = nullptr; + extendedParams.hTemplateFile = nullptr; + + Wrappers::FileHandle file( + CreateFile2( + filename->Data(), + GENERIC_READ, + FILE_SHARE_READ, + OPEN_EXISTING, + &extendedParams + ) + ); + if (file.Get()==INVALID_HANDLE_VALUE) + { + throw ref new Platform::FailureException(); + } + + FILE_STANDARD_INFO fileInfo = {0}; + if (!GetFileInformationByHandleEx( + file.Get(), + FileStandardInfo, + &fileInfo, + sizeof(fileInfo) + )) + { + throw ref new Platform::FailureException(); + } + + if (fileInfo.EndOfFile.HighPart != 0) + { + throw ref new Platform::OutOfMemoryException(); + } + + Platform::Array^ fileData = ref new Platform::Array(fileInfo.EndOfFile.LowPart); + + if (!ReadFile( + file.Get(), + fileData->Data, + fileData->Length, + nullptr, + nullptr + ) ) + { + throw ref new Platform::FailureException(); + } + + return fileData; +} void MediaStreamer::Initialize(__in const WCHAR* url) { - Microsoft::WRL::ComPtr outputMediaType; - Microsoft::WRL::ComPtr mediaType; - - ThrowIfFailed( - MFStartup(MF_VERSION) - ); - WCHAR filePath[MAX_PATH] = {0}; + WCHAR filePath[MAX_PATH] = {0}; if ((wcslen(url) > 1 && url[1] == ':')) { // path start with "x:", is absolute path @@ -53,163 +130,92 @@ void MediaStreamer::Initialize(__in const WCHAR* url) && (L'/' == url[0] || L'\\' == url[0])) { // path start with '/' or '\', is absolute path without driver name - wcscat_s(filePath, m_installedLocationPath->Data()); + wcscat_s(filePath, m_locationPath->Data()); // remove '/' or '\\' wcscat_s(filePath, (const WCHAR*)url[1]); }else { - wcscat_s(filePath, m_installedLocationPath->Data()); + wcscat_s(filePath, m_locationPath->Data()); wcscat_s(filePath, url); } - ThrowIfFailed( - MFCreateSourceReaderFromURL(filePath, nullptr, &m_reader) - ); - // Set the decoded output format as PCM - // XAudio2 on Windows can process PCM and ADPCM-encoded buffers. - // When using MF, this sample always decodes into PCM. + Platform::Array^ data = ReadData(ref new Platform::String(filePath)); + UINT32 length = data->Length; + const byte * dataPtr = data->Data; + UINT32 offset = 0; - ThrowIfFailed( - MFCreateMediaType(&mediaType) - ); + DWORD riffDataSize = 0; - ThrowIfFailed( - mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio) - ); + auto ReadChunk = [&length, &offset, &dataPtr, &riffDataSize](DWORD fourcc, DWORD& outChunkSize, DWORD& outChunkPos) -> HRESULT + { + while (true) + { + if (offset + sizeof(DWORD) * 2 >= length) + { + return E_FAIL; + } - ThrowIfFailed( - mediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM) - ); + // Read two DWORDs. + DWORD chunkType = *reinterpret_cast(&dataPtr[offset]); + DWORD chunkSize = *reinterpret_cast(&dataPtr[offset + sizeof(DWORD)]); + offset += sizeof(DWORD) * 2; - ThrowIfFailed( - m_reader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, mediaType.Get()) - ); + if (chunkType == MAKEFOURCC('R', 'I', 'F', 'F')) + { + riffDataSize = chunkSize; + chunkSize = sizeof(DWORD); + outChunkSize = sizeof(DWORD); + outChunkPos = offset; + } + else + { + outChunkSize = chunkSize; + outChunkPos = offset; + } - // Get the complete WAVEFORMAT from the Media Type - ThrowIfFailed( - m_reader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, &outputMediaType) - ); + offset += chunkSize; - uint32 formatSize = 0; - WAVEFORMATEX* waveFormat; - ThrowIfFailed( - MFCreateWaveFormatExFromMFMediaType(outputMediaType.Get(), &waveFormat, &formatSize) - ); - CopyMemory(&m_waveFormat, waveFormat, sizeof(m_waveFormat)); - CoTaskMemFree(waveFormat); + if (chunkType == fourcc) + { + return S_OK; + } + } + }; - // Get the total length of the stream in bytes - PROPVARIANT var; - ThrowIfFailed( - m_reader->GetPresentationAttribute(MF_SOURCE_READER_MEDIASOURCE, MF_PD_DURATION, &var) - ); - LONGLONG duration = var.uhVal.QuadPart; - double durationInSeconds = (duration / static_cast(10000000)); // duration is in 100ns units, convert to seconds - m_maxStreamLengthInBytes = static_cast(durationInSeconds * m_waveFormat.nAvgBytesPerSec); + // Locate riff chunk, check the file type. + DWORD chunkSize = 0; + DWORD chunkPos = 0; - // Round up the buffer size to the nearest four bytes - m_maxStreamLengthInBytes = (m_maxStreamLengthInBytes + 3) / 4 * 4; -} + ThrowIfFailed(ReadChunk(MAKEFOURCC('R', 'I', 'F', 'F'), chunkSize, chunkPos)); + if (*reinterpret_cast(&dataPtr[chunkPos]) != MAKEFOURCC('W', 'A', 'V', 'E')) ThrowIfFailed(E_FAIL); -bool MediaStreamer::GetNextBuffer(uint8* buffer, uint32 maxBufferSize, uint32* bufferLength) -{ - Microsoft::WRL::ComPtr sample; - Microsoft::WRL::ComPtr mediaBuffer; - BYTE *audioData = nullptr; - DWORD sampleBufferLength = 0; - DWORD flags = 0; + // Locate 'fmt ' chunk, copy to WAVEFORMATEXTENSIBLE. + ThrowIfFailed(ReadChunk(MAKEFOURCC('f', 'm', 't', ' '), chunkSize, chunkPos)); + ThrowIfFailed((chunkSize <= sizeof(m_waveFormat)) ? S_OK : E_FAIL); + CopyMemory(&m_waveFormat, &dataPtr[chunkPos], chunkSize); - *bufferLength = 0; + // Locate the 'data' chunk and copy its contents to a buffer. + ThrowIfFailed(ReadChunk(MAKEFOURCC('d', 'a', 't', 'a'), chunkSize, chunkPos)); + m_data.resize(chunkSize); + CopyMemory(m_data.data(), &dataPtr[chunkPos], chunkSize); - if (m_reader == nullptr) - { - return false; - } - - ThrowIfFailed( - m_reader->ReadSample(MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, nullptr, &flags, nullptr, &sample) - ); - - if (sample == nullptr) - { - if (flags & MF_SOURCE_READERF_ENDOFSTREAM) - { - return true; - } - else - { - return false; - } - } - - ThrowIfFailed( - sample->ConvertToContiguousBuffer(&mediaBuffer) - ); - - ThrowIfFailed( - mediaBuffer->Lock(&audioData, nullptr, &sampleBufferLength) - ); - - // If buffer isn't large enough, dump sample - if (sampleBufferLength <= maxBufferSize) - { - CopyMemory(buffer, audioData, sampleBufferLength); - *bufferLength = sampleBufferLength; - } - else - { -#if defined(COCOS2D_DEBUG) - OutputDebugString(L"Sample buffer dumped"); -#endif - } - - if (flags & MF_SOURCE_READERF_ENDOFSTREAM) - { - return true; - } - else - { - return false; - } + m_offset = 0; } void MediaStreamer::ReadAll(uint8* buffer, uint32 maxBufferSize, uint32* bufferLength) { - uint32 valuesWritten = 0; - uint32 sampleBufferLength = 0; + UINT32 toCopy = m_data.size() - m_offset; + if (toCopy > maxBufferSize) toCopy = maxBufferSize; - if (m_reader == nullptr) - { - return; - } + CopyMemory(buffer, m_data.data(), toCopy); + *bufferLength = toCopy; - *bufferLength = 0; - // If buffer isn't large enough, return - if (maxBufferSize < m_maxStreamLengthInBytes) - { - return; - } - - while (!GetNextBuffer(buffer + valuesWritten, maxBufferSize - valuesWritten, &sampleBufferLength)) - { - valuesWritten += sampleBufferLength; - } - - *bufferLength = valuesWritten + sampleBufferLength; + m_offset += toCopy; + if (m_offset > m_data.size()) m_offset = m_data.size(); } void MediaStreamer::Restart() { - if (m_reader == nullptr) - { - return; - } - - PROPVARIANT var = {0}; - var.vt = VT_I8; - - ThrowIfFailed( - m_reader->SetCurrentPosition(GUID_NULL, var) - ); + m_offset = 0; } diff --git a/cocos/audio/winrt/MediaStreamer.h b/cocos/audio/winrt/MediaStreamer.h index cafbfe0993..e72ac5974a 100644 --- a/cocos/audio/winrt/MediaStreamer.h +++ b/cocos/audio/winrt/MediaStreamer.h @@ -1,28 +1,46 @@ -//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF -//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO -//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A -//// PARTICULAR PURPOSE. -//// -//// Copyright (c) Microsoft Corporation. All rights reserved +/* +* cocos2d-x http://www.cocos2d-x.org +* +* Copyright (c) 2010-2011 - cocos2d-x community +* +* Portions Copyright (c) Microsoft Open Technologies, Inc. +* All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and limitations under the License. +*/ #pragma once -#include "pch.h" -class MediaStreamer +#include +#include +#include + +ref class MediaStreamer { private: - WAVEFORMATEX m_waveFormat; - uint32 m_maxStreamLengthInBytes; - Windows::Storage::StorageFolder^ m_installedLocation; - Platform::String^ m_installedLocationPath; + WAVEFORMATEX m_waveFormat; + uint32 m_maxStreamLengthInBytes; + std::vector m_data; + UINT32 m_offset; + Platform::Array^ ReadData( + _In_ Platform::String^ filename + ); +internal: + Windows::Storage::StorageFolder^ m_location; + Platform::String^ m_locationPath; public: - Microsoft::WRL::ComPtr m_reader; - Microsoft::WRL::ComPtr m_audioType; + virtual ~MediaStreamer(); -public: +internal: MediaStreamer(); - ~MediaStreamer(); WAVEFORMATEX& GetOutputWaveFormatEx() { @@ -31,11 +49,10 @@ public: UINT32 GetMaxStreamLengthInBytes() { - return m_maxStreamLengthInBytes; + return m_data.size(); } void Initialize(_In_ const WCHAR* url); - bool GetNextBuffer(uint8* buffer, uint32 maxBufferSize, uint32* bufferLength); void ReadAll(uint8* buffer, uint32 maxBufferSize, uint32* bufferLength); void Restart(); }; diff --git a/cocos/audio/winrt/SimpleAudioEngine.cpp b/cocos/audio/winrt/SimpleAudioEngine.cpp index 510cd6434c..6a9b17354b 100644 --- a/cocos/audio/winrt/SimpleAudioEngine.cpp +++ b/cocos/audio/winrt/SimpleAudioEngine.cpp @@ -1,52 +1,51 @@ -/**************************************************************************** -Copyright (c) 2010-2013 cocos2d-x.org -Copyright (c) Microsoft Open Technologies, Inc. +/* +* cocos2d-x http://www.cocos2d-x.org +* +* Copyright (c) 2010-2011 - cocos2d-x community +* +* Portions Copyright (c) Microsoft Open Technologies, Inc. +* All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and limitations under the License. +*/ -http://www.cocos2d-x.org - -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 "SimpleAudioEngine.h" #include "Audio.h" #include - //#include "CCCommon.h" using namespace std; namespace CocosDenshion { - - Audio* s_audioController = NULL; -// a flag that if the s_audioController should be re-initialiezed -// see also in SimpleAudioEngine::end() in this file -bool s_bAudioControllerNeedReInitialize = true; +bool s_initialized = false; + +SimpleAudioEngine* SimpleAudioEngine::getInstance() +{ + static SimpleAudioEngine s_SharedEngine; + return &s_SharedEngine; +} + static Audio* sharedAudioController() { - if ((! s_audioController) || s_bAudioControllerNeedReInitialize) + if (! s_audioController || !s_initialized) { - s_audioController = new Audio; + if(s_audioController == NULL) + { + s_audioController = new Audio; + } s_audioController->Initialize(); s_audioController->CreateResources(); - s_bAudioControllerNeedReInitialize = false; + s_initialized = true; } return s_audioController; @@ -60,29 +59,16 @@ SimpleAudioEngine::~SimpleAudioEngine() { } -SimpleAudioEngine* SimpleAudioEngine::sharedEngine() -{ - static SimpleAudioEngine s_SharedEngine; - return &s_SharedEngine; -} void SimpleAudioEngine::end() { sharedAudioController()->StopBackgroundMusic(true); - sharedAudioController()->StopAllSoundEffects(); + sharedAudioController()->StopAllSoundEffects(true); sharedAudioController()->ReleaseResources(); - //set here to tell the s_bAudioControllerNeedReInitialize should be re-initialized - s_bAudioControllerNeedReInitialize = true; + s_initialized = false; } -#if 0 -void SimpleAudioEngine::render() -{ - sharedAudioController()->Render(); -} -#endif - ////////////////////////////////////////////////////////////////////////// // BackgroundMusic @@ -132,11 +118,11 @@ bool SimpleAudioEngine::isBackgroundMusicPlaying() // effect function ////////////////////////////////////////////////////////////////////////// -unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath, bool bLoop) +unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath, bool bLoop,float pitch, float pan, float gain) { unsigned int sound; sharedAudioController()->PlaySoundEffect(pszFilePath, bLoop, sound); - + // TODO: need to support playEffect parameters return sound; } @@ -172,12 +158,12 @@ void SimpleAudioEngine::resumeAllEffects() void SimpleAudioEngine::stopAllEffects() { - sharedAudioController()->StopAllSoundEffects(); + sharedAudioController()->StopAllSoundEffects(false); } void SimpleAudioEngine::preloadBackgroundMusic(const char* pszFilePath) { - + UNUSED_PARAM(pszFilePath); } void SimpleAudioEngine::unloadEffect(const char* pszFilePath)