/// <summary> /// Produces PCM samples from Opus encoded data. /// </summary> /// <param name="inputOpusData">Opus encoded data to decode, null for dropped packet.</param> /// <param name="dataLength">Length of data to decode.</param> /// <param name="decodedLength">Set to the length of the decoded sample data.</param> /// <returns>PCM audio samples.</returns> public unsafe void DecodeFloat(ReadOnlySpan <byte> inputOpusData, Span <float> outputFloat, out int dataLength) { if (disposed) { throw new ObjectDisposedException("OpusDecoder"); } int frameCount = GetSamples(inputOpusData) * OutputChannels; int length; fixed(byte *inputPtr = inputOpusData) fixed(float *outputPtr = outputFloat) { if (inputOpusData != null) { length = OpusAPI.opus_decode_float(DecoderInstance, inputPtr, inputOpusData.Length, outputPtr, frameCount, 0); } else { length = OpusAPI.opus_decode_float(DecoderInstance, null, 0, outputPtr, frameCount, (ForwardErrorCorrection) ? 1 : 0); } } if (length < 0) { throw new Exception("Decoding failed - " + (Errors)length); } dataLength = length * OutputChannels; }
/// <summary> /// Produces PCM samples from Opus encoded data. /// </summary> /// <param name="inputOpusData">Opus encoded data to decode, null for dropped packet.</param> /// <param name="dataLength">Length of data to decode.</param> /// <param name="decodedLength">Set to the length of the decoded sample data.</param> /// <returns>PCM audio samples.</returns> public unsafe byte[] Decode(Span <byte> inputOpusData, int dataLength, out int decodedLength) { if (disposed) { throw new ObjectDisposedException("OpusDecoder"); } int frameCount = MaxDataBytes * OutputChannels; byte[] decoded = new byte[frameCount * 2]; int length = 0; fixed(byte *inputPtr = inputOpusData) fixed(byte *outputPtr = decoded) { if (inputOpusData != null) { length = OpusAPI.opus_decode(DecoderInstance, inputPtr, dataLength, outputPtr, frameCount, 0); } else { length = OpusAPI.opus_decode(DecoderInstance, null, 0, outputPtr, frameCount, (ForwardErrorCorrection) ? 1 : 0); } decodedLength = length * 2 * OutputChannels; if (length < 0) { throw new Exception("Decoding failed - " + ((Errors)length)); } return(decoded); } }
/// <summary> /// Produces PCM samples from Opus encoded data. /// </summary> /// <param name="inputOpusData">Opus encoded data to decode, null for dropped packet.</param> /// <param name="dataLength">Length of data to decode.</param> /// <param name="decodedLength">Set to the length of the decoded sample data.</param> /// <returns>PCM audio samples.</returns> public unsafe float[] DecodeFloat(ReadOnlySpan <byte> inputOpusData) { if (disposed) { throw new ObjectDisposedException("OpusDecoder"); } int frameCount = GetSamples(inputOpusData) * OutputChannels; float[] decoded = new float[frameCount]; int length = 0; fixed(byte *inputPtr = inputOpusData) fixed(float *outputPtr = decoded) { if (inputOpusData != null) { length = OpusAPI.opus_decode_float(DecoderInstance, inputPtr, inputOpusData.Length, outputPtr, frameCount, 0); } else { length = OpusAPI.opus_decode_float(DecoderInstance, null, 0, outputPtr, frameCount, (ForwardErrorCorrection) ? 1 : 0); } } if (length < 0) { throw new Exception("Decoding failed - " + (Errors)length); } //decodedCount = length * OutputChannels; Array.Resize(ref decoded, length * OutputChannels); return(decoded); }
/// <summary> /// Creates a new Opus decoder. /// </summary> /// <param name="outputSampleRate">Sample rate to decode at (Hz). This must be one of 8000, 12000, 16000, 24000, or 48000.</param> /// <param name="outputChannels">Number of channels to decode.</param> /// <returns>A new <c>OpusDecoder</c>.</returns> public static OpusDecoder Create(int outputSampleRate, int outputChannels) { if (outputSampleRate != 8000 && outputSampleRate != 12000 && outputSampleRate != 16000 && outputSampleRate != 24000 && outputSampleRate != 48000) { throw new ArgumentOutOfRangeException(nameof(outputSampleRate)); } if (outputChannels != 1 && outputChannels != 2) { throw new ArgumentOutOfRangeException(nameof(outputChannels)); } IntPtr decoder = OpusAPI.opus_decoder_create(outputSampleRate, outputChannels, out var error); if ((Errors)error != Errors.OK) { throw new Exception("Exception occured while creating decoder"); } return(new OpusDecoder(decoder, outputSampleRate, outputChannels)); }
/// <summary> /// Produces Opus encoded audio from PCM samples. /// </summary> /// <param name="inputPcmSamples">PCM samples to encode.</param> /// <param name="sampleLength">How many samples to encode.</param> /// <param name="encodedLength">Set to length of encoded audio.</param> /// <returns>Opus encoded audio buffer.</returns> public unsafe void Encode(ReadOnlySpan <float> inputPcmSamples, Span <byte> outputSpan, int sampleLength, out int encodedLength) { if (disposed) { throw new ObjectDisposedException("OpusEncoder"); } int length = 0; fixed(float *inputPtr = inputPcmSamples) fixed(byte *outputPtr = outputSpan) { length = OpusAPI.opus_encode_float(EncoderInstance, inputPtr, sampleLength, outputPtr, outputSpan.Length); } encodedLength = length; if (length < 0) { var exception = new Exception("Encoding failed - " + (Errors)length); exception.Data.Add("inputPcmSamples.Length", inputPcmSamples.Length); exception.Data.Add("sampleLength", sampleLength); exception.Data.Add("InputChannels", InputChannels); throw exception; } }
/// <summary> /// Produces Opus encoded audio from PCM samples. /// </summary> /// <param name="inputPcmSamples">PCM samples to encode.</param> /// <param name="sampleLength">How many bytes to encode.</param> /// <param name="encodedLength">Set to length of encoded audio.</param> /// <returns>Opus encoded audio buffer.</returns> public unsafe byte[] Encode(Span <byte> inputPcmSamples, int sampleLength, out int encodedLength) { if (disposed) { throw new ObjectDisposedException("OpusEncoder"); } int maxDataBytes = sampleLength * InputChannels * sizeof(short); byte[] encoded = new byte[maxDataBytes]; int length = 0; fixed(byte *inputPtr = inputPcmSamples) fixed(byte *outputPtr = encoded) { length = OpusAPI.opus_encode(EncoderInstance, inputPtr, sampleLength, outputPtr, maxDataBytes); } encodedLength = length; if (length < 0) { var exception = new Exception("Encoding failed - " + (Errors)length); exception.Data.Add("inputPcmSamples.Length", inputPcmSamples.Length.ToString()); exception.Data.Add("sampleLength", sampleLength.ToString()); exception.Data.Add("MaxDataBytes", maxDataBytes.ToString()); throw exception; } return(encoded); }
/// <summary> /// Creates a new Opus encoder. /// </summary> /// <param name="inputSamplingRate">Sampling rate of the input signal (Hz). This must be one of 8000, 12000, 16000, 24000, or 48000.</param> /// <param name="inputChannels">Number of channels (1 or 2) in input signal.</param> /// <param name="application">Coding mode.</param> /// <returns>A new <c>OpusEncoder</c></returns> public static OpusEncoder Create(int inputSamplingRate, int inputChannels, Application application) { if (inputSamplingRate != 8000 && inputSamplingRate != 12000 && inputSamplingRate != 16000 && inputSamplingRate != 24000 && inputSamplingRate != 48000) { throw new ArgumentOutOfRangeException(nameof(inputSamplingRate)); } if (inputChannels != 1 && inputChannels != 2) { throw new ArgumentOutOfRangeException(nameof(inputChannels)); } IntPtr encoder = OpusAPI.opus_encoder_create(inputSamplingRate, inputChannels, (int)application, out var error); if ((Errors)error != Errors.OK) { throw new Exception("Exception occured while creating encoder"); } return(new OpusEncoder(encoder, inputSamplingRate, inputChannels, application)); }
private void SetCtl(Ctl ctl, int value) { if (disposed) { throw new ObjectDisposedException("OpusEncoder"); } var ret = OpusAPI.opus_encoder_ctl(EncoderInstance, ctl, value); if (ret < 0) { throw new Exception("Encoder error - " + (Errors)ret); } }
private int GetCtl(Ctl ctl) { if (disposed) { throw new ObjectDisposedException("OpusEncoder"); } var ret = OpusAPI.opus_encoder_ctl_out(EncoderInstance, ctl, out int result); if (ret < 0) { throw new Exception("Encoder error - " + (Errors)ret); } return(result); }
public void Dispose() { if (disposed) { return; } GC.SuppressFinalize(this); if (DecoderInstance != IntPtr.Zero) { OpusAPI.opus_decoder_destroy(DecoderInstance); DecoderInstance = IntPtr.Zero; } disposed = true; }
public unsafe int GetSamples(ReadOnlySpan <byte> data) { fixed(byte *ptr = data) return(OpusAPI.opus_packet_get_nb_samples(ptr, data.Length, OutputSamplingRate)); }
public unsafe int GetFrames(byte[] data) { fixed(byte *ptr = data) return(OpusAPI.opus_packet_get_nb_frames(ptr, data.Length)); }
public unsafe int GetChannels(byte[] data) { fixed(byte *ptr = data) return(OpusAPI.opus_packet_get_nb_channels(ptr)); }