// Copyright 2020 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include #include #include "audio_core/common.h" #include "audio_core/splitter_context.h" #include "common/common_funcs.h" #include "common/common_types.h" namespace AudioCore { class BehaviorInfo; class EffectContext; class MixInfo { public: struct DirtyHeader { u32_le magic{}; u32_le mixer_count{}; INSERT_PADDING_BYTES(0x18); }; static_assert(sizeof(DirtyHeader) == 0x20, "MixInfo::DirtyHeader is an invalid size"); struct InParams { float_le volume{}; s32_le sample_rate{}; s32_le buffer_count{}; bool in_use{}; INSERT_PADDING_BYTES(3); s32_le mix_id{}; s32_le effect_count{}; u32_le node_id{}; INSERT_PADDING_WORDS(2); std::array, AudioCommon::MAX_MIX_BUFFERS> mix_volume{}; s32_le dest_mix_id{}; s32_le splitter_id{}; INSERT_PADDING_WORDS(1); }; static_assert(sizeof(MixInfo::InParams) == 0x930, "MixInfo::InParams is an invalid size"); }; class ServerMixInfo { public: struct InParams { float volume{}; s32 sample_rate{}; s32 buffer_count{}; bool in_use{}; s32 mix_id{}; u32 node_id{}; std::array, AudioCommon::MAX_MIX_BUFFERS> mix_volume{}; s32 dest_mix_id{}; s32 splitter_id{}; s32 buffer_offset{}; s32 final_mix_distance{}; }; ServerMixInfo(); ~ServerMixInfo(); [[nodiscard]] const ServerMixInfo::InParams& GetInParams() const; [[nodiscard]] ServerMixInfo::InParams& GetInParams(); bool Update(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix_in, BehaviorInfo& behavior_info, SplitterContext& splitter_context, EffectContext& effect_context); [[nodiscard]] bool HasAnyConnection() const; void Cleanup(); void SetEffectCount(std::size_t count); void ResetEffectProcessingOrder(); [[nodiscard]] s32 GetEffectOrder(std::size_t i) const; private: std::vector effect_processing_order; InParams in_params{}; bool UpdateConnection(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix_in, SplitterContext& splitter_context); }; class MixContext { public: MixContext(); ~MixContext(); void Initialize(const BehaviorInfo& behavior_info, std::size_t mix_count, std::size_t effect_count); void SortInfo(); bool TsortInfo(SplitterContext& splitter_context); [[nodiscard]] std::size_t GetCount() const; [[nodiscard]] ServerMixInfo& GetInfo(std::size_t i); [[nodiscard]] const ServerMixInfo& GetInfo(std::size_t i) const; [[nodiscard]] ServerMixInfo& GetSortedInfo(std::size_t i); [[nodiscard]] const ServerMixInfo& GetSortedInfo(std::size_t i) const; [[nodiscard]] ServerMixInfo& GetFinalMixInfo(); [[nodiscard]] const ServerMixInfo& GetFinalMixInfo() const; [[nodiscard]] EdgeMatrix& GetEdgeMatrix(); [[nodiscard]] const EdgeMatrix& GetEdgeMatrix() const; private: void CalcMixBufferOffset(); void UpdateDistancesFromFinalMix(); NodeStates node_states{}; EdgeMatrix edge_matrix{}; std::size_t info_count{}; std::vector infos{}; std::vector sorted_info{}; }; } // namespace AudioCore