public void HandleAudio(Audio.Codecs.CodecID codecid, byte[] encoded) { if (isDisposed) { return; } Audio.Codecs.INetworkChatCodec remoteCodec = Codecs.SingleOrDefault(m => m.CodecID == codecid); if (remoteCodec == null) { Console.WriteLine("Bad Audio Packet: Codec ID {0}", codecid); return; } if (codecid != LastCodec) { LastCodec = codecid; CodecName = remoteCodec.Name(); } TimeSpan buffered = waveOut == null ? TimeSpan.Zero : waveProvider.BufferedDuration; bool isPlaying = buffered != TimeSpan.Zero; if (waveOut == null || waveProvider.WaveFormat != remoteCodec.RecordFormat || (!isPlaying && ShouldTryRestartOutput)) { Start(remoteCodec); } else if (!isPlaying) { UnderRuns++; } if (buffered <= FrameDropThresholdMs) { byte[] decoded = remoteCodec.Decode(encoded, encoded.Length); int length = decoded.Length; if (!isPlaying && AudioOutWPF.shouldRampUnderruns) { InputResampler.RampPCM16Volume(ref decoded, length, InputResampler.RampDirection.ZeroToFull); } var volume = LevelManager.LevelScalar; if (volume < 1.0f) { InputResampler.ScalePCM16VolumeDb(ref decoded, length, volume); } if (length > 0 && ShouldDropSilence) { int dropped = DropSilence(silenceThreshhold, ref decoded, ref length); DroppedSilence += dropped; } else if (ShouldAddSilence && length > 5) { bool silent = true; for (int i = 0; i < 5; i += 2) { if (decoded[i + 1] != 0 || decoded[i] > addSilenceThreshold) { silent = false; break; } } if (silent) { var silenceBytes = length / 4; var silence = new byte[silenceBytes]; byte silenceLevel = (byte)(addSilenceThreshold / 2); for (int i = 0; i < silenceBytes - 1; i += 2) { silence[i + 1] = 0; silence[i] = silenceLevel; } waveProvider.AddSamples(silence, 0, silenceBytes); AddedSilence += length; } } waveProvider.AddSamples(decoded, 0, length); } else { DroppedPackets++; } if (shouldUpdateDuration) { BufferedDuration = buffered; shouldUpdateDuration = false; } LastReceived = DateTime.UtcNow; }