Reworked DSP serialization
This commit is contained in:
parent
55c75b5e3e
commit
c983528862
8 changed files with 128 additions and 13 deletions
2
externals/boost
vendored
2
externals/boost
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 6d7edc593be8e47c8de7bc5f7d6b32971fad0c24
|
Subproject commit eb10fac1e1dfa4881c273d87e23d41509017223a
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <boost/serialization/access.hpp>
|
||||||
#include "audio_core/audio_types.h"
|
#include "audio_core/audio_types.h"
|
||||||
#include "audio_core/time_stretch.h"
|
#include "audio_core/time_stretch.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -113,6 +114,10 @@ private:
|
||||||
Common::RingBuffer<s16, 0x2000, 2> fifo;
|
Common::RingBuffer<s16, 0x2000, 2> fifo;
|
||||||
std::array<s16, 2> last_frame{};
|
std::array<s16, 2> last_frame{};
|
||||||
TimeStretcher time_stretcher;
|
TimeStretcher time_stretcher;
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int) {}
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
|
#pragma optimize("", off)
|
||||||
// Copyright 2017 Citra Emulator Project
|
// Copyright 2017 Citra Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <boost/serialization/array.hpp>
|
||||||
|
#include <boost/serialization/base_object.hpp>
|
||||||
|
#include <boost/serialization/shared_ptr.hpp>
|
||||||
|
#include <boost/serialization/vector.hpp>
|
||||||
|
#include <boost/serialization/weak_ptr.hpp>
|
||||||
#include "audio_core/audio_types.h"
|
#include "audio_core/audio_types.h"
|
||||||
#ifdef HAVE_MF
|
#ifdef HAVE_MF
|
||||||
#include "audio_core/hle/wmf_decoder.h"
|
#include "audio_core/hle/wmf_decoder.h"
|
||||||
|
@ -22,11 +28,21 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
|
|
||||||
|
SERIALIZE_EXPORT_IMPL(AudioCore::DspHle)
|
||||||
|
|
||||||
using InterruptType = Service::DSP::DSP_DSP::InterruptType;
|
using InterruptType = Service::DSP::DSP_DSP::InterruptType;
|
||||||
using Service::DSP::DSP_DSP;
|
using Service::DSP::DSP_DSP;
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
|
|
||||||
|
DspHle::DspHle() : DspHle(Core::System::GetInstance().Memory()) {}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void DspHle::serialize(Archive& ar, const unsigned int) {
|
||||||
|
ar& boost::serialization::base_object<DspInterface>(*this);
|
||||||
|
ar&* impl.get();
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles
|
static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles
|
||||||
|
|
||||||
struct DspHle::Impl final {
|
struct DspHle::Impl final {
|
||||||
|
@ -60,7 +76,7 @@ private:
|
||||||
void AudioTickCallback(s64 cycles_late);
|
void AudioTickCallback(s64 cycles_late);
|
||||||
|
|
||||||
DspState dsp_state = DspState::Off;
|
DspState dsp_state = DspState::Off;
|
||||||
std::array<std::vector<u8>, num_dsp_pipe> pipe_data;
|
std::array<std::vector<u8>, num_dsp_pipe> pipe_data{};
|
||||||
|
|
||||||
HLE::DspMemory dsp_memory;
|
HLE::DspMemory dsp_memory;
|
||||||
std::array<HLE::Source, HLE::num_sources> sources{{
|
std::array<HLE::Source, HLE::num_sources> sources{{
|
||||||
|
@ -70,14 +86,25 @@ private:
|
||||||
HLE::Source(15), HLE::Source(16), HLE::Source(17), HLE::Source(18), HLE::Source(19),
|
HLE::Source(15), HLE::Source(16), HLE::Source(17), HLE::Source(18), HLE::Source(19),
|
||||||
HLE::Source(20), HLE::Source(21), HLE::Source(22), HLE::Source(23),
|
HLE::Source(20), HLE::Source(21), HLE::Source(22), HLE::Source(23),
|
||||||
}};
|
}};
|
||||||
HLE::Mixers mixers;
|
HLE::Mixers mixers{};
|
||||||
|
|
||||||
DspHle& parent;
|
DspHle& parent;
|
||||||
Core::TimingEventType* tick_event;
|
Core::TimingEventType* tick_event{};
|
||||||
|
|
||||||
std::unique_ptr<HLE::DecoderBase> decoder;
|
std::unique_ptr<HLE::DecoderBase> decoder{};
|
||||||
|
|
||||||
std::weak_ptr<DSP_DSP> dsp_dsp;
|
std::weak_ptr<DSP_DSP> dsp_dsp{};
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
|
ar& dsp_state;
|
||||||
|
ar& pipe_data;
|
||||||
|
ar& dsp_memory.raw_memory;
|
||||||
|
ar& sources;
|
||||||
|
ar& mixers;
|
||||||
|
ar& dsp_dsp;
|
||||||
|
}
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(parent_) {
|
DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(parent_) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <boost/serialization/export.hpp>
|
||||||
#include "audio_core/audio_types.h"
|
#include "audio_core/audio_types.h"
|
||||||
#include "audio_core/dsp_interface.h"
|
#include "audio_core/dsp_interface.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -42,6 +43,14 @@ private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
friend struct Impl;
|
friend struct Impl;
|
||||||
std::unique_ptr<Impl> impl;
|
std::unique_ptr<Impl> impl;
|
||||||
|
|
||||||
|
DspHle();
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int);
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
||||||
|
BOOST_CLASS_EXPORT_KEY(AudioCore::DspHle)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <boost/serialization/array.hpp>
|
||||||
#include "audio_core/audio_types.h"
|
#include "audio_core/audio_types.h"
|
||||||
#include "audio_core/hle/shared_memory.h"
|
#include "audio_core/hle/shared_memory.h"
|
||||||
|
|
||||||
|
@ -54,6 +55,17 @@ private:
|
||||||
void DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& samples);
|
void DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& samples);
|
||||||
/// INTERNAL: Generate DspStatus based on internal state.
|
/// INTERNAL: Generate DspStatus based on internal state.
|
||||||
DspStatus GetCurrentStatus() const;
|
DspStatus GetCurrentStatus() const;
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
|
ar& current_frame;
|
||||||
|
ar& state.intermediate_mixer_volume;
|
||||||
|
ar& state.mixer1_enabled;
|
||||||
|
ar& state.mixer2_enabled;
|
||||||
|
ar& state.intermediate_mix_buffer;
|
||||||
|
ar& state.output_format;
|
||||||
|
}
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::HLE
|
} // namespace AudioCore::HLE
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <boost/serialization/access.hpp>
|
||||||
#include "audio_core/audio_types.h"
|
#include "audio_core/audio_types.h"
|
||||||
#include "audio_core/hle/common.h"
|
#include "audio_core/hle/common.h"
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
|
@ -56,6 +57,12 @@ private:
|
||||||
return (value << 16) | (value >> 16);
|
return (value << 16) | (value >> 16);
|
||||||
}
|
}
|
||||||
u32_le storage;
|
u32_le storage;
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
|
ar& storage;
|
||||||
|
}
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
static_assert(std::is_trivially_copyable<u32_dsp>::value, "u32_dsp isn't trivially copyable");
|
static_assert(std::is_trivially_copyable<u32_dsp>::value, "u32_dsp isn't trivially copyable");
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <boost/serialization/array.hpp>
|
||||||
|
#include <boost/serialization/deque.hpp>
|
||||||
|
#include <boost/serialization/priority_queue.hpp>
|
||||||
|
#include <boost/serialization/vector.hpp>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include "audio_core/audio_types.h"
|
#include "audio_core/audio_types.h"
|
||||||
#include "audio_core/codec.h"
|
#include "audio_core/codec.h"
|
||||||
|
@ -85,6 +89,24 @@ private:
|
||||||
bool from_queue;
|
bool from_queue;
|
||||||
u32_dsp play_position; // = 0;
|
u32_dsp play_position; // = 0;
|
||||||
bool has_played; // = false;
|
bool has_played; // = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
|
ar& physical_address;
|
||||||
|
ar& length;
|
||||||
|
ar& adpcm_ps;
|
||||||
|
ar& adpcm_yn;
|
||||||
|
ar& adpcm_dirty;
|
||||||
|
ar& is_looping;
|
||||||
|
ar& buffer_id;
|
||||||
|
ar& mono_or_stereo;
|
||||||
|
ar& format;
|
||||||
|
ar& from_queue;
|
||||||
|
ar& play_position;
|
||||||
|
ar& has_played;
|
||||||
|
}
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BufferOrder {
|
struct BufferOrder {
|
||||||
|
@ -107,7 +129,7 @@ private:
|
||||||
|
|
||||||
// Buffer queue
|
// Buffer queue
|
||||||
|
|
||||||
std::priority_queue<Buffer, std::vector<Buffer>, BufferOrder> input_queue;
|
std::priority_queue<Buffer, std::vector<Buffer>, BufferOrder> input_queue = {};
|
||||||
MonoOrStereo mono_or_stereo = MonoOrStereo::Mono;
|
MonoOrStereo mono_or_stereo = MonoOrStereo::Mono;
|
||||||
Format format = Format::ADPCM;
|
Format format = Format::ADPCM;
|
||||||
|
|
||||||
|
@ -115,7 +137,7 @@ private:
|
||||||
|
|
||||||
u32 current_sample_number = 0;
|
u32 current_sample_number = 0;
|
||||||
u32 next_sample_number = 0;
|
u32 next_sample_number = 0;
|
||||||
AudioInterp::StereoBuffer16 current_buffer;
|
AudioInterp::StereoBuffer16 current_buffer = {};
|
||||||
|
|
||||||
// buffer_id state
|
// buffer_id state
|
||||||
|
|
||||||
|
@ -135,7 +157,27 @@ private:
|
||||||
|
|
||||||
// Filter state
|
// Filter state
|
||||||
|
|
||||||
SourceFilters filters;
|
SourceFilters filters = {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
|
ar& enabled;
|
||||||
|
ar& sync;
|
||||||
|
ar& gain;
|
||||||
|
ar& input_queue;
|
||||||
|
ar& mono_or_stereo;
|
||||||
|
ar& format;
|
||||||
|
ar& current_sample_number;
|
||||||
|
ar& next_sample_number;
|
||||||
|
ar& current_buffer;
|
||||||
|
ar& buffer_update;
|
||||||
|
ar& current_buffer_id;
|
||||||
|
ar& adpcm_coeffs;
|
||||||
|
ar& rate_multiplier;
|
||||||
|
ar& interpolation_mode;
|
||||||
|
}
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
|
@ -150,6 +192,12 @@ private:
|
||||||
bool DequeueBuffer();
|
bool DequeueBuffer();
|
||||||
/// INTERNAL: Generates a SourceStatus::Status based on our internal state.
|
/// INTERNAL: Generates a SourceStatus::Status based on our internal state.
|
||||||
SourceStatus::Status GetCurrentStatus();
|
SourceStatus::Status GetCurrentStatus();
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
|
ar& state;
|
||||||
|
}
|
||||||
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::HLE
|
} // namespace AudioCore::HLE
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#pragma optimize("", off)
|
||||||
// Copyright 2014 Citra Emulator Project
|
// Copyright 2014 Citra Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
@ -244,8 +245,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo
|
||||||
|
|
||||||
timing = std::make_unique<Timing>();
|
timing = std::make_unique<Timing>();
|
||||||
|
|
||||||
kernel = std::make_unique<Kernel::KernelSystem>(*memory, *timing,
|
kernel = std::make_unique<Kernel::KernelSystem>(
|
||||||
[this] { PrepareReschedule(); }, system_mode);
|
*memory, *timing, [this] { PrepareReschedule(); }, system_mode);
|
||||||
|
|
||||||
if (Settings::values.use_cpu_jit) {
|
if (Settings::values.use_cpu_jit) {
|
||||||
#ifdef ARCHITECTURE_x86_64
|
#ifdef ARCHITECTURE_x86_64
|
||||||
|
@ -445,14 +446,20 @@ void System::serialize(Archive& ar, const unsigned int file_version) {
|
||||||
ar&* service_manager.get();
|
ar&* service_manager.get();
|
||||||
ar& GPU::g_regs;
|
ar& GPU::g_regs;
|
||||||
ar& LCD::g_regs;
|
ar& LCD::g_regs;
|
||||||
ar & dsp_core->GetDspMemory();
|
if (Archive::is_loading::value) {
|
||||||
|
dsp_core.reset();
|
||||||
|
}
|
||||||
|
ar& dsp_core;
|
||||||
ar&* memory.get();
|
ar&* memory.get();
|
||||||
ar&* kernel.get();
|
ar&* kernel.get();
|
||||||
|
|
||||||
// This needs to be set from somewhere - might as well be here!
|
// This needs to be set from somewhere - might as well be here!
|
||||||
if (Archive::is_loading::value) {
|
if (Archive::is_loading::value) {
|
||||||
Service::GSP::SetGlobalModule(*this);
|
Service::GSP::SetGlobalModule(*this);
|
||||||
DSP().SetServiceToInterrupt(ServiceManager().GetService<Service::DSP::DSP_DSP>("dsp::DSP"));
|
|
||||||
|
memory->SetDSP(*dsp_core);
|
||||||
|
dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id);
|
||||||
|
dsp_core->EnableStretching(Settings::values.enable_audio_stretching);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue