Example #1
0
 internal static OpusBandwidth MAX(OpusBandwidth a, OpusBandwidth b)
 {
     if ((int)a > (int)b)
     {
         return(a);
     }
     return(b);
 }
Example #2
0
 /// <summary>
 /// OPUS_DECODER_RESET_START
 /// </summary>
 internal void PartialReset()
 {
     stream_channels      = 0;
     bandwidth            = 0;
     mode                 = 0;
     prev_mode            = 0;
     frame_size           = 0;
     prev_redundancy      = 0;
     last_packet_duration = 0;
     rangeFinal           = 0;
     // fixme: do these get reset here? I don't think they do because init_celt and init_silk should both call RESET_STATE on their respective states
     //SilkDecoder.Reset();
     //CeltDecoder.Reset();
 }
Example #3
0
        internal static byte gen_toc(OpusMode mode, int framerate, OpusBandwidth bandwidth, int channels)
        {
            int  period;
            byte toc;

            period = 0;
            while (framerate < 400)
            {
                framerate <<= 1;
                period++;
            }
            if (mode == OpusMode.MODE_SILK_ONLY)
            {
                toc  = (byte)((bandwidth - OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND) << 5);
                toc |= (byte)((period - 2) << 3);
            }
            else if (mode == OpusMode.MODE_CELT_ONLY)
            {
                int tmp = bandwidth - OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND;
                if (tmp < 0)
                {
                    tmp = 0;
                }
                toc  = 0x80;
                toc |= (byte)(tmp << 5);
                toc |= (byte)(period << 3);
            }
            else /* Hybrid */
            {
                toc  = 0x60;
                toc |= (byte)((bandwidth - OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND) << 4);
                toc |= (byte)((period - 2) << 3);
            }
            toc |= (byte)((channels == 2 ? 1 : 0) << 2);
            return(toc);
        }
Example #4
0
        internal int opus_decode_native(byte[] data, int data_ptr,
                                        int len, short[] pcm_out, int pcm_out_ptr, int frame_size, int decode_fec,
                                        int self_delimited, out int packet_offset, int soft_clip)
        {
            int  i, nb_samples;
            int  count, offset;
            byte toc;
            int  packet_frame_size, packet_stream_channels;

            packet_offset = 0;
            OpusBandwidth packet_bandwidth;
            OpusMode      packet_mode;

            /* 48 x 2.5 ms = 120 ms */
            // fixme: make sure these values can fit in an int16
            short[] size = new short[48];
            if (decode_fec < 0 || decode_fec > 1)
            {
                return(OpusError.OPUS_BAD_ARG);
            }
            /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
            if ((decode_fec != 0 || len == 0 || data == null) && frame_size % (this.Fs / 400) != 0)
            {
                return(OpusError.OPUS_BAD_ARG);
            }
            if (len == 0 || data == null)
            {
                int pcm_count = 0;
                do
                {
                    int ret;
                    ret = opus_decode_frame(null, 0, 0, pcm_out, pcm_out_ptr + (pcm_count * this.channels), frame_size - pcm_count, 0);
                    if (ret < 0)
                    {
                        return(ret);
                    }
                    pcm_count += ret;
                } while (pcm_count < frame_size);
                Inlines.OpusAssert(pcm_count == frame_size);
                this.last_packet_duration = pcm_count;
                return(pcm_count);
            }
            else if (len < 0)
            {
                return(OpusError.OPUS_BAD_ARG);
            }

            packet_mode            = OpusPacketInfo.GetEncoderMode(data, data_ptr);
            packet_bandwidth       = OpusPacketInfo.GetBandwidth(data, data_ptr);
            packet_frame_size      = OpusPacketInfo.GetNumSamplesPerFrame(data, data_ptr, this.Fs);
            packet_stream_channels = OpusPacketInfo.GetNumEncodedChannels(data, data_ptr);

            count = OpusPacketInfo.opus_packet_parse_impl(data, data_ptr, len, self_delimited, out toc, null, null, 0,
                                                          size, 0, out offset, out packet_offset);

            if (count < 0)
            {
                return(count);
            }

            data_ptr += offset;

            if (decode_fec != 0)
            {
                int dummy;
                int duration_copy;
                int ret;
                /* If no FEC can be present, run the PLC (recursive call) */
                if (frame_size < packet_frame_size || packet_mode == OpusMode.MODE_CELT_ONLY || this.mode == OpusMode.MODE_CELT_ONLY)
                {
                    return(opus_decode_native(null, 0, 0, pcm_out, pcm_out_ptr, frame_size, 0, 0, out dummy, soft_clip));
                }
                /* Otherwise, run the PLC on everything except the size for which we might have FEC */
                duration_copy = this.last_packet_duration;
                if (frame_size - packet_frame_size != 0)
                {
                    ret = opus_decode_native(null, 0, 0, pcm_out, pcm_out_ptr, frame_size - packet_frame_size, 0, 0, out dummy, soft_clip);
                    if (ret < 0)
                    {
                        this.last_packet_duration = duration_copy;
                        return(ret);
                    }
                    Inlines.OpusAssert(ret == frame_size - packet_frame_size);
                }
                /* Complete with FEC */
                this.mode            = packet_mode;
                this.bandwidth       = packet_bandwidth;
                this.frame_size      = packet_frame_size;
                this.stream_channels = packet_stream_channels;
                ret = opus_decode_frame(data, data_ptr, size[0], pcm_out, pcm_out_ptr + (this.channels * (frame_size - packet_frame_size)),
                                        packet_frame_size, 1);
                if (ret < 0)
                {
                    return(ret);
                }
                else
                {
                    this.last_packet_duration = frame_size;
                    return(frame_size);
                }
            }

            if (count * packet_frame_size > frame_size)
            {
                return(OpusError.OPUS_BUFFER_TOO_SMALL);
            }

            /* Update the state as the last step to avoid updating it on an invalid packet */
            this.mode            = packet_mode;
            this.bandwidth       = packet_bandwidth;
            this.frame_size      = packet_frame_size;
            this.stream_channels = packet_stream_channels;

            nb_samples = 0;
            for (i = 0; i < count; i++)
            {
                int ret;
                ret = opus_decode_frame(data, data_ptr, size[i], pcm_out, pcm_out_ptr + (nb_samples * this.channels), frame_size - nb_samples, 0);
                if (ret < 0)
                {
                    return(ret);
                }
                Inlines.OpusAssert(ret == packet_frame_size);
                data_ptr   += size[i];
                nb_samples += ret;
            }
            this.last_packet_duration = nb_samples;

            return(nb_samples);
        }
Example #5
0
 internal static int GetOrdinal(OpusBandwidth bw)
 {
     return((int)bw - (int)OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND);
 }
Example #6
0
        public AudioChunk Decompress(byte[] inputPacket)
        {
            int frameSize = GetFrameSize();
            
            short[] outputBuffer = new short[frameSize];

            bool lostPacket = new Random().Next(0, 100) < _packetLoss;
            if (!lostPacket)
            {
                // Normal decoding
                _timer.Reset();
                _timer.Start();
                int thisFrameSize = _decoder.Decode(inputPacket, 0, inputPacket.Length, outputBuffer, 0, frameSize, false);
                _timer.Stop();
            }
            else
            {
                // packet loss path
                _timer.Reset();
                _timer.Start();
                int thisFrameSize = _decoder.Decode(null, 0, 0, outputBuffer, 0, frameSize, true);
                _timer.Stop();
            }

            short[] finalOutput = new short[frameSize];
            Array.Copy(outputBuffer, finalOutput, finalOutput.Length);

            // Update statistics
            _statistics.Bitrate = inputPacket.Length * 8 * 48000 / 1024 / frameSize;
            OpusMode curMode = OpusPacketInfo.GetEncoderMode(inputPacket, 0);
            if (curMode == OpusMode.MODE_CELT_ONLY)
            {
                _statistics.Mode = "CELT";
            }
            else if (curMode == OpusMode.MODE_HYBRID)
            {
                _statistics.Mode = "Hybrid";
            }
            else if (curMode == OpusMode.MODE_SILK_ONLY)
            {
                _statistics.Mode = "SILK";
            }
            else
            {
                _statistics.Mode = "Unknown";
            }
            _statistics.DecodeSpeed = _frameSize / ((double)_timer.ElapsedTicks / Stopwatch.Frequency * 1000);
            OpusBandwidth curBandwidth = OpusPacketInfo.GetBandwidth(inputPacket, 0);
            if (curBandwidth == OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND)
            {
                _statistics.Bandwidth = 8000;
            }
            else if (curBandwidth == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND)
            {
                _statistics.Bandwidth = 12000;
            }
            else if (curBandwidth == OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND)
            {
                _statistics.Bandwidth = 16000;
            }
            else if (curBandwidth == OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND)
            {
                _statistics.Bandwidth = 24000;
            }
            else
            {
                _statistics.Bandwidth = 48000;
            }

            return new AudioChunk(finalOutput, 48000);
        }