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 "audio_core/common.h"
8 #include "common/common_funcs.h"
9 #include "common/common_types.h"
10 #include "common/swap.h"
11 
12 namespace AudioCore {
13 
14 using DownmixCoefficients = std::array<float_le, 4>;
15 
16 enum class SinkTypes : u8 {
17     Invalid = 0,
18     Device = 1,
19     Circular = 2,
20 };
21 
22 enum class SinkSampleFormat : u32_le {
23     None = 0,
24     Pcm8 = 1,
25     Pcm16 = 2,
26     Pcm24 = 3,
27     Pcm32 = 4,
28     PcmFloat = 5,
29     Adpcm = 6,
30 };
31 
32 class SinkInfo {
33 public:
34     struct CircularBufferIn {
35         u64_le address;
36         u32_le size;
37         u32_le input_count;
38         u32_le sample_count;
39         u32_le previous_position;
40         SinkSampleFormat sample_format;
41         std::array<u8, AudioCommon::MAX_CHANNEL_COUNT> input;
42         bool in_use;
43         INSERT_UNION_PADDING_BYTES(5);
44     };
45     static_assert(sizeof(CircularBufferIn) == 0x28,
46                   "SinkInfo::CircularBufferIn is in invalid size");
47 
48     struct DeviceIn {
49         std::array<u8, 255> device_name;
50         INSERT_UNION_PADDING_BYTES(1);
51         s32_le input_count;
52         std::array<u8, AudioCommon::MAX_CHANNEL_COUNT> input;
53         INSERT_UNION_PADDING_BYTES(1);
54         bool down_matrix_enabled;
55         DownmixCoefficients down_matrix_coef;
56     };
57     static_assert(sizeof(DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size");
58 
59     struct InParams {
60         SinkTypes type{};
61         bool in_use{};
62         INSERT_PADDING_BYTES(2);
63         u32_le node_id{};
64         INSERT_PADDING_WORDS(6);
65         union {
66             // std::array<u8, 0x120> raw{};
67             DeviceIn device;
68             CircularBufferIn circular_buffer;
69         };
70     };
71     static_assert(sizeof(InParams) == 0x140, "SinkInfo::InParams are an invalid size!");
72 };
73 
74 class SinkContext {
75 public:
76     explicit SinkContext(std::size_t sink_count_);
77     ~SinkContext();
78 
79     [[nodiscard]] std::size_t GetCount() const;
80 
81     void UpdateMainSink(const SinkInfo::InParams& in);
82     [[nodiscard]] bool InUse() const;
83     [[nodiscard]] std::vector<u8> OutputBuffers() const;
84 
85     [[nodiscard]] bool HasDownMixingCoefficients() const;
86     [[nodiscard]] const DownmixCoefficients& GetDownmixCoefficients() const;
87 
88 private:
89     bool in_use{false};
90     s32 use_count{};
91     std::array<u8, AudioCommon::MAX_CHANNEL_COUNT> buffers{};
92     std::size_t sink_count{};
93     bool has_downmix_coefs{false};
94     DownmixCoefficients downmix_coefficients{};
95 };
96 } // namespace AudioCore
97