Skip to content

Commit 3b1573b

Browse files
Merge pull request #37 from AvionBlock/dev
v1.6.1
2 parents e809965 + 6e7b2f0 commit 3b1573b

24 files changed

Lines changed: 1066 additions & 69 deletions

File tree

OpusSharp.Core/NativeOpus.cs

Lines changed: 440 additions & 8 deletions
Large diffs are not rendered by default.

OpusSharp.Core/OpusDecoder.cs

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// ReSharper disable MemberCanBePrivate.Global
55
// ReSharper disable FieldCanBeMadeReadOnly.Global
66
// ReSharper disable InconsistentNaming
7+
// ReSharper disable ClassNeverInstantiated.Global
78
namespace OpusSharp.Core
89
{
910
/// <summary>
@@ -44,6 +45,7 @@ public unsafe OpusDecoder(int sample_rate, int channels, bool use_static = false
4445
Dispose(false);
4546
}
4647

48+
#if NETSTANDARD2_1_OR_GREATER || NET8_0_OR_GREATER
4749
/// <summary>
4850
/// Decodes an opus encoded frame.
4951
/// </summary>
@@ -155,62 +157,119 @@ public unsafe int Decode(Span<byte> input, int length, Span<float> output, int f
155157
return result;
156158
}
157159
}
158-
160+
#endif
161+
159162
/// <summary>
160163
/// Decodes an opus encoded frame.
161164
/// </summary>
162165
/// <param name="input">Input payload. Use null to indicate packet loss</param>
163166
/// <param name="length">Number of bytes in payload.</param>
164-
/// <param name="output">Output signal (interleaved if 2 channels). length is frame_size*channels</param>
167+
/// <param name="output">Output signal (interleaved if 2 channels). length is frame_size*channels*sizeof(short).</param>
165168
/// <param name="frame_size">Number of samples per channel of available space in pcm. If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=true), then frame_size needs to be exactly the duration of audio that is missing, otherwise the decoder will not be in the optimal state to decode the next incoming packet. For the PLC and FEC cases, frame_size must be a multiple of 2.5 ms.</param>
166169
/// <param name="decode_fec">Request that any in-band forward error correction data be decoded. If no such data is available, the frame is decoded as if it were lost.</param>
167170
/// <returns>Number of decoded samples or <see cref="OpusErrorCodes"/>.</returns>
168171
/// <exception cref="OpusException" />
169172
/// <exception cref="ObjectDisposedException" />
170-
public int Decode(byte[]? input, int length, byte[] output, int frame_size, bool decode_fec) =>
171-
Decode(input.AsSpan(), length, output.AsSpan(), frame_size, decode_fec);
173+
public unsafe int Decode(byte[]? input, int length, byte[] output, int frame_size, bool decode_fec)
174+
{
175+
ThrowIfDisposed();
176+
177+
fixed (byte* inputPtr = input)
178+
fixed (byte* outputPtr = output)
179+
{
180+
var result = _useStatic
181+
? StaticNativeOpus.opus_decode(_handler, inputPtr, length, (short*)outputPtr, frame_size,
182+
decode_fec ? 1 : 0)
183+
: NativeOpus.opus_decode(_handler, inputPtr, length, (short*)outputPtr, frame_size,
184+
decode_fec ? 1 : 0);
185+
CheckError(result);
186+
return result;
187+
}
188+
}
172189

173190
/// <summary>
174191
/// Decodes an opus encoded frame.
175192
/// </summary>
176193
/// <param name="input">Input payload. Use null to indicate packet loss</param>
177194
/// <param name="length">Number of bytes in payload.</param>
178-
/// <param name="output">Output signal (interleaved if 2 channels). length is frame_size*channels*sizeof(short)</param>
195+
/// <param name="output">Output signal (interleaved if 2 channels). length is frame_size*channels.</param>
179196
/// <param name="frame_size">Number of samples per channel of available space in pcm. If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=true), then frame_size needs to be exactly the duration of audio that is missing, otherwise the decoder will not be in the optimal state to decode the next incoming packet. For the PLC and FEC cases, frame_size must be a multiple of 2.5 ms.</param>
180197
/// <param name="decode_fec">Request that any in-band forward error correction data be decoded. If no such data is available, the frame is decoded as if it were lost.</param>
181198
/// <returns>Number of decoded samples or <see cref="OpusErrorCodes"/>.</returns>
182199
/// <exception cref="OpusException" />
183200
/// <exception cref="ObjectDisposedException" />
184-
public int Decode(byte[]? input, int length, short[] output, int frame_size, bool decode_fec) =>
185-
Decode(input.AsSpan(), length, output.AsSpan(), frame_size, decode_fec);
201+
public unsafe int Decode(byte[]? input, int length, short[] output, int frame_size, bool decode_fec)
202+
{
203+
ThrowIfDisposed();
186204

205+
fixed (byte* inputPtr = input)
206+
fixed (short* outputPtr = output)
207+
{
208+
var result = _useStatic
209+
? StaticNativeOpus.opus_decode(_handler, inputPtr, length, outputPtr, frame_size,
210+
decode_fec ? 1 : 0)
211+
: NativeOpus.opus_decode(_handler, inputPtr, length, outputPtr, frame_size,
212+
decode_fec ? 1 : 0);
213+
CheckError(result);
214+
return result;
215+
}
216+
}
217+
187218
/// <summary>
188219
/// Decodes an opus encoded frame.
189220
/// </summary>
190221
/// <param name="input">Input payload. Use null to indicate packet loss</param>
191222
/// <param name="length">Number of bytes in payload.</param>
192-
/// <param name="output">Output signal (interleaved if 2 channels). length is (frame_size*channels)/2. Note: I don't know if this is correct.</param>
223+
/// <param name="output">Output signal (interleaved if 2 channels). length is frame_size*channels.</param>
193224
/// <param name="frame_size">Number of samples per channel of available space in pcm. If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=true), then frame_size needs to be exactly the duration of audio that is missing, otherwise the decoder will not be in the optimal state to decode the next incoming packet. For the PLC and FEC cases, frame_size must be a multiple of 2.5 ms.</param>
194225
/// <param name="decode_fec">Request that any in-band forward error correction data be decoded. If no such data is available, the frame is decoded as if it were lost.</param>
195226
/// <returns>Number of decoded samples or <see cref="OpusErrorCodes"/>.</returns>
196227
/// <exception cref="OpusException" />
197228
/// <exception cref="ObjectDisposedException" />
198-
public int Decode(byte[]? input, int length, int[] output, int frame_size, bool decode_fec) =>
199-
Decode(input.AsSpan(), length, output.AsSpan(), frame_size, decode_fec);
200-
229+
public unsafe int Decode(byte[]? input, int length, int[] output, int frame_size, bool decode_fec)
230+
{
231+
ThrowIfDisposed();
232+
233+
fixed (byte* inputPtr = input)
234+
fixed (int* outputPtr = output)
235+
{
236+
var result = _useStatic
237+
? StaticNativeOpus.opus_decode24(_handler, inputPtr, length, outputPtr, frame_size,
238+
decode_fec ? 1 : 0)
239+
: NativeOpus.opus_decode24(_handler, inputPtr, length, outputPtr, frame_size,
240+
decode_fec ? 1 : 0);
241+
CheckError(result);
242+
return result;
243+
}
244+
}
245+
201246
/// <summary>
202247
/// Decodes an opus encoded frame.
203248
/// </summary>
204249
/// <param name="input">Input payload. Use null to indicate packet loss</param>
205250
/// <param name="length">Number of bytes in payload.</param>
206-
/// <param name="output">Output signal (interleaved if 2 channels). length is frame_size*channels*sizeof(float)</param>
251+
/// <param name="output">Output signal (interleaved if 2 channels). length is (frame_size*channels)/2. Note: I don't know if this is correct.</param>
207252
/// <param name="frame_size">Number of samples per channel of available space in pcm. If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=true), then frame_size needs to be exactly the duration of audio that is missing, otherwise the decoder will not be in the optimal state to decode the next incoming packet. For the PLC and FEC cases, frame_size must be a multiple of 2.5 ms.</param>
208253
/// <param name="decode_fec">Request that any in-band forward error correction data be decoded. If no such data is available, the frame is decoded as if it were lost.</param>
209254
/// <returns>Number of decoded samples or <see cref="OpusErrorCodes"/>.</returns>
210255
/// <exception cref="OpusException" />
211256
/// <exception cref="ObjectDisposedException" />
212-
public int Decode(byte[]? input, int length, float[] output, int frame_size, bool decode_fec) =>
213-
Decode(input.AsSpan(), length, output.AsSpan(), frame_size, decode_fec);
257+
public unsafe int Decode(byte[]? input, int length, float[] output, int frame_size, bool decode_fec)
258+
{
259+
ThrowIfDisposed();
260+
261+
fixed (byte* inputPtr = input)
262+
fixed (float* outputPtr = output)
263+
{
264+
var result = _useStatic
265+
? StaticNativeOpus.opus_decode_float(_handler, inputPtr, length, outputPtr, frame_size,
266+
decode_fec ? 1 : 0)
267+
: NativeOpus.opus_decode_float(_handler, inputPtr, length, outputPtr, frame_size,
268+
decode_fec ? 1 : 0);
269+
CheckError(result);
270+
return result;
271+
}
272+
}
214273

215274
/// <summary>
216275
/// Performs a ctl request.

OpusSharp.Core/OpusEncoder.cs

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public unsafe OpusEncoder(int sample_rate, int channels, OpusPredefinedValues ap
4545
{
4646
Dispose(false);
4747
}
48-
48+
#if NETSTANDARD2_1_OR_GREATER || NET8_0_OR_GREATER
4949
/// <summary>
5050
/// Encodes a pcm frame.
5151
/// </summary>
@@ -141,6 +141,7 @@ public unsafe int Encode(Span<float> input, int frame_size, Span<byte> output, i
141141
return result;
142142
}
143143
}
144+
#endif
144145

145146
/// <summary>
146147
/// Encodes a pcm frame.
@@ -152,8 +153,19 @@ public unsafe int Encode(Span<float> input, int frame_size, Span<byte> output, i
152153
/// <returns>The length of the encoded packet (in bytes).</returns>
153154
/// <exception cref="OpusException" />
154155
/// <exception cref="ObjectDisposedException" />
155-
public int Encode(byte[] input, int frame_size, byte[] output, int max_data_bytes) =>
156-
Encode(input.AsSpan(), frame_size, output.AsSpan(), max_data_bytes);
156+
public unsafe int Encode(byte[] input, int frame_size, byte[] output, int max_data_bytes)
157+
{
158+
ThrowIfDisposed();
159+
fixed (byte* inputPtr = input)
160+
fixed (byte* outputPtr = output)
161+
{
162+
var result = _useStatic
163+
? StaticNativeOpus.opus_encode(_handler, (short*)inputPtr, frame_size, outputPtr, max_data_bytes)
164+
: NativeOpus.opus_encode(_handler, (short*)inputPtr, frame_size, outputPtr, max_data_bytes);
165+
CheckError(result);
166+
return result;
167+
}
168+
}
157169

158170
/// <summary>
159171
/// Encodes a pcm frame.
@@ -165,8 +177,19 @@ public int Encode(byte[] input, int frame_size, byte[] output, int max_data_byte
165177
/// <returns>The length of the encoded packet (in bytes).</returns>
166178
/// <exception cref="OpusException" />
167179
/// <exception cref="ObjectDisposedException" />
168-
public int Encode(short[] input, int frame_size, byte[] output, int max_data_bytes) =>
169-
Encode(input.AsSpan(), frame_size, output.AsSpan(), max_data_bytes);
180+
public unsafe int Encode(short[] input, int frame_size, byte[] output, int max_data_bytes)
181+
{
182+
ThrowIfDisposed();
183+
fixed (short* inputPtr = input)
184+
fixed (byte* outputPtr = output)
185+
{
186+
var result = _useStatic
187+
? StaticNativeOpus.opus_encode(_handler, inputPtr, frame_size, outputPtr, max_data_bytes)
188+
: NativeOpus.opus_encode(_handler, inputPtr, frame_size, outputPtr, max_data_bytes);
189+
CheckError(result);
190+
return result;
191+
}
192+
}
170193

171194
/// <summary>
172195
/// Encodes a pcm frame.
@@ -178,8 +201,19 @@ public int Encode(short[] input, int frame_size, byte[] output, int max_data_byt
178201
/// <returns>The length of the encoded packet (in bytes).</returns>
179202
/// <exception cref="OpusException" />
180203
/// <exception cref="ObjectDisposedException" />
181-
public int Encode(int[] input, int frame_size, byte[] output, int max_data_bytes) =>
182-
Encode(input.AsSpan(), frame_size, output.AsSpan(), max_data_bytes);
204+
public unsafe int Encode(int[] input, int frame_size, byte[] output, int max_data_bytes)
205+
{
206+
ThrowIfDisposed();
207+
fixed (int* inputPtr = input)
208+
fixed (byte* outputPtr = output)
209+
{
210+
var result = _useStatic
211+
? StaticNativeOpus.opus_encode24(_handler, inputPtr, frame_size, outputPtr, max_data_bytes)
212+
: NativeOpus.opus_encode24(_handler, inputPtr, frame_size, outputPtr, max_data_bytes);
213+
CheckError(result);
214+
return result;
215+
}
216+
}
183217

184218
/// <summary>
185219
/// Encodes a floating point pcm frame.
@@ -191,8 +225,19 @@ public int Encode(int[] input, int frame_size, byte[] output, int max_data_bytes
191225
/// <returns>The length of the encoded packet (in bytes).</returns>
192226
/// <exception cref="OpusException" />
193227
/// <exception cref="ObjectDisposedException" />
194-
public int Encode(float[] input, int frame_size, byte[] output, int max_data_bytes) =>
195-
Encode(input.AsSpan(), frame_size, output.AsSpan(), max_data_bytes);
228+
public unsafe int Encode(float[] input, int frame_size, byte[] output, int max_data_bytes)
229+
{
230+
ThrowIfDisposed();
231+
fixed (float* inputPtr = input)
232+
fixed (byte* outputPtr = output)
233+
{
234+
var result = _useStatic
235+
? StaticNativeOpus.opus_encode_float(_handler, inputPtr, frame_size, outputPtr, max_data_bytes)
236+
: NativeOpus.opus_encode_float(_handler, inputPtr, frame_size, outputPtr, max_data_bytes);
237+
CheckError(result);
238+
return result;
239+
}
240+
}
196241

197242
/// <summary>
198243
/// Performs a ctl request.

OpusSharp.Core/OpusSharp.Core.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
<AssemblyName>OpusSharp.Core</AssemblyName>
44
<Nullable>enable</Nullable>
55
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
6-
<TargetFramework>netstandard2.1</TargetFramework>
6+
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;</TargetFrameworks>
77
<GenerateDocumentationFile>True</GenerateDocumentationFile>
88
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
99
</PropertyGroup>
10+
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
11+
<NoWarn>$(NoWarn);nullable</NoWarn>
12+
<LangVersion>8.0</LangVersion>
13+
</PropertyGroup>
1014
</Project>
Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,39 @@
11
<?xml version="1.0"?>
22
<package>
3-
<metadata>
4-
<id>OpusSharp.Core</id>
5-
<version>1.6.0.0</version>
6-
<authors>SineVector241</authors>
7-
<description>Standard library for OpusSharp.</description>
8-
<requireLicenseAcceptance>false</requireLicenseAcceptance>
9-
<copyright>Copyright MIT</copyright>
10-
<license type="file">LICENSE.txt</license>
11-
<readme>docs/README.md</readme>
3+
<metadata>
4+
<id>OpusSharp.Core</id>
5+
<version>1.6.0.1</version>
6+
<authors>SineVector241</authors>
7+
<description>Standard library for OpusSharp.</description>
8+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
9+
<copyright>Copyright MIT</copyright>
10+
<license type="file">LICENSE.txt</license>
11+
<readme>docs/README.md</readme>
1212

13-
<projectUrl>https://avionblock.github.io/OpusSharp/index.html</projectUrl>
14-
<repository type="git" url="https://github.com/AvionBlock/OpusSharp" />
13+
<projectUrl>https://avionblock.github.io/OpusSharp/index.html</projectUrl>
14+
<repository type="git" url="https://github.com/AvionBlock/OpusSharp"/>
1515

16-
<dependencies>
17-
<group targetFramework="netstandard2.1">
18-
</group>
19-
</dependencies>
20-
</metadata>
16+
<dependencies>
17+
<group targetFramework="netstandard2.0">
18+
</group>
19+
<group targetFramework="netstandard2.1">
20+
</group>
21+
<group targetFramework="net8.0">
22+
</group>
23+
</dependencies>
24+
</metadata>
2125

22-
<files>
23-
<file src="bin/Release/netstandard2.1/OpusSharp.Core.dll" target="lib/netstandard2.1/OpusSharp.Core.dll" />
24-
<file src="bin/Release/netstandard2.1/OpusSharp.Core.pdb" target="lib/netstandard2.1/OpusSharp.Core.pdb" />
25-
<file src="bin/Release/netstandard2.1/OpusSharp.Core.xml" target="lib/netstandard2.1" />
26-
<file src="../README.md" target="docs" />
27-
<file src="../LICENSE.txt" target="" />
28-
</files>
26+
<files>
27+
<file src="bin/Release/netstandard2.0/OpusSharp.Core.dll" target="lib/netstandard2.0/OpusSharp.Core.dll"/>
28+
<file src="bin/Release/netstandard2.0/OpusSharp.Core.pdb" target="lib/netstandard2.0/OpusSharp.Core.pdb"/>
29+
<file src="bin/Release/netstandard2.0/OpusSharp.Core.xml" target="lib/netstandard2.0"/>
30+
<file src="bin/Release/netstandard2.1/OpusSharp.Core.dll" target="lib/netstandard2.1/OpusSharp.Core.dll"/>
31+
<file src="bin/Release/netstandard2.1/OpusSharp.Core.pdb" target="lib/netstandard2.1/OpusSharp.Core.pdb"/>
32+
<file src="bin/Release/netstandard2.1/OpusSharp.Core.xml" target="lib/netstandard2.1"/>
33+
<file src="bin/Release/net8.0/OpusSharp.Core.dll" target="lib/net8.0/OpusSharp.Core.dll"/>
34+
<file src="bin/Release/net8.0/OpusSharp.Core.pdb" target="lib/net8.0/OpusSharp.Core.pdb"/>
35+
<file src="bin/Release/net8.0/OpusSharp.Core.xml" target="lib/net8.0"/>
36+
<file src="../README.md" target="docs"/>
37+
<file src="../LICENSE.txt" target=""/>
38+
</files>
2939
</package>

0 commit comments

Comments
 (0)