Exemple #1
0
        /// <summary>
        /// Initializes a new <see cref="OpusEncoder"/> instance, with the specified codec usage tuning, sample rate and channels.
        /// </summary>
        /// <param name="optimized">The codec usage tuning.</param>
        /// <param name="sampleRate">The sample rate in the input audio.</param>
        /// <param name="audioChannels">The channels in the input audio - mono or stereo.</param>
        public OpusEncoder(OpusOptimizer optimized, OpusSampleRate sampleRate, OpusAudioChannels audioChannels)
        {
            if (!Enum.IsDefined(typeof(OpusOptimizer), optimized))
            {
                throw new ArgumentException("Value is not defined in the enumeration.", nameof(optimized));
            }

            if (!Enum.IsDefined(typeof(OpusSampleRate), sampleRate))
            {
                throw new ArgumentException("Value is not defined in the enumeration.", nameof(sampleRate));
            }

            if (!Enum.IsDefined(typeof(OpusAudioCHannels), audioChannels))
            {
                throw new ArgumentException("Value is not defined in the enumeration.", nameof(audioChannels));
            }

            _handle = FFI.opus_encoder_create((int)sampleRate, (int)audioChannels, (int)optimized, out int error);

            ThrowIfError(error);

            Optimized     = optimized;
            SampleRate    = sampleRate;
            AudioChannels = audioChannels;
            Bitrate       = -1;
        }
Exemple #2
0
        private OpusDecoder(double frameSize, OpusSampleRate sampleRate, OpusAudioChannels audioChannels, bool frameSizeWasSpecified)
        {
            switch (frameSize)
            {
            case 2.5:
            case 5:
            case 10:
            case 20:
            case 40:
            case 60:
                break;

            default:
                throw new ArgumentException("Value must be one of the following: 2.5, 5, 10, 20, 40 or 60.", nameof(frameSize));
            }

            if (!Enum.IsDefined(typeof(OpusSampleRate), sampleRate))
            {
                throw new ArgumentException("Value is not defined in the enumeration.", nameof(sampleRate));
            }

            if (!Enum.IsDefined(typeof(OpusAudioCHannels), audioChannels))
            {
                throw new ArgumentException("Value is not defined in the enumeration.", nameof(audioChannels));
            }

            if (frameSizeWasSpecified)
            {
                FrameSize = frameSize;
            }

            SampleRate    = sampleRate;
            AudioChannels = audioChannels;

            _samples   = GetSampleCount(frameSize);
            _pcmLength = GetPCMLength(_samples);
            _handle    = FFI.opus_decoder_create((int)sampleRate, (int)audioChannels, out int error);

            ThrowIfError(error);
        }
Exemple #3
0
        protected override bool ReleaseHandle()
        {
            FFI.opus_encoder_destroy(handle);

            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Encodes an Opus frame, the frame size must be one of the following: 2.5, 5, 10, 20, 40 or 60 ms.
        /// </summary>
        /// <param name="pcmBytes">The Opus frame.</param>
        /// <param name="pcmLength">The maximum number of bytes to read from <paramref name="pcmBytes"/>.</param>
        /// <param name="opusBytes">The buffer that the encoded audio will be stored in.</param>
        /// <param name="opusLength">The maximum number of bytes to write to <paramref name="opusBytes"/>.
        /// This will determine the bitrate in the encoded audio.</param>
        /// <returns>The number of bytes written to <paramref name="opusBytes"/>.</returns>
        public unsafe int Encode(byte[] pcmBytes, int pcmLength, byte[] opusBytes, int opusLength)
        {
            if (pcmBytes == null)
            {
                throw new ArgumentNullException(nameof(pcmBytes));
            }

            if (pcmLength < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(pcmLength), "Value cannot be negative.");
            }

            if (pcmBytes.Length < pcmLength)
            {
                throw new ArgumentOutOfRangeException(nameof(pcmLength), $"Value cannot be greater than the length of {nameof(pcmBytes)}.");
            }

            if (opusBytes == null)
            {
                throw new ArgumentNullException(nameof(opusBytes));
            }

            if (opusLength < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(opusLength), "Value cannot be negative.");
            }

            if (opusBytes.Length < opusLength)
            {
                throw new ArgumentOutOfRangeException(nameof(opusLength), $"Value cannot be greater than the length of {nameof(opusBytes)}.");
            }

            double frameSize = GetFrameSize(pcmLength);


            switch (frameSize)
            {
            case 2.5:
            case 5:
            case 10:
            case 20:
            case 40:
            case 60:
                break;

            default:
                throw new ArgumentException("The frame size must be one of the following: 2.5, 5, 10, 20, 40 or 60.", nameof(pcmLength));
            }

            ThrowIfDisposed();

            int result;
            int samples = GetSampleCount(frameSize);

            fixed(byte *input = pcmBytes)
            fixed(byte *output = opusBytes)
            {
                var inputPtr  = (IntPtr)input;
                var outputPtr = (IntPtr)output;

                result = FFI.opus_encode(_handle, inputPtr, samples, outputPtr, opusLength);
            }

            ThrowIfError(result);

            return(result);
        }