1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 04:02:42 +01:00

cellAudio updated, thread_t updated

This commit is contained in:
Nekotekina 2015-01-16 17:36:53 +03:00
parent 42b748a881
commit fd06f70387
19 changed files with 669 additions and 697 deletions

View File

@ -1,5 +1,6 @@
#include "stdafx.h" #include "stdafx.h"
#include "Log.h" #include "Log.h"
#include "rpcs3/Ini.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/CPU/CPUThread.h" #include "Emu/CPU/CPUThread.h"
#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SysCalls.h"
@ -285,7 +286,7 @@ void signal_handler(int sig, siginfo_t* info, void* uct)
ucontext_t* const ctx = (ucontext_t*)uct; ucontext_t* const ctx = (ucontext_t*)uct;
const u64 addr64 = (u64)info->si_addr - (u64)Memory.GetBaseAddr(); const u64 addr64 = (u64)info->si_addr - (u64)Memory.GetBaseAddr();
//const bool is_writing = false; // TODO: get it correctly //const bool is_writing = false; // TODO: get it correctly
if (addr64 < 0x100000000ull) if (addr64 < 0x100000000ull && GetCurrentNamedThread())
{ {
const u32 addr = (u32)addr64; const u32 addr = (u32)addr64;
if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) // RawSPU MMIO registers if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) // RawSPU MMIO registers
@ -384,7 +385,7 @@ NamedThreadBase* GetCurrentNamedThread()
void SetCurrentNamedThread(NamedThreadBase* value) void SetCurrentNamedThread(NamedThreadBase* value)
{ {
auto old_value = g_tls_this_thread; const auto old_value = g_tls_this_thread;
if (old_value == value) if (old_value == value)
{ {
@ -536,23 +537,40 @@ bool ThreadBase::TestDestroy() const
return m_destroy; return m_destroy;
} }
thread::thread(const std::string& name, std::function<void()> func) : m_name(name) thread_t::thread_t(const std::string& name, std::function<void()> func) : m_name(name), m_state(TS_NON_EXISTENT)
{ {
start(func); start(func);
} }
thread::thread(const std::string& name) : m_name(name) thread_t::thread_t(const std::string& name) : m_name(name), m_state(TS_NON_EXISTENT)
{ {
} }
thread::thread() thread_t::thread_t() : m_state(TS_NON_EXISTENT)
{ {
} }
void thread::start(std::function<void()> func) void thread_t::set_name(const std::string& name)
{ {
m_name = name;
}
thread_t::~thread_t()
{
if (m_state == TS_JOINABLE)
{
m_thr.detach();
}
}
void thread_t::start(std::function<void()> func)
{
if (m_state.exchange(TS_NON_EXISTENT) == TS_JOINABLE)
{
m_thr.join(); // forcefully join previously created thread
}
std::string name = m_name; std::string name = m_name;
m_thr = std::thread([func, name]() m_thr = std::thread([func, name]()
{ {
SetCurrentThreadDebugName(name.c_str()); SetCurrentThreadDebugName(name.c_str());
@ -567,6 +585,11 @@ void thread::start(std::function<void()> func)
SetCurrentNamedThread(&info); SetCurrentNamedThread(&info);
g_thread_count++; g_thread_count++;
if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(HLE, name + " started");
}
try try
{ {
func(); func();
@ -580,6 +603,15 @@ void thread::start(std::function<void()> func)
LOG_ERROR(GENERAL, "%s: %s", name.c_str(), e.c_str()); LOG_ERROR(GENERAL, "%s: %s", name.c_str(), e.c_str());
} }
if (Emu.IsStopped())
{
LOG_NOTICE(HLE, name + " aborted");
}
else if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(HLE, name + " ended");
}
SetCurrentNamedThread(nullptr); SetCurrentNamedThread(nullptr);
g_thread_count--; g_thread_count--;
@ -587,21 +619,41 @@ void thread::start(std::function<void()> func)
_set_se_translator(old_se_translator); _set_se_translator(old_se_translator);
#endif #endif
}); });
if (m_state.exchange(TS_JOINABLE) == TS_JOINABLE)
{
assert(!"thread_t::start() failed"); // probably started from another thread
}
} }
void thread::detach() void thread_t::detach()
{ {
m_thr.detach(); if (m_state.exchange(TS_NON_EXISTENT) == TS_JOINABLE)
{
m_thr.detach();
}
else
{
assert(!"thread_t::detach() failed"); // probably joined or detached
}
} }
void thread::join() void thread_t::join()
{ {
m_thr.join(); if (m_state.exchange(TS_NON_EXISTENT) == TS_JOINABLE)
{
m_thr.join();
}
else
{
assert(!"thread_t::join() failed"); // probably joined or detached
}
} }
bool thread::joinable() const bool thread_t::joinable() const
{ {
return m_thr.joinable(); //return m_thr.joinable();
return m_state == TS_JOINABLE;
} }
bool waiter_map_t::is_stopped(u64 signal_id) bool waiter_map_t::is_stopped(u64 signal_id)

View File

@ -54,18 +54,32 @@ public:
virtual void Task() = 0; virtual void Task() = 0;
}; };
class thread class thread_t
{ {
enum thread_state_t
{
TS_NON_EXISTENT,
TS_JOINABLE,
};
std::atomic<thread_state_t> m_state;
std::string m_name; std::string m_name;
std::thread m_thr; std::thread m_thr;
public: public:
thread(const std::string& name, std::function<void()> func); thread_t(const std::string& name, std::function<void()> func);
thread(const std::string& name); thread_t(const std::string& name);
thread(); thread_t();
~thread_t();
thread_t(const thread_t& right) = delete;
thread_t(thread_t&& right) = delete;
thread_t& operator =(const thread_t& right) = delete;
thread_t& operator =(thread_t&& right) = delete;
public: public:
void set_name(const std::string& name);
void start(std::function<void()> func); void start(std::function<void()> func);
void detach(); void detach();
void join(); void join();

View File

@ -11,8 +11,6 @@ ALCenum g_last_alc_error = ALC_NO_ERROR;
#define checkForAlError(sit) if((g_last_al_error = alGetError()) != AL_NO_ERROR) printAlError(g_last_al_error, sit) #define checkForAlError(sit) if((g_last_al_error = alGetError()) != AL_NO_ERROR) printAlError(g_last_al_error, sit)
#define checkForAlcError(sit) if((g_last_alc_error = alcGetError(m_device)) != ALC_NO_ERROR) printAlcError(g_last_alc_error, sit) #define checkForAlcError(sit) if((g_last_alc_error = alcGetError(m_device)) != ALC_NO_ERROR) printAlcError(g_last_alc_error, sit)
static const ALenum g_audio_format = Ini.AudioConvertToU16.GetValue() ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO_FLOAT32;
void printAlError(ALenum err, const char* situation) void printAlError(ALenum err, const char* situation)
{ {
if (err != AL_NO_ERROR) if (err != AL_NO_ERROR)
@ -102,7 +100,7 @@ void OpenALThread::Open(const void* src, int size)
for (uint i = 0; i<g_al_buffers_count; ++i) for (uint i = 0; i<g_al_buffers_count; ++i)
{ {
alBufferData(m_buffers[i], g_audio_format, src, m_buffer_size, 48000); alBufferData(m_buffers[i], Ini.AudioConvertToU16.GetValue() ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO_FLOAT32, src, m_buffer_size, 48000);
checkForAlError("alBufferData"); checkForAlError("alBufferData");
} }
@ -137,7 +135,7 @@ void OpenALThread::AddData(const void* src, int size)
int bsize = size < m_buffer_size ? size : m_buffer_size; int bsize = size < m_buffer_size ? size : m_buffer_size;
alBufferData(buffer, g_audio_format, bsrc, bsize, 48000); alBufferData(buffer, Ini.AudioConvertToU16.GetValue() ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO_FLOAT32, bsrc, bsize, 48000);
checkForAlError("alBufferData"); checkForAlError("alBufferData");
alSourceQueueBuffers(m_source, 1, &buffer); alSourceQueueBuffers(m_source, 1, &buffer);

View File

@ -1,22 +1,32 @@
#include "stdafx.h" #include "stdafx.h"
#include "AudioDumper.h" #include "AudioDumper.h"
AudioDumper::AudioDumper(u8 ch) : m_header(ch) AudioDumper::AudioDumper() : m_header(0), m_init(false)
{ {
} }
AudioDumper::~AudioDumper() AudioDumper::~AudioDumper()
{ {
Finalize();
} }
bool AudioDumper::Init() bool AudioDumper::Init(u8 ch)
{ {
return m_output.Open("audio.wav", rFile::write); if ((m_init = m_output.Open("audio.wav", rFile::write)))
{
m_header = WAVHeader(ch);
WriteHeader();
}
return m_init;
} }
void AudioDumper::WriteHeader() void AudioDumper::WriteHeader()
{ {
m_output.Write(&m_header, sizeof(m_header)); // write file header if (m_init)
{
m_output.Write(&m_header, sizeof(m_header)); // write file header
}
} }
size_t AudioDumper::WriteData(const void* buffer, size_t size) size_t AudioDumper::WriteData(const void* buffer, size_t size)
@ -31,17 +41,27 @@ size_t AudioDumper::WriteData(const void* buffer, size_t size)
{ {
if (((u8*)buffer)[i + (size & ~7)]) do_save = true; if (((u8*)buffer)[i + (size & ~7)]) do_save = true;
} }
if (!do_save) return size; // ignore empty data
if (m_init && do_save)
#else
if (m_init)
#endif #endif
size_t ret = m_output.Write(buffer, size); {
m_header.Size += (u32)ret; size_t ret = m_output.Write(buffer, size);
m_header.RIFF.Size += (u32)ret; m_header.Size += (u32)ret;
return ret; m_header.RIFF.Size += (u32)ret;
return ret;
}
return size;
} }
void AudioDumper::Finalize() void AudioDumper::Finalize()
{ {
m_output.Seek(0); if (m_init)
m_output.Write(&m_header, sizeof(m_header)); // write fixed file header {
m_output.Close(); m_output.Seek(0);
m_output.Write(&m_header, sizeof(m_header)); // write fixed file header
m_output.Close();
}
} }

View File

@ -55,15 +55,16 @@ struct WAVHeader
class AudioDumper class AudioDumper
{ {
private:
WAVHeader m_header; WAVHeader m_header;
rFile m_output; rFile m_output;
bool m_init;
public: public:
AudioDumper(u8 ch); AudioDumper();
~AudioDumper(); ~AudioDumper();
bool Init(); public:
bool Init(u8 ch);
void WriteHeader(); void WriteHeader();
size_t WriteData(const void* buffer, size_t size); size_t WriteData(const void* buffer, size_t size);
void Finalize(); void Finalize();

View File

@ -8,7 +8,7 @@
XAudio2Thread::~XAudio2Thread() XAudio2Thread::~XAudio2Thread()
{ {
Quit(); if (m_source_voice) Quit();
} }
void XAudio2Thread::Init() void XAudio2Thread::Init()
@ -87,13 +87,15 @@ void XAudio2Thread::Open(const void* src, int size)
{ {
HRESULT hr; HRESULT hr;
WORD sample_size = Ini.AudioConvertToU16.GetValue() ? sizeof(u16) : sizeof(float);
WAVEFORMATEX waveformatex; WAVEFORMATEX waveformatex;
waveformatex.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; waveformatex.wFormatTag = Ini.AudioConvertToU16.GetValue() ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
waveformatex.nChannels = 2; waveformatex.nChannels = 2;
waveformatex.nSamplesPerSec = 48000; waveformatex.nSamplesPerSec = 48000;
waveformatex.nAvgBytesPerSec = 48000 * 2 * sizeof(float); waveformatex.nAvgBytesPerSec = 48000 * 2 * (DWORD)sample_size;
waveformatex.nBlockAlign = 2 * sizeof(float); waveformatex.nBlockAlign = 2 * sample_size;
waveformatex.wBitsPerSample = 32; waveformatex.wBitsPerSample = sample_size * 8;
waveformatex.cbSize = 0; waveformatex.cbSize = 0;
hr = m_xaudio2_instance->CreateSourceVoice(&m_source_voice, &waveformatex, 0, XAUDIO2_DEFAULT_FREQ_RATIO); hr = m_xaudio2_instance->CreateSourceVoice(&m_source_voice, &waveformatex, 0, XAUDIO2_DEFAULT_FREQ_RATIO);

View File

@ -280,6 +280,7 @@ void CPUThread::Task()
return "unknown function"; return "unknown function";
} }
case CPU_THREAD_PPU: case CPU_THREAD_PPU:
{ {
if ((u32)syscall == syscall) if ((u32)syscall == syscall)
@ -290,6 +291,7 @@ void CPUThread::Task()
{ {
// TODO: // TODO:
//return SysCalls::GetSyscallName((u32)syscall); //return SysCalls::GetSyscallName((u32)syscall);
return "unknown syscall";
} }
else else
{ {
@ -302,13 +304,19 @@ void CPUThread::Task()
} }
} }
// fallthrough return "unknown function";
} }
case CPU_THREAD_SPU: case CPU_THREAD_SPU:
case CPU_THREAD_RAW_SPU: case CPU_THREAD_RAW_SPU:
default: default:
{ {
return "unknown syscall"; if (!syscall)
{
return{};
}
return "unknown function";
} }
} }
}; };

View File

@ -2350,7 +2350,7 @@ void RSXThread::Task()
m_last_flip_time = get_system_time() - 1000000; m_last_flip_time = get_system_time() - 1000000;
volatile bool is_vblank_stopped = false; volatile bool is_vblank_stopped = false;
thread vblank("VBlank thread", [&]() thread_t vblank("VBlank thread", [&]()
{ {
const u64 start_time = get_system_time(); const u64 start_time = get_system_time();

View File

@ -82,7 +82,7 @@ void CallbackManager::Init()
static_cast<PPUThread*>(m_cb_thread)->DoRun(); static_cast<PPUThread*>(m_cb_thread)->DoRun();
} }
thread cb_async_thread("CallbackManager::Async() thread", [this]() thread_t cb_async_thread("CallbackManager thread", [this]()
{ {
SetCurrentNamedThread(m_cb_thread); SetCurrentNamedThread(m_cb_thread);
@ -108,8 +108,6 @@ void CallbackManager::Init()
m_cb_thread->WaitForAnySignal(); m_cb_thread->WaitForAnySignal();
} }
}); });
cb_async_thread.detach();
} }
void CallbackManager::Clear() void CallbackManager::Clear()

View File

@ -224,7 +224,7 @@ u32 adecOpen(AudioDecoder* adec_ptr)
adec.id = adec_id; adec.id = adec_id;
adec.adecCb = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU); adec.adecCb = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
adec.adecCb->SetName("Audio Decoder[" + std::to_string(adec_id) + "] Callback"); adec.adecCb->SetName(fmt::format("AudioDecoder[%d] Callback", adec_id));
adec.adecCb->SetEntry(0); adec.adecCb->SetEntry(0);
adec.adecCb->SetPrio(1001); adec.adecCb->SetPrio(1001);
adec.adecCb->SetStackSize(0x10000); adec.adecCb->SetStackSize(0x10000);
@ -232,11 +232,9 @@ u32 adecOpen(AudioDecoder* adec_ptr)
adec.adecCb->InitRegs(); adec.adecCb->InitRegs();
adec.adecCb->DoRun(); adec.adecCb->DoRun();
thread t("Audio Decoder[" + std::to_string(adec_id) + "] Thread", [adec_ptr, sptr]() thread_t t(fmt::format("AudioDecoder[%d] Thread", adec_id), [adec_ptr, sptr]()
{ {
AudioDecoder& adec = *adec_ptr; AudioDecoder& adec = *adec_ptr;
cellAdec->Notice("Audio Decoder thread started");
AdecTask& task = adec.task; AdecTask& task = adec.task;
while (true) while (true)
@ -471,18 +469,15 @@ u32 adecOpen(AudioDecoder* adec_ptr)
default: default:
{ {
ADEC_ERROR("Audio Decoder thread error: unknown task(%d)", task.type); ADEC_ERROR("AudioDecoder thread error: unknown task(%d)", task.type);
} }
} }
} }
adec.is_finished = true; adec.is_finished = true;
if (adec.is_closed) cellAdec->Notice("Audio Decoder thread ended"); if (Emu.IsStopped()) cellAdec->Warning("AudioDecoder thread aborted");
if (Emu.IsStopped()) cellAdec->Warning("Audio Decoder thread aborted");
}); });
t.detach();
return adec_id; return adec_id;
} }

File diff suppressed because it is too large Load Diff

View File

@ -72,10 +72,32 @@ struct CellAudioPortConfig
be_t<u32> portAddr; be_t<u32> portAddr;
}; };
enum : u32
{
BUFFER_NUM = 32,
BUFFER_SIZE = 256,
AUDIO_PORT_COUNT = 8,
};
enum AudioState : u32
{
AUDIO_STATE_NOT_INITIALIZED,
AUDIO_STATE_INITIALIZED,
AUDIO_STATE_FINALIZED,
};
enum AudioPortState : u32
{
AUDIO_PORT_STATE_NOT_OPENED,
AUDIO_PORT_STATE_OPENED,
AUDIO_PORT_STATE_STARTED,
};
struct AudioPortConfig struct AudioPortConfig
{ {
bool m_is_audio_port_opened; std::mutex mutex;
bool m_is_audio_port_started; atomic_le_t<AudioPortState> state;
u8 channel; u8 channel;
u8 block; u8 block;
float level; float level;
@ -89,34 +111,20 @@ struct AudioPortConfig
struct AudioConfig //custom structure struct AudioConfig //custom structure
{ {
enum std::mutex mutex;
{ atomic_le_t<AudioState> state;
AUDIO_PORT_COUNT = 8, thread_t audio_thread;
};
AudioPortConfig m_ports[AUDIO_PORT_COUNT]; AudioPortConfig ports[AUDIO_PORT_COUNT];
u32 m_buffer; // 1 MB memory for audio ports u32 buffer; // 1 MB memory for audio ports
u32 m_indexes; // current block indexes and other info u32 indexes; // current block indexes and other info
bool m_is_audio_initialized;
bool m_is_audio_finalized;
u32 m_port_in_use;
u64 counter; u64 counter;
u64 start_time; u64 start_time;
std::vector<u64> m_keys; std::vector<u64> keys;
AudioConfig() AudioConfig() : audio_thread("Audio Thread")
: m_is_audio_initialized(false)
, m_is_audio_finalized(false)
, m_port_in_use(0)
, counter(0)
{ {
memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT);
}
void Clear()
{
memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT);
m_port_in_use = 0;
} }
}; };
extern AudioConfig m_config; extern AudioConfig g_audio;

View File

@ -306,7 +306,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
dmux.id = dmux_id; dmux.id = dmux_id;
dmux.dmuxCb = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU); dmux.dmuxCb = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
dmux.dmuxCb->SetName("Demuxer[" + std::to_string(dmux_id) + "] Callback"); dmux.dmuxCb->SetName(fmt::format("Demuxer[%d] Callback", dmux_id));
dmux.dmuxCb->SetEntry(0); dmux.dmuxCb->SetEntry(0);
dmux.dmuxCb->SetPrio(1001); dmux.dmuxCb->SetPrio(1001);
dmux.dmuxCb->SetStackSize(0x10000); dmux.dmuxCb->SetStackSize(0x10000);
@ -314,10 +314,9 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
dmux.dmuxCb->InitRegs(); dmux.dmuxCb->InitRegs();
dmux.dmuxCb->DoRun(); dmux.dmuxCb->DoRun();
thread t("Demuxer[" + std::to_string(dmux_id) + "] Thread", [dmux_ptr, sptr]() thread_t t(fmt::format("Demuxer[%d] Thread", dmux_id), [dmux_ptr, sptr]()
{ {
Demuxer& dmux = *dmux_ptr; Demuxer& dmux = *dmux_ptr;
cellDmux->Notice("Demuxer thread started (mem=0x%x, size=0x%x, cb_addr=0x%x, arg=0x%x)", dmux.memAddr, dmux.memSize, dmux.cbFunc.addr(), dmux.cbArg);
DemuxerTask task; DemuxerTask task;
DemuxerStream stream = {}; DemuxerStream stream = {};
@ -761,11 +760,8 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
dmux.is_finished = true; dmux.is_finished = true;
if (Emu.IsStopped()) cellDmux->Warning("Demuxer thread aborted"); if (Emu.IsStopped()) cellDmux->Warning("Demuxer thread aborted");
if (dmux.is_closed) cellDmux->Notice("Demuxer thread ended");
}); });
t.detach();
return dmux_id; return dmux_id;
} }

View File

@ -123,7 +123,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
std::string msg = msgString.get_ptr(); std::string msg = msgString.get_ptr();
thread t("MsgDialog thread", [type, msg, callback, userData, extParam]() thread_t t("MsgDialog Thread", [type, msg, callback, userData, extParam]()
{ {
switch (type & CELL_MSGDIALOG_TYPE_SE_TYPE) switch (type & CELL_MSGDIALOG_TYPE_SE_TYPE)
{ {
@ -186,7 +186,6 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
g_msg_dialog_state = msgDialogNone; g_msg_dialog_state = msgDialogNone;
}); });
}); });
t.detach();
return CELL_OK; return CELL_OK;
} }

View File

@ -214,7 +214,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr)
vdec.id = vdec_id; vdec.id = vdec_id;
vdec.vdecCb = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU); vdec.vdecCb = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
vdec.vdecCb->SetName("Video Decoder[" + std::to_string(vdec_id) + "] Callback"); vdec.vdecCb->SetName(fmt::format("VideoDecoder[%d] Callback", vdec_id));
vdec.vdecCb->SetEntry(0); vdec.vdecCb->SetEntry(0);
vdec.vdecCb->SetPrio(1001); vdec.vdecCb->SetPrio(1001);
vdec.vdecCb->SetStackSize(0x10000); vdec.vdecCb->SetStackSize(0x10000);
@ -222,11 +222,9 @@ u32 vdecOpen(VideoDecoder* vdec_ptr)
vdec.vdecCb->InitRegs(); vdec.vdecCb->InitRegs();
vdec.vdecCb->DoRun(); vdec.vdecCb->DoRun();
thread t("Video Decoder[" + std::to_string(vdec_id) + "] Thread", [vdec_ptr, sptr]() thread_t t(fmt::format("VideoDecoder[%d] Thread", vdec_id), [vdec_ptr, sptr]()
{ {
VideoDecoder& vdec = *vdec_ptr; VideoDecoder& vdec = *vdec_ptr;
cellVdec->Notice("Video Decoder thread started");
VdecTask& task = vdec.task; VdecTask& task = vdec.task;
while (true) while (true)
@ -431,7 +429,15 @@ u32 vdecOpen(VideoDecoder* vdec_ptr)
{ {
if (vdec.last_pts == -1) if (vdec.last_pts == -1)
{ {
vdec.last_pts = 0x8000; //av_frame_get_best_effort_timestamp(frame.data); u64 ts = av_frame_get_best_effort_timestamp(frame.data);
if (ts != AV_NOPTS_VALUE)
{
vdec.last_pts = ts;
}
else
{
vdec.last_pts = 0;
}
} }
else switch (vdec.frc_set) else switch (vdec.frc_set)
{ {
@ -539,18 +545,15 @@ u32 vdecOpen(VideoDecoder* vdec_ptr)
default: default:
{ {
VDEC_ERROR("Video Decoder thread error: unknown task(%d)", task.type); VDEC_ERROR("VideoDecoder thread error: unknown task(%d)", task.type);
} }
} }
} }
vdec.is_finished = true; vdec.is_finished = true;
if (Emu.IsStopped()) cellVdec->Warning("Video Decoder thread aborted"); if (Emu.IsStopped()) cellVdec->Warning("VideoDecoder thread aborted");
if (vdec.is_closed) cellVdec->Notice("Video Decoder thread ended");
}); });
t.detach();
return vdec_id; return vdec_id;
} }

View File

@ -5,7 +5,7 @@
#include "Emu/SysCalls/CB_FUNC.h" #include "Emu/SysCalls/CB_FUNC.h"
#include "Emu/CPU/CPUThreadManager.h" #include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Audio/cellAudio.h" #include "cellAudio.h"
#include "libmixer.h" #include "libmixer.h"
Module *libmixer = nullptr; Module *libmixer = nullptr;
@ -298,9 +298,9 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
surMixer = *config; surMixer = *config;
AudioPortConfig& port = m_config.m_ports[SUR_PORT]; AudioPortConfig& port = g_audio.ports[SUR_PORT];
if (port.m_is_audio_port_opened) if (!port.state.compare_and_swap_test(AUDIO_PORT_STATE_NOT_OPENED, AUDIO_PORT_STATE_OPENED))
{ {
return CELL_LIBMIXER_ERROR_FULL; return CELL_LIBMIXER_ERROR_FULL;
} }
@ -309,22 +309,19 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
port.block = 16; port.block = 16;
port.attr = 0; port.attr = 0;
port.level = 1.0f; port.level = 1.0f;
port.tag = 0;
libmixer->Warning("*** audio port opened(default)"); libmixer->Warning("*** audio port opened(default)");
port.m_is_audio_port_opened = true;
port.tag = 0;
m_config.m_port_in_use++;
libmixer->Warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)",
(u32)surMixer.chStrips1, (u32)surMixer.chStrips2, (u32)surMixer.chStrips6, (u32)surMixer.chStrips8);
mixcount = 0; mixcount = 0;
surMixerCb.set(0); surMixerCb.set(0);
thread t("Surmixer Thread", []() libmixer->Warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)",
(u32)surMixer.chStrips1, (u32)surMixer.chStrips2, (u32)surMixer.chStrips6, (u32)surMixer.chStrips8);
thread_t t("Surmixer Thread", []()
{ {
AudioPortConfig& port = m_config.m_ports[SUR_PORT]; AudioPortConfig& port = g_audio.ports[SUR_PORT];
PPUThread& cb_thread = *(PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU); PPUThread& cb_thread = *(PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
cb_thread.SetName("Surmixer Callback Thread"); cb_thread.SetName("Surmixer Callback Thread");
@ -335,7 +332,7 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
cb_thread.InitRegs(); cb_thread.InitRegs();
cb_thread.DoRun(); cb_thread.DoRun();
while (port.m_is_audio_port_opened) while (port.state.read_relaxed() != AUDIO_PORT_STATE_NOT_OPENED)
{ {
if (Emu.IsStopped()) if (Emu.IsStopped())
{ {
@ -349,7 +346,7 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
continue; continue;
} }
if (port.m_is_audio_port_started) if (port.state.read_relaxed() == AUDIO_PORT_STATE_STARTED)
{ {
//u64 stamp0 = get_system_time(); //u64 stamp0 = get_system_time();
@ -440,7 +437,7 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
//u64 stamp2 = get_system_time(); //u64 stamp2 = get_system_time();
auto buf = vm::get_ptr<be_t<float>>(m_config.m_buffer + (128 * 1024 * SUR_PORT) + (mixcount % port.block) * port.channel * 256 * sizeof(float)); auto buf = vm::get_ptr<be_t<float>>(g_audio.buffer + (128 * 1024 * SUR_PORT) + (mixcount % port.block) * port.channel * 256 * sizeof(float));
for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i++) for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i++)
{ {
@ -464,7 +461,6 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
Emu.GetCPU().RemoveThread(cb_thread.GetId()); Emu.GetCPU().RemoveThread(cb_thread.GetId());
surMixerCb.set(0); surMixerCb.set(0);
}); });
t.detach();
return CELL_OK; return CELL_OK;
} }
@ -515,13 +511,8 @@ int cellSurMixerStart()
{ {
libmixer->Warning("cellSurMixerStart()"); libmixer->Warning("cellSurMixerStart()");
AudioPortConfig& port = m_config.m_ports[SUR_PORT]; g_audio.ports[SUR_PORT].state.compare_and_swap(AUDIO_PORT_STATE_OPENED, AUDIO_PORT_STATE_STARTED);
if (port.m_is_audio_port_opened)
{
port.m_is_audio_port_started = true;
}
return CELL_OK; return CELL_OK;
} }
@ -535,14 +526,7 @@ int cellSurMixerFinalize()
{ {
libmixer->Warning("cellSurMixerFinalize()"); libmixer->Warning("cellSurMixerFinalize()");
AudioPortConfig& port = m_config.m_ports[SUR_PORT]; g_audio.ports[SUR_PORT].state.compare_and_swap(AUDIO_PORT_STATE_OPENED, AUDIO_PORT_STATE_NOT_OPENED);
if (port.m_is_audio_port_opened)
{
port.m_is_audio_port_started = false;
port.m_is_audio_port_opened = false;
m_config.m_port_in_use--;
}
return CELL_OK; return CELL_OK;
} }
@ -581,12 +565,7 @@ int cellSurMixerPause(u32 type)
{ {
libmixer->Warning("cellSurMixerPause(type=%d)", type); libmixer->Warning("cellSurMixerPause(type=%d)", type);
AudioPortConfig& port = m_config.m_ports[SUR_PORT]; g_audio.ports[SUR_PORT].state.compare_and_swap(AUDIO_PORT_STATE_STARTED, AUDIO_PORT_STATE_OPENED);
if (port.m_is_audio_port_opened)
{
port.m_is_audio_port_started = false;
}
return CELL_OK; return CELL_OK;
} }
@ -603,7 +582,7 @@ int cellSurMixerGetTimestamp(u64 tag, vm::ptr<u64> stamp)
{ {
libmixer->Log("cellSurMixerGetTimestamp(tag=0x%llx, stamp_addr=0x%x)", tag, stamp.addr()); libmixer->Log("cellSurMixerGetTimestamp(tag=0x%llx, stamp_addr=0x%x)", tag, stamp.addr());
*stamp = m_config.start_time + (tag) * 256000000 / 48000; // ??? *stamp = g_audio.start_time + (tag) * 256000000 / 48000; // ???
return CELL_OK; return CELL_OK;
} }

View File

@ -966,11 +966,7 @@ int cellFsAioRead(vm::ptr<CellFsAio> aio, vm::ptr<u32> id, vm::ptr<void(*)(vm::p
const u32 xid = g_FsAioReadID++; const u32 xid = g_FsAioReadID++;
*id = xid; *id = xid;
{ thread_t t("CellFsAio Reading Thread", std::bind(fsAioRead, fd, aio, xid, func));
thread t("fsAioRead", std::bind(fsAioRead, fd, aio, xid, func));
t.detach();
}
return CELL_OK; return CELL_OK;
} }

View File

@ -411,6 +411,7 @@
<ClInclude Include="Emu\SysCalls\Modules.h" /> <ClInclude Include="Emu\SysCalls\Modules.h" />
<ClInclude Include="Emu\SysCalls\Modules\cellAdec.h" /> <ClInclude Include="Emu\SysCalls\Modules\cellAdec.h" />
<ClInclude Include="Emu\SysCalls\Modules\cellAtrac.h" /> <ClInclude Include="Emu\SysCalls\Modules\cellAtrac.h" />
<ClInclude Include="Emu\SysCalls\Modules\cellAudio.h" />
<ClInclude Include="Emu\SysCalls\Modules\cellCamera.h" /> <ClInclude Include="Emu\SysCalls\Modules\cellCamera.h" />
<ClInclude Include="Emu\SysCalls\Modules\cellDmux.h" /> <ClInclude Include="Emu\SysCalls\Modules\cellDmux.h" />
<ClInclude Include="Emu\SysCalls\Modules\cellFiber.h" /> <ClInclude Include="Emu\SysCalls\Modules\cellFiber.h" />

View File

@ -1279,5 +1279,8 @@
<ClInclude Include="Emu\Audio\XAudio2\XAudio2Thread.h"> <ClInclude Include="Emu\Audio\XAudio2\XAudio2Thread.h">
<Filter>Emu\Audio\XAudio2</Filter> <Filter>Emu\Audio\XAudio2</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Emu\SysCalls\Modules\cellAudio.h">
<Filter>Emu\SysCalls\Modules</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>