Skip to content

Commit

Permalink
Merge pull request #664 from booto/dtk-surgery
Browse files Browse the repository at this point in the history
DTK: Adjustments attempting to increase accuracy
  • Loading branch information
dolphin-emu-bot committed Jul 26, 2014
2 parents 6bd5fb3 + a6a4229 commit 30962ec
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 56 deletions.
29 changes: 22 additions & 7 deletions Source/Core/Core/HW/AudioInterface.cpp
Expand Up @@ -58,7 +58,6 @@ This file mainly deals with the [Drive I/F], however [AIDFR] controls
#include "Core/CoreTiming.h"
#include "Core/HW/AudioInterface.h"
#include "Core/HW/CPU.h"
#include "Core/HW/DVDInterface.h"
#include "Core/HW/MMIO.h"
#include "Core/HW/ProcessorInterface.h"
#include "Core/HW/SystemTimers.h"
Expand Down Expand Up @@ -177,8 +176,18 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
MMIO::ComplexWrite<u32>([](u32, u32 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
if (tmpAICtrl.AISFR != m_Control.AISFR)
Expand Down Expand Up @@ -207,9 +216,6 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
m_Control.PSTAT = tmpAICtrl.PSTAT;
g_LastCPUTime = CoreTiming::GetTicks();

// Tell Drive Interface to start/stop streaming
DVDInterface::g_bStream = tmpAICtrl.PSTAT;

CoreTiming::RemoveEvent(et_AI);
CoreTiming::ScheduleEvent(((int)GetAIPeriod() / 2), et_AI);
}
Expand Down Expand Up @@ -253,6 +259,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
mmio->Register(base | AI_INTERRUPT_TIMING,
MMIO::DirectRead<u32>(&m_InterruptTiming),
MMIO::ComplexWrite<u32>([](u32, u32 val) {
DEBUG_LOG(AUDIO_INTERFACE, "AI_INTERRUPT_TIMING=%08x@%08x", val, PowerPC::ppcState.pc);
m_InterruptTiming = val;
CoreTiming::RemoveEvent(et_AI);
CoreTiming::ScheduleEvent(((int)GetAIPeriod() / 2), et_AI);
Expand Down Expand Up @@ -281,14 +288,22 @@ static void IncreaseSampleCount(const u32 _iAmount)
{
if (m_Control.PSTAT)
{
u32 old_SampleCounter = m_SampleCounter + 1;
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();
}
}
}

bool IsPlaying()
{
return (m_Control.PSTAT == 1);
}

unsigned int GetAIDSampleRate()
{
return g_AIDSampleRate;
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/HW/AudioInterface.h
Expand Up @@ -17,6 +17,7 @@ namespace AudioInterface
void Init();
void Shutdown();
void DoState(PointerWrap &p);
bool IsPlaying();

void RegisterMMIO(MMIO::Mapping* mmio, u32 base);

Expand Down
113 changes: 65 additions & 48 deletions Source/Core/Core/HW/DVDInterface.cpp
Expand Up @@ -200,15 +200,17 @@ static UDICR m_DICR;
static UDIIMMBUF m_DIIMMBUF;
static UDICFG m_DICFG;

static u32 LoopStart;
static u32 AudioPos;
static u32 CurrentStart;
static u32 LoopLength;
static u32 CurrentLength;
static u32 NextStart;
static u32 NextLength;


static u32 g_ErrorCode = 0;
static bool g_bDiscInside = false;
bool g_bStream = false;
static bool g_bStopAtTrackEnd = false;
static int tc = 0;
static int dtk = 0;

Expand Down Expand Up @@ -240,9 +242,9 @@ void DoState(PointerWrap &p)
p.Do(m_DIIMMBUF);
p.DoPOD(m_DICFG);

p.Do(LoopStart);
p.Do(NextStart);
p.Do(AudioPos);
p.Do(LoopLength);
p.Do(NextLength);

p.Do(g_ErrorCode);
p.Do(g_bDiscInside);
Expand All @@ -253,6 +255,8 @@ void DoState(PointerWrap &p)

p.Do(g_last_read_offset);
p.Do(g_last_read_time);

p.Do(g_bStopAtTrackEnd);
}

static void TransferComplete(u64 userdata, int cyclesLate)
Expand All @@ -268,18 +272,22 @@ static u32 ProcessDTKSamples(short *tempPCM, u32 num_samples)
{
if (AudioPos >= CurrentStart + CurrentLength)
{
AudioPos = LoopStart;
CurrentStart = LoopStart;
CurrentLength = LoopLength;
NGCADPCM::InitFilter();
AudioInterface::GenerateAISInterrupt();
DEBUG_LOG(DVDINTERFACE,
"ProcessDTKSamples: NextStart=%08x,NextLength=%08x,CurrentStart=%08x,CurrentLength=%08x,AudioPos=%08x",
NextStart, NextLength, CurrentStart, CurrentLength, AudioPos);

AudioPos = NextStart;
CurrentStart = NextStart;
CurrentLength = NextLength;

// If there isn't any audio to stream, stop streaming.
if (AudioPos >= CurrentStart + CurrentLength)
if (g_bStopAtTrackEnd)
{
g_bStopAtTrackEnd = false;
g_bStream = false;
break;
}
break;

NGCADPCM::InitFilter();
}

u8 tempADPCM[NGCADPCM::ONE_BLOCK_SIZE];
Expand All @@ -303,7 +311,7 @@ static void DTKStreamingCallback(u64 userdata, int cyclesLate)
static const int NUM_SAMPLES = 48000 / 2000 * 7; // 3.5ms of 48kHz samples
short tempPCM[NUM_SAMPLES * 2];
unsigned samples_processed;
if (g_bStream)
if (g_bStream && AudioInterface::IsPlaying())
{
samples_processed = ProcessDTKSamples(tempPCM, NUM_SAMPLES);
}
Expand Down Expand Up @@ -333,12 +341,13 @@ void Init()
m_DICFG.CONFIG = 1; // Disable bootrom descrambler

AudioPos = 0;
LoopStart = 0;
LoopLength = 0;
NextStart = 0;
NextLength = 0;
CurrentStart = 0;
CurrentLength = 0;

g_bStream = false;
g_bStopAtTrackEnd = false;

ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback);
insertDisc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback);
Expand Down Expand Up @@ -928,31 +937,41 @@ void ExecuteCommand()
// m_DICMDBUF[2].Hex = Length of the stream
case 0xE1:
{
u32 pos = m_DICMDBUF[1].Hex << 2;
u32 length = m_DICMDBUF[2].Hex;

// 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)
u8 cancel_stream = m_DICMDBUF[0].CMDBYTE1;
if (cancel_stream)
{
g_bStopAtTrackEnd = false;
g_bStream = false;
AudioPos = 0;
LoopStart = 0;
LoopLength = 0;
NextStart = 0;
NextLength = 0;
CurrentStart = 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",
m_DICMDBUF[0].Hex, m_DICMDBUF[1].Hex << 2, m_DICMDBUF[2].Hex);
Expand All @@ -965,25 +984,23 @@ void ExecuteCommand()
switch (m_DICMDBUF[0].CMDBYTE1)
{
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;
case 0x01: // Returns the current offset
if (g_bStream)
m_DIIMMBUF.Hex = (AudioPos - CurrentStart) >> 2;
else
m_DIIMMBUF.Hex = 0;
DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status AudioPos:%08x", AudioPos);
m_DIIMMBUF.Hex = AudioPos >> 2;
break;
case 0x02: // Returns the start offset
if (g_bStream)
m_DIIMMBUF.Hex = CurrentStart >> 2;
else
m_DIIMMBUF.Hex = 0;
DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status CurrentStart:%08x", CurrentStart);
m_DIIMMBUF.Hex = CurrentStart >> 2;
break;
case 0x03: // Returns the total length
if (g_bStream)
m_DIIMMBUF.Hex = CurrentLength;
else
m_DIIMMBUF.Hex = 0;
DEBUG_LOG(DVDINTERFACE, "(Audio): Stream Status: Request Audio status CurrentLength:%08x", CurrentLength);
m_DIIMMBUF.Hex = CurrentLength;
break;
default:
WARN_LOG(DVDINTERFACE, "(Audio): Subcommand: %02x Request Audio status %s", m_DICMDBUF[0].CMDBYTE1, g_bStream? "on":"off");
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/State.cpp
Expand Up @@ -63,7 +63,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread;

// 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
{
Expand Down

0 comments on commit 30962ec

Please sign in to comment.