DTK: Adjustments attempting to increase accuracy
This commit is contained in:
parent
e91db62f1b
commit
a6a4229865
|
@ -58,7 +58,6 @@ This file mainly deals with the [Drive I/F], however [AIDFR] controls
|
||||||
#include "Core/CoreTiming.h"
|
#include "Core/CoreTiming.h"
|
||||||
#include "Core/HW/AudioInterface.h"
|
#include "Core/HW/AudioInterface.h"
|
||||||
#include "Core/HW/CPU.h"
|
#include "Core/HW/CPU.h"
|
||||||
#include "Core/HW/DVDInterface.h"
|
|
||||||
#include "Core/HW/MMIO.h"
|
#include "Core/HW/MMIO.h"
|
||||||
#include "Core/HW/ProcessorInterface.h"
|
#include "Core/HW/ProcessorInterface.h"
|
||||||
#include "Core/HW/SystemTimers.h"
|
#include "Core/HW/SystemTimers.h"
|
||||||
|
@ -177,8 +176,18 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
MMIO::ComplexWrite<u32>([](u32, u32 val) {
|
MMIO::ComplexWrite<u32>([](u32, u32 val) {
|
||||||
AICR tmpAICtrl(val);
|
AICR tmpAICtrl(val);
|
||||||
|
|
||||||
m_Control.AIINTMSK = tmpAICtrl.AIINTMSK;
|
|
||||||
m_Control.AIINTVLD = tmpAICtrl.AIINTVLD;
|
if (m_Control.AIINTMSK != tmpAICtrl.AIINTMSK)
|
||||||
|
{
|
||||||
|
DEBUG_LOG(AUDIO_INTERFACE, "Change AIINTMSK to %d", tmpAICtrl.AIINTMSK);
|
||||||
|
m_Control.AIINTMSK = tmpAICtrl.AIINTMSK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Control.AIINTVLD != tmpAICtrl.AIINTVLD)
|
||||||
|
{
|
||||||
|
DEBUG_LOG(AUDIO_INTERFACE, "Change AIINTVLD to %d", tmpAICtrl.AIINTVLD);
|
||||||
|
m_Control.AIINTVLD = tmpAICtrl.AIINTVLD;
|
||||||
|
}
|
||||||
|
|
||||||
// Set frequency of streaming audio
|
// Set frequency of streaming audio
|
||||||
if (tmpAICtrl.AISFR != m_Control.AISFR)
|
if (tmpAICtrl.AISFR != m_Control.AISFR)
|
||||||
|
@ -205,9 +214,6 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
m_Control.PSTAT = tmpAICtrl.PSTAT;
|
m_Control.PSTAT = tmpAICtrl.PSTAT;
|
||||||
g_LastCPUTime = CoreTiming::GetTicks();
|
g_LastCPUTime = CoreTiming::GetTicks();
|
||||||
|
|
||||||
// Tell Drive Interface to start/stop streaming
|
|
||||||
DVDInterface::g_bStream = tmpAICtrl.PSTAT;
|
|
||||||
|
|
||||||
CoreTiming::RemoveEvent(et_AI);
|
CoreTiming::RemoveEvent(et_AI);
|
||||||
CoreTiming::ScheduleEvent(((int)GetAIPeriod() / 2), et_AI);
|
CoreTiming::ScheduleEvent(((int)GetAIPeriod() / 2), et_AI);
|
||||||
}
|
}
|
||||||
|
@ -251,6 +257,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
mmio->Register(base | AI_INTERRUPT_TIMING,
|
mmio->Register(base | AI_INTERRUPT_TIMING,
|
||||||
MMIO::DirectRead<u32>(&m_InterruptTiming),
|
MMIO::DirectRead<u32>(&m_InterruptTiming),
|
||||||
MMIO::ComplexWrite<u32>([](u32, u32 val) {
|
MMIO::ComplexWrite<u32>([](u32, u32 val) {
|
||||||
|
DEBUG_LOG(AUDIO_INTERFACE, "AI_INTERRUPT_TIMING=%08x@%08x", val, PowerPC::ppcState.pc);
|
||||||
m_InterruptTiming = val;
|
m_InterruptTiming = val;
|
||||||
CoreTiming::RemoveEvent(et_AI);
|
CoreTiming::RemoveEvent(et_AI);
|
||||||
CoreTiming::ScheduleEvent(((int)GetAIPeriod() / 2), et_AI);
|
CoreTiming::ScheduleEvent(((int)GetAIPeriod() / 2), et_AI);
|
||||||
|
@ -279,14 +286,22 @@ static void IncreaseSampleCount(const u32 _iAmount)
|
||||||
{
|
{
|
||||||
if (m_Control.PSTAT)
|
if (m_Control.PSTAT)
|
||||||
{
|
{
|
||||||
|
u32 old_SampleCounter = m_SampleCounter + 1;
|
||||||
m_SampleCounter += _iAmount;
|
m_SampleCounter += _iAmount;
|
||||||
if (m_Control.AIINTVLD && (m_SampleCounter >= m_InterruptTiming))
|
|
||||||
|
if ((m_InterruptTiming - old_SampleCounter) <= (m_SampleCounter - old_SampleCounter))
|
||||||
{
|
{
|
||||||
|
DEBUG_LOG(AUDIO_INTERFACE, "GenerateAudioInterrupt %08x:%08x @ %08x m_Control.AIINTVLD=%d", m_SampleCounter, m_InterruptTiming, PowerPC::ppcState.pc, m_Control.AIINTVLD);
|
||||||
GenerateAudioInterrupt();
|
GenerateAudioInterrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsPlaying()
|
||||||
|
{
|
||||||
|
return (m_Control.PSTAT == 1);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int GetAIDSampleRate()
|
unsigned int GetAIDSampleRate()
|
||||||
{
|
{
|
||||||
return g_AIDSampleRate;
|
return g_AIDSampleRate;
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace AudioInterface
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void DoState(PointerWrap &p);
|
void DoState(PointerWrap &p);
|
||||||
|
bool IsPlaying();
|
||||||
|
|
||||||
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||||
|
|
||||||
|
|
|
@ -200,15 +200,17 @@ static UDICR m_DICR;
|
||||||
static UDIIMMBUF m_DIIMMBUF;
|
static UDIIMMBUF m_DIIMMBUF;
|
||||||
static UDICFG m_DICFG;
|
static UDICFG m_DICFG;
|
||||||
|
|
||||||
static u32 LoopStart;
|
|
||||||
static u32 AudioPos;
|
static u32 AudioPos;
|
||||||
static u32 CurrentStart;
|
static u32 CurrentStart;
|
||||||
static u32 LoopLength;
|
|
||||||
static u32 CurrentLength;
|
static u32 CurrentLength;
|
||||||
|
static u32 NextStart;
|
||||||
|
static u32 NextLength;
|
||||||
|
|
||||||
|
|
||||||
static u32 g_ErrorCode = 0;
|
static u32 g_ErrorCode = 0;
|
||||||
static bool g_bDiscInside = false;
|
static bool g_bDiscInside = false;
|
||||||
bool g_bStream = false;
|
bool g_bStream = false;
|
||||||
|
static bool g_bStopAtTrackEnd = false;
|
||||||
static int tc = 0;
|
static int tc = 0;
|
||||||
static int dtk = 0;
|
static int dtk = 0;
|
||||||
|
|
||||||
|
@ -240,9 +242,9 @@ void DoState(PointerWrap &p)
|
||||||
p.Do(m_DIIMMBUF);
|
p.Do(m_DIIMMBUF);
|
||||||
p.DoPOD(m_DICFG);
|
p.DoPOD(m_DICFG);
|
||||||
|
|
||||||
p.Do(LoopStart);
|
p.Do(NextStart);
|
||||||
p.Do(AudioPos);
|
p.Do(AudioPos);
|
||||||
p.Do(LoopLength);
|
p.Do(NextLength);
|
||||||
|
|
||||||
p.Do(g_ErrorCode);
|
p.Do(g_ErrorCode);
|
||||||
p.Do(g_bDiscInside);
|
p.Do(g_bDiscInside);
|
||||||
|
@ -253,6 +255,8 @@ void DoState(PointerWrap &p)
|
||||||
|
|
||||||
p.Do(g_last_read_offset);
|
p.Do(g_last_read_offset);
|
||||||
p.Do(g_last_read_time);
|
p.Do(g_last_read_time);
|
||||||
|
|
||||||
|
p.Do(g_bStopAtTrackEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TransferComplete(u64 userdata, int cyclesLate)
|
static void TransferComplete(u64 userdata, int cyclesLate)
|
||||||
|
@ -268,18 +272,22 @@ static u32 ProcessDTKSamples(short *tempPCM, u32 num_samples)
|
||||||
{
|
{
|
||||||
if (AudioPos >= CurrentStart + CurrentLength)
|
if (AudioPos >= CurrentStart + CurrentLength)
|
||||||
{
|
{
|
||||||
AudioPos = LoopStart;
|
DEBUG_LOG(DVDINTERFACE,
|
||||||
CurrentStart = LoopStart;
|
"ProcessDTKSamples: NextStart=%08x,NextLength=%08x,CurrentStart=%08x,CurrentLength=%08x,AudioPos=%08x",
|
||||||
CurrentLength = LoopLength;
|
NextStart, NextLength, CurrentStart, CurrentLength, AudioPos);
|
||||||
NGCADPCM::InitFilter();
|
|
||||||
AudioInterface::GenerateAISInterrupt();
|
|
||||||
|
|
||||||
// If there isn't any audio to stream, stop streaming.
|
AudioPos = NextStart;
|
||||||
if (AudioPos >= CurrentStart + CurrentLength)
|
CurrentStart = NextStart;
|
||||||
|
CurrentLength = NextLength;
|
||||||
|
|
||||||
|
if (g_bStopAtTrackEnd)
|
||||||
{
|
{
|
||||||
|
g_bStopAtTrackEnd = false;
|
||||||
g_bStream = false;
|
g_bStream = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
NGCADPCM::InitFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 tempADPCM[NGCADPCM::ONE_BLOCK_SIZE];
|
u8 tempADPCM[NGCADPCM::ONE_BLOCK_SIZE];
|
||||||
|
@ -303,7 +311,7 @@ static void DTKStreamingCallback(u64 userdata, int cyclesLate)
|
||||||
static const int NUM_SAMPLES = 48000 / 2000 * 7; // 3.5ms of 48kHz samples
|
static const int NUM_SAMPLES = 48000 / 2000 * 7; // 3.5ms of 48kHz samples
|
||||||
short tempPCM[NUM_SAMPLES * 2];
|
short tempPCM[NUM_SAMPLES * 2];
|
||||||
unsigned samples_processed;
|
unsigned samples_processed;
|
||||||
if (g_bStream)
|
if (g_bStream && AudioInterface::IsPlaying())
|
||||||
{
|
{
|
||||||
samples_processed = ProcessDTKSamples(tempPCM, NUM_SAMPLES);
|
samples_processed = ProcessDTKSamples(tempPCM, NUM_SAMPLES);
|
||||||
}
|
}
|
||||||
|
@ -333,12 +341,13 @@ void Init()
|
||||||
m_DICFG.CONFIG = 1; // Disable bootrom descrambler
|
m_DICFG.CONFIG = 1; // Disable bootrom descrambler
|
||||||
|
|
||||||
AudioPos = 0;
|
AudioPos = 0;
|
||||||
LoopStart = 0;
|
NextStart = 0;
|
||||||
LoopLength = 0;
|
NextLength = 0;
|
||||||
CurrentStart = 0;
|
CurrentStart = 0;
|
||||||
CurrentLength = 0;
|
CurrentLength = 0;
|
||||||
|
|
||||||
g_bStream = false;
|
g_bStream = false;
|
||||||
|
g_bStopAtTrackEnd = false;
|
||||||
|
|
||||||
ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback);
|
ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback);
|
||||||
insertDisc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback);
|
insertDisc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback);
|
||||||
|
@ -928,31 +937,41 @@ void ExecuteCommand()
|
||||||
// m_DICMDBUF[2].Hex = Length of the stream
|
// m_DICMDBUF[2].Hex = Length of the stream
|
||||||
case 0xE1:
|
case 0xE1:
|
||||||
{
|
{
|
||||||
u32 pos = m_DICMDBUF[1].Hex << 2;
|
u8 cancel_stream = m_DICMDBUF[0].CMDBYTE1;
|
||||||
u32 length = m_DICMDBUF[2].Hex;
|
if (cancel_stream)
|
||||||
|
|
||||||
// Start playing
|
|
||||||
if (!g_bStream && m_DICMDBUF[0].CMDBYTE1 == 0 && pos != 0 && length != 0)
|
|
||||||
{
|
|
||||||
AudioPos = pos;
|
|
||||||
CurrentStart = pos;
|
|
||||||
CurrentLength = length;
|
|
||||||
NGCADPCM::InitFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
LoopStart = pos;
|
|
||||||
LoopLength = length;
|
|
||||||
g_bStream = (m_DICMDBUF[0].CMDBYTE1 == 0); // This command can start/stop the stream
|
|
||||||
|
|
||||||
// Stop stream
|
|
||||||
if (m_DICMDBUF[0].CMDBYTE1 == 1)
|
|
||||||
{
|
{
|
||||||
|
g_bStopAtTrackEnd = false;
|
||||||
|
g_bStream = false;
|
||||||
AudioPos = 0;
|
AudioPos = 0;
|
||||||
LoopStart = 0;
|
NextStart = 0;
|
||||||
LoopLength = 0;
|
NextLength = 0;
|
||||||
CurrentStart = 0;
|
CurrentStart = 0;
|
||||||
CurrentLength = 0;
|
CurrentLength = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u32 pos = m_DICMDBUF[1].Hex << 2;
|
||||||
|
u32 length = m_DICMDBUF[2].Hex;
|
||||||
|
|
||||||
|
if ((pos == 0) && (length == 0))
|
||||||
|
{
|
||||||
|
g_bStopAtTrackEnd = true;
|
||||||
|
}
|
||||||
|
else if (!g_bStopAtTrackEnd)
|
||||||
|
{
|
||||||
|
NextStart = pos;
|
||||||
|
NextLength = length;
|
||||||
|
if (!g_bStream)
|
||||||
|
{
|
||||||
|
CurrentStart = NextStart;
|
||||||
|
CurrentLength = NextLength;
|
||||||
|
AudioPos = CurrentStart;
|
||||||
|
NGCADPCM::InitFilter();
|
||||||
|
g_bStream = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WARN_LOG(DVDINTERFACE, "(Audio) Stream subcmd = %08x offset = %08x length=%08x",
|
WARN_LOG(DVDINTERFACE, "(Audio) Stream subcmd = %08x offset = %08x length=%08x",
|
||||||
m_DICMDBUF[0].Hex, m_DICMDBUF[1].Hex << 2, m_DICMDBUF[2].Hex);
|
m_DICMDBUF[0].Hex, m_DICMDBUF[1].Hex << 2, m_DICMDBUF[2].Hex);
|
||||||
|
@ -965,25 +984,23 @@ void ExecuteCommand()
|
||||||
switch (m_DICMDBUF[0].CMDBYTE1)
|
switch (m_DICMDBUF[0].CMDBYTE1)
|
||||||
{
|
{
|
||||||
case 0x00: // Returns streaming status
|
case 0x00: // Returns streaming status
|
||||||
m_DIIMMBUF.Hex = (AudioPos == 0) ? 0 : 1;
|
DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status AudioPos:%08x/%08x CurrentStart:%08x CurrentLength:%08x", AudioPos, CurrentStart + CurrentLength, CurrentStart, CurrentLength);
|
||||||
|
m_DIIMMBUF.REGVAL0 = 0;
|
||||||
|
m_DIIMMBUF.REGVAL1 = 0;
|
||||||
|
m_DIIMMBUF.REGVAL2 = 0;
|
||||||
|
m_DIIMMBUF.REGVAL3 = (g_bStream) ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
case 0x01: // Returns the current offset
|
case 0x01: // Returns the current offset
|
||||||
if (g_bStream)
|
DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status AudioPos:%08x", AudioPos);
|
||||||
m_DIIMMBUF.Hex = (AudioPos - CurrentStart) >> 2;
|
m_DIIMMBUF.Hex = AudioPos >> 2;
|
||||||
else
|
|
||||||
m_DIIMMBUF.Hex = 0;
|
|
||||||
break;
|
break;
|
||||||
case 0x02: // Returns the start offset
|
case 0x02: // Returns the start offset
|
||||||
if (g_bStream)
|
DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status CurrentStart:%08x", CurrentStart);
|
||||||
m_DIIMMBUF.Hex = CurrentStart >> 2;
|
m_DIIMMBUF.Hex = CurrentStart >> 2;
|
||||||
else
|
|
||||||
m_DIIMMBUF.Hex = 0;
|
|
||||||
break;
|
break;
|
||||||
case 0x03: // Returns the total length
|
case 0x03: // Returns the total length
|
||||||
if (g_bStream)
|
DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status CurrentLength:%08x", CurrentLength);
|
||||||
m_DIIMMBUF.Hex = CurrentLength;
|
m_DIIMMBUF.Hex = CurrentLength;
|
||||||
else
|
|
||||||
m_DIIMMBUF.Hex = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN_LOG(DVDINTERFACE, "(Audio): Subcommand: %02x Request Audio status %s", m_DICMDBUF[0].CMDBYTE1, g_bStream? "on":"off");
|
WARN_LOG(DVDINTERFACE, "(Audio): Subcommand: %02x Request Audio status %s", m_DICMDBUF[0].CMDBYTE1, g_bStream? "on":"off");
|
||||||
|
|
|
@ -63,7 +63,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
||||||
static std::thread g_save_thread;
|
static std::thread g_save_thread;
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// Don't forget to increase this after doing changes on the savestate system
|
||||||
static const u32 STATE_VERSION = 28;
|
static const u32 STATE_VERSION = 29;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue