Skip to content
Permalink
Browse files
Merge pull request #11633 from AdmiralCurtiss/ai-class
HW/AudioInterface: Refactor to class.
  • Loading branch information
lioncash committed Mar 9, 2023
2 parents 2f5d246 + d638d2d commit 40ff9b2
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 234 deletions.

Large diffs are not rendered by default.

@@ -5,50 +5,116 @@

#pragma once

#include <memory>

#include "Common/CommonTypes.h"

class PointerWrap;
namespace Core
{
class System;
}
namespace CoreTiming
{
struct EventType;
}
namespace MMIO
{
class Mapping;
}

namespace AudioInterface
{
class AudioInterfaceState
class AudioInterfaceManager
{
public:
AudioInterfaceState();
AudioInterfaceState(const AudioInterfaceState&) = delete;
AudioInterfaceState(AudioInterfaceState&&) = delete;
AudioInterfaceState& operator=(const AudioInterfaceState&) = delete;
AudioInterfaceState& operator=(AudioInterfaceState&&) = delete;
~AudioInterfaceState();
AudioInterfaceManager(Core::System& system);
AudioInterfaceManager(const AudioInterfaceManager&) = delete;
AudioInterfaceManager(AudioInterfaceManager&&) = delete;
AudioInterfaceManager& operator=(const AudioInterfaceManager&) = delete;
AudioInterfaceManager& operator=(AudioInterfaceManager&&) = delete;
~AudioInterfaceManager();

void Init();
void Shutdown();
void DoState(PointerWrap& p);
bool IsPlaying() const;

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

// Get the audio rate divisors (divisors for 48KHz or 32KHz only)
// Mixer::FIXED_SAMPLE_RATE_DIVIDEND will be the dividend used for these divisors
u32 GetAIDSampleRateDivisor() const;
u32 GetAISSampleRateDivisor() const;

struct Data;
Data& GetData() { return *m_data; }
u32 Get32KHzSampleRateDivisor() const;
u32 Get48KHzSampleRateDivisor() const;

void GenerateAISInterrupt();

private:
std::unique_ptr<Data> m_data;
};
enum class SampleRate
{
AI32KHz,
AI48KHz,
};

// AI Control Register
union AICR
{
AICR() = default;
explicit AICR(u32 hex_) : hex{hex_} {}
struct
{
u32 PSTAT : 1; // sample counter/playback enable
u32 AISFR : 1; // AIS Frequency (0=32khz 1=48khz)
u32 AIINTMSK : 1; // 0=interrupt masked 1=interrupt enabled
u32 AIINT : 1; // audio interrupt status
u32 AIINTVLD : 1; // This bit controls whether AIINT is affected by the Interrupt Timing
// register
// matching the sample counter. Once set, AIINT will hold its last value
u32 SCRESET : 1; // write to reset counter
u32 AIDFR : 1; // AID Frequency (0=48khz 1=32khz)
u32 : 25;
};
u32 hex = 0;
};

// AI Volume Register
union AIVR
{
struct
{
u32 left : 8;
u32 right : 8;
u32 : 16;
};
u32 hex = 0;
};

void Init();
void Shutdown();
void DoState(PointerWrap& p);
bool IsPlaying();
void UpdateInterrupts();
void GenerateAudioInterrupt();
void IncreaseSampleCount(const u32 amount);
int GetAIPeriod() const;
void SetAIDSampleRate(SampleRate sample_rate);
void SetAISSampleRate(SampleRate sample_rate);

void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
void Update(u64 userdata, s64 cycles_late);
static void GlobalUpdate(Core::System& system, u64 userdata, s64 cycles_late);

// Get the audio rate divisors (divisors for 48KHz or 32KHz only)
// Mixer::FIXED_SAMPLE_RATE_DIVIDEND will be the dividend used for these divisors
u32 GetAIDSampleRateDivisor();
u32 GetAISSampleRateDivisor();
// Registers
AICR m_control;
AIVR m_volume;

u32 Get32KHzSampleRateDivisor();
u32 Get48KHzSampleRateDivisor();
u32 m_sample_counter = 0;
u32 m_interrupt_timing = 0;

void GenerateAISInterrupt();
u64 m_last_cpu_time = 0;
u64 m_cpu_cycles_per_sample = 0;

u32 m_ais_sample_rate_divisor = 0;
u32 m_aid_sample_rate_divisor = 0;

CoreTiming::EventType* m_event_type_ai = nullptr;

Core::System& m_system;
};
} // namespace AudioInterface
@@ -311,11 +311,12 @@ static void DTKStreamingCallback(DIInterruptType interrupt_type, const std::vect
{
auto& system = Core::System::GetInstance();
auto& state = system.GetDVDInterfaceState().GetData();
auto& ai = system.GetAudioInterface();

// Actual games always set this to 48 KHz
// but let's make sure to use GetAISSampleRateDivisor()
// just in case it changes to 32 KHz
const u32 sample_rate_divisor = AudioInterface::GetAISSampleRateDivisor();
const u32 sample_rate_divisor = ai.GetAISSampleRateDivisor();

// Determine which audio data to read next.

@@ -334,7 +335,7 @@ static void DTKStreamingCallback(DIInterruptType interrupt_type, const std::vect
SoundStream* sound_stream = system.GetSoundStream();
sound_stream->GetMixer()->PushStreamingSamples(temp_pcm.data(), state.pending_samples);

if (state.stream && AudioInterface::IsPlaying())
if (state.stream && ai.IsPlaying())
{
read_offset = state.audio_position;
read_length = AdvanceDTK(maximum_samples, &state.pending_samples);
@@ -40,7 +40,7 @@ void Init(const Sram* override_sram)
State::Init();

// Init the whole Hardware
AudioInterface::Init();
system.GetAudioInterface().Init();
VideoInterface::Init();
SerialInterface::Init();
system.GetProcessorInterface().Init();
@@ -80,7 +80,7 @@ void Shutdown()
system.GetHSP().Shutdown();
ExpansionInterface::Shutdown();
SerialInterface::Shutdown();
AudioInterface::Shutdown();
system.GetAudioInterface().Shutdown();

State::Shutdown();
system.GetCoreTiming().Shutdown();
@@ -107,7 +107,7 @@ void DoState(PointerWrap& p)
p.DoMarker("GPFifo");
ExpansionInterface::DoState(p);
p.DoMarker("ExpansionInterface");
AudioInterface::DoState(p);
system.GetAudioInterface().DoState(p);
p.DoMarker("AudioInterface");
system.GetHSP().DoState(p);
p.DoMarker("HSP");
@@ -58,14 +58,14 @@ void MemoryManager::InitMMIO(bool is_wii)
DVDInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false);
SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006400);
ExpansionInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006800);
AudioInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006C00);
system.GetAudioInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006C00);
if (is_wii)
{
IOS::RegisterMMIO(m_mmio_mapping.get(), 0x0D000000);
DVDInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0D006000, true);
SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0D006400);
ExpansionInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0D006800);
AudioInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0D006C00);
system.GetAudioInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0D006C00);
}
}

@@ -105,7 +105,8 @@ void DSPCallback(Core::System& system, u64 userdata, s64 cyclesLate)
int GetAudioDMACallbackPeriod()
{
// System internal sample rate is fixed at 32KHz * 4 (16bit Stereo) / 32 bytes DMA
return static_cast<u64>(s_cpu_core_clock) * AudioInterface::GetAIDSampleRateDivisor() /
auto& system = Core::System::GetInstance();
return static_cast<u64>(s_cpu_core_clock) * system.GetAudioInterface().GetAIDSampleRateDivisor() /
(Mixer::FIXED_SAMPLE_RATE_DIVIDEND * 4 / 32);
}

@@ -36,15 +36,16 @@ namespace Core
struct System::Impl
{
explicit Impl(System& system)
: m_core_timing(system), m_gp_fifo(system), m_ppc_state(PowerPC::ppcState)
: m_audio_interface(system), m_core_timing(system), m_gp_fifo(system),
m_ppc_state(PowerPC::ppcState)
{
}

std::unique_ptr<SoundStream> m_sound_stream;
bool m_sound_stream_running = false;
bool m_audio_dump_started = false;

AudioInterface::AudioInterfaceState m_audio_interface_state;
AudioInterface::AudioInterfaceManager m_audio_interface;
CoreTiming::CoreTimingManager m_core_timing;
CommandProcessor::CommandProcessorManager m_command_processor;
CPU::CPUManager m_cpu;
@@ -112,9 +113,9 @@ void System::SetAudioDumpStarted(bool started)
m_impl->m_audio_dump_started = started;
}

AudioInterface::AudioInterfaceState& System::GetAudioInterfaceState() const
AudioInterface::AudioInterfaceManager& System::GetAudioInterface() const
{
return m_impl->m_audio_interface_state;
return m_impl->m_audio_interface;
}

CPU::CPUManager& System::GetCPU() const
@@ -13,7 +13,7 @@ class VertexShaderManager;

namespace AudioInterface
{
class AudioInterfaceState;
class AudioInterfaceManager;
};
namespace CPU
{
@@ -122,7 +122,7 @@ class System
bool IsAudioDumpStarted() const;
void SetAudioDumpStarted(bool started);

AudioInterface::AudioInterfaceState& GetAudioInterfaceState() const;
AudioInterface::AudioInterfaceManager& GetAudioInterface() const;
CPU::CPUManager& GetCPU() const;
CoreTiming::CoreTimingManager& GetCoreTiming() const;
CommandProcessor::CommandProcessorManager& GetCommandProcessor() const;

0 comments on commit 40ff9b2

Please sign in to comment.