mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue