Initial CStreamAudioManager implementation

This commit is contained in:
Jack Andersen 2017-01-15 22:40:33 -10:00
parent 7db63f3663
commit 01c31b4fc5
15 changed files with 1204 additions and 200 deletions

View File

@ -14,13 +14,13 @@ struct StreamedAudio : IScriptObject
DECL_YAML
String<-1> name;
Value<bool> active;
String<-1> channels;
Value<bool> unnknown1;
Value<float> unknown2;
Value<float> unknown3;
Value<atUint32> unknown4;
Value<atUint32> unknown5;
Value<bool> unknown6;
String<-1> fileName;
Value<bool> noStopOnDeactivate;
Value<float> fadeInTime;
Value<float> fadeOutTime;
Value<atUint32> volume;
Value<atUint32> oneShot;
Value<bool> music;
};
}
}

View File

@ -1,120 +0,0 @@
#include "CDSPAudioPlayer.hpp"
#include <memory>
namespace urde
{
struct SDSPStreamCacheEntry
{
std::string x0_fileName;
u32 x10_;
u32 x14_;
float x18_;
float x1c_;
u32 x20_;
float x24_;
bool x28_;
};
/* Standard DSPADPCM header */
struct dspadpcm_header
{
uint32_t x0_num_samples;
uint32_t x4_num_nibbles;
uint32_t x8_sample_rate;
uint16_t xc_loop_flag;
uint16_t xe_format; /* 0 for ADPCM */
uint32_t x10_loop_start_nibble;
uint32_t x14_loop_end_nibble;
uint32_t x18_ca;
int16_t x1c_coef[16];
int16_t x3c_gain;
int16_t x3e_ps;
int16_t x40_hist1;
int16_t x42_hist2;
int16_t x44_loop_ps;
int16_t x46_loop_hist1;
int16_t x48_loop_hist2;
uint16_t x4a_pad[11];
};
struct CDSPStreamManager
{
dspadpcm_header x0_header;
std::string x60_fileName; // arg1
union
{
u8 dummy = 0;
struct
{
bool x70_24_claimed : 1;
bool x70_25_ : 1;
u8 x70_26_ : 2;
};
};
u8 x71_ = -1;
u8 x72_ = -1;
u8 x73_arg3;
u8 x74_arg4;
u32 x78_handleId; // arg2
//DVDFileInfo x80_dvdHandle;
};
struct SDSPStreamInfo
{
const char* x0_fileName;
u32 x4_;
u32 x8_;
u32 xc_;
u32 x10_;
u32 x14_;
u32 x18_adpcmOffset;
u32 x1c_;
u32 x20_;
u32 x24_adpcmCur;
u32 x28_;
u32 x2c_;
u32 x30_;
u32 x34_;
u32 x38_;
};
struct SDSPStream
{
bool x0_active;
u32 x4_ownerId;
SDSPStream* x8_stereoLeft;
SDSPStream* xc_stereoRight;
SDSPStreamInfo x10_info;
u8 x4c_vol;
u8 x4d_pan;
//DVDFileInfo x50_dvdHandle1;
//DVDFileInfo x8c_dvdHandle2;
u32 xc8_streamId = -1; // MusyX stream handle
u32 xcc_adpcmCur2;
std::unique_ptr<u8[]> xd4_ringBuffer;
u32 xd8_ringBytes = 0x11DC0; // 73152 4sec in ADPCM bytes
u32 xdc_ringSamples = 0x1f410; // 128016 4sec in samples
bool xe0_curBuffer;
u32 xe8_silent;
u8 xec_readState; // 0: NoRead 1: Read 2: ReadWrap
void UpdateStreamVolume(u8 vol)
{
x4c_vol = vol;
if (!x0_active || xe8_silent)
return;
//sndStreamMixParameterEx(xc8_streamId, x4c_vol, x4d_pan, 0, 0, 0);
}
void SilenceStream()
{
if (!x0_active || xe8_silent)
return;
//sndStreamMixParameterEx(xc8_streamId, 0, x4d_pan, 0, 0, 0);
xe8_silent = true;
}
};
}

View File

@ -1,16 +0,0 @@
#ifndef __URDE_CDSPAUDIOPLAYER_HPP__
#define __URDE_CDSPAUDIOPLAYER_HPP__
#include "RetroTypes.hpp"
namespace urde
{
class CDSPAudioPlayer
{
};
}
#endif // __URDE_CDSPAUDIOPLAYER_HPP__

View File

@ -4,7 +4,7 @@ set(AUDIO_SOURCES
CAudioGroupSet.hpp CAudioGroupSet.cpp
CSfxManager.hpp CSfxManager.cpp
CStaticAudioPlayer.hpp CStaticAudioPlayer.cpp
CDSPAudioPlayer.hpp CDSPAudioPlayer.cpp
CStreamAudioManager.hpp CStreamAudioManager.cpp
g721.c g721.h)
runtime_add_list(Audio AUDIO_SOURCES)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
#ifndef __URDE_CSTREAMAUDIOMANAGER_HPP__
#define __URDE_CSTREAMAUDIOMANAGER_HPP__
#include "RetroTypes.hpp"
namespace urde
{
class CStreamAudioManager
{
static u8 g_MusicVolume;
static u8 g_SfxVolume;
static bool g_MusicUnmute;
static bool g_SfxUnmute;
static u8 GetTargetDSPVolume(u8 fileVol, bool music);
static void StopStreaming(bool oneshot);
static void UpdateDSP(bool oneshot, float dt);
static void UpdateDSPStreamers(float dt);
public:
static void Start(bool oneshot, const std::string& fileName, u8 volume,
bool music, float fadeIn, float fadeOut);
static void Stop(bool oneshot, const std::string& fileName);
static void FadeBackIn(bool oneshot, float fadeTime);
static void TemporaryFadeOut(bool oneshot, float fadeTime);
static void Update(float dt);
};
}
#endif // __URDE_CSTREAMAUDIOMANAGER_HPP__

View File

@ -15,6 +15,7 @@ class CFileDvdRequest : public IDvdRequest
int m_offset;
bool m_cancel = false;
bool m_complete = false;
std::function<void(u32)> m_callback;
public:
~CFileDvdRequest()
{
@ -40,20 +41,25 @@ public:
return EMediaType::File;
}
CFileDvdRequest(CDvdFile& file, void* buf, u32 len, ESeekOrigin whence, int off)
: m_reader(file.m_reader), m_buf(buf), m_len(len), m_whence(whence), m_offset(off) {}
CFileDvdRequest(CDvdFile& file, void* buf, u32 len, ESeekOrigin whence, int off, std::function<void(u32)>&& cb)
: m_reader(file.m_reader), m_buf(buf), m_len(len), m_whence(whence), m_offset(off), m_callback(std::move(cb)) {}
void DoRequest()
{
if (m_cancel)
return;
u32 readLen;
if (m_whence == ESeekOrigin::Cur && m_offset == 0)
m_reader->readBytesToBuf(m_buf, m_len);
{
readLen = m_reader->readBytesToBuf(m_buf, m_len);
}
else
{
m_reader->seek(m_offset, athena::SeekOrigin(m_whence));
m_reader->readBytesToBuf(m_buf, m_len);
readLen = m_reader->readBytesToBuf(m_buf, m_len);
}
if (m_callback)
m_callback(readLen);
m_complete = true;
}
};
@ -89,10 +95,11 @@ void CDvdFile::WorkerProc()
}
}
std::shared_ptr<IDvdRequest> CDvdFile::AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off)
std::shared_ptr<IDvdRequest> CDvdFile::AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence,
int off, std::function<void(u32)>&& cb)
{
std::shared_ptr<IDvdRequest> ret =
std::make_shared<CFileDvdRequest>(*this, buf, len, whence, off);
std::make_shared<CFileDvdRequest>(*this, buf, len, whence, off, std::move(cb));
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
m_RequestQueue.emplace_back(ret);
lk.unlock();

View File

@ -49,6 +49,7 @@ public:
: x18_path(path),
m_reader(std::make_shared<athena::io::FileReader>(
hecl::ProjectPath(m_DvdRoot, path).getAbsolutePath())) {}
operator bool() const { return m_reader->isOpen(); }
void UpdateFilePos(int pos)
{
m_reader->seek(pos, athena::SeekOrigin::Begin);
@ -61,19 +62,20 @@ public:
{
m_reader->close();
}
std::shared_ptr<IDvdRequest> AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off);
void SyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int offset)
std::shared_ptr<IDvdRequest> AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence,
int off, std::function<void(u32)>&& cb = {});
u32 SyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int offset)
{
m_reader->seek(offset, athena::SeekOrigin(whence));
m_reader->readBytesToBuf(buf, len);
return m_reader->readBytesToBuf(buf, len);
}
std::shared_ptr<IDvdRequest> AsyncRead(void* buf, u32 len)
std::shared_ptr<IDvdRequest> AsyncRead(void* buf, u32 len, std::function<void(u32)>&& cb = {})
{
return AsyncSeekRead(buf, len, ESeekOrigin::Cur, 0);
return AsyncSeekRead(buf, len, ESeekOrigin::Cur, 0, std::move(cb));
}
void SyncRead(void* buf, u32 len)
u32 SyncRead(void* buf, u32 len)
{
m_reader->readBytesToBuf(buf, len);
return m_reader->readBytesToBuf(buf, len);
}
u64 Length() {return m_reader->length();}
};

View File

@ -14,8 +14,17 @@ class CTweakValue
public:
struct Audio
{
Audio(float, float, float, const std::string&, u32);
void None();
float x0_fadeIn, x4_fadeOut, x8_volume;
std::string xc_fileName;
u32 x1c_handle;
Audio(float fadeIn, float fadeOut, float vol, const std::string& fileName, u32 handle)
: x0_fadeIn(fadeIn), x4_fadeOut(fadeOut), x8_volume(vol), xc_fileName(fileName), x1c_handle(handle) {}
float GetFadeIn() const { return x0_fadeIn; }
float GetFadeOut() const { return x4_fadeOut; }
float GetVolume() const { return x8_volume; }
const std::string& GetFileName() const { return xc_fileName; }
u32 GetHandle() const { return x1c_handle; }
static Audio None() { return Audio{0.f, 0.f, 0.f, "", 0}; }
};
enum class EType
{
@ -24,7 +33,13 @@ public:
EType x0_type;
std::string x4_key;
std::string x30_str;
std::string x14_str;
Audio x24_audio;
union
{
u32 x44_int;
float x44_flt;
};
public:
CTweakValue()=default;
//CTweakValue(CTextInputStream&);
@ -32,7 +47,7 @@ public:
const std::string& GetName() const { return x4_key; }
const std::string& GetValueAsString() const;
void SetValueFromString(const std::string&);
const Audio& GetAudio() const;
const Audio& GetAudio() const { return x24_audio; }
EType GetType() const { return x0_type; }
};

View File

@ -274,6 +274,7 @@ public:
void SetXRaySpeedAndTarget(float f1, float f2);
void SetThermalSpeedAndTarget(float f1, float f2);
ResId GetAreaAssetId() const { return x84_mrea; }
const CAreaFog* GetAreaFog() const { return GetPostConstructed()->x10c4_areaFog.get(); }
CAreaFog* AreaFog() { return const_cast<CAreaFog*>(GetAreaFog()); }
bool DoesAreaNeedEnvFx() const;

View File

@ -1,11 +1,16 @@
#include "CScriptStreamedMusic.hpp"
#include "CStringExtras.hpp"
#include "TCastTo.hpp"
#include "CStateManager.hpp"
#include "CWorld.hpp"
#include "CInGameTweakManagerBase.hpp"
#include "GameGlobalObjects.hpp"
#include "Audio/CStreamAudioManager.hpp"
namespace urde
{
bool CScriptStreamedMusic::ValidateFileName(const std::string& fileName)
bool CScriptStreamedMusic::IsDSPFile(const std::string& fileName)
{
if (!CStringExtras::CompareCaseInsensitive(fileName, "sw"))
return true;
@ -14,32 +19,83 @@ bool CScriptStreamedMusic::ValidateFileName(const std::string& fileName)
return false;
}
void CScriptStreamedMusic::StopStream(CStateManager& mgr)
{
CStreamAudioManager::Stop(!x46_loop, x34_fileName);
}
void CScriptStreamedMusic::StartStream(CStateManager& mgr)
{
CStreamAudioManager::Start(!x46_loop, x34_fileName, x50_volume,
x47_music, x48_fadeIn, x4c_fadeOut);
}
void CScriptStreamedMusic::TweakOverride(CStateManager& mgr)
{
const CWorld* wld = mgr.GetWorld();
const CGameArea* area = wld->GetAreaAlways(x4_areaId);
std::string twkName = hecl::Format("Area %8.8x MusicObject: %s",
area->GetAreaAssetId(), x10_name.c_str());
if (g_TweakManager->HasTweakValue(twkName))
{
const CTweakValue::Audio& audio = g_TweakManager->GetTweakValue(twkName)->GetAudio();
x34_fileName = audio.GetFileName();
x45_fileIsDsp = IsDSPFile(x34_fileName);
x48_fadeIn = audio.GetFadeIn();
x4c_fadeOut = audio.GetFadeOut();
x50_volume = audio.GetVolume() * 127.f;
}
}
CScriptStreamedMusic::CScriptStreamedMusic(TUniqueId id, const CEntityInfo& info, const std::string& name,
bool active, const std::string& fileName, bool b1, float f1, float f2,
u32 w1, bool b2, bool b3)
: CEntity(id, info, active, name), x34_fileName(fileName), x44_b1(b1),
x45_fileNameValid(ValidateFileName(fileName)), x46_b2(b2), x47_b3(b3),
x48_f1(f1), x4c_f2(f2), x50_w1(w1) {}
bool active, const std::string& fileName, bool noStopOnDeactivate,
float fadeIn, float fadeOut, u32 volume, bool loop, bool music)
: CEntity(id, info, active, name), x34_fileName(fileName), x44_noStopOnDeactivate(noStopOnDeactivate),
x45_fileIsDsp(IsDSPFile(fileName)), x46_loop(loop), x47_music(music),
x48_fadeIn(fadeIn), x4c_fadeOut(fadeOut), x50_volume(volume) {}
void CScriptStreamedMusic::Stop(CStateManager& mgr)
{
if (x45_fileIsDsp)
StopStream(mgr);
}
void CScriptStreamedMusic::Play(CStateManager& mgr)
{
TweakOverride(mgr);
if (x45_fileIsDsp)
StartStream(mgr);
}
void CScriptStreamedMusic::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptStreamedMusic::PreThink(float, CStateManager&)
{
}
void CScriptStreamedMusic::Think(float, CStateManager&)
{
}
void CScriptStreamedMusic::AcceptScriptMsg(EScriptObjectMessage msg,
TUniqueId objId, CStateManager& stateMgr)
{
CEntity::AcceptScriptMsg(msg, objId, stateMgr);
switch (msg)
{
case EScriptObjectMessage::Play:
if (x30_24_active)
Play(stateMgr);
break;
case EScriptObjectMessage::Stop:
if (x30_24_active)
Stop(stateMgr);
break;
case EScriptObjectMessage::Increment:
if (x45_fileIsDsp)
CStreamAudioManager::FadeBackIn(!x46_loop, x48_fadeIn);
break;
case EScriptObjectMessage::Decrement:
if (x45_fileIsDsp)
CStreamAudioManager::TemporaryFadeOut(!x46_loop, x4c_fadeOut);
break;
default: break;
}
}
}

View File

@ -9,27 +9,26 @@ namespace urde
class CScriptStreamedMusic : public CEntity
{
std::string x34_fileName;
bool x44_b1;
bool x45_fileNameValid;
bool x46_b2;
bool x47_b3;
float x48_f1;
float x4c_f2;
u32 x50_w1;
static bool ValidateFileName(const std::string& fileName);
bool x44_noStopOnDeactivate;
bool x45_fileIsDsp; // As opposed to .adp for DTK streaming
bool x46_loop;
bool x47_music;
float x48_fadeIn;
float x4c_fadeOut;
u32 x50_volume;
static bool IsDSPFile(const std::string& fileName);
void StopStream(CStateManager& mgr);
void StartStream(CStateManager& mgr);
void TweakOverride(CStateManager& mgr);
public:
CScriptStreamedMusic(TUniqueId id, const CEntityInfo& info, const std::string& name,
bool, const std::string& fileName, bool, float, float, u32,
bool, bool);
bool active, const std::string& fileName, bool noStopOnDeactivate,
float fadeIn, float fadeOut, u32 volume, bool loop, bool music);
void Stop(CStateManager& mgr);
void Play(CStateManager& mgr);
void Accept(IVisitor& visitor);
void PreThink(float, CStateManager&);
void Think(float, CStateManager&);
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr);
};

View File

@ -318,7 +318,7 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId)
x84_defAudioTrack = r.readString();
std::string trackKey = hecl::Format("WorldDefault: %8.8x", u32(x8_mlvlId));
if (g_TweakManager->HasTweakValue(trackKey))
x84_defAudioTrack = g_TweakManager->GetTweakValue(trackKey)->x30_str;
x84_defAudioTrack = g_TweakManager->GetTweakValue(trackKey)->GetAudio().GetFileName();
}
CWorldLayers::ReadWorldLayers(r);

View File

@ -1804,16 +1804,18 @@ CEntity* ScriptLoader::LoadStreamedAudio(CStateManager& mgr, CInputStream& in, i
return nullptr;
const std::string name = mgr.HashInstanceName(in);
bool b1 = in.readBool();
bool active = in.readBool();
std::string fileName = in.readString();
bool b2 = in.readBool();
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
u32 w1 = in.readUint32Big();
u32 w2 = in.readUint32Big();
bool b3 = in.readBool();
bool noStopOnDeactivate = in.readBool();
float fadeIn = in.readFloatBig();
float fadeOut = in.readFloatBig();
u32 volume = in.readUint32Big();
u32 oneShot = in.readUint32Big();
bool music = in.readBool();
return new CScriptStreamedMusic(mgr.AllocateUniqueId(), info, name, b1, fileName, b2, f1, f2, w1, !w2, b3);
return new CScriptStreamedMusic(mgr.AllocateUniqueId(), info, name,
active, fileName, noStopOnDeactivate,
fadeIn, fadeOut, volume, !oneShot, music);
}
CEntity* ScriptLoader::LoadRepulsor(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)

2
hecl

@ -1 +1 @@
Subproject commit 28e95cb6255cfe7334b483021ceffac4a5662b5c
Subproject commit 0c6a88a95af7a36cebda27f3c511ba585d195230