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); }
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(); unsafe { fixed(short *bdec = outputBuffer) { IntPtr decodedPtr = new IntPtr((byte *)(bdec)); int thisFrameSize = opus_decode(_decoder, inputPacket, inputPacket.Length, decodedPtr, frameSize, 0); } } _timer.Stop(); } else { // packet loss path _timer.Reset(); _timer.Start(); unsafe { fixed(short *bdec = outputBuffer) { IntPtr decodedPtr = new IntPtr((byte *)(bdec)); int thisFrameSize = opus_decode(_decoder, null, 0, decodedPtr, frameSize, 1); } } _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); return(new AudioChunk(finalOutput, 48000)); }