updated for Windows 8.1

This commit is contained in:
Dale Stammen 2014-10-14 14:13:14 -07:00
parent ec5af7ae90
commit 52fc6d618b
5 changed files with 362 additions and 303 deletions

View File

@ -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);
}

View File

@ -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 <wrl.h>
#include <d3d11_1.h>
#include <agile.h>
#include <DirectXMath.h>
#include <memory>
#define XAUDIO2_HELPER_FUNCTIONS 1
#include <xaudio2.h>
#include <map>
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<unsigned int, SoundEffectData> EffectList;
EffectList m_soundEffects;
typedef std::pair<unsigned int, SoundEffectData> 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);
};

View File

@ -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 <Mfidl.h>
#include <Mfreadwrite.h>
#include <Mfapi.h>
static inline void ThrowIfFailed(HRESULT hr)
#include <wrl\wrappers\corewrappers.h>
#include <ppltasks.h>
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<byte>^ 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<byte>^ fileData = ref new Platform::Array<byte>(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<IMFMediaType> outputMediaType;
Microsoft::WRL::ComPtr<IMFMediaType> 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<byte>^ 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<const DWORD *>(&dataPtr[offset]);
DWORD chunkSize = *reinterpret_cast<const DWORD *>(&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<double>(10000000)); // duration is in 100ns units, convert to seconds
m_maxStreamLengthInBytes = static_cast<unsigned int>(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<const DWORD *>(&dataPtr[chunkPos]) != MAKEFOURCC('W', 'A', 'V', 'E')) ThrowIfFailed(E_FAIL);
bool MediaStreamer::GetNextBuffer(uint8* buffer, uint32 maxBufferSize, uint32* bufferLength)
{
Microsoft::WRL::ComPtr<IMFSample> sample;
Microsoft::WRL::ComPtr<IMFMediaBuffer> 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;
}

View File

@ -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 <wrl.h>
#include <xaudio2.h>
#include <vector>
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<byte> m_data;
UINT32 m_offset;
Platform::Array<byte>^ ReadData(
_In_ Platform::String^ filename
);
internal:
Windows::Storage::StorageFolder^ m_location;
Platform::String^ m_locationPath;
public:
Microsoft::WRL::ComPtr<IMFSourceReader> m_reader;
Microsoft::WRL::ComPtr<IMFMediaType> 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();
};

View File

@ -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 <map>
//#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)