From 707a18ca17c1f57ddc67840079da52dc368f83e1 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 8 Jun 2024 16:33:21 -0400 Subject: [PATCH] Implement 3D sound, WIP --- CMakeLists.txt | 4 +- LEGO1/lego/legoomni/include/lego3dsound.h | 25 ++-- LEGO1/lego/legoomni/include/legocachsound.h | 35 ++--- .../include/legoloadcachesoundpresenter.h | 12 +- .../lego/legoomni/include/legosoundmanager.h | 1 - LEGO1/lego/legoomni/src/audio/lego3dsound.cpp | 79 +++++------ .../src/audio/lego3dwavepresenter.cpp | 27 ++-- .../lego/legoomni/src/audio/legocachsound.cpp | 126 +++++++----------- .../src/audio/legoloadcachesoundpresenter.cpp | 5 +- .../legoomni/src/audio/legosoundmanager.cpp | 50 ++----- LEGO1/omni/include/mxsoundmanager.h | 1 - LEGO1/omni/src/audio/mxwavepresenter.cpp | 3 +- 12 files changed, 147 insertions(+), 221 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b269444d..07f7e4c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -334,7 +334,7 @@ add_library(omni STATIC register_lego1_target(omni) set_property(TARGET omni PROPERTY ARCHIVE_OUTPUT_NAME "omni$<$:d>") target_include_directories(omni PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1/omni/include" "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAKE_SOURCE_DIR}/util") -target_link_libraries(omni PRIVATE dsound winmm libsmacker miniaudio) +target_link_libraries(omni PRIVATE winmm libsmacker miniaudio) add_library(lego1 SHARED LEGO1/define.cpp @@ -497,7 +497,7 @@ if (ISLE_BUILD_APP) target_link_libraries(isle PRIVATE SDL3::SDL3 iniparser-static) # Link DSOUND, WINMM, and LEGO1 - target_link_libraries(isle PRIVATE dsound winmm lego1) + target_link_libraries(isle PRIVATE winmm lego1) # Make sure filenames are ALL CAPS set_property(TARGET isle PROPERTY OUTPUT_NAME ISLE) diff --git a/LEGO1/lego/legoomni/include/lego3dsound.h b/LEGO1/lego/legoomni/include/lego3dsound.h index dc7840a3..ddf34782 100644 --- a/LEGO1/lego/legoomni/include/lego3dsound.h +++ b/LEGO1/lego/legoomni/include/lego3dsound.h @@ -4,7 +4,7 @@ #include "decomp.h" #include "mxtypes.h" -#include +#include class LegoActor; class LegoROI; @@ -17,10 +17,10 @@ class Lego3DSound { virtual ~Lego3DSound(); void Init(); - MxResult Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name, MxS32 p_volume); + MxResult Create(ma_sound* p_sound, const char* p_name, MxS32 p_volume); void Destroy(); - MxU32 UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer); - void FUN_10011a60(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name); + MxU32 UpdatePosition(ma_sound* p_sound); + void FUN_10011a60(ma_sound* p_sound, const char* p_name); void Reset(); MxS32 SetDistance(MxS32 p_min, MxS32 p_max); @@ -28,15 +28,14 @@ class Lego3DSound { // Lego3DSound::`scalar deleting destructor' private: - LPDIRECTSOUND3DBUFFER m_ds3dBuffer; // 0x08 - LegoROI* m_roi; // 0x0c - LegoROI* m_positionROI; // 0x10 - MxBool m_enabled; // 0x14 - MxBool m_isActor; // 0x15 - LegoActor* m_actor; // 0x18 - double m_frequencyFactor; // 0x20 - DWORD m_dwFrequency; // 0x28 - MxS32 m_volume; // 0x2c + ma_sound* m_sound; + LegoROI* m_roi; // 0x0c + LegoROI* m_positionROI; // 0x10 + MxBool m_enabled; // 0x14 + MxBool m_isActor; // 0x15 + LegoActor* m_actor; // 0x18 + double m_frequencyFactor; // 0x20 + MxS32 m_volume; // 0x2c }; // GLOBAL: LEGO1 0x100db6c0 diff --git a/LEGO1/lego/legoomni/include/legocachsound.h b/LEGO1/lego/legoomni/include/legocachsound.h index de312a93..792524b3 100644 --- a/LEGO1/lego/legoomni/include/legocachsound.h +++ b/LEGO1/lego/legoomni/include/legocachsound.h @@ -5,6 +5,7 @@ #include "lego3dsound.h" #include "mxcore.h" #include "mxstring.h" +#include "mxwavepresenter.h" // VTABLE: LEGO1 0x100d4718 // SIZE 0x88 @@ -27,7 +28,7 @@ class LegoCacheSound : public MxCore { } virtual MxResult Create( - LPPCMWAVEFORMAT p_pwfx, + MxWavePresenter::WaveFormat& p_pwfx, MxString p_mediaSrcPath, MxS32 p_volume, MxU8* p_data, @@ -54,20 +55,24 @@ class LegoCacheSound : public MxCore { void CopyData(MxU8* p_data, MxU32 p_dataSize); MxString FUN_10006d80(const MxString& p_str); - LPDIRECTSOUNDBUFFER m_dsBuffer; // 0x08 - undefined m_unk0x0c[4]; // 0x0c - Lego3DSound m_sound; // 0x10 - MxU8* m_data; // 0x40 - MxU32 m_dataSize; // 0x44 - MxString m_unk0x48; // 0x48 - MxBool m_unk0x58; // 0x58 - PCMWAVEFORMAT m_wfx; // 0x59 - MxBool m_looping; // 0x69 - MxBool m_unk0x6a; // 0x6a - MxS32 m_volume; // 0x6c - MxBool m_unk0x70; // 0x70 - MxString m_unk0x74; // 0x74 - MxBool m_muted; // 0x84 + // [library:audio] WAVE_FORMAT_PCM (audio in .SI files only used this format) + static const MxU32 supportedFormatTag = 1; + + ma_audio_buffer m_buffer; + ma_sound m_cacheSound; + undefined m_unk0x0c[4]; // 0x0c + Lego3DSound m_sound; // 0x10 + MxU8* m_data; // 0x40 + MxU32 m_dataSize; // 0x44 + MxString m_unk0x48; // 0x48 + MxBool m_unk0x58; // 0x58 + MxWavePresenter::WaveFormat m_wfx; // 0x59 + MxBool m_looping; // 0x69 + MxBool m_unk0x6a; // 0x6a + MxS32 m_volume; // 0x6c + MxBool m_unk0x70; // 0x70 + MxString m_unk0x74; // 0x74 + MxBool m_muted; // 0x84 }; #endif // LEGOCACHSOUND_H diff --git a/LEGO1/lego/legoomni/include/legoloadcachesoundpresenter.h b/LEGO1/lego/legoomni/include/legoloadcachesoundpresenter.h index 6def0dee..8aaefcee 100644 --- a/LEGO1/lego/legoomni/include/legoloadcachesoundpresenter.h +++ b/LEGO1/lego/legoomni/include/legoloadcachesoundpresenter.h @@ -36,12 +36,12 @@ class LegoLoadCacheSoundPresenter : public MxWavePresenter { void Init(); void Destroy(MxBool p_fromDestructor); - LegoCacheSound* m_cacheSound; // 0x6c - MxU8* m_data; // 0x70 - MxU8* m_pData; // 0x74 - MxU32 m_dataSize; // 0x78 - MxBool m_unk0x7c; // 0x7c - PCMWAVEFORMAT m_pcmWaveFormat; // 0x7d + LegoCacheSound* m_cacheSound; // 0x6c + MxU8* m_data; // 0x70 + MxU8* m_pData; // 0x74 + MxU32 m_dataSize; // 0x78 + MxBool m_unk0x7c; // 0x7c + WaveFormat m_waveFormat; // 0x7d }; // SYNTHETIC: LEGO1 0x10018460 diff --git a/LEGO1/lego/legoomni/include/legosoundmanager.h b/LEGO1/lego/legoomni/include/legosoundmanager.h index 72638c63..bc345d7f 100644 --- a/LEGO1/lego/legoomni/include/legosoundmanager.h +++ b/LEGO1/lego/legoomni/include/legosoundmanager.h @@ -27,7 +27,6 @@ class LegoSoundManager : public MxSoundManager { void Init(); void Destroy(MxBool p_fromDestructor); - LPDIRECTSOUND3DLISTENER m_listener; // 0x3c LegoCacheSoundManager* m_cacheSoundManager; // 0x40 }; diff --git a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp index 508cd395..4dafb36e 100644 --- a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp +++ b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp @@ -26,7 +26,7 @@ Lego3DSound::~Lego3DSound() // FUNCTION: LEGO1 0x10011680 void Lego3DSound::Init() { - m_ds3dBuffer = NULL; + m_sound = NULL; m_roi = NULL; m_positionROI = NULL; m_actor = NULL; @@ -37,23 +37,25 @@ void Lego3DSound::Init() // FUNCTION: LEGO1 0x100116a0 // FUNCTION: BETA10 0x10039647 -MxResult Lego3DSound::Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name, MxS32 p_volume) +MxResult Lego3DSound::Create(ma_sound* p_sound, const char* p_name, MxS32 p_volume) { m_volume = p_volume; if (MxOmni::IsSound3D()) { - p_directSoundBuffer->QueryInterface(IID_IDirectSound3DBuffer, (LPVOID*) &m_ds3dBuffer); - if (m_ds3dBuffer == NULL) { - return FAILURE; - } + m_sound = p_sound; - m_ds3dBuffer->SetMinDistance(15.0f, DS3D_IMMEDIATE); - m_ds3dBuffer->SetMaxDistance(100.0f, DS3D_IMMEDIATE); - m_ds3dBuffer->SetPosition(0.0f, 0.0f, -40.0f, DS3D_IMMEDIATE); - m_ds3dBuffer->SetConeOutsideVolume(-10000, DS3D_IMMEDIATE); + ma_sound_set_min_distance(m_sound, 15.0f); + ma_sound_set_max_distance(m_sound, 100.0f); + ma_sound_set_position(m_sound, 0.0f, 0.0f, -40.0f); + + // [library:audio] Which rolloff? + ma_sound_set_rolloff(m_sound, 1.0f); + + // [library:audio] Do we need this? + // m_ds3dBuffer->SetConeOutsideVolume(-10000, DS3D_IMMEDIATE); } - if (m_ds3dBuffer == NULL || p_name == NULL) { + if (m_sound == NULL || p_name == NULL) { return SUCCESS; } @@ -86,7 +88,7 @@ MxResult Lego3DSound::Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char if (MxOmni::IsSound3D()) { const float* position = m_positionROI->GetWorldPosition(); - m_ds3dBuffer->SetPosition(position[0], position[1], position[2], DS3D_IMMEDIATE); + ma_sound_set_position(m_sound, position[0], position[1], position[2]); } LegoEntity* entity = m_roi->GetEntity(); @@ -94,13 +96,11 @@ MxResult Lego3DSound::Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char m_actor = ((LegoActor*) entity); } - p_directSoundBuffer->GetFrequency(&m_dwFrequency); - if (m_actor != NULL) { m_frequencyFactor = m_actor->GetSoundFrequencyFactor(); if (m_frequencyFactor != 0.0) { - p_directSoundBuffer->SetFrequency(m_frequencyFactor * m_dwFrequency); + ma_sound_set_pitch(p_sound, m_frequencyFactor); } } @@ -110,10 +110,7 @@ MxResult Lego3DSound::Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char // FUNCTION: LEGO1 0x10011880 void Lego3DSound::Destroy() { - if (m_ds3dBuffer) { - m_ds3dBuffer->Release(); - m_ds3dBuffer = NULL; - } + m_sound = NULL; if (m_enabled && m_roi && CharacterManager()) { if (m_isActor) { @@ -129,7 +126,7 @@ void Lego3DSound::Destroy() // FUNCTION: LEGO1 0x100118e0 // FUNCTION: BETA10 0x10039a2a -MxU32 Lego3DSound::UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer) +MxU32 Lego3DSound::UpdatePosition(ma_sound* p_sound) { MxU32 updated = FALSE; @@ -146,8 +143,8 @@ MxU32 Lego3DSound::UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer) return FALSE; } - if (m_ds3dBuffer != NULL) { - m_ds3dBuffer->SetPosition(position[0], position[1], position[2], DS3D_IMMEDIATE); + if (m_sound != NULL) { + ma_sound_set_position(m_sound, position[0], position[1], position[2]); } else { MxS32 newVolume = m_volume; @@ -165,8 +162,7 @@ MxU32 Lego3DSound::UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer) } newVolume = newVolume * SoundManager()->GetVolume() / 100; - newVolume = SoundManager()->GetAttenuation(newVolume); - p_directSoundBuffer->SetVolume(newVolume); + ma_sound_set_volume(p_sound, SoundManager()->GetAttenuation(newVolume)); } updated = TRUE; @@ -175,7 +171,7 @@ MxU32 Lego3DSound::UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer) if (m_actor != NULL) { if (abs(m_frequencyFactor - m_actor->GetSoundFrequencyFactor()) > 0.0001) { m_frequencyFactor = m_actor->GetSoundFrequencyFactor(); - p_directSoundBuffer->SetFrequency(m_frequencyFactor * m_dwFrequency); + ma_sound_set_pitch(p_sound, m_frequencyFactor); updated = TRUE; } } @@ -185,13 +181,13 @@ MxU32 Lego3DSound::UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer) // FUNCTION: LEGO1 0x10011a60 // FUNCTION: BETA10 0x10039d04 -void Lego3DSound::FUN_10011a60(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name) +void Lego3DSound::FUN_10011a60(ma_sound* p_sound, const char* p_name) { - assert(p_directSoundBuffer); + assert(p_sound); if (p_name == NULL) { - if (m_ds3dBuffer != NULL) { - m_ds3dBuffer->SetMode(DS3DMODE_DISABLE, DS3D_IMMEDIATE); + if (m_sound != NULL) { + ma_sound_set_spatialization_enabled(m_sound, MA_FALSE); } } else { @@ -222,16 +218,10 @@ void Lego3DSound::FUN_10011a60(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const ch m_positionROI = m_roi; } - if (m_ds3dBuffer != NULL) { - DWORD dwMode; - m_ds3dBuffer->GetMode(&dwMode); - - if (dwMode & DS3DMODE_DISABLE) { - m_ds3dBuffer->SetMode(DS3DMODE_NORMAL, DS3D_IMMEDIATE); - } - + if (m_sound != NULL) { + ma_sound_set_spatialization_enabled(m_sound, MA_TRUE); const float* position = m_positionROI->GetWorldPosition(); - m_ds3dBuffer->SetPosition(position[0], position[1], position[2], DS3D_IMMEDIATE); + ma_sound_set_position(m_sound, position[0], position[1], position[2]); } else { const float* position = m_positionROI->GetWorldPosition(); @@ -256,8 +246,7 @@ void Lego3DSound::FUN_10011a60(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const ch } newVolume = newVolume * SoundManager()->GetVolume() / 100; - newVolume = SoundManager()->GetAttenuation(newVolume); - p_directSoundBuffer->SetVolume(newVolume); + ma_sound_set_volume(p_sound, SoundManager()->GetAttenuation(newVolume)); } } @@ -266,13 +255,11 @@ void Lego3DSound::FUN_10011a60(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const ch m_actor = ((LegoActor*) entity); } - p_directSoundBuffer->GetFrequency(&m_dwFrequency); - if (m_actor != NULL) { m_frequencyFactor = m_actor->GetSoundFrequencyFactor(); if (m_frequencyFactor != 0.0) { - p_directSoundBuffer->SetFrequency(m_frequencyFactor * m_dwFrequency); + ma_sound_set_pitch(p_sound, m_frequencyFactor); } } } @@ -299,12 +286,12 @@ void Lego3DSound::Reset() MxS32 Lego3DSound::SetDistance(MxS32 p_min, MxS32 p_max) { if (MxOmni::IsSound3D()) { - if (m_ds3dBuffer == NULL) { + if (m_sound == NULL) { return -1; } - m_ds3dBuffer->SetMinDistance(p_min, DS3D_IMMEDIATE); - m_ds3dBuffer->SetMaxDistance(p_max, DS3D_IMMEDIATE); + ma_sound_set_min_distance(m_sound, p_min); + ma_sound_set_max_distance(m_sound, p_max); return 0; } diff --git a/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp b/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp index a36b9250..c9000c27 100644 --- a/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp +++ b/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp @@ -40,23 +40,20 @@ void Lego3DWavePresenter::StartingTickle() MxWavePresenter::StartingTickle(); - /* - if (m_dsBuffer != NULL) { - MxU16 extraLength; - char* buff; - m_action->GetExtra(extraLength, buff); + if (ma_sound_get_engine(&(MxWavePresenter::m_sound))) { + MxU16 extraLength; + char* buff; + m_action->GetExtra(extraLength, buff); - if (!strcmp(buff, "FROM_PARENT") && m_compositePresenter != NULL) { - m_compositePresenter->GetAction()->GetExtra(extraLength, buff); - } - - if (m_sound.Create(m_dsBuffer, buff, m_volume) != SUCCESS) { - m_dsBuffer->Release(); - m_dsBuffer = NULL; - EndAction(); - } + if (!strcmp(buff, "FROM_PARENT") && m_compositePresenter != NULL) { + m_compositePresenter->GetAction()->GetExtra(extraLength, buff); } - */ + + if (m_sound.Create(&(MxWavePresenter::m_sound), buff, m_volume) != SUCCESS) { + ma_sound_uninit(&(MxWavePresenter::m_sound)); + EndAction(); + } + } } // FUNCTION: LEGO1 0x1004a8b0 diff --git a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp index 244b83cb..96d64a74 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp @@ -4,6 +4,8 @@ #include "misc.h" #include "mxomni.h" +#include + DECOMP_SIZE_ASSERT(LegoCacheSound, 0x88) // FUNCTION: LEGO1 0x100064d0 @@ -21,7 +23,8 @@ LegoCacheSound::~LegoCacheSound() // FUNCTION: LEGO1 0x100066d0 void LegoCacheSound::Init() { - m_dsBuffer = NULL; + SDL_zero(m_buffer); + SDL_zero(m_cacheSound); m_data = NULL; m_unk0x58 = FALSE; memset(&m_wfx, 0, sizeof(m_wfx)); @@ -35,60 +38,53 @@ void LegoCacheSound::Init() // FUNCTION: LEGO1 0x10006710 // FUNCTION: BETA10 0x10066505 MxResult LegoCacheSound::Create( - LPPCMWAVEFORMAT p_pwfx, + MxWavePresenter::WaveFormat& p_pwfx, MxString p_mediaSrcPath, MxS32 p_volume, MxU8* p_data, MxU32 p_dataSize ) { - /* - WAVEFORMATEX wfx; - wfx.wFormatTag = p_pwfx->wf.wFormatTag; - wfx.nChannels = p_pwfx->wf.nChannels; - wfx.nSamplesPerSec = p_pwfx->wf.nSamplesPerSec; - wfx.nAvgBytesPerSec = p_pwfx->wf.nAvgBytesPerSec; - wfx.nBlockAlign = p_pwfx->wf.nBlockAlign; - wfx.wBitsPerSample = p_pwfx->wBitsPerSample; - wfx.cbSize = 0; + // [library:audio] These should never be null + assert(p_data != NULL && p_dataSize != 0); - DSBUFFERDESC desc; - memset(&desc, 0, sizeof(desc)); - desc.dwSize = sizeof(desc); + assert(p_pwfx.m_formatTag == supportedFormatTag); + assert(p_pwfx.m_bitsPerSample == 8 || p_pwfx.m_bitsPerSample == 16); - if (MxOmni::IsSound3D()) { - desc.dwFlags = - DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLVOLUME; - } - else { - desc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME; + CopyData(p_data, p_dataSize); + + ma_format format = p_pwfx.m_bitsPerSample == 16 ? ma_format_s16 : ma_format_u8; + ma_uint32 bytesPerFrame = ma_get_bytes_per_frame(format, p_pwfx.m_channels); + ma_uint32 bufferSizeInFrames = p_dataSize / bytesPerFrame; + ma_audio_buffer_config config = + ma_audio_buffer_config_init(format, p_pwfx.m_channels, bufferSizeInFrames, m_data, NULL); + config.sampleRate = p_pwfx.m_samplesPerSec; + + if (ma_audio_buffer_init(&config, &m_buffer) != MA_SUCCESS) { + return FAILURE; } - desc.dwBufferBytes = p_dataSize; - desc.lpwfxFormat = &wfx; - - if (SoundManager()->GetDirectSound()->CreateSoundBuffer(&desc, &m_dsBuffer, NULL) != DS_OK) { + if (ma_sound_init_from_data_source( + SoundManager()->GetEngine(), + &m_buffer, + MxOmni::IsSound3D() ? 0 : MA_SOUND_FLAG_NO_SPATIALIZATION, + NULL, + &m_cacheSound + ) != MA_SUCCESS) { return FAILURE; } m_volume = p_volume; MxS32 volume = m_volume * SoundManager()->GetVolume() / 100; - MxS32 attenuation = SoundManager()->GetAttenuation(volume); - m_dsBuffer->SetVolume(attenuation); + ma_sound_set_volume(&m_cacheSound, SoundManager()->GetAttenuation(volume)); - if (m_sound.Create(m_dsBuffer, NULL, m_volume) != SUCCESS) { - m_dsBuffer->Release(); - m_dsBuffer = NULL; + if (m_sound.Create(&m_cacheSound, NULL, m_volume) != SUCCESS) { return FAILURE; } - if (p_data != NULL && p_dataSize != 0) { - CopyData(p_data, p_dataSize); - } - m_unk0x48 = FUN_10006d80(p_mediaSrcPath); - m_wfx = *p_pwfx;*/ + m_wfx = p_pwfx; return SUCCESS; } @@ -105,11 +101,8 @@ void LegoCacheSound::CopyData(MxU8* p_data, MxU32 p_dataSize) // FUNCTION: LEGO1 0x10006920 void LegoCacheSound::Destroy() { - if (m_dsBuffer) { - m_dsBuffer->Stop(); - m_dsBuffer->Release(); - m_dsBuffer = NULL; - } + ma_sound_uninit(&m_cacheSound); + ma_audio_buffer_uninit(&m_buffer); delete[] m_data; Init(); @@ -121,7 +114,7 @@ LegoCacheSound* LegoCacheSound::Clone() { LegoCacheSound* pnew = new LegoCacheSound(); - if (pnew->Create(&m_wfx, m_unk0x48, m_volume, m_data, m_dataSize) == SUCCESS) { + if (pnew->Create(m_wfx, m_unk0x48, m_volume, m_data, m_dataSize) == SUCCESS) { return pnew; } @@ -138,35 +131,20 @@ MxResult LegoCacheSound::Play(const char* p_name, MxBool p_looping) } m_unk0x6a = FALSE; - m_sound.FUN_10011a60(m_dsBuffer, p_name); + m_sound.FUN_10011a60(&m_cacheSound, p_name); if (p_name != NULL) { m_unk0x74 = p_name; } - DWORD dwStatus; - m_dsBuffer->GetStatus(&dwStatus); - - if (dwStatus == DSBSTATUS_BUFFERLOST) { - m_dsBuffer->Restore(); - m_dsBuffer->GetStatus(&dwStatus); + if (ma_sound_seek_to_pcm_frame(&m_cacheSound, 0) != MA_SUCCESS) { + return FAILURE; } - if (dwStatus != DSBSTATUS_BUFFERLOST) { - LPVOID pvAudioPtr1, pvAudioPtr2; - DWORD dwAudioBytes1, dwAudioBytes2; + ma_sound_set_looping(&m_cacheSound, p_looping); - if (m_dsBuffer->Lock(0, m_dataSize, &pvAudioPtr1, &dwAudioBytes1, &pvAudioPtr2, &dwAudioBytes2, 0) == DS_OK) { - memcpy(pvAudioPtr1, m_data, dwAudioBytes1); - - if (dwAudioBytes2 != 0) { - memcpy(pvAudioPtr2, m_data + dwAudioBytes1, dwAudioBytes2); - } - - m_dsBuffer->Unlock(pvAudioPtr1, dwAudioBytes1, pvAudioPtr2, dwAudioBytes2); - m_dsBuffer->SetCurrentPosition(0); - m_dsBuffer->Play(0, 0, p_looping); - } + if (ma_sound_start(&m_cacheSound) != MA_SUCCESS) { + return FAILURE; } if (p_looping == FALSE) { @@ -184,12 +162,7 @@ MxResult LegoCacheSound::Play(const char* p_name, MxBool p_looping) // FUNCTION: LEGO1 0x10006b80 void LegoCacheSound::FUN_10006b80() { - DWORD dwStatus; - m_dsBuffer->GetStatus(&dwStatus); - - if (dwStatus) { - m_dsBuffer->Stop(); - } + ma_sound_stop(&m_cacheSound); m_unk0x58 = FALSE; m_unk0x6a = FALSE; @@ -204,19 +177,16 @@ void LegoCacheSound::FUN_10006b80() void LegoCacheSound::FUN_10006be0() { if (!m_looping) { - DWORD dwStatus; - m_dsBuffer->GetStatus(&dwStatus); - if (m_unk0x70) { - if (dwStatus == 0) { + if (!ma_sound_is_playing(&m_cacheSound)) { return; } m_unk0x70 = FALSE; } - if (dwStatus == 0) { - m_dsBuffer->Stop(); + if (!ma_sound_is_playing(&m_cacheSound)) { + ma_sound_stop(&m_cacheSound); m_sound.Reset(); if (m_unk0x74.GetLength() != 0) { m_unk0x74 = ""; @@ -228,16 +198,16 @@ void LegoCacheSound::FUN_10006be0() } if (m_unk0x74.GetLength() != 0 && !m_muted) { - if (!m_sound.UpdatePosition(m_dsBuffer)) { + if (!m_sound.UpdatePosition(&m_cacheSound)) { if (m_unk0x6a) { return; } - m_dsBuffer->Stop(); + ma_sound_stop(&m_cacheSound); m_unk0x6a = TRUE; } else if (m_unk0x6a) { - m_dsBuffer->Play(0, 0, m_looping); + ma_sound_start(&m_cacheSound); m_unk0x6a = FALSE; } } @@ -262,10 +232,10 @@ void LegoCacheSound::Mute(MxBool p_muted) m_muted = p_muted; if (m_muted) { - m_dsBuffer->Stop(); + ma_sound_stop(&m_cacheSound); } else { - m_dsBuffer->Play(0, 0, m_looping); + ma_sound_start(&m_cacheSound); } } } diff --git a/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp b/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp index 5603ac2f..8adb79df 100644 --- a/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp +++ b/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp @@ -43,7 +43,6 @@ void LegoLoadCacheSoundPresenter::Destroy(MxBool p_fromDestructor) void LegoLoadCacheSoundPresenter::ReadyTickle() { MxStreamChunk* chunk = NextChunk(); - return EndAction(); if (chunk) { WaveFormat* header = (WaveFormat*) chunk->GetData(); @@ -54,7 +53,7 @@ void LegoLoadCacheSoundPresenter::ReadyTickle() m_pData = data; m_cacheSound = new LegoCacheSound(); - // m_pcmWaveFormat = header->m_pcmWaveFormat; + m_waveFormat = *header; m_subscriber->FreeDataChunk(chunk); ProgressTickleState(e_streaming); @@ -70,7 +69,7 @@ void LegoLoadCacheSoundPresenter::StreamingTickle() if (chunk) { if (chunk->GetChunkFlags() & DS_CHUNK_END_OF_STREAM) { m_cacheSound->Create( - &m_pcmWaveFormat, + m_waveFormat, ((MxDSSound*) m_action)->GetMediaSrcPath(), ((MxDSSound*) m_action)->GetVolume(), m_data + 2, diff --git a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp index bba0c012..fe287b90 100644 --- a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp @@ -22,7 +22,6 @@ LegoSoundManager::~LegoSoundManager() void LegoSoundManager::Init() { m_cacheSoundManager = NULL; - m_listener = NULL; } // FUNCTION: LEGO1 0x100299b0 @@ -43,31 +42,9 @@ MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) MxResult result = FAILURE; if (MxSoundManager::Create(10, FALSE) == SUCCESS) { - /* m_criticalSection.Enter(); locked = TRUE; - - if (MxOmni::IsSound3D()) { - if (m_dsBuffer->QueryInterface(IID_IDirectSound3DListener, (LPVOID*) &m_listener) != DS_OK) { - goto done; - } - - MxOmni* omni = MxOmni::GetInstance(); - LPDIRECTSOUND sound; - - if (omni && omni->GetSoundManager() && (sound = omni->GetSoundManager()->GetDirectSound())) { - DSCAPS caps; - memset(&caps, 0, sizeof(DSCAPS)); - caps.dwSize = sizeof(DSCAPS); - - if (sound->GetCaps(&caps) == S_OK && caps.dwMaxHw3DAllBuffers == 0) { - m_listener->SetDistanceFactor(0.026315790f, 0); - m_listener->SetRolloffFactor(10, 0); - } - } - } - - m_cacheSoundManager = new LegoCacheSoundManager;*/ + m_cacheSoundManager = new LegoCacheSoundManager; result = SUCCESS; } @@ -107,29 +84,22 @@ void LegoSoundManager::UpdateListener( const float* p_velocity ) { - if (m_listener != NULL) { + if (MxOmni::IsSound3D()) { + // [library:audio] + // miniaudio expects the right-handed OpenGL coordinate system, while LEGO Island + // uses DirectX' left-handed system? Figure out the proper conversions + if (p_position != NULL) { - m_listener->SetPosition(p_position[0], p_position[1], p_position[2], DS3D_DEFERRED); + ma_engine_listener_set_position(&m_engine, 0, p_position[0], p_position[1], p_position[2]); } if (p_direction != NULL && p_up != NULL) { - m_listener->SetOrientation( - p_direction[0], - p_direction[1], - p_direction[2], - p_up[0], - p_up[1], - p_up[2], - DS3D_DEFERRED - ); + ma_engine_listener_set_direction(&m_engine, 0, p_direction[0], p_direction[1], p_direction[2]); + ma_engine_listener_set_world_up(&m_engine, 0, p_up[0], p_up[1], p_up[2]); } if (p_velocity != NULL) { - m_listener->SetVelocity(p_velocity[0], p_velocity[1], p_velocity[2], DS3D_DEFERRED); - } - - if (p_position != NULL || (p_direction != NULL && p_up != NULL) || p_velocity != NULL) { - m_listener->CommitDeferredSettings(); + ma_engine_listener_set_velocity(&m_engine, 0, p_velocity[0], p_velocity[1], p_velocity[2]); } } } diff --git a/LEGO1/omni/include/mxsoundmanager.h b/LEGO1/omni/include/mxsoundmanager.h index 79aebd27..26b8b1cc 100644 --- a/LEGO1/omni/include/mxsoundmanager.h +++ b/LEGO1/omni/include/mxsoundmanager.h @@ -6,7 +6,6 @@ #include "mxaudiomanager.h" #include -#include #include // VTABLE: LEGO1 0x100dc128 diff --git a/LEGO1/omni/src/audio/mxwavepresenter.cpp b/LEGO1/omni/src/audio/mxwavepresenter.cpp index 1314d71a..22354e9e 100644 --- a/LEGO1/omni/src/audio/mxwavepresenter.cpp +++ b/LEGO1/omni/src/audio/mxwavepresenter.cpp @@ -197,7 +197,8 @@ void MxWavePresenter::StreamingTickle() // FUNCTION: LEGO1 0x100b20c0 void MxWavePresenter::DoneTickle() { - if (!ma_sound_get_engine(&m_sound) || m_action->GetFlags() & MxDSAction::c_bit7 || !ma_sound_is_playing(&m_sound)) { + if (!ma_sound_get_engine(&m_sound) || m_action->GetFlags() & MxDSAction::c_bit7 || + ma_pcm_rb_pointer_distance(&m_rb) == 0) { MxMediaPresenter::DoneTickle(); } }