1+ using System ;
2+ using OpusSharp . Core . Interfaces ;
3+ using OpusSharp . Core . SafeHandlers ;
4+
5+ // ReSharper disable MemberCanBePrivate.Global
6+ // ReSharper disable FieldCanBeMadeReadOnly.Global
7+ // ReSharper disable InconsistentNaming
8+ // ReSharper disable ClassNeverInstantiated.Global
9+ namespace OpusSharp . Core . Dynamic
10+ {
11+ /// <summary>
12+ /// An opus decoder using dynamic binding calls.
13+ /// </summary>
14+ public class OpusDecoder : IOpusDecoder
15+ {
16+ /// <summary>
17+ /// Direct safe handle for the <see cref="OpusDecoder"/>. IT IS NOT RECOMMENDED TO CLOSE THE HANDLE DIRECTLY! Instead, use <see cref="Dispose(bool)"/> to dispose the handle and object safely.
18+ /// </summary>
19+ protected OpusDecoderSafeHandle _handler ;
20+
21+ private bool _disposed ;
22+
23+ /// <summary>
24+ /// Creates a new opus decoder.
25+ /// </summary>
26+ /// <param name="sample_rate">The sample rate, this must be one of 8000, 12000, 16000, 24000, or 48000.</param>
27+ /// <param name="channels">Number of channels, this must be 1 or 2.</param>
28+ /// <exception cref="OpusException" />
29+ public unsafe OpusDecoder ( int sample_rate , int channels )
30+ {
31+ var error = 0 ;
32+ _handler = NativeOpus . opus_decoder_create ( sample_rate , channels , & error ) ;
33+ CheckError ( error ) ;
34+ }
35+
36+ /// <summary>
37+ /// Opus decoder destructor.
38+ /// </summary>
39+ ~ OpusDecoder ( )
40+ {
41+ Dispose ( false ) ;
42+ }
43+
44+ /// <inheritdoc/>
45+ public void Dispose ( )
46+ {
47+ Dispose ( true ) ;
48+ GC . SuppressFinalize ( this ) ;
49+ }
50+
51+ #if NETSTANDARD2_1_OR_GREATER || NET8_0_OR_GREATER
52+ /// <inheritdoc/>
53+ public unsafe int Decode ( Span < byte > input , int length , Span < byte > output , int frame_size , bool decode_fec )
54+ {
55+ ThrowIfDisposed ( ) ;
56+
57+ fixed ( byte * inputPtr = input )
58+ fixed ( byte * outputPtr = output )
59+ {
60+ var result = NativeOpus . opus_decode ( _handler , inputPtr , length , ( short * ) outputPtr , frame_size ,
61+ decode_fec ? 1 : 0 ) ;
62+ CheckError ( result ) ;
63+ return result ;
64+ }
65+ }
66+
67+ /// <inheritdoc/>
68+ public unsafe int Decode ( Span < byte > input , int length , Span < short > output , int frame_size , bool decode_fec )
69+ {
70+ ThrowIfDisposed ( ) ;
71+
72+ fixed ( byte * inputPtr = input )
73+ fixed ( short * outputPtr = output )
74+ {
75+ var result = NativeOpus . opus_decode ( _handler , inputPtr , length , outputPtr , frame_size ,
76+ decode_fec ? 1 : 0 ) ;
77+ CheckError ( result ) ;
78+ return result ;
79+ }
80+ }
81+
82+ /// <inheritdoc/>
83+ public unsafe int Decode ( Span < byte > input , int length , Span < int > output , int frame_size , bool decode_fec )
84+ {
85+ ThrowIfDisposed ( ) ;
86+
87+ fixed ( byte * inputPtr = input )
88+ fixed ( int * outputPtr = output )
89+ {
90+ var result = NativeOpus . opus_decode24 ( _handler , inputPtr , length , outputPtr , frame_size ,
91+ decode_fec ? 1 : 0 ) ;
92+ CheckError ( result ) ;
93+ return result ;
94+ }
95+ }
96+
97+ /// <inheritdoc/>
98+ public unsafe int Decode ( Span < byte > input , int length , Span < float > output , int frame_size , bool decode_fec )
99+ {
100+ ThrowIfDisposed ( ) ;
101+
102+ fixed ( byte * inputPtr = input )
103+ fixed ( float * outputPtr = output )
104+ {
105+ var result = NativeOpus . opus_decode_float ( _handler , inputPtr , length , outputPtr , frame_size ,
106+ decode_fec ? 1 : 0 ) ;
107+ CheckError ( result ) ;
108+ return result ;
109+ }
110+ }
111+ #endif
112+
113+ /// <inheritdoc/>
114+ public unsafe int Decode ( byte [ ] ? input , int length , byte [ ] output , int frame_size , bool decode_fec )
115+ {
116+ ThrowIfDisposed ( ) ;
117+
118+ fixed ( byte * inputPtr = input )
119+ fixed ( byte * outputPtr = output )
120+ {
121+ var result = NativeOpus . opus_decode ( _handler , inputPtr , length , ( short * ) outputPtr , frame_size ,
122+ decode_fec ? 1 : 0 ) ;
123+ CheckError ( result ) ;
124+ return result ;
125+ }
126+ }
127+
128+ /// <inheritdoc/>
129+ public unsafe int Decode ( byte [ ] ? input , int length , short [ ] output , int frame_size , bool decode_fec )
130+ {
131+ ThrowIfDisposed ( ) ;
132+
133+ fixed ( byte * inputPtr = input )
134+ fixed ( short * outputPtr = output )
135+ {
136+ var result = NativeOpus . opus_decode ( _handler , inputPtr , length , outputPtr , frame_size ,
137+ decode_fec ? 1 : 0 ) ;
138+ CheckError ( result ) ;
139+ return result ;
140+ }
141+ }
142+
143+ /// <inheritdoc/>
144+ public unsafe int Decode ( byte [ ] ? input , int length , int [ ] output , int frame_size , bool decode_fec )
145+ {
146+ ThrowIfDisposed ( ) ;
147+
148+ fixed ( byte * inputPtr = input )
149+ fixed ( int * outputPtr = output )
150+ {
151+ var result = NativeOpus . opus_decode24 ( _handler , inputPtr , length , outputPtr , frame_size ,
152+ decode_fec ? 1 : 0 ) ;
153+ CheckError ( result ) ;
154+ return result ;
155+ }
156+ }
157+
158+ /// <inheritdoc/>
159+ public unsafe int Decode ( byte [ ] ? input , int length , float [ ] output , int frame_size , bool decode_fec )
160+ {
161+ ThrowIfDisposed ( ) ;
162+
163+ fixed ( byte * inputPtr = input )
164+ fixed ( float * outputPtr = output )
165+ {
166+ var result = NativeOpus . opus_decode_float ( _handler , inputPtr , length , outputPtr , frame_size ,
167+ decode_fec ? 1 : 0 ) ;
168+ CheckError ( result ) ;
169+ return result ;
170+ }
171+ }
172+
173+ /// <inheritdoc/>
174+ public int Ctl ( DecoderCTL request )
175+ {
176+ ThrowIfDisposed ( ) ;
177+ var result = NativeOpus . opus_decoder_ctl ( _handler , ( int ) request ) ;
178+ CheckError ( result ) ;
179+ return result ;
180+ }
181+
182+ /// <inheritdoc/>
183+ public int Ctl ( DecoderCTL request , int value )
184+ {
185+ ThrowIfDisposed ( ) ;
186+ var result = NativeOpus . opus_decoder_ctl ( _handler , ( int ) request , value ) ;
187+ CheckError ( result ) ;
188+ return result ;
189+ }
190+
191+ /// <inheritdoc/>
192+ public unsafe int Ctl < T > ( DecoderCTL request , ref T value ) where T : unmanaged
193+ {
194+ ThrowIfDisposed ( ) ;
195+ fixed ( void * valuePtr = & value )
196+ {
197+ var result = NativeOpus . opus_decoder_ctl ( _handler , ( int ) request , valuePtr ) ;
198+ CheckError ( result ) ;
199+ return result ;
200+ }
201+ }
202+
203+ /// <inheritdoc/>
204+ public int Ctl ( GenericCTL request )
205+ {
206+ ThrowIfDisposed ( ) ;
207+ var result = NativeOpus . opus_decoder_ctl ( _handler , ( int ) request ) ;
208+ CheckError ( result ) ;
209+ return result ;
210+ }
211+
212+ /// <inheritdoc/>
213+ public int Ctl ( GenericCTL request , int value )
214+ {
215+ ThrowIfDisposed ( ) ;
216+ var result = NativeOpus . opus_decoder_ctl ( _handler , ( int ) request , value ) ;
217+ CheckError ( result ) ;
218+ return result ;
219+ }
220+
221+ /// <inheritdoc/>
222+ public unsafe int Ctl < T > ( GenericCTL request , ref T value ) where T : unmanaged
223+ {
224+ ThrowIfDisposed ( ) ;
225+ fixed ( void * valuePtr = & value )
226+ {
227+ var result = NativeOpus . opus_decoder_ctl ( _handler , ( int ) request , valuePtr ) ;
228+ CheckError ( result ) ;
229+ return result ;
230+ }
231+ }
232+
233+ /// <summary>
234+ /// Dispose logic.
235+ /// </summary>
236+ /// <param name="disposing">Set to true if fully disposing.</param>
237+ protected virtual void Dispose ( bool disposing )
238+ {
239+ if ( _disposed ) return ;
240+
241+ if ( disposing )
242+ {
243+ if ( ! _handler . IsClosed )
244+ _handler . Close ( ) ;
245+ }
246+
247+ _disposed = true ;
248+ }
249+
250+ /// <summary>
251+ /// Throws an exception if this object is disposed or the handler is closed.
252+ /// </summary>
253+ /// <exception cref="ObjectDisposedException" />
254+ protected virtual void ThrowIfDisposed ( )
255+ {
256+ if ( _disposed || _handler . IsClosed )
257+ throw new ObjectDisposedException ( GetType ( ) . FullName ) ;
258+ }
259+
260+ /// <summary>
261+ /// Checks if there is an opus error and throws if the error is a negative value.
262+ /// </summary>
263+ /// <param name="error">The error code to input.</param>
264+ /// <exception cref="OpusException"></exception>
265+ protected static void CheckError ( int error )
266+ {
267+ if ( error < 0 )
268+ throw new OpusException ( ( ( OpusErrorCodes ) error ) . ToString ( ) ) ;
269+ }
270+ }
271+ }
0 commit comments