audio system rewrite, added 3D audio support

This commit is contained in:
turanszkij
2019-10-05 18:19:13 +01:00
parent 4503fffe30
commit 40700a2de1
27 changed files with 1169 additions and 778 deletions
+44 -17
View File
@@ -16,9 +16,7 @@ The documentation completion is still pending....
3. MovingTexAnim
4. DrawRecAnim
3. Texture
4. Sound
1. SoundEffect
2. Music
4. Audio
5. Vector
6. Matrix
7. Scene System (using entity-component system)
@@ -280,21 +278,50 @@ Animate sprite frame by frame.
Just holds texture information in VRAM.
- [void-constructor]Texture()
### Sound
Load a Sound file, either sound effect or music.
- [outer]SoundVolume(opt float volume)
- [outer]MusicVolume(opt float volume)
- [void-constructor]Sound()
- Play(opt int delay)
- Stop()
### Audio
Loads and plays an audio files.
- [outer]audio -- the audio device
- CreateSound(string filename, Sound sound) : bool -- Creates a sound file, returns true if successful, false otherwise
- CreateSoundInstance(Sound sound, SoundInstance soundinstance) : bool -- Creates a sound instance that can be replayed, returns true if successful, false otherwise
- Destroy(Sound sound)
- Destroy(SoundInsance soundinstance)
- Play(SoundInsance soundinstance)
- Pause(SoundInsance soundinstance)
- Stop(SoundInsance soundinstance)
- GetVolume(opt SoundInsance soundinstance) : float -- returns the volume of a soundinstance. If soundinstance is not provided, returns the master volume
- SetVolume(float volume, opt SoundInsance soundinstance) -- sets the volume of a soundinstance. If soundinstance is not provided, sets the master volume
- GetSubmixVolume(int submixtype) : float -- returns the volume of the submix group
- SetSubmixVolume(int submixtype, float volume) -- sets the volume for a submix group
- Update3D(SoundInstance soundinstance, SoundInstance3D instance3D) -- adds 3D effect to the sound instance
#### SoundEffect
Sound Effects are for playing a sound file once. Inherits the methods from Sound.
- [constructor]SoundEffect(string soundFile)
#### Sound
An audio file. Can be instanced several times via SoundInstance.
- [constructor]Sound() -- creates an empty sound. Use the audio device to load sounds from files
#### Music
Music is for playing sound files in the background, along with sound effects. Inherits the methods from Sound.
- [constructor]Music(string soundFile)
#### SoundInstance
An audio file instance that can be played.
- [constructor]SoundInstance() -- creates an empty soundinstance. Use the audio device to clone sounds
- SetSubmixType(int submixtype) -- set a submix type group (default is SUBMIX_TYPE_SOUNDEFFECT)
#### SoundInstance3D
Describes the relation between a sound instance and a listener in a 3D world
- [constructor]SoundInstance3D() -- creates the 3D relation object. By default, the listener and emitter are on the same position, and that disables the 3D effect
- SetListenerPos(Vector value)
- SetListenerUp(Vector value)
- SetListenerFront(Vector value)
- SetListenerVelocity(Vector value)
- SetEmitterPos(Vector value)
- SetEmitterUp(Vector value)
- SetEmitterFront(Vector value)
- SetEmitterVelocity(Vector value)
- SetEmitterRadius(float radius)
#### Submix Types
The submix types group sound instances together to be controlled together
- [outer]SUBMIX_TYPE_SOUNDEFFECT : int -- sound effect group
- [outer]SUBMIX_TYPE_MUSIC : int -- music group
- [outer]SUBMIX_TYPE_USER0 : int -- user submix group
- [outer]SUBMIX_TYPE_USER1 : int -- user submix group
### Vector
A four component floating point vector. Provides efficient calculations with SIMD support.
@@ -704,7 +731,7 @@ Describes a touch contact point
- [outer]GAMEPAD_ANALOG_TRIGGER_R : int
### ResourceManager
Stores and manages resources such as textures, sounds and shaders.
Stores and manages resources such as textures, audio and shaders.
- [outer]globalResources : Resource
- [void-constructor]Resource()
- Get(string name)
@@ -98,6 +98,15 @@ The following quick reference shows an overview of common resource formats and s
![InformationSheet](information_sheet.png)
## Audio
The audio system handles audio playback and spatial audio.
- wiAudio
- The namespace that is a collection of audio related functionality
- Sound
- Represents a sound file in memory. Load a sound file via wiAudio interface.
- SoundInstance
- An instance of a sound file that can be played and controlled in various ways through the wiAudio interface.
## Helpers
A collection of engine-level helper classes
+14 -9
View File
@@ -115,13 +115,13 @@ main.ActivatePath(&myMenuScreen); // activate the menu, the previous path (myGam
wiSprite mySprite("image.png"); // There are many utilities, such as a "sprite" helper class
myMenuScreen.addSprite(&mySprite); // The 2D render path is ready to handle sprite and font rendering for you
wiSoundEffect soundEffect("explosion.wav"); // you can load sound effects, or music
soundEffect.Play(); // you can play sounds
soundEffect.Stop(); // you can stop sounds
wiMusic myMusic("music.wav"); // music is the same as sound effects, but they can be controlled independently
myMusic.Play(); // plays a music
wiMusic::SetVolume(0.5f); // set volume for every music, but don't modify sound effect volume
wiAudio::Sound mySound;
wiAudio::CreateSound("explosion.wav", &mySound); // Loads a sound file
wiAudio::SoundInstance mySoundInstance;
wiAudio::CreateSoundInstance(&mySound, &mySoundInstance); // Instances the sound file, it can be played now
wiAudio::Play(&mySoundInstance); // Play the sound instance
wiAudio::SetVolume(0.6, &mySoundInstance); // Set the volume of this soundinstance
wiAudio::SetVolume(0.2); // Set the master volume
if (wiInputManager::press(VK_SPACE)) { soundEffect.Stop(); } // You can check if a button is pressed or not (this only triggers once)
if (wiInputManager::down(VK_SPACE)) { soundEffect.Play(); } // You can check if a button is pushed down or not (this triggers repeatedly)
@@ -159,8 +159,13 @@ getprops(scene); -- prints the Scene class methods
getprops(path); -- prints the deferred render path methods
-- Play a sound:
sound = SoundEffect("whoosh.wav");
sound.Play();
sound = Sound()
audio.CreateSound("explosion.wav", sound)
soundinstance = SoundInstance()
audio.CreateSoundInstance(sound, soundinstance) -- several instances can be created from one file
audio.Play(soundinstance)
audio.SetVolume(0.6, soundinstance) -- sets the volume of this soundinstance
audio.SetVolume(0.2) -- sets the master volume
-- Check for input:
if(input.press(VK_LEFT)) then
+13 -4
View File
@@ -40,6 +40,8 @@ TestsRenderer::TestsRenderer()
label->SetPos(XMFLOAT2(screenW / 2.f - label->scale.x / 2.f, screenH*0.95f));
GetGUI().AddWidget(label);
static wiAudio::Sound* sound = nullptr;
static wiAudio::SoundInstance* soundinstance = nullptr;
wiButton* audioTest = new wiButton("AudioTest");
audioTest->SetText("Play Test Audio");
@@ -48,17 +50,24 @@ TestsRenderer::TestsRenderer()
audioTest->SetColor(wiColor(255, 205, 43, 200), wiWidget::WIDGETSTATE::IDLE);
audioTest->SetColor(wiColor(255, 235, 173, 255), wiWidget::WIDGETSTATE::FOCUS);
audioTest->OnClick([=](wiEventArgs args) {
static wiMusic music("sound/music.wav");
static bool playing = false;
if (sound == nullptr)
{
sound = new wiAudio::Sound;
wiAudio::CreateSound("sound/music.wav", sound);
soundinstance = new wiAudio::SoundInstance;
wiAudio::CreateSoundInstance(sound, soundinstance);
}
if (playing)
{
music.Stop();
wiAudio::Stop(soundinstance);
audioTest->SetText("Play Test Audio");
}
else
{
music.Play();
wiAudio::Play(soundinstance);
audioTest->SetText("Stop Test Audio");
}
@@ -74,7 +83,7 @@ TestsRenderer::TestsRenderer()
volume->SetColor(wiColor(255, 205, 43, 200), wiWidget::WIDGETSTATE::IDLE);
volume->SetColor(wiColor(255, 235, 173, 255), wiWidget::WIDGETSTATE::FOCUS);
volume->OnSlide([](wiEventArgs args) {
wiMusic::SetVolume(args.fValue / 100.0f);
wiAudio::SetVolume(args.fValue / 100.0f, soundinstance);
});
GetGUI().AddWidget(volume);
+3
View File
@@ -38,5 +38,8 @@ using namespace DirectX::PackedVector;
static const XMFLOAT4X4 IDENTITYMATRIX = XMFLOAT4X4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
typedef uint64_t wiCPUHandle;
static const wiCPUHandle WI_NULL_HANDLE = 0;
#endif //WICKEDENGINE_COMMONINCLUDE_H
+1 -1
View File
@@ -35,7 +35,7 @@
#include "wiXInput.h"
#include "wiRawInput.h"
#include "wiMath.h"
#include "wiSound.h"
#include "wiAudio.h"
#include "wiResourceManager.h"
#include "wiTimer.h"
#include "wiHelper.h"
+4 -4
View File
@@ -259,6 +259,8 @@
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\stb_truetype.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiAllocators.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiArchive.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiAudio.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiAudio_BindLua.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiContainers.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiECS.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiFFTGenerator.h" />
@@ -357,8 +359,6 @@
<ClInclude Include="$(MSBuildThisFileDirectory)wiSceneSystem.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiSceneSystem_Decl.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiServer.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiSound.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiSound_BindLua.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiSpinLock.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiSprite.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiSprite_BindLua.h" />
@@ -522,6 +522,8 @@
<ClCompile Include="$(MSBuildThisFileDirectory)RenderPath3D_TiledForward_BindLua.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)Utility\utility_common.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiArchive.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiAudio.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiAudio_BindLua.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiFFTGenerator.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiGPUBVH.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiGPUSortLib.cpp" />
@@ -687,8 +689,6 @@
<ClCompile Include="$(MSBuildThisFileDirectory)wiSceneSystem.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiSceneSystem_Serializers.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiServer.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiSound.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiSound_BindLua.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiSprite.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiSprite_BindLua.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiStartupArguments.cpp" />
@@ -201,9 +201,6 @@
<ClInclude Include="$(MSBuildThisFileDirectory)wiResourceManager_BindLua.h">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)wiSound_BindLua.h">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)wiSprite_BindLua.h">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClInclude>
@@ -900,9 +897,6 @@
<ClInclude Include="$(MSBuildThisFileDirectory)wiServer.h">
<Filter>ENGINE\Network</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)wiSound.h">
<Filter>ENGINE\Audio</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)wiCube.h">
<Filter>ENGINE\Graphics</Filter>
</ClInclude>
@@ -1134,6 +1128,12 @@
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_Postprocess.h">
<Filter>ENGINE\Graphics\GPUMapping</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)wiAudio.h">
<Filter>ENGINE\Audio</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)wiAudio_BindLua.h">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(MSBuildThisFileDirectory)LUA\lapi.c">
@@ -1280,9 +1280,6 @@
<ClCompile Include="$(MSBuildThisFileDirectory)wiResourceManager_BindLua.cpp">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)wiSound_BindLua.cpp">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)wiSprite_BindLua.cpp">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClCompile>
@@ -1751,9 +1748,6 @@
<ClCompile Include="$(MSBuildThisFileDirectory)wiServer.cpp">
<Filter>ENGINE\Network</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)wiSound.cpp">
<Filter>ENGINE\Audio</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)wiCube.cpp">
<Filter>ENGINE\Graphics</Filter>
</ClCompile>
@@ -1907,6 +1901,12 @@
<ClCompile Include="$(MSBuildThisFileDirectory)wiIntersect_BindLua.cpp">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)wiAudio.cpp">
<Filter>ENGINE\Audio</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)wiAudio_BindLua.cpp">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Image Include="$(MSBuildThisFileDirectory)fonts\default_font.dds">
+424
View File
@@ -0,0 +1,424 @@
#include "wiAudio.h"
#include "wiBackLog.h"
#include "wiHelper.h"
#include <vector>
#include <xaudio2.h>
#include <x3daudio.h>
#pragma comment(lib,"xaudio2.lib")
#ifdef _XBOX //Big-Endian
#define fourccRIFF 'RIFF'
#define fourccDATA 'data'
#define fourccFMT 'fmt '
#define fourccWAVE 'WAVE'
#define fourccXWMA 'XWMA'
#define fourccDPDS 'dpds'
#endif
#ifndef _XBOX //Little-Endian
#define fourccRIFF 'FFIR'
#define fourccDATA 'atad'
#define fourccFMT ' tmf'
#define fourccWAVE 'EVAW'
#define fourccXWMA 'AMWX'
#define fourccDPDS 'sdpd'
#endif
namespace wiAudio
{
IXAudio2* audioEngine = nullptr;
IXAudio2MasteringVoice* masteringVoice = nullptr;
XAUDIO2_VOICE_DETAILS masteringVoiceDetails = {};
X3DAUDIO_HANDLE audio3D = {};
IXAudio2SubmixVoice* submixVoices[SUBMIX_TYPE_COUNT] = {};
Sound::~Sound()
{
Destroy(this);
}
SoundInstance::~SoundInstance()
{
Destroy(this);
}
struct SoundInternal
{
WAVEFORMATEX wfx = {};
XAUDIO2_BUFFER buffer = {};
};
struct SoundInstanceInternal
{
IXAudio2SourceVoice* sourceVoice = nullptr;
XAUDIO2_VOICE_DETAILS voiceDetails = {};
std::vector<float> outputMatrix;
const SoundInternal* soundinternal = nullptr;
};
void Initialize()
{
HRESULT hr;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
assert(SUCCEEDED(hr));
hr = XAudio2Create(&audioEngine, 0, XAUDIO2_DEFAULT_PROCESSOR);
assert(SUCCEEDED(hr));
#ifdef _DEBUG
XAUDIO2_DEBUG_CONFIGURATION debugConfig = {};
debugConfig.TraceMask = XAUDIO2_LOG_ERRORS | XAUDIO2_LOG_WARNINGS;
debugConfig.BreakMask = XAUDIO2_LOG_ERRORS | XAUDIO2_LOG_WARNINGS;
audioEngine->SetDebugConfiguration(&debugConfig);
#endif // _DEBUG
hr = audioEngine->CreateMasteringVoice(&masteringVoice);
assert(SUCCEEDED(hr));
masteringVoice->GetVoiceDetails(&masteringVoiceDetails);
DWORD channelMask;
masteringVoice->GetChannelMask(&channelMask);
hr = X3DAudioInitialize(channelMask, X3DAUDIO_SPEED_OF_SOUND, audio3D);
assert(SUCCEEDED(hr));
for (int i = 0; i < SUBMIX_TYPE_COUNT; ++i)
{
audioEngine->CreateSubmixVoice(
&submixVoices[i],
masteringVoiceDetails.InputChannels,
masteringVoiceDetails.InputSampleRate,
0, 0, 0, 0);
}
if (SUCCEEDED(hr))
{
wiBackLog::post("wiAudio Initialized");
}
}
void CleanUp()
{
if (masteringVoice != nullptr) masteringVoice->DestroyVoice();
SAFE_DELETE(masteringVoice);
SAFE_RELEASE(audioEngine);
SAFE_DELETE(audioEngine);
}
HRESULT FindChunk(HANDLE hFile, DWORD fourcc, DWORD& dwChunkSize, DWORD& dwChunkDataPosition)
{
HRESULT hr = S_OK;
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hFile, LARGE_INTEGER(), NULL, FILE_BEGIN))
return HRESULT_FROM_WIN32(GetLastError());
DWORD dwChunkType;
DWORD dwChunkDataSize;
DWORD dwRIFFDataSize = 0;
DWORD dwFileType;
DWORD bytesRead = 0;
DWORD dwOffset = 0;
while (hr == S_OK)
{
DWORD dwRead;
if (0 == ReadFile(hFile, &dwChunkType, sizeof(DWORD), &dwRead, NULL))
hr = HRESULT_FROM_WIN32(GetLastError());
if (0 == ReadFile(hFile, &dwChunkDataSize, sizeof(DWORD), &dwRead, NULL))
hr = HRESULT_FROM_WIN32(GetLastError());
switch (dwChunkType)
{
case fourccRIFF:
dwRIFFDataSize = dwChunkDataSize;
dwChunkDataSize = 4;
if (0 == ReadFile(hFile, &dwFileType, sizeof(DWORD), &dwRead, NULL))
hr = HRESULT_FROM_WIN32(GetLastError());
break;
default:
LARGE_INTEGER li = LARGE_INTEGER();
li.QuadPart = dwChunkDataSize;
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hFile, li, NULL, FILE_CURRENT))
return HRESULT_FROM_WIN32(GetLastError());
}
dwOffset += sizeof(DWORD) * 2;
if (dwChunkType == fourcc)
{
dwChunkSize = dwChunkDataSize;
dwChunkDataPosition = dwOffset;
return S_OK;
}
dwOffset += dwChunkDataSize;
if (bytesRead >= dwRIFFDataSize) return S_FALSE;
}
return S_OK;
}
HRESULT ReadChunkData(HANDLE hFile, void* buffer, DWORD buffersize, DWORD bufferoffset)
{
HRESULT hr = S_OK;
LARGE_INTEGER li = LARGE_INTEGER();
li.QuadPart = bufferoffset;
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hFile, li, NULL, FILE_BEGIN))
return HRESULT_FROM_WIN32(GetLastError());
DWORD dwRead;
if (0 == ReadFile(hFile, buffer, buffersize, &dwRead, NULL))
hr = HRESULT_FROM_WIN32(GetLastError());
return hr;
}
HRESULT CreateSound(const std::string& filename, Sound* sound)
{
Destroy(sound);
std::wstring wfilename;
wiHelper::StringConvert(filename, wfilename);
HANDLE hFile = CreateFile2(
wfilename.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
OPEN_EXISTING,
nullptr
);
HRESULT hr;
if (INVALID_HANDLE_VALUE == hFile)
{
hr = HRESULT_FROM_WIN32(GetLastError());
return hr;
}
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hFile, LARGE_INTEGER(), NULL, FILE_BEGIN))
{
hr = HRESULT_FROM_WIN32(GetLastError());
return hr;
}
DWORD dwChunkSize;
DWORD dwChunkPosition;
FindChunk(hFile, fourccRIFF, dwChunkSize, dwChunkPosition);
DWORD filetype;
hr = ReadChunkData(hFile, &filetype, sizeof(DWORD), dwChunkPosition);
assert(SUCCEEDED(hr));
assert(filetype == fourccWAVE);
SoundInternal* soundinternal = new SoundInternal;
hr = FindChunk(hFile, fourccFMT, dwChunkSize, dwChunkPosition);
assert(SUCCEEDED(hr));
hr = ReadChunkData(hFile, &soundinternal->wfx, dwChunkSize, dwChunkPosition);
assert(SUCCEEDED(hr));
soundinternal->wfx.wFormatTag = WAVE_FORMAT_PCM;
hr = FindChunk(hFile, fourccDATA, dwChunkSize, dwChunkPosition);
assert(SUCCEEDED(hr));
BYTE* pDataBuffer = new BYTE[dwChunkSize];
hr = ReadChunkData(hFile, pDataBuffer, dwChunkSize, dwChunkPosition);
assert(SUCCEEDED(hr));
soundinternal->buffer.AudioBytes = dwChunkSize;
soundinternal->buffer.pAudioData = pDataBuffer;
soundinternal->buffer.Flags = XAUDIO2_END_OF_STREAM;
sound->handle = (wiCPUHandle)soundinternal;
return S_OK;
}
HRESULT CreateSoundInstance(const Sound* sound, SoundInstance* instance)
{
Destroy(instance);
HRESULT hr;
const SoundInternal* soundinternal = (const SoundInternal*)sound->handle;
SoundInstanceInternal* instanceinternal = new SoundInstanceInternal;
instanceinternal->soundinternal = soundinternal;
XAUDIO2_SEND_DESCRIPTOR SFXSend = { 0, submixVoices[instance->type] };
XAUDIO2_VOICE_SENDS SFXSendList = { 1, &SFXSend };
hr = audioEngine->CreateSourceVoice(&instanceinternal->sourceVoice, &soundinternal->wfx,
XAUDIO2_VOICE_USEFILTER, XAUDIO2_DEFAULT_FREQ_RATIO, NULL, &SFXSendList, NULL);
if (FAILED(hr))
{
assert(0);
return hr;
}
instanceinternal->sourceVoice->GetVoiceDetails(&instanceinternal->voiceDetails);
instanceinternal->outputMatrix.resize(masteringVoiceDetails.InputChannels);
hr = instanceinternal->sourceVoice->SubmitSourceBuffer(&soundinternal->buffer);
if (FAILED(hr))
{
assert(0);
return hr;
}
instance->handle = (wiCPUHandle)instanceinternal;
return S_OK;
}
void Destroy(Sound* sound)
{
if (sound != nullptr && sound->handle != WI_NULL_HANDLE)
{
SoundInternal* soundinternal = (SoundInternal*)sound->handle;
delete[] soundinternal->buffer.pAudioData;
delete soundinternal;
sound->handle = WI_NULL_HANDLE;
}
}
void Destroy(SoundInstance* instance)
{
if (instance != nullptr && instance->handle != WI_NULL_HANDLE)
{
SoundInstanceInternal* instanceinternal = (SoundInstanceInternal*)instance->handle;
instanceinternal->sourceVoice->Stop();
instanceinternal->sourceVoice->DestroyVoice();
delete instanceinternal;
instance->handle = WI_NULL_HANDLE;
}
}
void Play(SoundInstance* instance)
{
if (instance != nullptr && instance->handle != WI_NULL_HANDLE)
{
SoundInstanceInternal* instanceinternal = (SoundInstanceInternal*)instance->handle;
HRESULT hr = instanceinternal->sourceVoice->Start();
assert(SUCCEEDED(hr));
}
}
void Pause(SoundInstance* instance)
{
if (instance != nullptr && instance->handle != WI_NULL_HANDLE)
{
SoundInstanceInternal* instanceinternal = (SoundInstanceInternal*)instance->handle;
HRESULT hr = instanceinternal->sourceVoice->Stop(); // preserves cursor position
assert(SUCCEEDED(hr));
}
}
void Stop(SoundInstance* instance)
{
if (instance != nullptr && instance->handle != WI_NULL_HANDLE)
{
SoundInstanceInternal* instanceinternal = (SoundInstanceInternal*)instance->handle;
HRESULT hr = instanceinternal->sourceVoice->Stop(); // preserves cursor position
assert(SUCCEEDED(hr));
hr = instanceinternal->sourceVoice->FlushSourceBuffers(); // reset submitted audio buffer
assert(SUCCEEDED(hr));
hr = instanceinternal->sourceVoice->SubmitSourceBuffer(&instanceinternal->soundinternal->buffer); // resubmit
assert(SUCCEEDED(hr));
}
}
void SetVolume(float volume, SoundInstance* instance)
{
if (instance == nullptr || instance->handle == WI_NULL_HANDLE)
{
HRESULT hr = masteringVoice->SetVolume(volume);
assert(SUCCEEDED(hr));
}
else
{
SoundInstanceInternal* instanceinternal = (SoundInstanceInternal*)instance->handle;
HRESULT hr = instanceinternal->sourceVoice->SetVolume(volume);
assert(SUCCEEDED(hr));
}
}
float GetVolume(const SoundInstance* instance)
{
float volume = 0;
if (instance == nullptr || instance->handle == WI_NULL_HANDLE)
{
masteringVoice->GetVolume(&volume);
}
else
{
const SoundInstanceInternal* instanceinternal = (const SoundInstanceInternal*)instance->handle;
instanceinternal->sourceVoice->GetVolume(&volume);
}
return volume;
}
void SetSubmixVolume(SUBMIX_TYPE type, float volume)
{
submixVoices[type]->SetVolume(volume);
}
float GetSubmixVolume(SUBMIX_TYPE type)
{
float volume;
submixVoices[type]->GetVolume(&volume);
return volume;
}
void Update3D(SoundInstance* instance, const SoundInstance3D& instance3D)
{
if (instance != nullptr && instance->handle != WI_NULL_HANDLE)
{
SoundInstanceInternal* instanceinternal = (SoundInstanceInternal*)instance->handle;
X3DAUDIO_LISTENER listener = {};
listener.Position = instance3D.listenerPos;
listener.OrientFront = instance3D.listenerFront;
listener.OrientTop = instance3D.listenerUp;
listener.Velocity = instance3D.listenerVelocity;
X3DAUDIO_EMITTER emitter = {};
emitter.Position = instance3D.emitterPos;
emitter.OrientFront = instance3D.emitterFront;
emitter.OrientTop = instance3D.emitterUp;
emitter.Velocity = instance3D.emitterVelocity;
emitter.CurveDistanceScaler = 1;
emitter.ChannelCount = 1;
emitter.InnerRadius = instance3D.emitterRadius;
UINT32 flags = 0;
flags |= X3DAUDIO_CALCULATE_MATRIX;
flags |= X3DAUDIO_CALCULATE_LPF_DIRECT;
flags |= X3DAUDIO_CALCULATE_REVERB;
flags |= X3DAUDIO_CALCULATE_DOPPLER;
//flags |= X3DAUDIO_CALCULATE_DELAY;
//flags |= X3DAUDIO_CALCULATE_LPF_REVERB;
//flags |= X3DAUDIO_CALCULATE_EMITTER_ANGLE;
//flags |= X3DAUDIO_CALCULATE_ZEROCENTER;
//flags |= X3DAUDIO_CALCULATE_REDIRECT_TO_LFE;
X3DAUDIO_DSP_SETTINGS settings = {};
settings.SrcChannelCount = instanceinternal->voiceDetails.InputChannels;
settings.DstChannelCount = masteringVoiceDetails.InputChannels;
settings.pMatrixCoefficients = instanceinternal->outputMatrix.data();
X3DAudioCalculate(audio3D, &listener, &emitter, flags, &settings);
HRESULT hr;
hr = instanceinternal->sourceVoice->SetOutputMatrix(
submixVoices[instance->type],
settings.SrcChannelCount,
settings.DstChannelCount,
settings.pMatrixCoefficients
);
assert(SUCCEEDED(hr));
hr = instanceinternal->sourceVoice->SetFrequencyRatio(settings.DopplerFactor);
assert(SUCCEEDED(hr));
XAUDIO2_FILTER_PARAMETERS filterParams =
{
LowPassFilter,
2.0f * sinf(X3DAUDIO_PI / 6.0f * settings.LPFDirectCoefficient),
1.0f
};
hr = instanceinternal->sourceVoice->SetFilterParameters(&filterParams);
assert(SUCCEEDED(hr));
}
}
}
+59
View File
@@ -0,0 +1,59 @@
#pragma once
#include "CommonInclude.h"
#include <string>
namespace wiAudio
{
void Initialize();
void CleanUp();
enum SUBMIX_TYPE
{
SUBMIX_TYPE_SOUNDEFFECT,
SUBMIX_TYPE_MUSIC,
SUBMIX_TYPE_USER0,
SUBMIX_TYPE_USER1,
SUBMIX_TYPE_COUNT,
};
struct Sound
{
wiCPUHandle handle = WI_NULL_HANDLE;
~Sound();
};
struct SoundInstance
{
SUBMIX_TYPE type = SUBMIX_TYPE_SOUNDEFFECT;
wiCPUHandle handle = WI_NULL_HANDLE;
~SoundInstance();
};
HRESULT CreateSound(const std::string& filename, Sound* sound);
HRESULT CreateSoundInstance(const Sound* sound, SoundInstance* instance);
void Destroy(Sound* sound);
void Destroy(SoundInstance* instance);
void Play(SoundInstance* instance);
void Pause(SoundInstance* instance);
void Stop(SoundInstance* instance);
void SetVolume(float volume, SoundInstance* instance = nullptr);
float GetVolume(const SoundInstance* instance = nullptr);
void SetSubmixVolume(SUBMIX_TYPE type, float volume);
float GetSubmixVolume(SUBMIX_TYPE type);
struct SoundInstance3D
{
XMFLOAT3 listenerPos = XMFLOAT3(0, 0, 0);
XMFLOAT3 listenerUp = XMFLOAT3(0, 1, 0);
XMFLOAT3 listenerFront = XMFLOAT3(0, 0, 1);
XMFLOAT3 listenerVelocity = XMFLOAT3(0, 0, 0);
XMFLOAT3 emitterPos = XMFLOAT3(0, 0, 0);
XMFLOAT3 emitterUp = XMFLOAT3(0, 1, 0);
XMFLOAT3 emitterFront = XMFLOAT3(0, 0, 1);
XMFLOAT3 emitterVelocity = XMFLOAT3(0, 0, 0);
float emitterRadius = 0;
};
void Update3D(SoundInstance* instance, const SoundInstance3D& instance3D);
}
+463
View File
@@ -0,0 +1,463 @@
#include "wiAudio_BindLua.h"
#include "wiAudio.h"
#include "Vector_BindLua.h"
const char wiAudio_BindLua::className[] = "Audio";
Luna<wiAudio_BindLua>::FunctionType wiAudio_BindLua::methods[] = {
lunamethod(wiAudio_BindLua, CreateSound),
lunamethod(wiAudio_BindLua, CreateSoundInstance),
lunamethod(wiAudio_BindLua, Destroy),
lunamethod(wiAudio_BindLua, Play),
lunamethod(wiAudio_BindLua, Pause),
lunamethod(wiAudio_BindLua, Stop),
lunamethod(wiAudio_BindLua, GetVolume),
lunamethod(wiAudio_BindLua, SetVolume),
lunamethod(wiAudio_BindLua, GetSubmixVolume),
lunamethod(wiAudio_BindLua, SetSubmixVolume),
lunamethod(wiAudio_BindLua, Update3D),
{ NULL, NULL }
};
Luna<wiAudio_BindLua>::PropertyType wiAudio_BindLua::properties[] = {
{ NULL, NULL }
};
int wiAudio_BindLua::CreateSound(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiSound_BindLua* sound = Luna<wiSound_BindLua>::lightcheck(L, 2);
if (sound != nullptr)
{
HRESULT hr = wiAudio::CreateSound(wiLua::SGetString(L, 1), sound->sound);
wiLua::SSetBool(L, SUCCEEDED(hr));
}
else
{
wiLua::SError(L, "CreateSound(string filename, Sound sound) second argument is not a Sound!");
}
}
else
wiLua::SError(L, "CreateSound(string filename, Sound sound) not enough arguments!");
return 0;
}
int wiAudio_BindLua::CreateSoundInstance(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiSound_BindLua* sound = Luna<wiSound_BindLua>::lightcheck(L, 1);
wiSoundInstance_BindLua* soundinstance = Luna<wiSoundInstance_BindLua>::lightcheck(L, 2);
if (sound != nullptr && soundinstance != nullptr)
{
HRESULT hr = wiAudio::CreateSoundInstance(sound->sound, &soundinstance->soundinstance);
wiLua::SSetBool(L, SUCCEEDED(hr));
return 1;
}
else
{
wiLua::SError(L, "CreateSoundInstance(Sound sound, SoundInstance soundinstance) argument types don't match!");
}
}
else
wiLua::SError(L, "CreateSoundInstance(Sound sound, SoundInstance soundinstance) not enough arguments!");
return 0;
}
int wiAudio_BindLua::Destroy(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiSound_BindLua* sound = Luna<wiSound_BindLua>::lightcheck(L, 1);
if (sound != nullptr)
{
wiAudio::Destroy(sound->sound);
}
else
{
wiSoundInstance_BindLua* soundinstance = Luna<wiSoundInstance_BindLua>::lightcheck(L, 1);
if (soundinstance != nullptr)
{
wiAudio::Destroy(&soundinstance->soundinstance);
}
else
{
wiLua::SError(L, "Destroy(Sound sound); Destroy(SoundInstance soundinstance) argument types mismatch!");
}
}
}
else
wiLua::SError(L, "Destroy(Sound sound); Destroy(SoundInstance soundinstance) not enough arguments!");
return 0;
}
int wiAudio_BindLua::Play(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiSoundInstance_BindLua* soundinstance = Luna<wiSoundInstance_BindLua>::lightcheck(L, 1);
if (soundinstance != nullptr)
{
wiAudio::Play(&soundinstance->soundinstance);
}
else
{
wiLua::SError(L, "Play(SoundInstance soundinstance) argument is not a SoundInstance!");
}
}
else
wiLua::SError(L, "Play(SoundInstance soundinstance) not enough arguments!");
return 0;
}
int wiAudio_BindLua::Pause(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiSoundInstance_BindLua* soundinstance = Luna<wiSoundInstance_BindLua>::lightcheck(L, 1);
if (soundinstance != nullptr)
{
wiAudio::Pause(&soundinstance->soundinstance);
}
else
{
wiLua::SError(L, "Pause(SoundInstance soundinstance) argument is not a SoundInstance!");
}
}
else
wiLua::SError(L, "Pause(SoundInstance soundinstance) not enough arguments!");
return 0;
}
int wiAudio_BindLua::Stop(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiSoundInstance_BindLua* soundinstance = Luna<wiSoundInstance_BindLua>::lightcheck(L, 1);
if (soundinstance != nullptr)
{
wiAudio::Stop(&soundinstance->soundinstance);
}
else
{
wiLua::SError(L, "Stop(SoundInstance soundinstance) argument is not a SoundInstance!");
}
}
else
wiLua::SError(L, "Stop(SoundInstance soundinstance) not enough arguments!");
return 0;
}
int wiAudio_BindLua::GetVolume(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiSoundInstance_BindLua* soundinstance = Luna<wiSoundInstance_BindLua>::lightcheck(L, 1);
float volume = wiAudio::GetVolume(soundinstance == nullptr ? nullptr : &soundinstance->soundinstance);
wiLua::SSetFloat(L, volume);
return 1;
}
else
wiLua::SError(L, "GetVolume(opt SoundInstance soundinstance) not enough arguments!");
return 0;
}
int wiAudio_BindLua::SetVolume(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
float volume = wiLua::SGetFloat(L, 1);
wiSoundInstance_BindLua* soundinstance = Luna<wiSoundInstance_BindLua>::lightcheck(L, 2);
wiAudio::SetVolume(volume, soundinstance == nullptr ? nullptr : &soundinstance->soundinstance);
return 0;
}
else
wiLua::SError(L, "SetVolume(float volume, opt SoundInstance soundinstance) not enough arguments!");
return 0;
}
int wiAudio_BindLua::GetSubmixVolume(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiAudio::SUBMIX_TYPE type = (wiAudio::SUBMIX_TYPE)wiLua::SGetInt(L, 1);
float volume = wiAudio::GetSubmixVolume(type);
wiLua::SSetFloat(L, volume);
return 1;
}
else
wiLua::SError(L, "GetSubmixVolume(int submixtype) not enough arguments!");
return 0;
}
int wiAudio_BindLua::SetSubmixVolume(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 1)
{
wiAudio::SUBMIX_TYPE type = (wiAudio::SUBMIX_TYPE)wiLua::SGetInt(L, 1);
float volume = wiLua::SGetFloat(L, 2);
wiAudio::SetSubmixVolume(type, volume);
return 0;
}
else
wiLua::SError(L, "SetSubmixVolume(int submixtype, float volume) not enough arguments!");
return 0;
}
int wiAudio_BindLua::Update3D(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 1)
{
wiSoundInstance_BindLua* soundinstance = Luna<wiSoundInstance_BindLua>::lightcheck(L, 1);
wiSoundInstance3D_BindLua* soundinstance3D = Luna<wiSoundInstance3D_BindLua>::lightcheck(L, 2);
if (soundinstance != nullptr && soundinstance3D != nullptr)
{
wiAudio::Update3D(&soundinstance->soundinstance, soundinstance3D->soundinstance3D);
}
else
{
wiLua::SError(L, "Update3D(SoundInstance soundinstance, SoundInstance3D instance3D) argument types mismatch!");
}
}
else
wiLua::SError(L, "Update3D(SoundInstance soundinstance, SoundInstance3D instance3D) not enough arguments!");
return 0;
}
void wiAudio_BindLua::Bind()
{
static bool initialized = false;
if (!initialized)
{
initialized = true;
Luna<wiAudio_BindLua>::Register(wiLua::GetGlobal()->GetLuaState());
wiLua::GetGlobal()->RunText("audio = Audio()");
wiSound_BindLua::Bind();
wiSoundInstance_BindLua::Bind();
wiSoundInstance3D_BindLua::Bind();
}
}
const char wiSound_BindLua::className[] = "Sound";
Luna<wiSound_BindLua>::FunctionType wiSound_BindLua::methods[] = {
{ NULL, NULL }
};
Luna<wiSound_BindLua>::PropertyType wiSound_BindLua::properties[] = {
{ NULL, NULL }
};
void wiSound_BindLua::Bind()
{
static bool initialized = false;
if (!initialized)
{
initialized = true;
Luna<wiSound_BindLua>::Register(wiLua::GetGlobal()->GetLuaState());
}
}
const char wiSoundInstance_BindLua::className[] = "SoundInstance";
Luna<wiSoundInstance_BindLua>::FunctionType wiSoundInstance_BindLua::methods[] = {
lunamethod(wiSoundInstance_BindLua, SetSubmixType),
{ NULL, NULL }
};
Luna<wiSoundInstance_BindLua>::PropertyType wiSoundInstance_BindLua::properties[] = {
{ NULL, NULL }
};
int wiSoundInstance_BindLua::SetSubmixType(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiAudio::SUBMIX_TYPE type = (wiAudio::SUBMIX_TYPE)wiLua::SGetInt(L, 1);
soundinstance.type = type;
}
else
wiLua::SError(L, "SetSubmixType(int submixtype) not enough arguments!");
return 0;
}
void wiSoundInstance_BindLua::Bind()
{
static bool initialized = false;
if (!initialized)
{
initialized = true;
Luna<wiSoundInstance_BindLua>::Register(wiLua::GetGlobal()->GetLuaState());
}
}
const char wiSoundInstance3D_BindLua::className[] = "SoundInstance3D";
Luna<wiSoundInstance3D_BindLua>::FunctionType wiSoundInstance3D_BindLua::methods[] = {
lunamethod(wiSoundInstance3D_BindLua, SetListenerPos),
lunamethod(wiSoundInstance3D_BindLua, SetListenerUp),
lunamethod(wiSoundInstance3D_BindLua, SetListenerFront),
lunamethod(wiSoundInstance3D_BindLua, SetListenerVelocity),
lunamethod(wiSoundInstance3D_BindLua, SetEmitterPos),
lunamethod(wiSoundInstance3D_BindLua, SetEmitterUp),
lunamethod(wiSoundInstance3D_BindLua, SetEmitterFront),
lunamethod(wiSoundInstance3D_BindLua, SetEmitterVelocity),
lunamethod(wiSoundInstance3D_BindLua, SetEmitterRadius),
{ NULL, NULL }
};
Luna<wiSoundInstance3D_BindLua>::PropertyType wiSoundInstance3D_BindLua::properties[] = {
{ NULL, NULL }
};
int wiSoundInstance3D_BindLua::SetListenerPos(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 1);
if (vec != nullptr)
{
XMStoreFloat3(&soundinstance3D.listenerPos, vec->vector);
}
}
else
wiLua::SError(L, "SetListenerPos(Vector value) not enough arguments!");
return 0;
}
int wiSoundInstance3D_BindLua::SetListenerUp(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 1);
if (vec != nullptr)
{
XMStoreFloat3(&soundinstance3D.listenerUp, vec->vector);
}
}
else
wiLua::SError(L, "SetListenerUp(Vector value) not enough arguments!");
return 0;
}
int wiSoundInstance3D_BindLua::SetListenerFront(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 1);
if (vec != nullptr)
{
XMStoreFloat3(&soundinstance3D.listenerFront, vec->vector);
}
}
else
wiLua::SError(L, "SetListenerFront(Vector value) not enough arguments!");
return 0;
}
int wiSoundInstance3D_BindLua::SetListenerVelocity(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 1);
if (vec != nullptr)
{
XMStoreFloat3(&soundinstance3D.listenerVelocity, vec->vector);
}
}
else
wiLua::SError(L, "SetListenerVelocity(Vector value) not enough arguments!");
return 0;
}
int wiSoundInstance3D_BindLua::SetEmitterPos(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 1);
if (vec != nullptr)
{
XMStoreFloat3(&soundinstance3D.emitterPos, vec->vector);
}
}
else
wiLua::SError(L, "SetEmitterPos(Vector value) not enough arguments!");
return 0;
}
int wiSoundInstance3D_BindLua::SetEmitterUp(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 1);
if (vec != nullptr)
{
XMStoreFloat3(&soundinstance3D.emitterUp, vec->vector);
}
}
else
wiLua::SError(L, "SetEmitterUp(Vector value) not enough arguments!");
return 0;
}
int wiSoundInstance3D_BindLua::SetEmitterFront(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 1);
if (vec != nullptr)
{
XMStoreFloat3(&soundinstance3D.emitterFront, vec->vector);
}
}
else
wiLua::SError(L, "SetEmitterFront(Vector value) not enough arguments!");
return 0;
}
int wiSoundInstance3D_BindLua::SetEmitterVelocity(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 1);
if (vec != nullptr)
{
XMStoreFloat3(&soundinstance3D.emitterVelocity, vec->vector);
}
}
else
wiLua::SError(L, "SetEmitterVelocity(Vector value) not enough arguments!");
return 0;
}
int wiSoundInstance3D_BindLua::SetEmitterRadius(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
soundinstance3D.emitterRadius = wiLua::SGetFloat(L, 1);
}
else
wiLua::SError(L, "SetEmitterVelocity(Vector value) not enough arguments!");
return 0;
}
void wiSoundInstance3D_BindLua::Bind()
{
static bool initialized = false;
if (!initialized)
{
initialized = true;
Luna<wiSoundInstance3D_BindLua>::Register(wiLua::GetGlobal()->GetLuaState());
}
}
+93
View File
@@ -0,0 +1,93 @@
#pragma once
#include "wiLua.h"
#include "wiLuna.h"
#include "wiAudio.h"
class wiAudio_BindLua
{
public:
static const char className[];
static Luna<wiAudio_BindLua>::FunctionType methods[];
static Luna<wiAudio_BindLua>::PropertyType properties[];
wiAudio_BindLua(lua_State* L) {}
~wiAudio_BindLua() {}
int CreateSound(lua_State* L);
int CreateSoundInstance(lua_State* L);
int Destroy(lua_State* L);
int Play(lua_State* L);
int Pause(lua_State* L);
int Stop(lua_State* L);
int GetVolume(lua_State* L);
int SetVolume(lua_State* L);
int GetSubmixVolume(lua_State* L);
int SetSubmixVolume(lua_State* L);
int Update3D(lua_State* L);
static void Bind();
};
class wiSound_BindLua
{
public:
wiAudio::Sound* sound = nullptr;
bool owned = false;
static const char className[];
static Luna<wiSound_BindLua>::FunctionType methods[];
static Luna<wiSound_BindLua>::PropertyType properties[];
wiSound_BindLua(lua_State* L) { sound = new wiAudio::Sound; owned = true; }
wiSound_BindLua(wiAudio::Sound* sound) :sound(sound) {}
~wiSound_BindLua() { if (owned) delete sound; }
static void Bind();
};
class wiSoundInstance_BindLua
{
public:
wiAudio::SoundInstance soundinstance;
static const char className[];
static Luna<wiSoundInstance_BindLua>::FunctionType methods[];
static Luna<wiSoundInstance_BindLua>::PropertyType properties[];
wiSoundInstance_BindLua(lua_State* L) { }
wiSoundInstance_BindLua(const wiAudio::SoundInstance& soundinstance) : soundinstance(soundinstance) {}
~wiSoundInstance_BindLua() { }
int SetSubmixType(lua_State* L);
static void Bind();
};
class wiSoundInstance3D_BindLua
{
public:
wiAudio::SoundInstance3D soundinstance3D;
bool owned = false;
static const char className[];
static Luna<wiSoundInstance3D_BindLua>::FunctionType methods[];
static Luna<wiSoundInstance3D_BindLua>::PropertyType properties[];
wiSoundInstance3D_BindLua(lua_State* L) { }
wiSoundInstance3D_BindLua(const wiAudio::SoundInstance3D& soundinstance3D) : soundinstance3D(soundinstance3D) {}
~wiSoundInstance3D_BindLua() { }
int SetListenerPos(lua_State* L);
int SetListenerUp(lua_State* L);
int SetListenerFront(lua_State* L);
int SetListenerVelocity(lua_State* L);
int SetEmitterPos(lua_State* L);
int SetEmitterUp(lua_State* L);
int SetEmitterFront(lua_State* L);
int SetEmitterVelocity(lua_State* L);
int SetEmitterRadius(lua_State* L);
static void Bind();
};
-3
View File
@@ -6,9 +6,6 @@
namespace wiGraphics
{
typedef uint64_t wiCPUHandle;
static const wiCPUHandle WI_NULL_HANDLE = 0;
class GraphicsDevice;
struct GraphicsDeviceChild
-20
View File
@@ -17,26 +17,6 @@ using namespace std;
namespace wiHelper
{
DataBlob::DataBlob(const string& fileName) : DATA(nullptr), dataSize(0), dataPos(0)
{
ifstream file(fileName, ios::binary | ios::ate);
if (file.is_open())
{
dataSize = static_cast<size_t>(file.tellg());
file.seekg(0, file.beg);
DATA = new char[dataSize];
file.read(DATA, dataSize);
file.close();
dataPos = reinterpret_cast<size_t>(DATA);
}
}
DataBlob::~DataBlob()
{
SAFE_DELETE_ARRAY(DATA);
}
string toUpper(const std::string& s)
{
std::string result;
-20
View File
@@ -14,26 +14,6 @@ namespace wiHelper
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
// Simple binary reader utility
struct DataBlob
{
char* DATA;
size_t dataSize;
size_t dataPos;
DataBlob(const std::string& fileName = "");
~DataBlob();
template<typename T>
void read(T& data)
{
assert(DATA != nullptr);
assert(dataPos - (size_t)DATA < dataSize);
memcpy(&data, reinterpret_cast<void*>(dataPos), sizeof(T));
dataPos += sizeof(T);
}
};
std::string toUpper(const std::string& s);
bool readByteData(const std::string& fileName, std::vector<uint8_t>& data);
+1 -1
View File
@@ -28,7 +28,7 @@ namespace wiInitializer
wiJobSystem::Execute(ctx, [] { wiImage::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiInputManager::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiRenderer::Initialize(); wiWidget::LoadShaders(); });
wiJobSystem::Execute(ctx, [] { wiSoundEffect::Initialize(); wiMusic::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiAudio::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiTextureHelper::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiSceneSystem::wiHairParticle::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiSceneSystem::wiEmittedParticle::Initialize(); });
+10 -4
View File
@@ -12,7 +12,7 @@
#include "RenderPath3D_TiledDeferred_BindLua.h"
#include "Texture_BindLua.h"
#include "wiRenderer_BindLua.h"
#include "wiSound_BindLua.h"
#include "wiAudio_BindLua.h"
#include "wiSprite_BindLua.h"
#include "wiImageParams_BindLua.h"
#include "SpriteAnim_BindLua.h"
@@ -64,9 +64,7 @@ wiLua* wiLua::GetGlobal()
RenderPath3D_TiledDeferred_BindLua::Bind();
Texture_BindLua::Bind();
wiRenderer_BindLua::Bind();
wiSound_BindLua::Bind();
wiSoundEffect_BindLua::Bind();
wiMusic_BindLua::Bind();
wiAudio_BindLua::Bind();
wiSprite_BindLua::Bind();
wiImageParams_BindLua::Bind();
SpriteAnim_BindLua::Bind();
@@ -377,6 +375,14 @@ void wiLua::SSetInt(lua_State* L, int data)
{
lua_pushinteger(L, (lua_Integer)data);
}
void wiLua::SSetLong(lua_State* L, long data)
{
lua_pushinteger(L, (lua_Integer)data);
}
void wiLua::SSetLongLong(lua_State* L, long long data)
{
lua_pushinteger(L, (lua_Integer)data);
}
void wiLua::SSetFloat(lua_State* L, float data)
{
lua_pushnumber(L, (lua_Number)data);
+4
View File
@@ -110,6 +110,10 @@ public:
//push int to lua stack
static void SSetInt(lua_State* L, int data);
//push long to lua stack
static void SSetLong(lua_State* L, long data);
//push long long to lua stack
static void SSetLongLong(lua_State* L, long long data);
//push float to lua stack
static void SSetFloat(lua_State* L, float data);
//push float2 to lua stack
+7 -9
View File
@@ -1,6 +1,6 @@
#include "wiResourceManager.h"
#include "wiRenderer.h"
#include "wiSound.h"
#include "wiAudio.h"
#include "wiHelper.h"
#include "wiTextureHelper.h"
@@ -287,12 +287,11 @@ const void* wiResourceManager::add(const wiHashString& name, Data_Type newType)
break;
case Data_Type::SOUND:
{
success = new wiSoundEffect(name.GetString());
}
break;
case Data_Type::MUSIC:
{
success = new wiMusic(name.GetString());
wiAudio::Sound* sound = new wiAudio::Sound;
if (SUCCEEDED(wiAudio::CreateSound(name.GetString(), sound)))
{
success = sound;
}
}
break;
case Data_Type::VERTEXSHADER:
@@ -425,8 +424,7 @@ bool wiResourceManager::del(const wiHashString& name, bool forceDelete)
SAFE_DELETE(reinterpret_cast<const ComputeShader*&>(res.data));
break;
case Data_Type::SOUND:
case Data_Type::MUSIC:
SAFE_DELETE(reinterpret_cast<const wiSound*&>(res.data));
SAFE_DELETE(reinterpret_cast<const wiAudio::Sound*&>(res.data));
break;
default:
success = false;
+1 -1
View File
@@ -16,7 +16,7 @@ public:
IMAGE_1D,
IMAGE_2D,
IMAGE_3D,
SOUND,MUSIC,
SOUND,
VERTEXSHADER,
PIXELSHADER,
GEOMETRYSHADER,
+4 -14
View File
@@ -1,7 +1,7 @@
#include "wiResourceManager_BindLua.h"
#include "wiSound_BindLua.h"
#include "wiHelper.h"
#include "Texture_BindLua.h"
#include "wiAudio_BindLua.h"
#include "wiRenderer.h"
#include <sstream>
@@ -53,9 +53,8 @@ int wiResourceManager_BindLua::Get(lua_State *L)
Luna<Texture_BindLua>::push(L, new Texture_BindLua((Texture2D*)data.data));
return 1;
break;
case wiResourceManager::Data_Type::MUSIC:
case wiResourceManager::Data_Type::SOUND:
Luna<wiSound_BindLua>::push(L, new wiSound_BindLua((wiSound*)data.data));
Luna<wiSound_BindLua>::push(L, new wiSound_BindLua((wiAudio::Sound*)data.data));
return 1;
break;
default:
@@ -86,22 +85,13 @@ int wiResourceManager_BindLua::Add(lua_State *L)
if (argc > 0)
{
string name = wiLua::SGetString(L, 1);
wiResourceManager::Data_Type type = wiResourceManager::Data_Type::DYNAMIC;
if (argc > 1) //type info also provided in this case
{
string typeStr = wiHelper::toUpper( wiLua::SGetString(L, 2) );
if (!typeStr.compare("SOUND"))
type = wiResourceManager::Data_Type::SOUND;
else if (!typeStr.compare("MUSIC"))
type = wiResourceManager::Data_Type::MUSIC;
}
const void* data = resources->add(name, type);
const void* data = resources->add(name);
wiLua::SSetString(L, (data != nullptr ? "ok" : "not found"));
return 1;
}
else
{
wiLua::SError(L, "Resource:Add(string name, (opt) string type) not enough arguments!");
wiLua::SError(L, "Resource:Add(string name) not enough arguments!");
}
return 0;
}
-356
View File
@@ -1,356 +0,0 @@
#include "wiSound.h"
#include "wiBackLog.h"
using namespace std;
wiAudioEngine* wiSoundEffect::audioEngine = nullptr;
wiAudioEngine* wiMusic::audioEngine = nullptr;
wiAudioEngine::wiAudioEngine()
{
INITIALIZED = false;
pXAudio2 = nullptr;
pMasterVoice = nullptr;
Initialize();
}
wiAudioEngine::~wiAudioEngine()
{
if (pMasterVoice != nullptr) pMasterVoice->DestroyVoice();
if (pXAudio2 != nullptr) pXAudio2->Release();
SAFE_DELETE(pMasterVoice);
SAFE_DELETE(pXAudio2);
INITIALIZED = false;
}
HRESULT wiAudioEngine::Initialize()
{
if (INITIALIZED)
return S_OK;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
HRESULT hr;
pXAudio2 = nullptr;
if (FAILED(hr = XAudio2Create(&pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)))
return hr;
pMasterVoice = nullptr;
if (FAILED(hr = pXAudio2->CreateMasteringVoice(&pMasterVoice)))
return hr;
INITIALIZED = true;
return EXIT_SUCCESS;
}
void wiAudioEngine::SetVolume(float vol) {
if (INITIALIZED && pMasterVoice != nullptr)
pMasterVoice->SetVolume(vol);
}
float wiAudioEngine::GetVolume() {
float vol;
if (pMasterVoice != nullptr)
pMasterVoice->GetVolume(&vol);
return vol;
}
wiSound::wiSound()
{
pSourceVoice = nullptr;
}
wiSound::~wiSound()
{
//if (pSourceVoice != nullptr) pSourceVoice->DestroyVoice();
//SAFE_DELETE(pSourceVoice);
}
HRESULT wiSound::FindChunk(HANDLE hFile, DWORD fourcc, DWORD & dwChunkSize, DWORD & dwChunkDataPosition)
{
HRESULT hr = S_OK;
if( INVALID_SET_FILE_POINTER == SetFilePointerEx( hFile, LARGE_INTEGER(), NULL, FILE_BEGIN ) )
return HRESULT_FROM_WIN32( GetLastError() );
DWORD dwChunkType;
DWORD dwChunkDataSize;
DWORD dwRIFFDataSize = 0;
DWORD dwFileType;
DWORD bytesRead = 0;
DWORD dwOffset = 0;
while (hr == S_OK)
{
DWORD dwRead;
if( 0 == ReadFile( hFile, &dwChunkType, sizeof(DWORD), &dwRead, NULL ) )
hr = HRESULT_FROM_WIN32( GetLastError() );
if( 0 == ReadFile( hFile, &dwChunkDataSize, sizeof(DWORD), &dwRead, NULL ) )
hr = HRESULT_FROM_WIN32( GetLastError() );
switch (dwChunkType)
{
case fourccRIFF:
dwRIFFDataSize = dwChunkDataSize;
dwChunkDataSize = 4;
if( 0 == ReadFile( hFile, &dwFileType, sizeof(DWORD), &dwRead, NULL ) )
hr = HRESULT_FROM_WIN32( GetLastError() );
break;
default:
LARGE_INTEGER li = LARGE_INTEGER();
li.QuadPart = dwChunkDataSize;
if( INVALID_SET_FILE_POINTER == SetFilePointerEx( hFile, li, NULL, FILE_CURRENT ) )
return HRESULT_FROM_WIN32( GetLastError() );
}
dwOffset += sizeof(DWORD) * 2;
if (dwChunkType == fourcc)
{
dwChunkSize = dwChunkDataSize;
dwChunkDataPosition = dwOffset;
return S_OK;
}
dwOffset += dwChunkDataSize;
if (bytesRead >= dwRIFFDataSize) return S_FALSE;
}
return S_OK;
}
HRESULT wiSound::ReadChunkData(HANDLE hFile, void * buffer, DWORD buffersize, DWORD bufferoffset)
{
HRESULT hr = S_OK;
LARGE_INTEGER li = LARGE_INTEGER();
li.QuadPart=bufferoffset;
if( INVALID_SET_FILE_POINTER == SetFilePointerEx( hFile, li, NULL, FILE_BEGIN ) )
return HRESULT_FROM_WIN32( GetLastError() );
DWORD dwRead;
if( 0 == ReadFile( hFile, buffer, buffersize, &dwRead, NULL ) )
hr = HRESULT_FROM_WIN32( GetLastError() );
return hr;
}
HRESULT wiSound::OpenFile(const TCHAR* strFileName)
{
HRESULT hr;
wfx = WAVEFORMATEX();
buffer = XAUDIO2_BUFFER();
// Open the file
HANDLE hFile;
hFile = CreateFile2(
strFileName,
GENERIC_READ,
FILE_SHARE_READ,
OPEN_EXISTING,
nullptr
);
if (INVALID_HANDLE_VALUE == hFile)
return HRESULT_FROM_WIN32(GetLastError());
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hFile, LARGE_INTEGER(), NULL, FILE_BEGIN))
return HRESULT_FROM_WIN32(GetLastError());
DWORD dwChunkSize;
DWORD dwChunkPosition;
//check the file type, should be fourccWAVE or 'XWMA'
FindChunk(hFile,fourccRIFF,dwChunkSize, dwChunkPosition );
DWORD filetype;
if(FAILED( hr = ReadChunkData(hFile,&filetype,sizeof(DWORD),dwChunkPosition) ))
return hr;
if (filetype != fourccWAVE)
return S_FALSE;
if(FAILED( hr = FindChunk(hFile,fourccFMT, dwChunkSize, dwChunkPosition ) ))
return hr;
if(FAILED( hr = ReadChunkData(hFile, &wfx, dwChunkSize, dwChunkPosition ) ))
return hr;
wfx.wFormatTag=WAVE_FORMAT_PCM;
//fill out the audio data buffer with the contents of the fourccDATA chunk
if(FAILED( hr = FindChunk(hFile,fourccDATA,dwChunkSize, dwChunkPosition ) ))
return hr;
BYTE * pDataBuffer = new BYTE[dwChunkSize];
if(FAILED( hr = ReadChunkData(hFile, pDataBuffer, dwChunkSize, dwChunkPosition) ))
return hr;
buffer.AudioBytes = dwChunkSize; //buffer containing audio data
buffer.pAudioData = pDataBuffer; //size of the audio buffer in bytes
buffer.Flags = XAUDIO2_END_OF_STREAM; // tell the source voice not to expect any data after this buffer
return EXIT_SUCCESS;
}
HRESULT wiSound::Load(wstring filename)
{
return OpenFile(filename.data());
}
HRESULT wiSound::Load(string filename)
{
return OpenFile(wstring(filename.begin(),filename.end()).data());
}
void wiSound::Stop(){
StopSound();
}
void wiSound::Initialize()
{
pSourceVoice = nullptr;
}
HRESULT wiSound::PlaySound(wiAudioEngine* engine)
{
if (engine == nullptr)
return E_FAIL;
if (!engine->INITIALIZED)
return E_FAIL;
HRESULT hr;
pSourceVoice = nullptr;
if (FAILED(hr = engine->pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx)))
return hr;
if (FAILED(hr = pSourceVoice->SubmitSourceBuffer(&buffer)))
return hr;
if (FAILED(hr = pSourceVoice->Start(0)))
return hr;
return EXIT_SUCCESS;
}
void wiSound::StopSound()
{
if (pSourceVoice != nullptr) {
pSourceVoice->Stop();
}
}
void wiSoundEffect::SetVolume(float vol) {
if (audioEngine == nullptr)
return;
audioEngine->SetVolume(vol);
}
float wiSoundEffect::GetVolume() {
if (audioEngine == nullptr)
return 0;
return audioEngine->GetVolume();
}
wiSoundEffect::wiSoundEffect()
{
wiSound::Initialize();
}
wiSoundEffect::wiSoundEffect(wstring filename)
{
wiSound::Initialize();
Load(filename);
}
wiSoundEffect::wiSoundEffect(string filename)
{
wiSound::Initialize();
Load(filename);
}
wiSoundEffect::~wiSoundEffect()
{
}
HRESULT wiSoundEffect::Initialize()
{
if (audioEngine == nullptr)
{
audioEngine = new wiAudioEngine;
}
if (audioEngine->INITIALIZED)
{
wiBackLog::post("wiSoundEffect Initialized");
return S_OK;
}
else
{
wiBackLog::post("wiSoundEffect Initialization FAILED!");
return E_FAIL;
}
}
HRESULT wiSoundEffect::Play(DWORD delay)
{
if (delay > 0) {
thread([=] {
Sleep(delay);
PlaySound(audioEngine);
}).detach();
return S_OK;
}
return PlaySound(audioEngine);
}
void wiMusic::SetVolume(float vol){
if (audioEngine == nullptr)
return;
audioEngine->SetVolume(vol);
}
float wiMusic::GetVolume(){
if (audioEngine == nullptr)
return 0;
return audioEngine->GetVolume();
}
wiMusic::wiMusic()
{
wiSound::Initialize();
pSourceVoice = nullptr;
}
wiMusic::wiMusic(wstring filename)
{
wiSound::Initialize();
Load(filename);
}
wiMusic::wiMusic(string filename)
{
wiSound::Initialize();
Load(filename);
}
wiMusic::~wiMusic()
{
}
HRESULT wiMusic::Initialize()
{
if (audioEngine == nullptr)
{
audioEngine = new wiAudioEngine;
}
if (audioEngine->INITIALIZED)
{
wiBackLog::post("wiMusic Initialized");
return S_OK;
}
else
{
wiBackLog::post("wiMusic Initialization FAILED!");
return E_FAIL;
}
}
HRESULT wiMusic::Play(DWORD delay)
{
if (delay > 0) {
thread([=] {
Sleep(delay);
PlaySound(audioEngine);
}).detach();
return S_OK;
}
return PlaySound(audioEngine);
}
-100
View File
@@ -1,100 +0,0 @@
#pragma once
#include "CommonInclude.h"
#include <xaudio2.h>
#pragma comment(lib,"xaudio2.lib")
#include <string>
#include <thread>
#ifdef _XBOX //Big-Endian
#define fourccRIFF 'RIFF'
#define fourccDATA 'data'
#define fourccFMT 'fmt '
#define fourccWAVE 'WAVE'
#define fourccXWMA 'XWMA'
#define fourccDPDS 'dpds'
#endif
#ifndef _XBOX //Little-Endian
#define fourccRIFF 'FFIR'
#define fourccDATA 'atad'
#define fourccFMT ' tmf'
#define fourccWAVE 'EVAW'
#define fourccXWMA 'AMWX'
#define fourccDPDS 'sdpd'
#endif
class wiAudioEngine
{
public:
wiAudioEngine();
~wiAudioEngine();
IXAudio2MasteringVoice* pMasterVoice;
IXAudio2* pXAudio2;
bool INITIALIZED;
void SetVolume(float);
float GetVolume();
HRESULT Initialize();
};
class wiSound
{
protected:
WAVEFORMATEX wfx;
XAUDIO2_BUFFER buffer;
IXAudio2SourceVoice* pSourceVoice;
HRESULT FindChunk(HANDLE hFile, DWORD fourcc, DWORD & dwChunkSize, DWORD & dwChunkDataPosition);
HRESULT ReadChunkData(HANDLE hFile, void * buffer, DWORD buffersize, DWORD bufferoffset);
HRESULT OpenFile(const TCHAR*);
HRESULT PlaySound(wiAudioEngine* engine);
void StopSound();
public:
wiSound();
virtual ~wiSound();
virtual void Initialize();
HRESULT Load(std::wstring);
HRESULT Load(std::string);
virtual HRESULT Play(DWORD delay = 0) = 0;
void Stop();
};
class wiSoundEffect : public wiSound
{
private:
static wiAudioEngine* audioEngine;
public:
wiSoundEffect();
wiSoundEffect(std::wstring);
wiSoundEffect(std::string);
~wiSoundEffect();
static HRESULT Initialize();
static void SetVolume(float);
static float GetVolume();
HRESULT Play(DWORD delay = 0) override;
};
class wiMusic : public wiSound
{
private:
static wiAudioEngine* audioEngine;
public:
wiMusic();
wiMusic(std::wstring);
wiMusic(std::string);
~wiMusic();
static HRESULT Initialize();
static void SetVolume(float);
static float GetVolume();
HRESULT Play(DWORD delay = 0) override;
};
-152
View File
@@ -1,152 +0,0 @@
#include "wiSound_BindLua.h"
const char wiSound_BindLua::className[] = "Sound";
Luna<wiSound_BindLua>::FunctionType wiSound_BindLua::methods[] = {
lunamethod(wiSound_BindLua, Play),
lunamethod(wiSound_BindLua, Stop),
{ NULL, NULL }
};
Luna<wiSound_BindLua>::PropertyType wiSound_BindLua::properties[] = {
{ NULL, NULL }
};
wiSound_BindLua::wiSound_BindLua(wiSound* sound) :sound(sound)
{
}
wiSound_BindLua::wiSound_BindLua(lua_State *L)
{
sound = nullptr;
}
wiSound_BindLua::~wiSound_BindLua()
{
}
int wiSound_BindLua::Play(lua_State* L)
{
if (sound == nullptr)
{
wiLua::SError(L, "Play(opt int delay) sound resource not loaded!");
return 0;
}
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
sound->Play((DWORD)wiLua::SGetInt(L, 2));
else
sound->Play();
return 0;
}
int wiSound_BindLua::Stop(lua_State *L)
{
if (sound == nullptr)
{
wiLua::SError(L, "Stop() sound resource not loaded!");
return 0;
}
sound->Stop();
return 0;
}
void wiSound_BindLua::Bind()
{
static bool initialized = false;
if (!initialized)
{
initialized = true;
Luna<wiSound_BindLua>::Register(wiLua::GetGlobal()->GetLuaState());
wiLua::GetGlobal()->RegisterFunc("SoundVolume", SoundVolume);
wiLua::GetGlobal()->RegisterFunc("MusicVolume", MusicVolume);
}
}
int wiSound_BindLua::SoundVolume(lua_State *L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiSoundEffect::SetVolume(wiLua::SGetFloat(L, 1));
}
wiLua::SSetFloat(L, wiSoundEffect::GetVolume());
return 1;
}
int wiSound_BindLua::MusicVolume(lua_State *L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
wiMusic::SetVolume(wiLua::SGetFloat(L, 1));
}
wiLua::SSetFloat(L, wiMusic::GetVolume());
return 1;
}
const char wiSoundEffect_BindLua::className[] = "SoundEffect";
Luna<wiSoundEffect_BindLua>::FunctionType wiSoundEffect_BindLua::methods[] = {
lunamethod(wiSoundEffect_BindLua, Play),
lunamethod(wiSoundEffect_BindLua, Stop),
{ NULL, NULL }
};
Luna<wiSoundEffect_BindLua>::PropertyType wiSoundEffect_BindLua::properties[] = {
{ NULL, NULL }
};
wiSoundEffect_BindLua::wiSoundEffect_BindLua(lua_State *L) :wiSound_BindLua()
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
sound = new wiSoundEffect(wiLua::SGetString(L, 1));
}
}
void wiSoundEffect_BindLua::Bind()
{
static bool initialized = false;
if (!initialized)
{
initialized = true;
Luna<wiSoundEffect_BindLua>::Register(wiLua::GetGlobal()->GetLuaState());
}
}
const char wiMusic_BindLua::className[] = "Music";
Luna<wiMusic_BindLua>::FunctionType wiMusic_BindLua::methods[] = {
lunamethod(wiMusic_BindLua, Play),
lunamethod(wiMusic_BindLua, Stop),
{ NULL, NULL }
};
Luna<wiMusic_BindLua>::PropertyType wiMusic_BindLua::properties[] = {
{ NULL, NULL }
};
wiMusic_BindLua::wiMusic_BindLua(lua_State *L) :wiSound_BindLua()
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
sound = new wiMusic(wiLua::SGetString(L, 1));
}
}
void wiMusic_BindLua::Bind()
{
static bool initialized = false;
if (!initialized)
{
initialized = true;
Luna<wiMusic_BindLua>::Register(wiLua::GetGlobal()->GetLuaState());
}
}
-48
View File
@@ -1,48 +0,0 @@
#pragma once
#include "wiLua.h"
#include "wiLuna.h"
#include "wiSound.h"
class wiSound_BindLua
{
public:
wiSound* sound;
static const char className[];
static Luna<wiSound_BindLua>::FunctionType methods[];
static Luna<wiSound_BindLua>::PropertyType properties[];
wiSound_BindLua(wiSound* sound = nullptr);
wiSound_BindLua(lua_State *L);
~wiSound_BindLua();
int Play(lua_State *L);
int Stop(lua_State *L);
static void Bind();
static int SoundVolume(lua_State *L);
static int MusicVolume(lua_State *L);
};
class wiSoundEffect_BindLua : public wiSound_BindLua
{
public:
static const char className[];
static Luna<wiSoundEffect_BindLua>::FunctionType methods[];
static Luna<wiSoundEffect_BindLua>::PropertyType properties[];
wiSoundEffect_BindLua(lua_State *L);
static void Bind();
};
class wiMusic_BindLua : public wiSound_BindLua
{
public:
static const char className[];
static Luna<wiMusic_BindLua>::FunctionType methods[];
static Luna<wiMusic_BindLua>::PropertyType properties[];
wiMusic_BindLua(lua_State *L);
static void Bind();
};
+2 -2
View File
@@ -7,9 +7,9 @@ namespace wiVersion
// main engine core
const int major = 0;
// minor features, major updates
const int minor = 28;
const int minor = 29;
// minor bug fixes, alterations, refactors, updates
const int revision = 28;
const int revision = 0;
long GetVersion()
+1 -1
View File
@@ -43,7 +43,7 @@ Soft shadows
[removed] Rigid body physics simulation (HAVOK) [PRIVATE]
Rigid body physics simulation (BULLET)
Soft body physics simulation (BULLET)
Sound (Xaudio2)
3D Audio (Xaudio2)
Input: Windows Keyboard,Windows Mouse,DirectInput(Joypad,Keyboard,Mouse),XINPUT(Joypad)
Backlog: log,input,scripting
Gamma correction