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