void CPUThread::Wait(const CPUThread& thr) { wxCriticalSectionLocker lock(m_cs_sync); m_wait_thread_id = thr.GetId(); m_sync_wait = true; }
void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event) { CPUThread* thr = (CPUThread*)event.GetClientData(); event.Skip(); if(!thr) { switch(event.GetId()) { case DID_STOPPED_EMU: UpdateUnitList(); break; case DID_PAUSED_EMU: //DoUpdate(); break; } } else if(CPU && thr->GetId() == CPU->GetId()) { switch(event.GetId()) { case DID_PAUSE_THREAD: m_btn_run->Disable(); m_btn_step->Disable(); m_btn_pause->Disable(); break; case DID_PAUSED_THREAD: m_btn_run->Enable(); m_btn_step->Enable(); m_btn_pause->Disable(); DoUpdate(); break; case DID_START_THREAD: case DID_EXEC_THREAD: case DID_RESUME_THREAD: m_btn_run->Disable(); m_btn_step->Disable(); m_btn_pause->Enable(); break; case DID_REMOVE_THREAD: case DID_STOP_THREAD: m_btn_run->Disable(); m_btn_step->Disable(); m_btn_pause->Disable(); if(event.GetId() == DID_REMOVE_THREAD) { //m_choice_units->SetSelection(-1); //wxCommandEvent event; //event.SetInt(-1); //event.SetClientData(nullptr); //OnSelectUnit(event); UpdateUnitList(); //DoUpdate(); } break; } } else { switch(event.GetId()) { case DID_CREATE_THREAD: UpdateUnitList(); if(m_choice_units->GetSelection() == -1) { //m_choice_units->SetSelection(0); //wxCommandEvent event; //event.SetInt(0); //event.SetClientData(&Emu.GetCPU().GetThreads()[0]); //OnSelectUnit(event); } break; case DID_REMOVED_THREAD: UpdateUnitList(); break; } } }
void CPUThread::Wait(const CPUThread& thr) { std::lock_guard<std::mutex> lock(m_cs_sync); m_wait_thread_id = thr.GetId(); m_sync_wait = true; }
int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config) { libmixer->Warning("cellSurMixerCreate(config_addr=0x%x)", config.addr()); surMixer = *config; AudioPortConfig& port = m_config.m_ports[SUR_PORT]; if (port.m_is_audio_port_opened) { return CELL_LIBMIXER_ERROR_FULL; } port.channel = 8; port.block = 16; port.attr = 0; port.level = 1.0f; 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; surMixerCb = 0; thread t("Surmixer Thread", []() { AudioPortConfig& port = m_config.m_ports[SUR_PORT]; CPUThread* mixerCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU); mixerCb->SetName("Surmixer Callback"); while (port.m_is_audio_port_opened) { if (Emu.IsStopped()) { libmixer->Warning("Surmixer aborted"); break; } if (mixcount > (port.tag + 0)) // adding positive value (1-15): preemptive buffer filling (hack) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); continue; } if (port.m_is_audio_port_started) { //u64 stamp0 = get_system_time(); memset(mixdata, 0, sizeof(mixdata)); if (surMixerCb) mixerCb->ExecAsCallback(surMixerCb, true, surMixerCbArg, mixcount, 256); //u64 stamp1 = get_system_time(); { std::lock_guard<std::mutex> lock(mixer_mutex); for (auto& p : ssp) if (p.m_active && p.m_created) { auto v = vm::lptrl<s16>::make(p.m_addr); // 16-bit LE audio data float left = 0.0f; float right = 0.0f; float speed = fabs(p.m_speed); float fpos = 0.0f; for (int i = 0; i < 256; i++) if (p.m_active) { u32 pos = p.m_position; int pos_inc = 0; if (p.m_speed > 0.0f) // select direction { pos_inc = 1; } else if (p.m_speed < 0.0f) { pos_inc = -1; } int shift = i - (int)fpos; // change playback speed (simple and rough) if (shift > 0) { // slow playback pos_inc = 0; // duplicate one sample at this time fpos += 1.0f; fpos += speed; } else if (shift < 0) { // fast playback i--; // mix two sample into one at this time fpos -= 1.0f; } else { fpos += speed; } p.m_position += (u32)pos_inc; if (p.m_channels == 1) // get mono data { left = right = (float)v[pos] / 0x8000 * p.m_level; } else if (p.m_channels == 2) // get stereo data { left = (float)v[pos * 2 + 0] / 0x8000 * p.m_level; right = (float)v[pos * 2 + 1] / 0x8000 * p.m_level; } if (p.m_connected) // mix { // TODO: m_x, m_y, m_z ignored mixdata[i * 8 + 0] += left; mixdata[i * 8 + 1] += right; } if ((p.m_position == p.m_samples && p.m_speed > 0.0f) || (p.m_position == ~0 && p.m_speed < 0.0f)) // loop or stop { if (p.m_loop_mode == CELL_SSPLAYER_LOOP_ON) { p.m_position = p.m_loop_start; } else if (p.m_loop_mode == CELL_SSPLAYER_ONESHOT_CONT) { p.m_position -= (u32)pos_inc; // restore position } else // oneshot { p.m_active = false; p.m_position = p.m_loop_start; // TODO: check value } } } } } //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)); for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i++) { // reverse byte order buf[i] = mixdata[i]; } //u64 stamp3 = get_system_time(); //ConLog.Write("Libmixer perf: start=%lld (cb=%lld, ssp=%lld, finalize=%lld)", stamp0 - m_config.start_time, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2); } mixcount++; } { std::lock_guard<std::mutex> lock(mixer_mutex); ssp.clear(); } Emu.GetCPU().RemoveThread(mixerCb->GetId()); }); t.detach(); return CELL_OK; }