1- using System . Diagnostics ;
2- using System . Diagnostics . CodeAnalysis ;
3- using System . Runtime . CompilerServices ;
41using System . Runtime . InteropServices ;
52
63namespace NetCord . Gateway . Voice ;
74
85[ StructLayout ( LayoutKind . Auto ) ]
96public readonly ref struct VoiceReceiveEventArgs
107{
11- internal const uint FecFlag = 1u << 31 ;
12-
13- private VoiceReceiveEventArgs ( ReadOnlySpan < byte > frame , uint fecAndSamples , uint ssrc , uint timestamp , ushort sequenceNumber )
8+ public VoiceReceiveEventArgs ( ReadOnlySpan < byte > frame , uint ssrc , uint timestamp , ushort sequenceNumber )
149 {
15- _frame = frame ;
16- _fecAndSamples = fecAndSamples ;
10+ Frame = frame ;
1711 Ssrc = ssrc ;
1812 Timestamp = timestamp ;
1913 SequenceNumber = sequenceNumber ;
2014 }
2115
22- public static VoiceReceiveEventArgs Delivered ( ReadOnlySpan < byte > frame , uint ssrc , uint timestamp , ushort sequenceNumber )
23- {
24- return new ( frame , 0 , ssrc , timestamp , sequenceNumber ) ;
25- }
26-
27- public static VoiceReceiveEventArgs Lost ( uint ssrc , uint timestamp , ushort sequenceNumber , int samplesPerChannel , ReadOnlySpan < byte > fecData = default )
28- {
29- ArgumentOutOfRangeException . ThrowIfNegativeOrZero ( samplesPerChannel ) ;
30-
31- var fecAndSamples = ( uint ) samplesPerChannel | ( fecData . IsEmpty ? 0 : FecFlag ) ;
32-
33- return new ( fecData , fecAndSamples , ssrc , timestamp , sequenceNumber ) ;
34- }
35-
36- private readonly ReadOnlySpan < byte > _frame ;
37-
38- private readonly uint _fecAndSamples ;
39-
4016 /// <summary>
41- /// The voice frame data. Empty if the frame was lost.
17+ /// The voice frame data.
4218 /// </summary>
43- public readonly ReadOnlySpan < byte > Frame
44- {
45- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
46- get => IsLost ? null : _frame ;
47- }
19+ public readonly ReadOnlySpan < byte > Frame { get ; }
4820
4921 /// <summary>
5022 /// The synchronization source (SSRC) of the sender of the voice frame.
@@ -60,88 +32,4 @@ public readonly ReadOnlySpan<byte> Frame
6032 /// The sequence number of the voice frame.
6133 /// </summary>
6234 public readonly ushort SequenceNumber { get ; }
63-
64- /// <summary>
65- /// Whether the voice frame was lost. If true, the <see cref="Frame"/> property will be empty
66- /// and the <see cref="AsLost"/> method can be used to retrieve the lost-specific data.
67- /// </summary>
68- public readonly bool IsLost
69- {
70- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
71- get => _fecAndSamples is not 0 ;
72- }
73-
74- /// <summary>
75- /// Converts this <see cref="VoiceReceiveEventArgs"/> to a <see cref="LostVoiceReceiveEventArgs"/>.
76- /// </summary>
77- /// <exception cref="InvalidOperationException">Thrown when the voice frame was successfully delivered and is not considered lost.</exception>
78- /// <returns><see cref="LostVoiceReceiveEventArgs"/> containing the lost-specific data of this event args.</returns>
79- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
80- public LostVoiceReceiveEventArgs AsLost ( )
81- {
82- if ( ! IsLost )
83- ThrowNotLost ( ) ;
84-
85- return new ( Ssrc , Timestamp , SequenceNumber , _frame , _fecAndSamples ) ;
86- }
87-
88- [ DoesNotReturn ]
89- [ StackTraceHidden ]
90- private static void ThrowNotLost ( )
91- {
92- throw new InvalidOperationException ( "This event args is not lost." ) ;
93- }
94- }
95-
96- [ StructLayout ( LayoutKind . Auto ) ]
97- public readonly ref struct LostVoiceReceiveEventArgs
98- {
99- internal LostVoiceReceiveEventArgs ( uint ssrc , uint timestamp , ushort sequenceNumber , ReadOnlySpan < byte > fecData , uint fecAndSamples )
100- {
101- FecData = fecData ;
102- Ssrc = ssrc ;
103- Timestamp = timestamp ;
104- SequenceNumber = sequenceNumber ;
105- _fecAndSamples = fecAndSamples ;
106- }
107-
108- /// <summary>
109- /// The FEC data of the lost voice frame, if any. This will be empty if no FEC data is available for the lost frame.
110- /// </summary>
111- public readonly ReadOnlySpan < byte > FecData { get ; }
112-
113- /// <summary>
114- /// The synchronization source (SSRC) of the sender of the voice frame.
115- /// </summary>
116- public readonly uint Ssrc { get ; }
117-
118- /// <summary>
119- /// The timestamp of the voice frame.
120- /// </summary>
121- public readonly uint Timestamp { get ; }
122-
123- /// <summary>
124- /// The sequence number of the voice frame.
125- /// </summary>
126- public readonly ushort SequenceNumber { get ; }
127-
128- /// <summary>
129- /// The number of samples per channel in the lost voice frame.
130- /// </summary>
131- public readonly int SamplesPerChannel
132- {
133- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
134- get => ( int ) ( _fecAndSamples & ~ VoiceReceiveEventArgs . FecFlag ) ;
135- }
136-
137- /// <summary>
138- /// Whether the frame should be decoded using FEC.
139- /// </summary>
140- public readonly bool DecodeFec
141- {
142- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
143- get => ( _fecAndSamples & VoiceReceiveEventArgs . FecFlag ) is not 0 ;
144- }
145-
146- private readonly uint _fecAndSamples ;
14735}
0 commit comments