mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 02:29:51 +01:00
Merge pull request #20242 from hrydgard/audio-investigation
ImDebugger: Add some audio investigation tools
This commit is contained in:
16 files changed
+235
-131
No files matched your search
@@ -263,6 +263,7 @@ public:
|
||||
int iDefaultTab;
|
||||
int iScreenshotMode;
|
||||
bool bVulkanDisableImplicitLayers;
|
||||
bool bForceFfmpegForAudioDec;
|
||||
|
||||
std::vector<std::string> vPostShaderNames; // Off for chain end (only Off for no shader)
|
||||
std::map<std::string, float> mPostShaderSetting;
|
||||
|
||||
@@ -207,7 +207,7 @@ void Atrac::WriteContextToPSPMem() {
|
||||
if (track_.firstSampleOffset != 0) {
|
||||
context->info.firstValidSample = track_.FirstSampleOffsetFull();
|
||||
} else {
|
||||
context->info.firstValidSample = (track_.codecType == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES);
|
||||
context->info.firstValidSample = (track_.codecType == PSP_CODEC_AT3PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES);
|
||||
}
|
||||
context->info.sampleSize = track_.bytesPerFrame;
|
||||
context->info.numChan = track_.channels;
|
||||
@@ -226,7 +226,7 @@ void Atrac::WriteContextToPSPMem() {
|
||||
|
||||
void Track::DebugLog() const {
|
||||
DEBUG_LOG(Log::ME, "ATRAC analyzed: %s channels: %d filesize: %d bitrate: %d kbps jointStereo: %d",
|
||||
codecType == PSP_MODE_AT_3 ? "AT3" : "AT3Plus", channels, fileSize, bitrate / 1024, jointStereo);
|
||||
codecType == PSP_CODEC_AT3 ? "AT3" : "AT3Plus", channels, fileSize, bitrate / 1024, jointStereo);
|
||||
DEBUG_LOG(Log::ME, "dataoff: %d firstSampleOffset: %d endSample: %d", dataByteOffset, firstSampleOffset, endSample);
|
||||
DEBUG_LOG(Log::ME, "loopStartSample: %d loopEndSample: %d", loopStartSample, loopEndSample);
|
||||
DEBUG_LOG(Log::ME, "sampleSize: %d (%03x", bytesPerFrame, bytesPerFrame);
|
||||
@@ -308,7 +308,7 @@ void AtracBase::CreateDecoder(int codecType, int bytesPerFrame, int channels) {
|
||||
}
|
||||
|
||||
// First, init the standalone decoder.
|
||||
if (codecType == PSP_MODE_AT_3) {
|
||||
if (codecType == PSP_CODEC_AT3) {
|
||||
// TODO: This is maybe not entirely reliable? Mui Mui house in LocoRoco 2 fails. Although also fails
|
||||
// when I override this, so maybe the issue is something different...
|
||||
bool jointStereo = IsAtrac3StreamJointStereo(codecType, bytesPerFrame, channels);
|
||||
@@ -435,7 +435,7 @@ int Atrac::SetData(const Track &track, u32 buffer, u32 readSize, u32 bufferSize,
|
||||
ResetData();
|
||||
UpdateBufferState();
|
||||
|
||||
if (track_.codecType != PSP_MODE_AT_3 && track_.codecType != PSP_MODE_AT_3_PLUS) {
|
||||
if (track_.codecType != PSP_CODEC_AT3 && track_.codecType != PSP_CODEC_AT3PLUS) {
|
||||
// Shouldn't have gotten here, Analyze() checks this.
|
||||
bufferState_ = ATRAC_STATUS_NO_DATA;
|
||||
ERROR_LOG(Log::ME, "unexpected codec type %d in set data", track_.codecType);
|
||||
@@ -454,7 +454,7 @@ int Atrac::SetData(const Track &track, u32 buffer, u32 readSize, u32 bufferSize,
|
||||
bufferValidBytes_ = first_.size - bufferPos_;
|
||||
}
|
||||
|
||||
const char *codecName = track_.codecType == PSP_MODE_AT_3 ? "atrac3" : "atrac3+";
|
||||
const char *codecName = track_.codecType == PSP_CODEC_AT3 ? "atrac3" : "atrac3+";
|
||||
const char *channelName = track_.channels == 1 ? "mono" : "stereo";
|
||||
|
||||
// Over-allocate databuf to prevent going off the end if the bitstream is bad or if there are
|
||||
@@ -897,7 +897,7 @@ int Atrac::ResetPlayPosition(int sample, int bytesWrittenFirstBuf, int bytesWrit
|
||||
bufferValidBytes_ = bytesWrittenFirstBuf - bufferPos_;
|
||||
}
|
||||
|
||||
if (track_.codecType == PSP_MODE_AT_3 || track_.codecType == PSP_MODE_AT_3_PLUS) {
|
||||
if (track_.codecType == PSP_CODEC_AT3 || track_.codecType == PSP_CODEC_AT3PLUS) {
|
||||
SeekToSample(sample);
|
||||
}
|
||||
|
||||
@@ -916,11 +916,11 @@ void Atrac::InitLowLevel(const Atrac3LowLevelParams ¶ms, int codecType) {
|
||||
first_.writableBytes = track_.bytesPerFrame;
|
||||
ResetData();
|
||||
|
||||
if (codecType == PSP_MODE_AT_3) {
|
||||
if (codecType == PSP_CODEC_AT3) {
|
||||
track_.bitrate = (track_.bytesPerFrame * 352800) / 1000;
|
||||
track_.bitrate = (track_.bitrate + 511) >> 10;
|
||||
track_.jointStereo = IsAtrac3StreamJointStereo(codecType, params.bytesPerFrame, params.encodedChannels);
|
||||
} else if (codecType == PSP_MODE_AT_3_PLUS) {
|
||||
} else if (codecType == PSP_CODEC_AT3PLUS) {
|
||||
track_.bitrate = (track_.bytesPerFrame * 352800) / 1000;
|
||||
track_.bitrate = ((track_.bitrate >> 11) + 8) & 0xFFFFFFF0;
|
||||
track_.jointStereo = false;
|
||||
|
||||
@@ -819,7 +819,7 @@ int Atrac2::SetData(const Track &track, u32 bufferAddr, u32 readSize, u32 buffer
|
||||
|
||||
SceAtracIdInfo &info = context_->info;
|
||||
|
||||
if (track.codecType != PSP_MODE_AT_3 && track.codecType != PSP_MODE_AT_3_PLUS) {
|
||||
if (track.codecType != PSP_CODEC_AT3 && track.codecType != PSP_CODEC_AT3PLUS) {
|
||||
// Shouldn't have gotten here, Analyze() checks this.
|
||||
ERROR_LOG(Log::ME, "unexpected codec type %d in set data", track.codecType);
|
||||
return SCE_ERROR_ATRAC_UNKNOWN_FORMAT;
|
||||
@@ -832,7 +832,7 @@ int Atrac2::SetData(const Track &track, u32 bufferAddr, u32 readSize, u32 buffer
|
||||
if (readSize >= track.fileSize) {
|
||||
INFO_LOG(Log::ME, "The full file was set directly - we can dump it.");
|
||||
char filename[512];
|
||||
snprintf(filename, sizeof(filename), "%s_%d%s", track.codecType == PSP_MODE_AT_3 ? "at3" : "at3plus", track.endSample, track.channels == 1 ? "_mono" : "");
|
||||
snprintf(filename, sizeof(filename), "%s_%d%s", track.codecType == PSP_CODEC_AT3 ? "at3" : "at3plus", track.endSample, track.channels == 1 ? "_mono" : "");
|
||||
DumpFileIfEnabled(Memory::GetPointer(bufferAddr), readSize, filename, DumpFileType::Atrac3);
|
||||
}
|
||||
|
||||
@@ -1004,7 +1004,7 @@ int Atrac2::Bitrate() const {
|
||||
const SceAtracIdInfo &info = context_->info;
|
||||
|
||||
int bitrate = (info.sampleSize * 352800) / 1000;
|
||||
if (info.codec == PSP_MODE_AT_3_PLUS)
|
||||
if (info.codec == PSP_CODEC_AT3PLUS)
|
||||
bitrate = ((bitrate >> 11) + 8) & 0xFFFFFFF0;
|
||||
else
|
||||
bitrate = (bitrate + 511) >> 10;
|
||||
|
||||
+46
-28
@@ -91,6 +91,15 @@ static u32 atracLibCrc = 0;
|
||||
static int g_atracMaxContexts = 6;
|
||||
static int g_atracBSS = 0;
|
||||
|
||||
static bool g_muteFlag[PSP_MAX_ATRAC_IDS]{}; // Not saved, just for debugging.
|
||||
|
||||
bool *__AtracMuteFlag(int atracID) {
|
||||
if (atracID < 0 || atracID >= PSP_MAX_ATRAC_IDS) {
|
||||
return nullptr;
|
||||
}
|
||||
return &g_muteFlag[atracID];
|
||||
}
|
||||
|
||||
// For debugger only.
|
||||
const AtracBase *__AtracGetCtx(int i, u32 *type) {
|
||||
if (type) {
|
||||
@@ -110,12 +119,13 @@ void __AtracInit() {
|
||||
atracInited = true; // TODO: This should probably only happen in __AtracNotifyLoadModule.
|
||||
|
||||
memset(atracContexts, 0, sizeof(atracContexts));
|
||||
memset(g_muteFlag, 0, sizeof(g_muteFlag));
|
||||
|
||||
// Start with 2 of each in this order.
|
||||
atracContextTypes[0] = PSP_MODE_AT_3_PLUS;
|
||||
atracContextTypes[1] = PSP_MODE_AT_3_PLUS;
|
||||
atracContextTypes[2] = PSP_MODE_AT_3;
|
||||
atracContextTypes[3] = PSP_MODE_AT_3;
|
||||
atracContextTypes[0] = PSP_CODEC_AT3PLUS;
|
||||
atracContextTypes[1] = PSP_CODEC_AT3PLUS;
|
||||
atracContextTypes[2] = PSP_CODEC_AT3;
|
||||
atracContextTypes[3] = PSP_CODEC_AT3;
|
||||
atracContextTypes[4] = 0;
|
||||
atracContextTypes[5] = 0;
|
||||
}
|
||||
@@ -127,6 +137,10 @@ void __AtracShutdown() {
|
||||
}
|
||||
}
|
||||
|
||||
int __AtracMaxContexts() {
|
||||
return g_atracMaxContexts;
|
||||
}
|
||||
|
||||
void __AtracNotifyLoadModule(int version, u32 crc, u32 bssAddr, int bssSize) {
|
||||
atracLibVersion = version;
|
||||
atracLibCrc = crc;
|
||||
@@ -241,7 +255,7 @@ static int UnregisterAndDeleteAtrac(int atracID) {
|
||||
// Really, allocate an Atrac context of a specific codec type.
|
||||
// Useful to initialize a context for low level decode.
|
||||
static u32 sceAtracGetAtracID(int codecType) {
|
||||
if (codecType != PSP_MODE_AT_3 && codecType != PSP_MODE_AT_3_PLUS) {
|
||||
if (codecType != PSP_CODEC_AT3 && codecType != PSP_CODEC_AT3PLUS) {
|
||||
return hleReportError(Log::ME, SCE_ERROR_ATRAC_INVALID_CODECTYPE, "invalid codecType");
|
||||
}
|
||||
|
||||
@@ -311,13 +325,15 @@ static u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32
|
||||
return hleLogError(Log::ME, SCE_ERROR_ATRAC_BAD_ALIGNMENT);
|
||||
}
|
||||
|
||||
int numSamples = 0;
|
||||
|
||||
int numSamplesWritten = 0;
|
||||
int finish = 0;
|
||||
int remains = 0;
|
||||
int ret = atrac->DecodeData(outAddr ? Memory::GetPointerWrite(outAddr) : nullptr, outAddr, &numSamples, &finish, &remains);
|
||||
u8 *outPtr = outAddr ? Memory::GetPointerWrite(outAddr) : nullptr;
|
||||
int ret = atrac->DecodeData(outPtr, outAddr, &numSamplesWritten, &finish, &remains);
|
||||
if (ret != (int)SCE_ERROR_ATRAC_BAD_ATRACID && ret != (int)SCE_ERROR_ATRAC_NO_DATA) {
|
||||
if (Memory::IsValidAddress(numSamplesAddr))
|
||||
Memory::WriteUnchecked_U32(numSamples, numSamplesAddr);
|
||||
Memory::WriteUnchecked_U32(numSamplesWritten, numSamplesAddr);
|
||||
if (Memory::IsValidAddress(finishFlagAddr))
|
||||
Memory::WriteUnchecked_U32(finish, finishFlagAddr);
|
||||
// On error, no remaining frame value is written.
|
||||
@@ -325,20 +341,25 @@ static u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32
|
||||
Memory::WriteUnchecked_U32(remains, remainAddr);
|
||||
}
|
||||
DEBUG_LOG(Log::ME, "%08x=sceAtracDecodeData(%i, %08x, %08x[%08x], %08x[%08x], %08x[%d])", ret, atracID, outAddr,
|
||||
numSamplesAddr, numSamples,
|
||||
finishFlagAddr, finish,
|
||||
remainAddr, remains);
|
||||
numSamplesAddr, numSamplesWritten,
|
||||
finishFlagAddr, finish,
|
||||
remainAddr, remains);
|
||||
|
||||
if (outPtr && g_muteFlag[atracID]) {
|
||||
memset(outPtr, 0, atrac->GetOutputChannels() * 2 * numSamplesWritten);
|
||||
}
|
||||
|
||||
if (ret == 0 || ret == SCE_ERROR_ATRAC_API_FAIL) {
|
||||
// decode data successfully, delay thread
|
||||
// Decoded or at least attempted to decode data, delay thread
|
||||
return hleDelayResult(hleNoLog(ret), "atrac decode data", atracDecodeDelay);
|
||||
}
|
||||
|
||||
return hleNoLog(ret);
|
||||
}
|
||||
|
||||
// Likely a bogus brute-forced name?
|
||||
static u32 sceAtracEndEntry() {
|
||||
ERROR_LOG_REPORT(Log::ME, "UNIMPL sceAtracEndEntry()");
|
||||
return hleNoLog(0);
|
||||
static u32 sceAtracReleaseResources() {
|
||||
// In the real implementation, this just calls sceAudioCodecReleaseEDRAM if any has been allocated.
|
||||
return hleLogDebug(Log::ME, 0);
|
||||
}
|
||||
|
||||
// Obtains information about what needs to be in the buffer to seek (or "reset")
|
||||
@@ -356,13 +377,6 @@ static u32 sceAtracGetBufferInfoForResetting(int atracID, int sample, u32 buffer
|
||||
return hleLogError(Log::ME, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid buffer, should crash");
|
||||
}
|
||||
|
||||
/*
|
||||
DEBUG_LOG(Log::ME, "GetBufferInfoForResetting: First: %08x %08x %08x %08x", bufferInfo->first.writePosPtr, bufferInfo->first.writableBytes, bufferInfo->first.minWriteBytes, bufferInfo->first.filePos);
|
||||
if (bufferInfo->second.filePos) {
|
||||
DEBUG_LOG(Log::ME, "GetBufferInfoForResetting: Second: %08x %08x %08x %08x", bufferInfo->second.writePosPtr, bufferInfo->second.writableBytes, bufferInfo->second.minWriteBytes, bufferInfo->second.filePos);
|
||||
}
|
||||
*/
|
||||
|
||||
// Note: If we error here, it's because of the internal SkipFrames.
|
||||
// We delayresult if we skip frames, which indeed can happen.
|
||||
bool delay = false;
|
||||
@@ -794,13 +808,13 @@ static int sceAtracReinit(int at3Count, int at3plusCount) {
|
||||
for (int i = 0; i < at3plusCount; ++i) {
|
||||
space -= 2;
|
||||
if (space >= 0) {
|
||||
atracContextTypes[next++] = PSP_MODE_AT_3_PLUS;
|
||||
atracContextTypes[next++] = PSP_CODEC_AT3PLUS;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < at3Count; ++i) {
|
||||
space -= 1;
|
||||
if (space >= 0) {
|
||||
atracContextTypes[next++] = PSP_MODE_AT_3;
|
||||
atracContextTypes[next++] = PSP_CODEC_AT3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1030,7 +1044,7 @@ static const At3HeaderMap at3HeaderMap[] = {
|
||||
};
|
||||
|
||||
bool IsAtrac3StreamJointStereo(int codecType, int bytesPerFrame, int channels) {
|
||||
if (codecType != PSP_MODE_AT_3) {
|
||||
if (codecType != PSP_CODEC_AT3) {
|
||||
// Well, might actually be, but it's not used in codec setup.
|
||||
return false;
|
||||
}
|
||||
@@ -1061,7 +1075,7 @@ static int sceAtracLowLevelInitDecoder(int atracID, u32 paramsAddr) {
|
||||
|
||||
atrac->InitLowLevel(*params, codecType);
|
||||
|
||||
const char *codecName = codecType == PSP_MODE_AT_3 ? "atrac3" : "atrac3+";
|
||||
const char *codecName = codecType == PSP_CODEC_AT3 ? "atrac3" : "atrac3+";
|
||||
const char *encodedChannelName = params->encodedChannels == 1 ? "mono" : "stereo";
|
||||
const char *outputChannelName = params->outputChannels == 1 ? "mono" : "stereo";
|
||||
return hleLogInfo(Log::ME, 0, "%s %s->%s audio", codecName, encodedChannelName, outputChannelName);
|
||||
@@ -1090,6 +1104,10 @@ static int sceAtracLowLevelDecode(int atracID, u32 sourceAddr, u32 sourceBytesCo
|
||||
*srcConsumed = bytesConsumed;
|
||||
*outWritten = bytesWritten;
|
||||
|
||||
if (g_muteFlag[atracID]) {
|
||||
memset(outp, 0, bytesWritten);
|
||||
}
|
||||
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, bytesWritten, "AtracLowLevelDecode");
|
||||
return hleDelayResult(hleLogDebug(Log::ME, retval), "low level atrac decode data", atracDecodeDelay);
|
||||
}
|
||||
@@ -1164,7 +1182,7 @@ const char *AtracStatusToString(AtracStatus status) {
|
||||
const HLEFunction sceAtrac3plus[] = {
|
||||
{0X7DB31251, &WrapU_IU<sceAtracAddStreamData>, "sceAtracAddStreamData", 'x', "ix" },
|
||||
{0X6A8C3CD5, &WrapU_IUUUU<sceAtracDecodeData>, "sceAtracDecodeData", 'x', "ixppp"},
|
||||
{0XD5C28CC0, &WrapU_V<sceAtracEndEntry>, "sceAtracEndEntry", 'x', "" },
|
||||
{0XD5C28CC0, &WrapU_V<sceAtracReleaseResources>, "sceAtracReleaseResources", 'x', "" }, // previously had the wrong name sceAtracEndEntry. The new name is a guess, but accurate in meaning.
|
||||
{0X780F88D1, &WrapU_I<sceAtracGetAtracID>, "sceAtracGetAtracID", 'i', "x" },
|
||||
{0XCA3CA3D2, &WrapU_IIU<sceAtracGetBufferInfoForResetting>, "sceAtracGetBufferInfoForReseting", 'x', "iix" },
|
||||
{0XA554A158, &WrapU_IU<sceAtracGetBitrate>, "sceAtracGetBitrate", 'x', "ip" },
|
||||
|
||||
@@ -26,6 +26,7 @@ void Register_sceAtrac3plus();
|
||||
void __AtracInit();
|
||||
void __AtracDoState(PointerWrap &p);
|
||||
void __AtracShutdown();
|
||||
int __AtracMaxContexts();
|
||||
|
||||
void __AtracNotifyLoadModule(int version, u32 crc, u32 bssAddr, int bssSize);
|
||||
void __AtracNotifyUnloadModule();
|
||||
@@ -141,3 +142,7 @@ bool IsAtrac3StreamJointStereo(int codecType, int bytesPerFrame, int channels);
|
||||
u32 AtracSasAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd);
|
||||
void AtracSasDecodeData(int atracID, u8* outbuf, int *SamplesNum, int *finish);
|
||||
int AtracSasBindContextAndGetID(u32 contextAddr);
|
||||
|
||||
// To provide checkboxes in the debugger UI.
|
||||
// This setting is not saved.
|
||||
bool *__AtracMuteFlag(int atracID);
|
||||
@@ -171,6 +171,7 @@ const HLEFunction SysMemForKernel[] = {
|
||||
{ 0X536AD5E1, &WrapU_V<sceKernelGetUidmanCB>, "sceKernelGetUidmanCB", 'i', "i" , HLE_KERNEL_SYSCALL },
|
||||
{ 0X7B749390, &WrapI_IU<sceKernelFreeHeapMemory>, "sceKernelFreeHeapMemory", 'i', "ix" , HLE_KERNEL_SYSCALL },
|
||||
{ 0XEB7A74DB, &WrapI_IUU<sceKernelAllocHeapMemoryWithOption>, "sceKernelAllocHeapMemoryWithOption", 'i', "ixp" , HLE_KERNEL_SYSCALL },
|
||||
{ 0x6373995d, nullptr, "sceKernelGetModel", 'i', "", HLE_KERNEL_SYSCALL },
|
||||
};
|
||||
|
||||
void Register_SysMemForKernel() {
|
||||
|
||||
+12
-3
@@ -79,6 +79,12 @@ static volatile int sasThreadState = SasThreadState::DISABLED;
|
||||
static SasThreadParams sasThreadParams;
|
||||
static int sasMixEvent = -1;
|
||||
|
||||
static bool g_sasMuteFlag = false;
|
||||
|
||||
bool *__SasGetGlobalMuteFlag() {
|
||||
return &g_sasMuteFlag;
|
||||
}
|
||||
|
||||
int __SasThread() {
|
||||
SetCurrentThreadName("SAS");
|
||||
|
||||
@@ -86,8 +92,8 @@ int __SasThread() {
|
||||
while (sasThreadState != SasThreadState::DISABLED) {
|
||||
sasWake.wait(guard);
|
||||
if (sasThreadState == SasThreadState::QUEUED) {
|
||||
sas->Mix(sasThreadParams.outAddr, sasThreadParams.inAddr, sasThreadParams.leftVol, sasThreadParams.rightVol);
|
||||
|
||||
const bool mute = g_sasMuteFlag;
|
||||
sas->Mix(sasThreadParams.outAddr, sasThreadParams.inAddr, sasThreadParams.leftVol, sasThreadParams.rightVol, mute);
|
||||
std::lock_guard<std::mutex> doneGuard(sasDoneMutex);
|
||||
sasThreadState = SasThreadState::READY;
|
||||
sasDone.notify_one();
|
||||
@@ -105,7 +111,8 @@ static void __SasDrain() {
|
||||
static void __SasEnqueueMix(u32 outAddr, u32 inAddr = 0, int leftVol = 0, int rightVol = 0) {
|
||||
if (sasThreadState == SasThreadState::DISABLED) {
|
||||
// No thread, call it immediately.
|
||||
sas->Mix(outAddr, inAddr, leftVol, rightVol);
|
||||
const bool mute = g_sasMuteFlag;
|
||||
sas->Mix(outAddr, inAddr, leftVol, rightVol, mute);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,6 +169,8 @@ static void sasMixFinish(u64 userdata, int cycleslate) {
|
||||
void __SasInit() {
|
||||
sas = new SasInstance();
|
||||
|
||||
g_sasMuteFlag = false;
|
||||
|
||||
sasMixEvent = CoreTiming::RegisterEvent("SasMix", sasMixFinish);
|
||||
|
||||
if (g_Config.bSeparateSASThread) {
|
||||
|
||||
@@ -22,6 +22,7 @@ void __SasDoState(PointerWrap &p);
|
||||
void __SasShutdown();
|
||||
|
||||
void __SasGetDebugStats(char *stats, size_t bufsize);
|
||||
bool *__SasGetGlobalMuteFlag();
|
||||
|
||||
void Register_sceSasCore();
|
||||
|
||||
|
||||
@@ -623,7 +623,7 @@ void SasInstance::MixVoice(SasVoice &voice) {
|
||||
}
|
||||
}
|
||||
|
||||
void SasInstance::Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol) {
|
||||
void SasInstance::Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol, bool mute) {
|
||||
for (int v = 0; v < PSP_SAS_VOICES_MAX; v++) {
|
||||
SasVoice &voice = voices[v];
|
||||
if (!voice.playing || voice.paused)
|
||||
@@ -631,6 +631,12 @@ void SasInstance::Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol) {
|
||||
MixVoice(voice);
|
||||
}
|
||||
|
||||
// Apply mute if needed (note: we try to keep everything else identical to the non-muted case).
|
||||
if (mute) {
|
||||
memset(mixBuffer, 0, grainSize * sizeof(int) * 2);
|
||||
memset(sendBuffer, 0, grainSize * sizeof(int) * 2);
|
||||
}
|
||||
|
||||
// Then mix the send buffer in with the rest.
|
||||
|
||||
// Alright, all voices mixed. Let's convert and clip, and at the same time, wipe mixBuffer for next time. Could also dither.
|
||||
@@ -664,6 +670,7 @@ void SasInstance::Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol) {
|
||||
memset(sendBuffer, 0, grainSize * sizeof(int) * 2);
|
||||
}
|
||||
|
||||
// Note: leftVol/rightVol here are how much to scale the inp content by, not the mixBuffer.
|
||||
void SasInstance::WriteMixedOutput(s16 *outp, const s16 *inp, int leftVol, int rightVol) {
|
||||
const bool dry = waveformEffect.isDryOn != 0;
|
||||
const bool wet = waveformEffect.isWetOn != 0;
|
||||
|
||||
+1
-1
@@ -315,7 +315,7 @@ public:
|
||||
|
||||
FILE *audioDump = nullptr;
|
||||
|
||||
void Mix(u32 outAddr, u32 inAddr = 0, int leftVol = 0, int rightVol = 0);
|
||||
void Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol, bool mute);
|
||||
void MixVoice(SasVoice &voice);
|
||||
|
||||
// Applies reverb to send buffer, according to waveformEffect.
|
||||
|
||||
@@ -39,6 +39,7 @@ extern "C" {
|
||||
|
||||
#include "Core/FFMPEGCompat.h"
|
||||
}
|
||||
#include "Core/Config.h"
|
||||
|
||||
#else
|
||||
|
||||
@@ -136,15 +137,23 @@ private:
|
||||
};
|
||||
|
||||
AudioDecoder *CreateAudioDecoder(PSPAudioType audioType, int sampleRateHz, int channels, size_t blockAlign, const uint8_t *extraData, size_t extraDataSize) {
|
||||
bool forceFfmpeg = false;
|
||||
#ifdef USE_FFMPEG
|
||||
forceFfmpeg = g_Config.bForceFfmpegForAudioDec;
|
||||
#endif
|
||||
if (forceFfmpeg) {
|
||||
return new FFmpegAudioDecoder(audioType, sampleRateHz, channels);
|
||||
}
|
||||
|
||||
switch (audioType) {
|
||||
case PSP_CODEC_MP3:
|
||||
return new MiniMp3Audio();
|
||||
case PSP_CODEC_AT3:
|
||||
return CreateAtrac3Audio(channels, blockAlign, extraData, extraDataSize);
|
||||
return CreateAtrac3Audio(channels, blockAlign, extraData, extraDataSize);
|
||||
case PSP_CODEC_AT3PLUS:
|
||||
return CreateAtrac3PlusAudio(channels, blockAlign);
|
||||
default:
|
||||
// Only AAC falls back to FFMPEG now.
|
||||
// Only AAC normally falls back to FFMPEG now.
|
||||
return new FFmpegAudioDecoder(audioType, sampleRateHz, channels);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
#include "Core/HLE/ErrorCodes.h"
|
||||
#include "Core/MemMap.h"
|
||||
|
||||
// Atrac file parsing constants
|
||||
#define AT3_MAGIC 0x0270
|
||||
#define AT3_PLUS_MAGIC 0xFFFE // This is normally a marker for WAVE_FORMAT_EXTENSIBLE
|
||||
|
||||
const int RIFF_CHUNK_MAGIC = 0x46464952;
|
||||
const int RIFF_WAVE_MAGIC = 0x45564157;
|
||||
const int FMT_CHUNK_MAGIC = 0x20746D66;
|
||||
@@ -110,9 +114,9 @@ int AnalyzeAtracTrack(const u8 *buffer, u32 size, Track *track, std::string *err
|
||||
}
|
||||
|
||||
if (at3fmt->fmtTag == AT3_MAGIC)
|
||||
track->codecType = PSP_MODE_AT_3;
|
||||
track->codecType = PSP_CODEC_AT3;
|
||||
else if (at3fmt->fmtTag == AT3_PLUS_MAGIC)
|
||||
track->codecType = PSP_MODE_AT_3_PLUS;
|
||||
track->codecType = PSP_CODEC_AT3PLUS;
|
||||
else {
|
||||
*error = "AnalyzeTrack: invalid fmt magic: %04x";
|
||||
return SCE_ERROR_ATRAC_UNKNOWN_FORMAT;
|
||||
@@ -288,14 +292,14 @@ int AnalyzeAA3Track(const u8 *buffer, u32 size, u32 fileSize, Track *track, std:
|
||||
|
||||
switch (buffer[32]) {
|
||||
case 0:
|
||||
track->codecType = PSP_MODE_AT_3;
|
||||
track->codecType = PSP_CODEC_AT3;
|
||||
track->bytesPerFrame = (codecParams & 0x03FF) * 8;
|
||||
track->bitrate = at3SampleRates[(codecParams >> 13) & 7] * track->bytesPerFrame * 8 / 1024;
|
||||
track->channels = 2;
|
||||
track->jointStereo = (codecParams >> 17) & 1;
|
||||
break;
|
||||
case 1:
|
||||
track->codecType = PSP_MODE_AT_3_PLUS;
|
||||
track->codecType = PSP_CODEC_AT3PLUS;
|
||||
track->bytesPerFrame = ((codecParams & 0x03FF) * 8) + 8;
|
||||
track->bitrate = at3SampleRates[(codecParams >> 13) & 7] * track->bytesPerFrame * 8 / 2048;
|
||||
track->channels = (codecParams >> 10) & 7;
|
||||
|
||||
@@ -5,11 +5,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// Atrac file parsing.
|
||||
#define AT3_MAGIC 0x0270
|
||||
#define AT3_PLUS_MAGIC 0xFFFE
|
||||
#define PSP_MODE_AT_3_PLUS 0x00001000
|
||||
#define PSP_MODE_AT_3 0x00001001
|
||||
#include "Core/HLE/sceAudiocodec.h"
|
||||
|
||||
constexpr u32 ATRAC3_MAX_SAMPLES = 0x400; // 1024
|
||||
constexpr u32 ATRAC3PLUS_MAX_SAMPLES = 0x800; // 2048
|
||||
@@ -72,7 +68,7 @@ struct Track {
|
||||
|
||||
inline int FirstOffsetExtra() const {
|
||||
// These first samples are skipped, after first possibly skipping 0-2 full frames, it seems.
|
||||
return codecType == PSP_MODE_AT_3_PLUS ? 0x170 : 0x45;
|
||||
return codecType == PSP_CODEC_AT3PLUS ? 0x170 : 0x45;
|
||||
}
|
||||
|
||||
// Includes the extra offset. See firstSampleOffset comment above.
|
||||
@@ -82,12 +78,12 @@ struct Track {
|
||||
|
||||
// Output frame size, different between the two supported codecs.
|
||||
int SamplesPerFrame() const {
|
||||
return codecType == PSP_MODE_AT_3_PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES;
|
||||
return codecType == PSP_CODEC_AT3PLUS ? ATRAC3PLUS_MAX_SAMPLES : ATRAC3_MAX_SAMPLES;
|
||||
}
|
||||
|
||||
int Bitrate() const {
|
||||
int bitrate = (bytesPerFrame * 352800) / 1000;
|
||||
if (codecType == PSP_MODE_AT_3_PLUS)
|
||||
if (codecType == PSP_CODEC_AT3PLUS)
|
||||
bitrate = ((bitrate >> 11) + 8) & 0xFFFFFFF0;
|
||||
else
|
||||
bitrate = (bitrate + 511) >> 10;
|
||||
|
||||
+73
-55
@@ -100,11 +100,10 @@ void DeveloperToolsScreen::CreateTextureReplacementTab(UI::LinearLayout *list) {
|
||||
void DeveloperToolsScreen::CreateGeneralTab(UI::LinearLayout *list) {
|
||||
using namespace UI;
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
auto si = GetI18NCategory(I18NCat::SYSINFO);
|
||||
auto sy = GetI18NCategory(I18NCat::SYSTEM);
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
|
||||
list->Add(new ItemHeader(sy->T("General")));
|
||||
list->Add(new ItemHeader(sy->T("CPU Core")));
|
||||
|
||||
bool canUseJit = System_GetPropertyBool(SYSPROP_CAN_JIT);
|
||||
// iOS can now use JIT on all modes, apparently.
|
||||
@@ -130,14 +129,10 @@ void DeveloperToolsScreen::CreateGeneralTab(UI::LinearLayout *list) {
|
||||
list->Add(new Choice(dev->T("JIT debug tools")))->OnClick.Handle(this, &DeveloperToolsScreen::OnJitDebugTools);
|
||||
list->Add(new CheckBox(&g_Config.bShowDeveloperMenu, dev->T("Show Developer Menu")));
|
||||
|
||||
#if !PPSSPP_PLATFORM(UWP)
|
||||
Choice *cpuTests = new Choice(dev->T("Run CPU Tests"));
|
||||
list->Add(cpuTests)->OnClick.Handle(this, &DeveloperToolsScreen::OnRunCPUTests);
|
||||
cpuTests->SetEnabled(TestsAvailable() && !PSP_IsInited());
|
||||
#endif
|
||||
|
||||
AddOverlayList(list, screenManager());
|
||||
|
||||
list->Add(new ItemHeader(sy->T("General")));
|
||||
|
||||
list->Add(new CheckBox(&g_Config.bEnableLogging, dev->T("Enable Logging")))->OnClick.Handle(this, &DeveloperToolsScreen::OnLoggingChanged);
|
||||
list->Add(new Choice(dev->T("Logging Channels")))->OnClick.Handle(this, &DeveloperToolsScreen::OnLogConfig);
|
||||
list->Add(new CheckBox(&g_Config.bLogFrameDrops, dev->T("Log Dropped Frame Statistics")));
|
||||
@@ -145,37 +140,7 @@ void DeveloperToolsScreen::CreateGeneralTab(UI::LinearLayout *list) {
|
||||
list->Add(new CheckBox(&g_Config.bGpuLogProfiler, dev->T("GPU log profiler")));
|
||||
}
|
||||
|
||||
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
|
||||
list->Add(new CheckBox(&g_Config.bRenderMultiThreading, dev->T("Multi-threaded rendering"), ""))->OnClick.Add([](UI::EventParams &e) {
|
||||
// TODO: Not translating yet. Will combine with other translations of settings that need restart.
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, "Restart required");
|
||||
return UI::EVENT_DONE;
|
||||
});
|
||||
}
|
||||
|
||||
if (GetGPUBackend() == GPUBackend::VULKAN && SupportsCustomDriver()) {
|
||||
auto driverChoice = list->Add(new Choice(gr->T("AdrenoTools driver manager")));
|
||||
driverChoice->OnClick.Add([=](UI::EventParams &e) {
|
||||
screenManager()->push(new DriverManagerScreen(gamePath_));
|
||||
return UI::EVENT_DONE;
|
||||
});
|
||||
}
|
||||
|
||||
// For now, we only implement GPU driver tests for Vulkan and OpenGL. This is simply
|
||||
// because the D3D drivers are generally solid enough to not need this type of investigation.
|
||||
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN || g_Config.iGPUBackend == (int)GPUBackend::OPENGL) {
|
||||
list->Add(new Choice(dev->T("GPU Driver Test")))->OnClick.Handle(this, &DeveloperToolsScreen::OnGPUDriverTest);
|
||||
}
|
||||
list->Add(new CheckBox(&g_Config.bVendorBugChecksEnabled, dev->T("Enable driver bug workarounds")));
|
||||
Choice *frameDumpTests = list->Add(new Choice(dev->T("Framedump tests")));
|
||||
frameDumpTests->OnClick.Add([this](UI::EventParams &e) {
|
||||
screenManager()->push(new FrameDumpTestScreen());
|
||||
return UI::EVENT_DONE;
|
||||
});
|
||||
frameDumpTests->SetEnabled(!PSP_IsInited());
|
||||
|
||||
list->Add(new Choice(dev->T("Touchscreen Test")))->OnClick.Handle(this, &DeveloperToolsScreen::OnTouchscreenTest);
|
||||
// list->Add(new Choice(dev->T("Memstick Test")))->OnClick.Handle(this, &DeveloperToolsScreen::OnMemstickTest);
|
||||
list->Add(new CheckBox(&g_Config.bShowOnScreenMessages, dev->T("Show on-screen messages")));
|
||||
|
||||
allowDebugger_ = !WebServerStopped(WebServerFlags::DEBUGGER);
|
||||
canAllowDebugger_ = !WebServerStopping(WebServerFlags::DEBUGGER);
|
||||
@@ -183,8 +148,6 @@ void DeveloperToolsScreen::CreateGeneralTab(UI::LinearLayout *list) {
|
||||
list->Add(allowDebugger)->OnClick.Handle(this, &DeveloperToolsScreen::OnRemoteDebugger);
|
||||
allowDebugger->SetEnabledPtr(&canAllowDebugger_);
|
||||
|
||||
list->Add(new CheckBox(&g_Config.bShowOnScreenMessages, dev->T("Show on-screen messages")));
|
||||
|
||||
list->Add(new Choice(dev->T("GPI/GPO switches/LEDs")))->OnClick.Add([=](UI::EventParams &e) {
|
||||
screenManager()->push(new GPIGPOScreen(dev->T("GPI/GPO switches/LEDs")));
|
||||
return UI::EVENT_DONE;
|
||||
@@ -209,20 +172,35 @@ void DeveloperToolsScreen::CreateGeneralTab(UI::LinearLayout *list) {
|
||||
});
|
||||
#endif
|
||||
|
||||
static const char *ffModes[] = { "Render all frames", "", "Frame Skipping" };
|
||||
PopupMultiChoice *ffMode = list->Add(new PopupMultiChoice(&g_Config.iFastForwardMode, dev->T("Fast-forward mode"), ffModes, 0, ARRAY_SIZE(ffModes), I18NCat::GRAPHICS, screenManager()));
|
||||
ffMode->SetEnabledFunc([]() { return !g_Config.bVSync; });
|
||||
ffMode->HideChoice(1); // not used
|
||||
|
||||
auto displayRefreshRate = list->Add(new PopupSliderChoice(&g_Config.iDisplayRefreshRate, 60, 1000, 60, dev->T("Display refresh rate"), 1, screenManager()));
|
||||
displayRefreshRate->SetFormat(si->T("%d Hz"));
|
||||
|
||||
// Makes it easy to get savestates out of an iOS device. The file listing shown in MacOS doesn't allow
|
||||
// you to descend into directories.
|
||||
#if PPSSPP_PLATFORM(IOS)
|
||||
list->Add(new Choice(dev->T("Copy savestates to memstick root")))->OnClick.Handle(this, &DeveloperToolsScreen::OnCopyStatesToRoot);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DeveloperToolsScreen::CreateTestsTab(UI::LinearLayout *list) {
|
||||
using namespace UI;
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
|
||||
list->Add(new Choice(dev->T("Touchscreen Test")))->OnClick.Handle(this, &DeveloperToolsScreen::OnTouchscreenTest);
|
||||
// list->Add(new Choice(dev->T("Memstick Test")))->OnClick.Handle(this, &DeveloperToolsScreen::OnMemstickTest);
|
||||
Choice *frameDumpTests = list->Add(new Choice(dev->T("Framedump tests")));
|
||||
frameDumpTests->OnClick.Add([this](UI::EventParams &e) {
|
||||
screenManager()->push(new FrameDumpTestScreen());
|
||||
return UI::EVENT_DONE;
|
||||
});
|
||||
frameDumpTests->SetEnabled(!PSP_IsInited());
|
||||
#if !PPSSPP_PLATFORM(UWP)
|
||||
Choice *cpuTests = new Choice(dev->T("Run CPU Tests"));
|
||||
list->Add(cpuTests)->OnClick.Handle(this, &DeveloperToolsScreen::OnRunCPUTests);
|
||||
cpuTests->SetEnabled(TestsAvailable() && !PSP_IsInited());
|
||||
#endif
|
||||
// For now, we only implement GPU driver tests for Vulkan and OpenGL. This is simply
|
||||
// because the D3D drivers are generally solid enough to not need this type of investigation.
|
||||
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN || g_Config.iGPUBackend == (int)GPUBackend::OPENGL) {
|
||||
list->Add(new Choice(dev->T("GPU Driver Test")))->OnClick.Handle(this, &DeveloperToolsScreen::OnGPUDriverTest);
|
||||
}
|
||||
}
|
||||
|
||||
void DeveloperToolsScreen::CreateDumpFileTab(UI::LinearLayout *list) {
|
||||
@@ -313,17 +291,52 @@ void DeveloperToolsScreen::CreateMIPSTracerTab(UI::LinearLayout *list) {
|
||||
ClearMIPSTracer->OnClick.Handle(this, &DeveloperToolsScreen::OnMIPSTracerClearTracer);
|
||||
}
|
||||
|
||||
void DeveloperToolsScreen::CreateAudioTab(UI::LinearLayout *list) {
|
||||
using namespace UI;
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
list->Add(new CheckBox(&g_Config.bForceFfmpegForAudioDec, dev->T("Use FFMPEG for all compressed audio")));
|
||||
}
|
||||
|
||||
void DeveloperToolsScreen::CreateGraphicsTab(UI::LinearLayout *list) {
|
||||
using namespace UI;
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
auto ps = GetI18NCategory(I18NCat::POSTSHADERS);
|
||||
auto sy = GetI18NCategory(I18NCat::SYSTEM);
|
||||
auto si = GetI18NCategory(I18NCat::SYSINFO);
|
||||
|
||||
Draw::DrawContext *draw = screenManager()->getDrawContext();
|
||||
|
||||
list->Add(new ItemHeader(sy->T("General")));
|
||||
list->Add(new CheckBox(&g_Config.bVendorBugChecksEnabled, dev->T("Enable driver bug workarounds")));
|
||||
|
||||
static const char *ffModes[] = { "Render all frames", "", "Frame Skipping" };
|
||||
PopupMultiChoice *ffMode = list->Add(new PopupMultiChoice(&g_Config.iFastForwardMode, dev->T("Fast-forward mode"), ffModes, 0, ARRAY_SIZE(ffModes), I18NCat::GRAPHICS, screenManager()));
|
||||
ffMode->SetEnabledFunc([]() { return !g_Config.bVSync; });
|
||||
ffMode->HideChoice(1); // not used
|
||||
|
||||
auto displayRefreshRate = list->Add(new PopupSliderChoice(&g_Config.iDisplayRefreshRate, 60, 1000, 60, dev->T("Display refresh rate"), 1, screenManager()));
|
||||
displayRefreshRate->SetFormat(si->T("%d Hz"));
|
||||
|
||||
list->Add(new ItemHeader(dev->T("Vulkan")));
|
||||
list->Add(new CheckBox(&g_Config.bVulkanDisableImplicitLayers, dev->T("Prevent loading overlays")));
|
||||
|
||||
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
|
||||
list->Add(new CheckBox(&g_Config.bRenderMultiThreading, dev->T("Multi-threaded rendering"), ""))->OnClick.Add([](UI::EventParams &e) {
|
||||
// TODO: Not translating yet. Will combine with other translations of settings that need restart.
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, "Restart required");
|
||||
return UI::EVENT_DONE;
|
||||
});
|
||||
}
|
||||
|
||||
if (GetGPUBackend() == GPUBackend::VULKAN && SupportsCustomDriver()) {
|
||||
auto driverChoice = list->Add(new Choice(gr->T("AdrenoTools driver manager")));
|
||||
driverChoice->OnClick.Add([=](UI::EventParams &e) {
|
||||
screenManager()->push(new DriverManagerScreen(gamePath_));
|
||||
return UI::EVENT_DONE;
|
||||
});
|
||||
}
|
||||
|
||||
list->Add(new ItemHeader(dev->T("Ubershaders")));
|
||||
if (draw->GetShaderLanguageDesc().bitwiseOps && !draw->GetBugs().Has(Draw::Bugs::UNIFORM_INDEXING_BROKEN)) {
|
||||
// If the above if fails, the checkbox is redundant since it'll be force disabled anyway.
|
||||
@@ -392,11 +405,20 @@ void DeveloperToolsScreen::CreateTabs() {
|
||||
auto sy = GetI18NCategory(I18NCat::SYSTEM);
|
||||
auto ms = GetI18NCategory(I18NCat::MAINSETTINGS);
|
||||
|
||||
AddTab("General", sy->T("General"), [this](UI::LinearLayout *parent) {
|
||||
CreateGeneralTab(parent);
|
||||
});
|
||||
AddTab("TextureReplacement", dev->T("Texture Replacement"), [this](UI::LinearLayout *parent) {
|
||||
CreateTextureReplacementTab(parent);
|
||||
});
|
||||
AddTab("General", sy->T("General"), [this](UI::LinearLayout *parent) {
|
||||
CreateGeneralTab(parent);
|
||||
AddTab("Graphics", ms->T("Graphics"), [this](UI::LinearLayout *parent) {
|
||||
CreateGraphicsTab(parent);
|
||||
});
|
||||
AddTab("Audio", ms->T("Audio"), [this](UI::LinearLayout *parent) {
|
||||
CreateAudioTab(parent);
|
||||
});
|
||||
AddTab("Tests", dev->T("Tests"), [this](UI::LinearLayout *parent) {
|
||||
CreateTestsTab(parent);
|
||||
});
|
||||
AddTab("DumpFiles", sy->T("Dump files"), [this](UI::LinearLayout *parent) {
|
||||
CreateDumpFileTab(parent);
|
||||
@@ -410,10 +432,6 @@ void DeveloperToolsScreen::CreateTabs() {
|
||||
CreateMIPSTracerTab(parent);
|
||||
});
|
||||
#endif
|
||||
AddTab("Graphics", ms->T("Graphics"), [this](UI::LinearLayout *parent) {
|
||||
CreateGraphicsTab(parent);
|
||||
});
|
||||
|
||||
// Reconsider whenever recreating views.
|
||||
hasTexturesIni_ = HasIni::MAYBE;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ private:
|
||||
void CreateDumpFileTab(UI::LinearLayout *parent);
|
||||
void CreateHLETab(UI::LinearLayout *parent);
|
||||
void CreateMIPSTracerTab(UI::LinearLayout *list);
|
||||
void CreateTestsTab(UI::LinearLayout *list);
|
||||
void CreateAudioTab(UI::LinearLayout *list);
|
||||
void CreateGraphicsTab(UI::LinearLayout *list);
|
||||
|
||||
UI::EventReturn OnRunCPUTests(UI::EventParams &e);
|
||||
|
||||
@@ -957,43 +957,58 @@ void DrawAudioDecodersView(ImConfig &cfg, ImControl &control) {
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("sceAtrac", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||
if (ImGui::BeginTable("atracs", 7, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) {
|
||||
ImGui::Checkbox("Force FFMPEG", &g_Config.bForceFfmpegForAudioDec);
|
||||
if (ImGui::BeginTable("atracs", 8, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) {
|
||||
ImGui::TableSetupColumn("Index", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Mute", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Channels", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("CurrentSample", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("RemainingFrames", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("CurSample", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("RemFrames", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Impl", ImGuiTableColumnFlags_WidthFixed);
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (int i = 0; i < PSP_MAX_ATRAC_IDS; i++) {
|
||||
u32 type = 0;
|
||||
const AtracBase *ctx = __AtracGetCtx(i, &type);
|
||||
if (!ctx) {
|
||||
continue;
|
||||
}
|
||||
const int maxContexts = __AtracMaxContexts();
|
||||
for (int i = 0; i < maxContexts; i++) {
|
||||
u32 codecType = 0;
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushID(i);
|
||||
ImGui::SetNextItemAllowOverlap();
|
||||
char temp[16];
|
||||
snprintf(temp, sizeof(temp), "%d", i);
|
||||
if (ImGui::Selectable(temp, i == cfg.selectedAtracCtx, ImGuiSelectableFlags_SpanAllColumns)) {
|
||||
cfg.selectedAtracCtx = i;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
switch (type) {
|
||||
case PSP_MODE_AT_3_PLUS:
|
||||
bool *mutePtr = __AtracMuteFlag(i);
|
||||
if (mutePtr) {
|
||||
ImGui::Checkbox("", mutePtr);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
switch (codecType) {
|
||||
case 0:
|
||||
ImGui::TextUnformatted("-"); // Uninitialized
|
||||
break;
|
||||
case PSP_CODEC_AT3PLUS:
|
||||
ImGui::TextUnformatted("Atrac3+");
|
||||
break;
|
||||
case PSP_MODE_AT_3:
|
||||
case PSP_CODEC_AT3:
|
||||
ImGui::TextUnformatted("Atrac3");
|
||||
break;
|
||||
default:
|
||||
ImGui::Text("%04x", type);
|
||||
ImGui::Text("%04x", codecType);
|
||||
break;
|
||||
}
|
||||
|
||||
const AtracBase *ctx = __AtracGetCtx(i, &codecType);
|
||||
if (!ctx) {
|
||||
// Nothing more we can display about uninitialized contexts.
|
||||
ImGui::PopID();
|
||||
continue;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(AtracStatusToString(ctx->BufferState()));
|
||||
ImGui::TableNextColumn();
|
||||
@@ -1014,6 +1029,7 @@ void DrawAudioDecodersView(ImConfig &cfg, ImControl &control) {
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(ctx->GetContextVersion() >= 2 ? "NewImpl" : "Legacy");
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
@@ -1291,6 +1307,8 @@ void DrawSasAudio(ImConfig &cfg) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Mute", __SasGetGlobalMuteFlag());
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Show all voices", &cfg.sasShowAllVoices);
|
||||
|
||||
if (ImGui::BeginTable("saschannels", 9, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) {
|
||||
@@ -1834,6 +1852,10 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
|
||||
System_CopyStringToClipboard(StringFromFormat("%016llx", (uint64_t)(uintptr_t)Memory::base));
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Close")) {
|
||||
g_Config.bShowImDebugger = false;
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Core")) {
|
||||
@@ -1952,11 +1974,22 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
|
||||
ImGui::MenuItem("Dear ImGui Style editor", nullptr, &cfg_.styleEditorOpen);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
// Let's have this at the top level, to help anyone confused.
|
||||
if (ImGui::BeginMenu("Close Debugger")) {
|
||||
if (ImGui::MenuItem("Close")) {
|
||||
g_Config.bShowImDebugger = false;
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
switch (coreState) {
|
||||
case CoreState::CORE_STEPPING_CPU:
|
||||
if (ImGui::MenuItem(">> Run")) {
|
||||
Core_Resume();
|
||||
}
|
||||
break;
|
||||
case CoreState::CORE_RUNNING_CPU:
|
||||
if (ImGui::MenuItem("|| Break")) {
|
||||
Core_Break(BreakReason::DebugBreak);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user