|
4 | 4 | // ReSharper disable MemberCanBePrivate.Global |
5 | 5 | // ReSharper disable FieldCanBeMadeReadOnly.Global |
6 | 6 | // ReSharper disable InconsistentNaming |
| 7 | +// ReSharper disable ClassNeverInstantiated.Global |
7 | 8 | namespace OpusSharp.Core |
8 | 9 | { |
9 | 10 | /// <summary> |
@@ -44,6 +45,7 @@ public unsafe OpusDecoder(int sample_rate, int channels, bool use_static = false |
44 | 45 | Dispose(false); |
45 | 46 | } |
46 | 47 |
|
| 48 | +#if NETSTANDARD2_1_OR_GREATER || NET8_0_OR_GREATER |
47 | 49 | /// <summary> |
48 | 50 | /// Decodes an opus encoded frame. |
49 | 51 | /// </summary> |
@@ -155,62 +157,119 @@ public unsafe int Decode(Span<byte> input, int length, Span<float> output, int f |
155 | 157 | return result; |
156 | 158 | } |
157 | 159 | } |
158 | | - |
| 160 | +#endif |
| 161 | + |
159 | 162 | /// <summary> |
160 | 163 | /// Decodes an opus encoded frame. |
161 | 164 | /// </summary> |
162 | 165 | /// <param name="input">Input payload. Use null to indicate packet loss</param> |
163 | 166 | /// <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> |
165 | 168 | /// <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> |
166 | 169 | /// <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> |
167 | 170 | /// <returns>Number of decoded samples or <see cref="OpusErrorCodes"/>.</returns> |
168 | 171 | /// <exception cref="OpusException" /> |
169 | 172 | /// <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 | + } |
172 | 189 |
|
173 | 190 | /// <summary> |
174 | 191 | /// Decodes an opus encoded frame. |
175 | 192 | /// </summary> |
176 | 193 | /// <param name="input">Input payload. Use null to indicate packet loss</param> |
177 | 194 | /// <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> |
179 | 196 | /// <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> |
180 | 197 | /// <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> |
181 | 198 | /// <returns>Number of decoded samples or <see cref="OpusErrorCodes"/>.</returns> |
182 | 199 | /// <exception cref="OpusException" /> |
183 | 200 | /// <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(); |
186 | 204 |
|
| 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 | + |
187 | 218 | /// <summary> |
188 | 219 | /// Decodes an opus encoded frame. |
189 | 220 | /// </summary> |
190 | 221 | /// <param name="input">Input payload. Use null to indicate packet loss</param> |
191 | 222 | /// <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> |
193 | 224 | /// <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> |
194 | 225 | /// <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> |
195 | 226 | /// <returns>Number of decoded samples or <see cref="OpusErrorCodes"/>.</returns> |
196 | 227 | /// <exception cref="OpusException" /> |
197 | 228 | /// <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 | + |
201 | 246 | /// <summary> |
202 | 247 | /// Decodes an opus encoded frame. |
203 | 248 | /// </summary> |
204 | 249 | /// <param name="input">Input payload. Use null to indicate packet loss</param> |
205 | 250 | /// <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> |
207 | 252 | /// <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> |
208 | 253 | /// <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> |
209 | 254 | /// <returns>Number of decoded samples or <see cref="OpusErrorCodes"/>.</returns> |
210 | 255 | /// <exception cref="OpusException" /> |
211 | 256 | /// <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 | + } |
214 | 273 |
|
215 | 274 | /// <summary> |
216 | 275 | /// Performs a ctl request. |
|
0 commit comments