2024-09-06 22:23:32 -03:00
|
|
|
#include "xna-dx/framework.hpp"
|
2024-12-13 17:28:46 -03:00
|
|
|
#include "csharp/io/stream.hpp"
|
2024-04-20 13:39:19 -03:00
|
|
|
|
|
|
|
using DxSoundEffect = DirectX::SoundEffect;
|
|
|
|
|
|
|
|
namespace xna {
|
2024-05-24 23:12:29 -03:00
|
|
|
SoundEffectInstance::SoundEffectInstance() {
|
2024-05-29 15:58:37 -03:00
|
|
|
impl = unew<PlatformImplementation>();
|
2024-05-24 23:12:29 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
SoundEffectInstance::~SoundEffectInstance() {
|
|
|
|
impl = nullptr;
|
2024-06-04 17:08:04 -03:00
|
|
|
}
|
2024-05-28 09:06:10 -03:00
|
|
|
|
2024-05-27 21:12:46 -03:00
|
|
|
SoundEffect::SoundEffect(String const& fileName) {
|
|
|
|
if (!AudioEngine::impl || !AudioEngine::impl->_dxAudioEngine)
|
2024-04-20 13:39:19 -03:00
|
|
|
return;
|
|
|
|
|
2024-12-02 14:42:09 -03:00
|
|
|
const auto file = misc::ToWString(fileName);
|
2024-05-27 21:12:46 -03:00
|
|
|
impl->_dxSoundEffect = unew<DxSoundEffect>(AudioEngine::impl->_dxAudioEngine.get(), file.c_str());
|
2024-05-24 23:12:29 -03:00
|
|
|
}
|
|
|
|
|
2024-05-31 12:01:46 -03:00
|
|
|
SoundEffect::~SoundEffect() {
|
|
|
|
impl = nullptr;
|
|
|
|
}
|
|
|
|
|
2024-05-28 09:06:10 -03:00
|
|
|
SoundEffect::SoundEffect(
|
2024-05-29 15:58:37 -03:00
|
|
|
std::vector<Byte> const& format,
|
|
|
|
std::vector<Byte> const& data,
|
2024-05-28 09:06:10 -03:00
|
|
|
Int loopStart,
|
|
|
|
Int loopLength,
|
2024-05-29 15:58:37 -03:00
|
|
|
//We must evaluate how to use the time duration
|
2024-12-14 17:24:36 -03:00
|
|
|
csharp::TimeSpan const& duration) {
|
2024-05-28 09:06:10 -03:00
|
|
|
if (!AudioEngine::impl || !AudioEngine::impl->_dxAudioEngine)
|
2024-05-29 15:58:37 -03:00
|
|
|
return;
|
|
|
|
|
|
|
|
//We expect 'format' to always be 16 bytes
|
2024-12-13 17:28:46 -03:00
|
|
|
csharp::MemoryStream stream(format);
|
2024-05-29 15:58:37 -03:00
|
|
|
WORD word = 0;
|
|
|
|
DWORD dword = 0;
|
|
|
|
|
|
|
|
auto bWord = reinterpret_cast<Byte*>(&word);
|
|
|
|
auto bDword = reinterpret_cast<Byte*>(&dword);
|
|
|
|
|
|
|
|
stream.Read(bWord, 2, 0, 2);
|
|
|
|
auto tag = word;
|
|
|
|
stream.Read(bWord, 2, 0, 2);
|
|
|
|
auto channels = word;
|
|
|
|
stream.Read(bDword, 4, 0, 4);
|
|
|
|
auto samplesPerSec = dword;
|
|
|
|
stream.Read(bDword, 4, 0, 4);
|
|
|
|
auto bytesPerSec = dword;
|
|
|
|
stream.Read(bWord, 2, 0, 2);
|
|
|
|
auto blockAlign = word;
|
|
|
|
stream.Read(bWord, 2, 0, 2);
|
|
|
|
auto bitsPerSample = word;
|
|
|
|
stream.Read(bWord, 2, 0, 2);
|
|
|
|
auto cbSize = word;
|
2024-05-28 09:06:10 -03:00
|
|
|
|
|
|
|
auto wavData = unew<Byte[]>(data.size());
|
|
|
|
for (size_t i = 0; i < data.size(); ++i)
|
|
|
|
wavData[i] = data[i];
|
|
|
|
|
2024-05-29 15:58:37 -03:00
|
|
|
auto wfx = reinterpret_cast<WAVEFORMATEX*>(wavData.get());
|
|
|
|
wfx->wFormatTag = tag;
|
|
|
|
wfx->nChannels = channels;
|
|
|
|
wfx->nSamplesPerSec = samplesPerSec;
|
|
|
|
wfx->nAvgBytesPerSec = bytesPerSec;
|
|
|
|
wfx->nBlockAlign = blockAlign;
|
|
|
|
wfx->wBitsPerSample = bitsPerSample;
|
|
|
|
wfx->cbSize = cbSize;
|
|
|
|
|
|
|
|
auto startAudio = wavData.get();
|
|
|
|
|
|
|
|
auto se = unew<DxSoundEffect>(
|
2024-05-28 09:06:10 -03:00
|
|
|
AudioEngine::impl->_dxAudioEngine.get(),
|
|
|
|
wavData,
|
2024-05-29 15:58:37 -03:00
|
|
|
wfx,
|
2024-05-28 09:06:10 -03:00
|
|
|
startAudio,
|
|
|
|
data.size(),
|
|
|
|
loopStart,
|
|
|
|
loopLength);
|
2024-05-29 15:58:37 -03:00
|
|
|
|
|
|
|
impl = unew<PlatformImplementation>();
|
|
|
|
impl->_dxSoundEffect = std::move(se);
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundEffect::Play() {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxSoundEffect)
|
2024-04-20 13:39:19 -03:00
|
|
|
return;
|
2024-05-30 22:14:01 -03:00
|
|
|
|
|
|
|
impl->_dxSoundEffect->Play();
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundEffect::Play(float volume, float pitch, float pan) {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxSoundEffect)
|
2024-05-30 22:14:01 -03:00
|
|
|
return;
|
|
|
|
|
|
|
|
impl->_dxSoundEffect->Play(volume, pitch, pan);
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
uptr<SoundEffectInstance> SoundEffect::CreateInstance() {
|
|
|
|
if (!impl->_dxSoundEffect)
|
|
|
|
return unew<SoundEffectInstance>();
|
2024-04-20 13:39:19 -03:00
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
auto instance = unew<SoundEffectInstance>();
|
|
|
|
instance->impl->_dxInstance = impl->_dxSoundEffect->CreateInstance();
|
2024-04-20 13:39:19 -03:00
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
return instance;
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundEffectInstance::Play(bool loop) {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxInstance)
|
2024-04-20 13:39:19 -03:00
|
|
|
return;
|
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
impl->_dxInstance->Play(loop);
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundEffectInstance::Stop(bool immediate) {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxInstance)
|
2024-04-20 13:39:19 -03:00
|
|
|
return;
|
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
impl->_dxInstance->Stop(immediate);
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundEffectInstance::Pause() {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxInstance)
|
2024-04-20 13:39:19 -03:00
|
|
|
return;
|
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
impl->_dxInstance->Pause();
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundEffectInstance::Resume() {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxInstance)
|
2024-04-20 13:39:19 -03:00
|
|
|
return;
|
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
impl->_dxInstance->Resume();
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundEffectInstance::Volume(float volume) {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxInstance)
|
2024-04-20 13:39:19 -03:00
|
|
|
return;
|
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
impl->_dxInstance->SetVolume(volume);
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundEffectInstance::Pitch(float pitch) {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxInstance)
|
2024-04-20 13:39:19 -03:00
|
|
|
return;
|
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
impl->_dxInstance->SetPitch(pitch);
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundEffectInstance::Pan(float pan) {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxInstance)
|
2024-04-20 13:39:19 -03:00
|
|
|
return;
|
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
impl->_dxInstance->SetPan(pan);
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SoundEffectInstance::IsLooped() {
|
2024-05-24 23:12:29 -03:00
|
|
|
if (!impl->_dxInstance)
|
2024-04-20 13:39:19 -03:00
|
|
|
return false;
|
|
|
|
|
2024-05-24 23:12:29 -03:00
|
|
|
return impl->_dxInstance->IsLooped();
|
2024-04-20 13:39:19 -03:00
|
|
|
}
|
|
|
|
}
|