aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Audio/Renderer/Common/EdgeMatrix.cs
blob: 24a9350fc216f3366bd4bf61f47142a38fa689e2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using Ryujinx.Audio.Renderer.Utils;
using Ryujinx.Common;
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Ryujinx.Audio.Renderer.Common
{
    /// <summary>
    /// Represents a adjacent matrix.
    /// </summary>
    /// <remarks>This is used for splitter routing.</remarks>
    public class EdgeMatrix
    {
        /// <summary>
        /// Backing <see cref="BitArray"/> used for node connections.
        /// </summary>
        private BitArray _storage;

        /// <summary>
        /// The count of nodes of the current instance.
        /// </summary>
        private int _nodeCount;

        /// <summary>
        /// Get the required work buffer size memory needed for the <see cref="EdgeMatrix"/>.
        /// </summary>
        /// <param name="nodeCount">The count of nodes.</param>
        /// <returns>The size required for the given <paramref name="nodeCount"/>.</returns>
        public static int GetWorkBufferSize(int nodeCount)
        {
            int size = BitUtils.AlignUp(nodeCount * nodeCount, Constants.BufferAlignment);

            return size / Unsafe.SizeOf<byte>();
        }

        /// <summary>
        /// Initializes the <see cref="EdgeMatrix"/> instance with backing memory.
        /// </summary>
        /// <param name="edgeMatrixWorkBuffer">The backing memory.</param>
        /// <param name="nodeCount">The count of nodes.</param>
        public void Initialize(Memory<byte> edgeMatrixWorkBuffer, int nodeCount)
        {
            Debug.Assert(edgeMatrixWorkBuffer.Length >= GetWorkBufferSize(nodeCount));

            _storage = new BitArray(edgeMatrixWorkBuffer);

            _nodeCount = nodeCount;

            _storage.Reset();
        }

        /// <summary>
        /// Test if the bit at the given index is set.
        /// </summary>
        /// <param name="index">A bit index.</param>
        /// <returns>Returns true if the bit at the given index is set</returns>
        public bool Test(int index)
        {
            return _storage.Test(index);
        }

        /// <summary>
        /// Reset all bits in the storage.
        /// </summary>
        public void Reset()
        {
            _storage.Reset();
        }

        /// <summary>
        /// Reset the bit at the given index.
        /// </summary>
        /// <param name="index">A bit index.</param>
        public void Reset(int index)
        {
            _storage.Reset(index);
        }

        /// <summary>
        /// Set the bit at the given index.
        /// </summary>
        /// <param name="index">A bit index.</param>
        public void Set(int index)
        {
            _storage.Set(index);
        }

        /// <summary>
        /// Connect a given source to a given destination.
        /// </summary>
        /// <param name="source">The source index.</param>
        /// <param name="destination">The destination index.</param>
        public void Connect(int source, int destination)
        {
            Debug.Assert(source < _nodeCount);
            Debug.Assert(destination < _nodeCount);

            _storage.Set(_nodeCount * source + destination);
        }

        /// <summary>
        /// Check if the given source is connected to the given destination.
        /// </summary>
        /// <param name="source">The source index.</param>
        /// <param name="destination">The destination index.</param>
        /// <returns>Returns true if the given source is connected to the given destination.</returns>
        public bool Connected(int source, int destination)
        {
            Debug.Assert(source < _nodeCount);
            Debug.Assert(destination < _nodeCount);

            return _storage.Test(_nodeCount * source + destination);
        }

        /// <summary>
        /// Disconnect a given source from a given destination.
        /// </summary>
        /// <param name="source">The source index.</param>
        /// <param name="destination">The destination index.</param>
        public void Disconnect(int source, int destination)
        {
            Debug.Assert(source < _nodeCount);
            Debug.Assert(destination < _nodeCount);

            _storage.Reset(_nodeCount * source + destination);
        }

        /// <summary>
        /// Remove all edges from a given source.
        /// </summary>
        /// <param name="source">The source index.</param>
        public void RemoveEdges(int source)
        {
            for (int i = 0; i < _nodeCount; i++)
            {
                Disconnect(source, i);
            }
        }

        /// <summary>
        /// Get the total node count.
        /// </summary>
        /// <returns>The total node count.</returns>
        public int GetNodeCount()
        {
            return _nodeCount;
        }
    }
}