Skip to content

Commit c675962

Browse files
Merge pull request #42 from AvionBlock/master
Sync with master.
2 parents 94d2357 + 03e4cdd commit c675962

14 files changed

Lines changed: 1723 additions & 770 deletions

Directory.Build.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22
<PropertyGroup>
3-
<OpusSharpVersion>1.6.2</OpusSharpVersion>
4-
<OpusSharpCoreVersion>1.6.0.2</OpusSharpCoreVersion>
3+
<OpusSharpVersion>1.6.3</OpusSharpVersion>
4+
<OpusSharpCoreVersion>1.6.0.3</OpusSharpCoreVersion>
55
<OpusSharpNativesVersion>1.6.0.2</OpusSharpNativesVersion>
66
<PackageProjectUrl>https://avionblock.github.io/OpusSharp/index.html</PackageProjectUrl>
77
<RepositoryUrl>https://github.com/AvionBlock/OpusSharp</RepositoryUrl>
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
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

Comments
 (0)