mirror of https://github.com/AxioDL/metaforce.git
Fix TSan-reported race conditions
This commit is contained in:
parent
4062b2dfb7
commit
56a5cfd115
|
@ -1301,7 +1301,7 @@ void SpecBase::backgroundIndexRecursiveProc(const hecl::ProjectPath& dir,
|
||||||
|
|
||||||
void SpecBase::backgroundIndexProc()
|
void SpecBase::backgroundIndexProc()
|
||||||
{
|
{
|
||||||
logvisor::RegisterThreadName("Resource Index Thread");
|
logvisor::RegisterThreadName("Resource Index");
|
||||||
|
|
||||||
hecl::ProjectPath tagCachePath(m_project.getProjectCookedPath(getOriginalSpec()), _S("tag_cache.yaml"));
|
hecl::ProjectPath tagCachePath(m_project.getProjectCookedPath(getOriginalSpec()), _S("tag_cache.yaml"));
|
||||||
hecl::ProjectPath nameCachePath(m_project.getProjectCookedPath(getOriginalSpec()), _S("name_cache.yaml"));
|
hecl::ProjectPath nameCachePath(m_project.getProjectCookedPath(getOriginalSpec()), _S("name_cache.yaml"));
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct Application : boo::IApplicationCallback
|
||||||
hecl::CVarCommons m_cvarCommons;
|
hecl::CVarCommons m_cvarCommons;
|
||||||
std::unique_ptr<ViewManager> m_viewManager;
|
std::unique_ptr<ViewManager> m_viewManager;
|
||||||
|
|
||||||
bool m_running = true;
|
std::atomic_bool m_running = {true};
|
||||||
|
|
||||||
Application() :
|
Application() :
|
||||||
m_fileMgr(_S("urde")),
|
m_fileMgr(_S("urde")),
|
||||||
|
@ -77,7 +77,7 @@ struct Application : boo::IApplicationCallback
|
||||||
{
|
{
|
||||||
initialize(app);
|
initialize(app);
|
||||||
m_viewManager->init(app);
|
m_viewManager->init(app);
|
||||||
while (m_running)
|
while (m_running.load())
|
||||||
{
|
{
|
||||||
if (!m_viewManager->proc())
|
if (!m_viewManager->proc())
|
||||||
break;
|
break;
|
||||||
|
@ -90,7 +90,7 @@ struct Application : boo::IApplicationCallback
|
||||||
}
|
}
|
||||||
void appQuitting(boo::IApplication*)
|
void appQuitting(boo::IApplication*)
|
||||||
{
|
{
|
||||||
m_running = false;
|
m_running.store(false);
|
||||||
}
|
}
|
||||||
void appFilesOpen(boo::IApplication*, const std::vector<boo::SystemString>& paths)
|
void appFilesOpen(boo::IApplication*, const std::vector<boo::SystemString>& paths)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct SDSPStreamInfo
|
||||||
u32 x4_sampleRate;
|
u32 x4_sampleRate;
|
||||||
u32 x8_headerSize = sizeof(dspadpcm_header);
|
u32 x8_headerSize = sizeof(dspadpcm_header);
|
||||||
u32 xc_adpcmBytes;
|
u32 xc_adpcmBytes;
|
||||||
u32 x10_loopFlag;
|
bool x10_loopFlag;
|
||||||
u32 x14_loopStartByte;
|
u32 x14_loopStartByte;
|
||||||
u32 x18_loopEndByte;
|
u32 x18_loopEndByte;
|
||||||
s16 x1c_coef[8][2];
|
s16 x1c_coef[8][2];
|
||||||
|
@ -54,7 +54,7 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
{
|
{
|
||||||
bool x0_active;
|
bool x0_active;
|
||||||
bool x1_oneshot;
|
bool x1_oneshot;
|
||||||
u32 x4_ownerId;
|
s32 x4_ownerId;
|
||||||
SDSPStream* x8_stereoLeft;
|
SDSPStream* x8_stereoLeft;
|
||||||
SDSPStream* xc_companionRight;
|
SDSPStream* xc_companionRight;
|
||||||
SDSPStreamInfo x10_info;
|
SDSPStreamInfo x10_info;
|
||||||
|
@ -68,7 +68,7 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
u32 xd8_ringBytes = 0x11DC0; // 73152 4sec in ADPCM bytes
|
u32 xd8_ringBytes = 0x11DC0; // 73152 4sec in ADPCM bytes
|
||||||
u32 xdc_ringSamples = 0x1f410; // 128016 4sec in samples
|
u32 xdc_ringSamples = 0x1f410; // 128016 4sec in samples
|
||||||
s8 xe0_curBuffer = -1;
|
s8 xe0_curBuffer = -1;
|
||||||
u32 xe8_silent = true;
|
bool xe8_silent = true;
|
||||||
u8 xec_readState = 0; // 0: NoRead 1: Read 2: ReadWrap
|
u8 xec_readState = 0; // 0: NoRead 1: Read 2: ReadWrap
|
||||||
|
|
||||||
std::experimental::optional<CDvdFile> m_file;
|
std::experimental::optional<CDvdFile> m_file;
|
||||||
|
@ -171,20 +171,22 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 m_curSample = 0;
|
unsigned m_curSample = 0;
|
||||||
u32 m_totalSamples = 0;
|
unsigned m_totalSamples = 0;
|
||||||
s16 m_prev1 = 0;
|
s16 m_prev1 = 0;
|
||||||
s16 m_prev2 = 0;
|
s16 m_prev2 = 0;
|
||||||
|
|
||||||
void preSupplyAudio(boo::IAudioVoice&, double) {}
|
void preSupplyAudio(boo::IAudioVoice&, double) {}
|
||||||
|
|
||||||
void decompressChunk(u32 readToSample, int16_t*& data)
|
unsigned decompressChunk(unsigned readToSample, int16_t*& data)
|
||||||
{
|
{
|
||||||
auto sampDiv = std::div(m_curSample, 14);
|
unsigned startSamp = m_curSample;
|
||||||
|
|
||||||
|
auto sampDiv = std::div(int(m_curSample), int(14));
|
||||||
if (sampDiv.rem)
|
if (sampDiv.rem)
|
||||||
{
|
{
|
||||||
unsigned samps = DSPDecompressFrameRanged(data, xd4_ringBuffer.get() + sampDiv.quot * 8,
|
unsigned samps = DSPDecompressFrameRanged(data, xd4_ringBuffer.get() + sampDiv.quot * 8,
|
||||||
x10_info.x1c_coef, &m_prev1, &m_prev2, sampDiv.rem,
|
x10_info.x1c_coef, &m_prev1, &m_prev2, unsigned(sampDiv.rem),
|
||||||
readToSample - m_curSample);
|
readToSample - m_curSample);
|
||||||
m_curSample += samps;
|
m_curSample += samps;
|
||||||
data += samps;
|
data += samps;
|
||||||
|
@ -200,6 +202,8 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
data += samps;
|
data += samps;
|
||||||
++sampDiv.quot;
|
++sampDiv.quot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return m_curSample - startSamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t supplyAudio(boo::IAudioVoice&, size_t frames, int16_t* data)
|
size_t supplyAudio(boo::IAudioVoice&, size_t frames, int16_t* data)
|
||||||
|
@ -217,43 +221,52 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xec_readState != 2 || (xe0_curBuffer == 0 && m_curSample >= xdc_ringSamples / 2))
|
unsigned halfRingSamples = xdc_ringSamples / 2;
|
||||||
|
|
||||||
|
size_t remFrames = frames;
|
||||||
|
while (remFrames)
|
||||||
{
|
{
|
||||||
if (!BufferStream())
|
if (xec_readState != 2 || (xe0_curBuffer == 0 && m_curSample >= halfRingSamples))
|
||||||
{
|
{
|
||||||
memset(data, 0, frames * 2);
|
if (!BufferStream())
|
||||||
return frames;
|
{
|
||||||
|
memset(data, 0, remFrames * 2);
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
u32 readToSample = m_curSample + frames;
|
unsigned readToSample = std::min(m_curSample + unsigned(remFrames),
|
||||||
if (!x10_info.x10_loopFlag)
|
(m_curSample / halfRingSamples + 1) * halfRingSamples);
|
||||||
{
|
|
||||||
m_totalSamples += frames;
|
if (!x10_info.x10_loopFlag)
|
||||||
u32 fileSamples = x10_info.xc_adpcmBytes * 14 / 8;
|
|
||||||
if (m_totalSamples >= fileSamples)
|
|
||||||
{
|
{
|
||||||
u32 leftover = m_totalSamples - fileSamples;
|
m_totalSamples += remFrames;
|
||||||
readToSample -= leftover;
|
size_t fileSamples = x10_info.xc_adpcmBytes * 14 / 8;
|
||||||
memset(data + frames - leftover, 0, leftover * 2);
|
if (m_totalSamples >= fileSamples)
|
||||||
StopStream();
|
{
|
||||||
|
size_t leftover = m_totalSamples - fileSamples;
|
||||||
|
readToSample -= leftover;
|
||||||
|
remFrames -= leftover;
|
||||||
|
memset(data + remFrames, 0, leftover * 2);
|
||||||
|
StopStream();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
u32 leftoverSamples = 0;
|
unsigned leftoverSamples = 0;
|
||||||
if (readToSample > xdc_ringSamples)
|
if (readToSample > xdc_ringSamples)
|
||||||
{
|
{
|
||||||
leftoverSamples = readToSample - xdc_ringSamples;
|
leftoverSamples = readToSample - xdc_ringSamples;
|
||||||
readToSample = xdc_ringSamples;
|
readToSample = xdc_ringSamples;
|
||||||
}
|
}
|
||||||
|
|
||||||
decompressChunk(readToSample, data);
|
remFrames -= decompressChunk(readToSample, data);
|
||||||
|
|
||||||
if (leftoverSamples)
|
if (leftoverSamples)
|
||||||
{
|
{
|
||||||
BufferStream();
|
BufferStream();
|
||||||
m_curSample = 0;
|
m_curSample = 0;
|
||||||
decompressChunk(leftoverSamples, data);
|
remFrames -= decompressChunk(leftoverSamples, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return frames;
|
return frames;
|
||||||
|
@ -294,14 +307,18 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
SDSPStream& stream = g_Streams[i];
|
SDSPStream& stream = g_Streams[i];
|
||||||
stream.m_booVoice.reset();
|
stream.m_booVoice.reset();
|
||||||
stream.x0_active = false;
|
stream.x0_active = false;
|
||||||
|
for (int j=0 ; j<2 ; ++j)
|
||||||
|
if (stream.m_readReqs[j])
|
||||||
|
{
|
||||||
|
stream.m_readReqs[j]->PostCancelRequest();
|
||||||
|
stream.m_readReqs[j].reset();
|
||||||
|
}
|
||||||
stream.xd4_ringBuffer.reset();
|
stream.xd4_ringBuffer.reset();
|
||||||
stream.m_readReqs[0].reset();
|
|
||||||
stream.m_readReqs[1].reset();
|
|
||||||
stream.m_file = std::experimental::nullopt;
|
stream.m_file = std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 PickFreeStream(SDSPStream*& streamOut, bool oneshot)
|
static s32 PickFreeStream(SDSPStream*& streamOut, bool oneshot)
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<4 ; ++i)
|
for (int i=0 ; i<4 ; ++i)
|
||||||
{
|
{
|
||||||
|
@ -320,9 +337,9 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 FindStreamIdx(u32 id)
|
static s32 FindStreamIdx(s32 id)
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<4 ; ++i)
|
for (s32 i=0 ; i<4 ; ++i)
|
||||||
{
|
{
|
||||||
SDSPStream& stream = g_Streams[i];
|
SDSPStream& stream = g_Streams[i];
|
||||||
if (stream.x4_ownerId == id)
|
if (stream.x4_ownerId == id)
|
||||||
|
@ -337,14 +354,14 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
if (!x0_active || xe8_silent)
|
if (!x0_active || xe8_silent)
|
||||||
return;
|
return;
|
||||||
float coefs[8] = {};
|
float coefs[8] = {};
|
||||||
coefs[int(boo::AudioChannel::FrontLeft)] = m_leftgain * vol * 0.7f;
|
coefs[int(boo::AudioChannel::FrontLeft)] = m_leftgain * vol;
|
||||||
coefs[int(boo::AudioChannel::FrontRight)] = m_rightgain * vol * 0.7f;
|
coefs[int(boo::AudioChannel::FrontRight)] = m_rightgain * vol;
|
||||||
m_booVoice->setMonoChannelLevels(nullptr, coefs, true);
|
m_booVoice->setMonoChannelLevels(nullptr, coefs, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateVolume(u32 id, float vol)
|
static void UpdateVolume(s32 id, float vol)
|
||||||
{
|
{
|
||||||
u32 idx = FindStreamIdx(id);
|
s32 idx = FindStreamIdx(id);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -366,9 +383,9 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
x0_active = false;
|
x0_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Silence(u32 id)
|
static void Silence(s32 id)
|
||||||
{
|
{
|
||||||
u32 idx = FindStreamIdx(id);
|
s32 idx = FindStreamIdx(id);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -387,9 +404,9 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
m_file = std::experimental::nullopt;
|
m_file = std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsStreamActive(u32 id)
|
static bool IsStreamActive(s32 id)
|
||||||
{
|
{
|
||||||
u32 idx = FindStreamIdx(id);
|
s32 idx = FindStreamIdx(id);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -397,9 +414,9 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
return stream.x0_active;
|
return stream.x0_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsStreamAvailable(u32 id)
|
static bool IsStreamAvailable(s32 id)
|
||||||
{
|
{
|
||||||
u32 idx = FindStreamIdx(id);
|
s32 idx = FindStreamIdx(id);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -407,10 +424,10 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
return !stream.x0_active;
|
return !stream.x0_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 AllocateMono(const SDSPStreamInfo& info, float vol, bool oneshot)
|
static s32 AllocateMono(const SDSPStreamInfo& info, float vol, bool oneshot)
|
||||||
{
|
{
|
||||||
SDSPStream* stream;
|
SDSPStream* stream;
|
||||||
u32 id = PickFreeStream(stream, oneshot);
|
s32 id = PickFreeStream(stream, oneshot);
|
||||||
if (id == -1)
|
if (id == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -419,12 +436,12 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 AllocateStereo(const SDSPStreamInfo& linfo,
|
static s32 AllocateStereo(const SDSPStreamInfo& linfo,
|
||||||
const SDSPStreamInfo& rinfo,
|
const SDSPStreamInfo& rinfo,
|
||||||
float vol, bool oneshot)
|
float vol, bool oneshot)
|
||||||
{
|
{
|
||||||
SDSPStream* lstream;
|
SDSPStream* lstream;
|
||||||
u32 lid = PickFreeStream(lstream, oneshot);
|
s32 lid = PickFreeStream(lstream, oneshot);
|
||||||
if (lid == -1)
|
if (lid == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -446,8 +463,12 @@ struct SDSPStream : boo::IAudioVoiceCallback
|
||||||
m_file.emplace(x10_info.x0_fileName);
|
m_file.emplace(x10_info.x0_fileName);
|
||||||
if (!xd4_ringBuffer)
|
if (!xd4_ringBuffer)
|
||||||
DoAllocateStream();
|
DoAllocateStream();
|
||||||
m_readReqs[0].reset();
|
for (int j=0 ; j<2 ; ++j)
|
||||||
m_readReqs[1].reset();
|
if (m_readReqs[j])
|
||||||
|
{
|
||||||
|
m_readReqs[j]->PostCancelRequest();
|
||||||
|
m_readReqs[j].reset();
|
||||||
|
}
|
||||||
x4c_vol = vol;
|
x4c_vol = vol;
|
||||||
m_leftgain = left;
|
m_leftgain = left;
|
||||||
m_rightgain = right;
|
m_rightgain = right;
|
||||||
|
@ -500,8 +521,8 @@ private:
|
||||||
s8 x72_companionLeft = -1;
|
s8 x72_companionLeft = -1;
|
||||||
float x73_volume = 0.f;
|
float x73_volume = 0.f;
|
||||||
bool x74_oneshot;
|
bool x74_oneshot;
|
||||||
u32 x78_handleId = -1; // arg2
|
s32 x78_handleId = -1; // arg2
|
||||||
u32 x7c_streamId = -1;
|
s32 x7c_streamId = -1;
|
||||||
std::shared_ptr<IDvdRequest> m_dvdReq;
|
std::shared_ptr<IDvdRequest> m_dvdReq;
|
||||||
//DVDFileInfo x80_dvdHandle;
|
//DVDFileInfo x80_dvdHandle;
|
||||||
static CDSPStreamManager g_Streams[4];
|
static CDSPStreamManager g_Streams[4];
|
||||||
|
@ -512,16 +533,16 @@ public:
|
||||||
x70_24_unclaimed = true;
|
x70_24_unclaimed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDSPStreamManager(std::string_view fileName, u32 handle, float volume, bool oneshot)
|
CDSPStreamManager(std::string_view fileName, s32 handle, float volume, bool oneshot)
|
||||||
: x60_fileName(fileName), x73_volume(volume), x74_oneshot(oneshot), x78_handleId(handle)
|
: x60_fileName(fileName), x73_volume(volume), x74_oneshot(oneshot), x78_handleId(handle)
|
||||||
{
|
{
|
||||||
if (!CDvdFile::FileExists(fileName))
|
if (!CDvdFile::FileExists(fileName))
|
||||||
x70_24_unclaimed = true;
|
x70_24_unclaimed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 FindUnclaimedStreamIdx()
|
static s32 FindUnclaimedStreamIdx()
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<4 ; ++i)
|
for (s32 i=0 ; i<4 ; ++i)
|
||||||
{
|
{
|
||||||
CDSPStreamManager& stream = g_Streams[i];
|
CDSPStreamManager& stream = g_Streams[i];
|
||||||
if (stream.x70_24_unclaimed)
|
if (stream.x70_24_unclaimed)
|
||||||
|
@ -530,9 +551,9 @@ public:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool FindUnclaimedStereoPair(u32& left, u32& right)
|
static bool FindUnclaimedStereoPair(s32& left, s32& right)
|
||||||
{
|
{
|
||||||
u32 idx = FindUnclaimedStreamIdx();
|
s32 idx = FindUnclaimedStreamIdx();
|
||||||
|
|
||||||
for (u32 i=0 ; i<4 ; ++i)
|
for (u32 i=0 ; i<4 ; ++i)
|
||||||
{
|
{
|
||||||
|
@ -548,9 +569,9 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 FindClaimedStreamIdx(u32 handle)
|
static s32 FindClaimedStreamIdx(s32 handle)
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<4 ; ++i)
|
for (s32 i=0 ; i<4 ; ++i)
|
||||||
{
|
{
|
||||||
CDSPStreamManager& stream = g_Streams[i];
|
CDSPStreamManager& stream = g_Streams[i];
|
||||||
if (!stream.x70_24_unclaimed && stream.x78_handleId == handle)
|
if (!stream.x70_24_unclaimed && stream.x78_handleId == handle)
|
||||||
|
@ -559,9 +580,9 @@ public:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 GetFreeHandleId()
|
static s32 GetFreeHandleId()
|
||||||
{
|
{
|
||||||
u32 handle;
|
s32 handle;
|
||||||
bool good;
|
bool good;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -588,9 +609,9 @@ public:
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EState GetStreamState(u32 handle)
|
static EState GetStreamState(s32 handle)
|
||||||
{
|
{
|
||||||
u32 idx = FindClaimedStreamIdx(handle);
|
s32 idx = FindClaimedStreamIdx(handle);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return EState::Oneshot;
|
return EState::Oneshot;
|
||||||
|
|
||||||
|
@ -606,9 +627,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CanStop(u32 handle)
|
static bool CanStop(s32 handle)
|
||||||
{
|
{
|
||||||
u32 idx = FindClaimedStreamIdx(handle);
|
s32 idx = FindClaimedStreamIdx(handle);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -622,9 +643,9 @@ public:
|
||||||
return !SDSPStream::IsStreamActive(stream.x7c_streamId);
|
return !SDSPStream::IsStreamActive(stream.x7c_streamId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsStreamAvailable(u32 handle)
|
static bool IsStreamAvailable(s32 handle)
|
||||||
{
|
{
|
||||||
u32 idx = FindClaimedStreamIdx(handle);
|
s32 idx = FindClaimedStreamIdx(handle);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -638,7 +659,7 @@ public:
|
||||||
return SDSPStream::IsStreamAvailable(stream.x7c_streamId);
|
return SDSPStream::IsStreamAvailable(stream.x7c_streamId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AllocateStream(u32 idx)
|
static void AllocateStream(s32 idx)
|
||||||
{
|
{
|
||||||
CDSPStreamManager& stream = g_Streams[idx];
|
CDSPStreamManager& stream = g_Streams[idx];
|
||||||
SDSPStreamInfo info(stream);
|
SDSPStreamInfo info(stream);
|
||||||
|
@ -669,7 +690,7 @@ public:
|
||||||
|
|
||||||
void HeaderReadComplete()
|
void HeaderReadComplete()
|
||||||
{
|
{
|
||||||
u32 selfIdx = -1;
|
s32 selfIdx = -1;
|
||||||
for (int i=0 ; i<4 ; ++i)
|
for (int i=0 ; i<4 ; ++i)
|
||||||
{
|
{
|
||||||
if (this == &g_Streams[i])
|
if (this == &g_Streams[i])
|
||||||
|
@ -687,7 +708,7 @@ public:
|
||||||
|
|
||||||
x70_26_headerReadState = 2;
|
x70_26_headerReadState = 2;
|
||||||
|
|
||||||
u32 companion = -1;
|
s32 companion = -1;
|
||||||
if (x72_companionLeft != -1)
|
if (x72_companionLeft != -1)
|
||||||
companion = x72_companionLeft;
|
companion = x72_companionLeft;
|
||||||
else if (x71_companionRight != -1)
|
else if (x71_companionRight != -1)
|
||||||
|
@ -780,17 +801,17 @@ public:
|
||||||
m_dvdReq.reset();
|
m_dvdReq.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 StartStreaming(std::string_view fileName, float volume, bool oneshot)
|
static s32 StartStreaming(std::string_view fileName, float volume, bool oneshot)
|
||||||
{
|
{
|
||||||
auto pipePos = fileName.find('|');
|
auto pipePos = fileName.find('|');
|
||||||
if (pipePos == std::string::npos)
|
if (pipePos == std::string::npos)
|
||||||
{
|
{
|
||||||
/* Mono stream */
|
/* Mono stream */
|
||||||
u32 idx = FindUnclaimedStreamIdx();
|
s32 idx = FindUnclaimedStreamIdx();
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
u32 handle = GetFreeHandleId();
|
s32 handle = GetFreeHandleId();
|
||||||
CDSPStreamManager tmpStream(fileName, handle, volume, oneshot);
|
CDSPStreamManager tmpStream(fileName, handle, volume, oneshot);
|
||||||
if (tmpStream.x70_24_unclaimed)
|
if (tmpStream.x70_24_unclaimed)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -811,23 +832,23 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Stereo stream */
|
/* Stereo stream */
|
||||||
u32 leftIdx = 0;
|
s32 leftIdx = 0;
|
||||||
u32 rightIdx = 0;
|
s32 rightIdx = 0;
|
||||||
if (!FindUnclaimedStereoPair(leftIdx, rightIdx))
|
if (!FindUnclaimedStereoPair(leftIdx, rightIdx))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
std::string leftFile(fileName.begin(), fileName.begin() + pipePos);
|
std::string leftFile(fileName.begin(), fileName.begin() + pipePos);
|
||||||
std::string rightFile(fileName.begin() + pipePos + 1, fileName.end());
|
std::string rightFile(fileName.begin() + pipePos + 1, fileName.end());
|
||||||
|
|
||||||
u32 leftHandle = GetFreeHandleId();
|
s32 leftHandle = GetFreeHandleId();
|
||||||
u32 rightHandle = GetFreeHandleId();
|
s32 rightHandle = GetFreeHandleId();
|
||||||
CDSPStreamManager tmpLeftStream(leftFile, leftHandle, volume, oneshot);
|
CDSPStreamManager tmpLeftStream(leftFile, leftHandle, volume, oneshot);
|
||||||
CDSPStreamManager tmpRightStream(rightFile, rightHandle, volume, oneshot);
|
CDSPStreamManager tmpRightStream(rightFile, rightHandle, volume, oneshot);
|
||||||
if (tmpLeftStream.x70_24_unclaimed || tmpRightStream.x70_24_unclaimed)
|
if (tmpLeftStream.x70_24_unclaimed || tmpRightStream.x70_24_unclaimed)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
tmpLeftStream.x71_companionRight = rightIdx;
|
tmpLeftStream.x71_companionRight = s8(rightIdx);
|
||||||
tmpRightStream.x72_companionLeft = leftIdx;
|
tmpRightStream.x72_companionLeft = s8(leftIdx);
|
||||||
|
|
||||||
CDSPStreamManager& leftStream = g_Streams[leftIdx];
|
CDSPStreamManager& leftStream = g_Streams[leftIdx];
|
||||||
CDSPStreamManager& rightStream = g_Streams[rightIdx];
|
CDSPStreamManager& rightStream = g_Streams[rightIdx];
|
||||||
|
@ -849,9 +870,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StopStreaming(u32 handle)
|
static void StopStreaming(s32 handle)
|
||||||
{
|
{
|
||||||
u32 idx = FindClaimedStreamIdx(handle);
|
s32 idx = FindClaimedStreamIdx(handle);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -873,9 +894,9 @@ public:
|
||||||
stream = CDSPStreamManager();
|
stream = CDSPStreamManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateVolume(u32 handle, float volume)
|
static void UpdateVolume(s32 handle, float volume)
|
||||||
{
|
{
|
||||||
u32 idx = FindClaimedStreamIdx(handle);
|
s32 idx = FindClaimedStreamIdx(handle);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -955,13 +976,13 @@ struct SDSPPlayer
|
||||||
float x14_volume = 0.f;
|
float x14_volume = 0.f;
|
||||||
float x18_fadeIn = 0.f;
|
float x18_fadeIn = 0.f;
|
||||||
float x1c_fadeOut = 0.f;
|
float x1c_fadeOut = 0.f;
|
||||||
u32 x20_internalHandle = -1;
|
s32 x20_internalHandle = -1;
|
||||||
float x24_fadeFactor = 0.f;
|
float x24_fadeFactor = 0.f;
|
||||||
bool x28_music = true;
|
bool x28_music = true;
|
||||||
|
|
||||||
SDSPPlayer() = default;
|
SDSPPlayer() = default;
|
||||||
SDSPPlayer(EPlayerState playing, std::string_view fileName, float volume,
|
SDSPPlayer(EPlayerState playing, std::string_view fileName, float volume,
|
||||||
float fadeIn, float fadeOut, u32 handle, bool music)
|
float fadeIn, float fadeOut, s32 handle, bool music)
|
||||||
: x0_fileName(fileName), x10_playState(playing), x14_volume(volume),
|
: x0_fileName(fileName), x10_playState(playing), x14_volume(volume),
|
||||||
x18_fadeIn(fadeIn), x1c_fadeOut(fadeOut), x20_internalHandle(handle), x28_music(music) {}
|
x18_fadeIn(fadeIn), x1c_fadeOut(fadeOut), x20_internalHandle(handle), x28_music(music) {}
|
||||||
};
|
};
|
||||||
|
@ -977,10 +998,8 @@ float CStreamAudioManager::GetTargetDSPVolume(float fileVol, bool music)
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStreamAudioManager::Start(bool oneshot, std::string_view fileName,
|
void CStreamAudioManager::Start(bool oneshot, std::string_view fileName,
|
||||||
u8 volume, bool music, float fadeIn, float fadeOut)
|
float volume, bool music, float fadeIn, float fadeOut)
|
||||||
{
|
{
|
||||||
float fvol = volume / 127.f;
|
|
||||||
|
|
||||||
SDSPPlayer& p = s_Players[oneshot];
|
SDSPPlayer& p = s_Players[oneshot];
|
||||||
SDSPPlayer& qp = s_QueuedPlayers[oneshot];
|
SDSPPlayer& qp = s_QueuedPlayers[oneshot];
|
||||||
|
|
||||||
|
@ -988,7 +1007,7 @@ void CStreamAudioManager::Start(bool oneshot, std::string_view fileName,
|
||||||
CStringExtras::CompareCaseInsensitive(fileName, p.x0_fileName))
|
CStringExtras::CompareCaseInsensitive(fileName, p.x0_fileName))
|
||||||
{
|
{
|
||||||
/* Enque new stream */
|
/* Enque new stream */
|
||||||
qp = SDSPPlayer(EPlayerState::FadeIn, fileName, fvol, fadeIn, fadeOut, -1, music);
|
qp = SDSPPlayer(EPlayerState::FadeIn, fileName, volume, fadeIn, fadeOut, -1, music);
|
||||||
Stop(oneshot, p.x0_fileName);
|
Stop(oneshot, p.x0_fileName);
|
||||||
}
|
}
|
||||||
else if (p.x10_playState != EPlayerState::Stopped)
|
else if (p.x10_playState != EPlayerState::Stopped)
|
||||||
|
@ -996,7 +1015,7 @@ void CStreamAudioManager::Start(bool oneshot, std::string_view fileName,
|
||||||
/* Fade existing stream back in */
|
/* Fade existing stream back in */
|
||||||
p.x18_fadeIn = fadeIn;
|
p.x18_fadeIn = fadeIn;
|
||||||
p.x1c_fadeOut = fadeOut;
|
p.x1c_fadeOut = fadeOut;
|
||||||
p.x14_volume = fvol;
|
p.x14_volume = volume;
|
||||||
if (p.x18_fadeIn <= FLT_EPSILON)
|
if (p.x18_fadeIn <= FLT_EPSILON)
|
||||||
{
|
{
|
||||||
CDSPStreamManager::UpdateVolume(p.x20_internalHandle,
|
CDSPStreamManager::UpdateVolume(p.x20_internalHandle,
|
||||||
|
@ -1022,12 +1041,12 @@ void CStreamAudioManager::Start(bool oneshot, std::string_view fileName,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state = EPlayerState::Playing;
|
state = EPlayerState::Playing;
|
||||||
vol = fvol;
|
vol = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 handle = CDSPStreamManager::StartStreaming(fileName, GetTargetDSPVolume(vol, music), oneshot);
|
s32 handle = CDSPStreamManager::StartStreaming(fileName, GetTargetDSPVolume(vol, music), oneshot);
|
||||||
if (handle != -1)
|
if (handle != -1)
|
||||||
p = SDSPPlayer(state, fileName, fvol, fadeIn, fadeOut, handle, music);
|
p = SDSPPlayer(state, fileName, volume, fadeIn, fadeOut, handle, music);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1166,7 +1185,7 @@ void CStreamAudioManager::StopAllStreams()
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<2 ; ++i)
|
for (int i=0 ; i<2 ; ++i)
|
||||||
{
|
{
|
||||||
StopStreaming(i);
|
StopStreaming(bool(i));
|
||||||
SDSPPlayer& p = s_Players[i];
|
SDSPPlayer& p = s_Players[i];
|
||||||
SDSPPlayer& qp = s_QueuedPlayers[i];
|
SDSPPlayer& qp = s_QueuedPlayers[i];
|
||||||
p = SDSPPlayer();
|
p = SDSPPlayer();
|
||||||
|
|
|
@ -20,7 +20,7 @@ class CStreamAudioManager
|
||||||
static void StopAllStreams();
|
static void StopAllStreams();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Start(bool oneshot, std::string_view fileName, u8 volume,
|
static void Start(bool oneshot, std::string_view fileName, float volume,
|
||||||
bool music, float fadeIn, float fadeOut);
|
bool music, float fadeIn, float fadeOut);
|
||||||
static void Stop(bool oneshot, std::string_view fileName);
|
static void Stop(bool oneshot, std::string_view fileName);
|
||||||
static void FadeBackIn(bool oneshot, float fadeTime);
|
static void FadeBackIn(bool oneshot, float fadeTime);
|
||||||
|
|
|
@ -14,8 +14,8 @@ class CFileDvdRequest : public IDvdRequest
|
||||||
u32 m_len;
|
u32 m_len;
|
||||||
ESeekOrigin m_whence;
|
ESeekOrigin m_whence;
|
||||||
int m_offset;
|
int m_offset;
|
||||||
bool m_cancel = false;
|
std::atomic_bool m_cancel = {false};
|
||||||
bool m_complete = false;
|
std::atomic_bool m_complete = {false};
|
||||||
std::function<void(u32)> m_callback;
|
std::function<void(u32)> m_callback;
|
||||||
public:
|
public:
|
||||||
~CFileDvdRequest()
|
~CFileDvdRequest()
|
||||||
|
@ -25,16 +25,16 @@ public:
|
||||||
|
|
||||||
void WaitUntilComplete()
|
void WaitUntilComplete()
|
||||||
{
|
{
|
||||||
while (!m_complete && !m_cancel)
|
while (!m_complete.load() && !m_cancel.load())
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(CDvdFile::m_WaitMutex);
|
std::unique_lock<std::mutex> lk(CDvdFile::m_WaitMutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool IsComplete() {return m_complete;}
|
bool IsComplete() {return m_complete.load();}
|
||||||
void PostCancelRequest()
|
void PostCancelRequest()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> waitlk(CDvdFile::m_WaitMutex);
|
std::unique_lock<std::mutex> waitlk(CDvdFile::m_WaitMutex);
|
||||||
m_cancel = true;
|
m_cancel.store(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMediaType GetMediaType() const
|
EMediaType GetMediaType() const
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
|
|
||||||
void DoRequest()
|
void DoRequest()
|
||||||
{
|
{
|
||||||
if (m_cancel)
|
if (m_cancel.load())
|
||||||
return;
|
return;
|
||||||
u32 readLen;
|
u32 readLen;
|
||||||
if (m_whence == ESeekOrigin::Cur && m_offset == 0)
|
if (m_whence == ESeekOrigin::Cur && m_offset == 0)
|
||||||
|
@ -61,7 +61,7 @@ public:
|
||||||
}
|
}
|
||||||
if (m_callback)
|
if (m_callback)
|
||||||
m_callback(readLen);
|
m_callback(readLen);
|
||||||
m_complete = true;
|
m_complete.store(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,12 +69,12 @@ std::thread CDvdFile::m_WorkerThread;
|
||||||
std::mutex CDvdFile::m_WorkerMutex;
|
std::mutex CDvdFile::m_WorkerMutex;
|
||||||
std::condition_variable CDvdFile::m_WorkerCV;
|
std::condition_variable CDvdFile::m_WorkerCV;
|
||||||
std::mutex CDvdFile::m_WaitMutex;
|
std::mutex CDvdFile::m_WaitMutex;
|
||||||
bool CDvdFile::m_WorkerRun = false;
|
std::atomic_bool CDvdFile::m_WorkerRun = {false};
|
||||||
std::vector<std::shared_ptr<IDvdRequest>> CDvdFile::m_RequestQueue;
|
std::vector<std::shared_ptr<IDvdRequest>> CDvdFile::m_RequestQueue;
|
||||||
void CDvdFile::WorkerProc()
|
void CDvdFile::WorkerProc()
|
||||||
{
|
{
|
||||||
logvisor::RegisterThreadName("CDvdFile Thread");
|
logvisor::RegisterThreadName("CDvdFile");
|
||||||
while (m_WorkerRun)
|
while (m_WorkerRun.load())
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
|
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
|
||||||
while (CDvdFile::m_RequestQueue.size())
|
while (CDvdFile::m_RequestQueue.size())
|
||||||
|
@ -92,7 +92,7 @@ void CDvdFile::WorkerProc()
|
||||||
swapQueue.clear();
|
swapQueue.clear();
|
||||||
lk.lock();
|
lk.lock();
|
||||||
}
|
}
|
||||||
if (!m_WorkerRun)
|
if (!m_WorkerRun.load())
|
||||||
break;
|
break;
|
||||||
m_WorkerCV.wait(lk);
|
m_WorkerCV.wait(lk);
|
||||||
}
|
}
|
||||||
|
@ -113,17 +113,17 @@ std::shared_ptr<IDvdRequest> CDvdFile::AsyncSeekRead(void* buf, u32 len, ESeekOr
|
||||||
void CDvdFile::Initialize(const hecl::ProjectPath& path)
|
void CDvdFile::Initialize(const hecl::ProjectPath& path)
|
||||||
{
|
{
|
||||||
m_DvdRoot = path;
|
m_DvdRoot = path;
|
||||||
if (m_WorkerRun)
|
if (m_WorkerRun.load())
|
||||||
return;
|
return;
|
||||||
m_WorkerRun = true;
|
m_WorkerRun.store(true);
|
||||||
m_WorkerThread = std::thread(WorkerProc);
|
m_WorkerThread = std::thread(WorkerProc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDvdFile::Shutdown()
|
void CDvdFile::Shutdown()
|
||||||
{
|
{
|
||||||
if (!m_WorkerRun)
|
if (!m_WorkerRun.load())
|
||||||
return;
|
return;
|
||||||
m_WorkerRun = false;
|
m_WorkerRun.store(false);
|
||||||
m_WorkerCV.notify_one();
|
m_WorkerCV.notify_one();
|
||||||
if (m_WorkerThread.joinable())
|
if (m_WorkerThread.joinable())
|
||||||
m_WorkerThread.join();
|
m_WorkerThread.join();
|
||||||
|
|
|
@ -30,7 +30,7 @@ class CDvdFile
|
||||||
static std::mutex m_WorkerMutex;
|
static std::mutex m_WorkerMutex;
|
||||||
static std::condition_variable m_WorkerCV;
|
static std::condition_variable m_WorkerCV;
|
||||||
static std::mutex m_WaitMutex;
|
static std::mutex m_WaitMutex;
|
||||||
static bool m_WorkerRun;
|
static std::atomic_bool m_WorkerRun;
|
||||||
static std::vector<std::shared_ptr<IDvdRequest>> m_RequestQueue;
|
static std::vector<std::shared_ptr<IDvdRequest>> m_RequestQueue;
|
||||||
static void WorkerProc();
|
static void WorkerProc();
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ void CScriptStreamedMusic::StopStream(CStateManager& mgr)
|
||||||
|
|
||||||
void CScriptStreamedMusic::StartStream(CStateManager& mgr)
|
void CScriptStreamedMusic::StartStream(CStateManager& mgr)
|
||||||
{
|
{
|
||||||
CStreamAudioManager::Start(!x46_loop, x34_fileName, x50_volume,
|
CStreamAudioManager::Start(!x46_loop, x34_fileName, x50_volume / 127.f,
|
||||||
x47_music, x48_fadeIn, x4c_fadeOut);
|
x47_music, x48_fadeIn, x4c_fadeOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptStreamedMusic::TweakOverride(CStateManager& mgr)
|
void CScriptStreamedMusic::TweakOverride(CStateManager& mgr)
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit 2cbe8cfc814458788af7c087d57ecf2685004f2f
|
Subproject commit 7ae053a6ea6a7b8b40e0e40f2daa362d4c227433
|
2
nod
2
nod
|
@ -1 +1 @@
|
||||||
Subproject commit 4d9071bad75f0f8de94777052cec6bfd5e1e585c
|
Subproject commit 42589c36046e0cc4b00ab14e74f24024d75346fe
|
2
specter
2
specter
|
@ -1 +1 @@
|
||||||
Subproject commit cb3bf9e09e0da856563438af420f9a9d2930394a
|
Subproject commit 5881cd0368e43a4a5c3f2e9164593852c364422e
|
Loading…
Reference in New Issue