1 // Copyright 2020 yuzu Emulator Project 2 // Licensed under GPLv2 or any later version 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <array> 8 #include <vector> 9 #include "audio_core/common.h" 10 #include "audio_core/splitter_context.h" 11 #include "common/common_funcs.h" 12 #include "common/common_types.h" 13 14 namespace AudioCore { 15 class BehaviorInfo; 16 class EffectContext; 17 18 class MixInfo { 19 public: 20 struct DirtyHeader { 21 u32_le magic{}; 22 u32_le mixer_count{}; 23 INSERT_PADDING_BYTES(0x18); 24 }; 25 static_assert(sizeof(DirtyHeader) == 0x20, "MixInfo::DirtyHeader is an invalid size"); 26 27 struct InParams { 28 float_le volume{}; 29 s32_le sample_rate{}; 30 s32_le buffer_count{}; 31 bool in_use{}; 32 INSERT_PADDING_BYTES(3); 33 s32_le mix_id{}; 34 s32_le effect_count{}; 35 u32_le node_id{}; 36 INSERT_PADDING_WORDS(2); 37 std::array<std::array<float_le, AudioCommon::MAX_MIX_BUFFERS>, AudioCommon::MAX_MIX_BUFFERS> 38 mix_volume{}; 39 s32_le dest_mix_id{}; 40 s32_le splitter_id{}; 41 INSERT_PADDING_WORDS(1); 42 }; 43 static_assert(sizeof(MixInfo::InParams) == 0x930, "MixInfo::InParams is an invalid size"); 44 }; 45 46 class ServerMixInfo { 47 public: 48 struct InParams { 49 float volume{}; 50 s32 sample_rate{}; 51 s32 buffer_count{}; 52 bool in_use{}; 53 s32 mix_id{}; 54 u32 node_id{}; 55 std::array<std::array<float_le, AudioCommon::MAX_MIX_BUFFERS>, AudioCommon::MAX_MIX_BUFFERS> 56 mix_volume{}; 57 s32 dest_mix_id{}; 58 s32 splitter_id{}; 59 s32 buffer_offset{}; 60 s32 final_mix_distance{}; 61 }; 62 ServerMixInfo(); 63 ~ServerMixInfo(); 64 65 [[nodiscard]] const ServerMixInfo::InParams& GetInParams() const; 66 [[nodiscard]] ServerMixInfo::InParams& GetInParams(); 67 68 bool Update(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix_in, 69 BehaviorInfo& behavior_info, SplitterContext& splitter_context, 70 EffectContext& effect_context); 71 [[nodiscard]] bool HasAnyConnection() const; 72 void Cleanup(); 73 void SetEffectCount(std::size_t count); 74 void ResetEffectProcessingOrder(); 75 [[nodiscard]] s32 GetEffectOrder(std::size_t i) const; 76 77 private: 78 std::vector<s32> effect_processing_order; 79 InParams in_params{}; 80 bool UpdateConnection(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix_in, 81 SplitterContext& splitter_context); 82 }; 83 84 class MixContext { 85 public: 86 MixContext(); 87 ~MixContext(); 88 89 void Initialize(const BehaviorInfo& behavior_info, std::size_t mix_count, 90 std::size_t effect_count); 91 void SortInfo(); 92 bool TsortInfo(SplitterContext& splitter_context); 93 94 [[nodiscard]] std::size_t GetCount() const; 95 [[nodiscard]] ServerMixInfo& GetInfo(std::size_t i); 96 [[nodiscard]] const ServerMixInfo& GetInfo(std::size_t i) const; 97 [[nodiscard]] ServerMixInfo& GetSortedInfo(std::size_t i); 98 [[nodiscard]] const ServerMixInfo& GetSortedInfo(std::size_t i) const; 99 [[nodiscard]] ServerMixInfo& GetFinalMixInfo(); 100 [[nodiscard]] const ServerMixInfo& GetFinalMixInfo() const; 101 [[nodiscard]] EdgeMatrix& GetEdgeMatrix(); 102 [[nodiscard]] const EdgeMatrix& GetEdgeMatrix() const; 103 104 private: 105 void CalcMixBufferOffset(); 106 void UpdateDistancesFromFinalMix(); 107 108 NodeStates node_states{}; 109 EdgeMatrix edge_matrix{}; 110 std::size_t info_count{}; 111 std::vector<ServerMixInfo> infos{}; 112 std::vector<ServerMixInfo*> sorted_info{}; 113 }; 114 } // namespace AudioCore 115