<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace Gablarski.Audio.Speex
{
	public class SpeexJitterBuffer
		: IDisposable
	{
		public SpeexJitterBuffer (int span)
		{
			this.state = jitter_buffer_init (span);
		}

		public int AvailableCount
		{
			get { return GetValue (JITTER_BUFFER.GET_AVAILABLE_COUNT); }
		}

		public unsafe void Push (SpeexJitterBufferPacket packet)
		{
			fixed (byte* pBuffer = packet.Data)
			{
				JitterBufferPacket p = new JitterBufferPacket();
				p.data = pBuffer;
				p.len = (uint)packet.Data.Length;
				p.sequence = (ushort)packet.Sequence;
				p.span = packet.Span;
				p.timestamp = packet.TimeStamp;

				lock (sync)
				{
					jitter_buffer_put (this.state, &p);
				}
			}
		}

		public unsafe SpeexJitterBufferPacket Pull (int span)
		{
			int offset;

			byte[] buffer = new byte[4096];

			var p = new JitterBufferPacket();
			JitterBufferStatus result;
			fixed (byte* pbuffer = buffer)
			{
				p.data = pbuffer;
				p.len = (uint)buffer.Length;
				lock (sync)
				{
					result = jitter_buffer_get (this.state, &p, span, out offset);
				}
			}

			switch (result)
			{
				case JitterBufferStatus.BadArgument:
					throw new ArgumentException();

				case JitterBufferStatus.InternalError:
					throw new Exception();

				case JitterBufferStatus.Ok:
					var sp = new SpeexJitterBufferPacket
					{
						Encoded = true,
						Sequence = p.sequence,
						Span = p.span,
						TimeStamp = p.timestamp,
						Data = new byte[p.len]
					};

					Array.Copy (buffer, sp.Data, p.len);

					Tick();

					return sp;

				default:
					var d = UpdateDelay();
					Tick();
					return d;
			}		
		}

		public void Tick()
		{
			lock (sync)
			{
				jitter_buffer_tick (this.state);
			}
		}

		public unsafe SpeexJitterBufferPacket UpdateDelay ()
		{
			SpeexJitterBufferPacket packet = new SpeexJitterBufferPacket();

			JitterBufferPacket p = new JitterBufferPacket();
			lock (sync)
			{
			    jitter_buffer_update_delay (this.state, &p, IntPtr.Zero);
			}

			packet.Data = new byte[0];
			packet.Encoded = false;
			packet.Sequence = p.sequence;
			packet.Span = p.span;
			packet.TimeStamp = p.timestamp;

			return packet;
		}

		#region IDisposable Members
		public void Dispose ()
		{
			GC.SuppressFinalize (this);
			Dispose (true);
		}<commit_msg> * Fixed the scratchiness issue in the new audio engine<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace Gablarski.Audio.Speex
{
	public class SpeexJitterBuffer
		: IDisposable
	{
		public SpeexJitterBuffer (int span)
		{
			this.state = jitter_buffer_init (span);
		}

		public int AvailableCount
		{
			get { return GetValue (JITTER_BUFFER.GET_AVAILABLE_COUNT); }
		}

		public unsafe void Push (SpeexJitterBufferPacket packet)
		{
			fixed (byte* pBuffer = packet.Data)
			{
				JitterBufferPacket p = new JitterBufferPacket();
				p.data = pBuffer;
				p.len = (uint)packet.Data.Length;
				p.sequence = (ushort)packet.Sequence;
				p.span = packet.Span;
				p.timestamp = packet.TimeStamp;

				lock (sync)
				{
					jitter_buffer_put (this.state, &p);
				}
			}
		}

		public unsafe SpeexJitterBufferPacket Pull (int span)
		{
			int offset;

			byte[] buffer = new byte[4096];

			var p = new JitterBufferPacket();
			JitterBufferStatus result;
			fixed (byte* pbuffer = buffer)
			{
				p.data = pbuffer;
				p.len = (uint)buffer.Length;
				lock (sync)
				{
					result = jitter_buffer_get (this.state, &p, span, out offset);
				}
			}

			switch (result)
			{
				case JitterBufferStatus.BadArgument:
					throw new ArgumentException();

				case JitterBufferStatus.InternalError:
					throw new Exception();

				case JitterBufferStatus.Ok:
					var sp = new SpeexJitterBufferPacket
					{
						Encoded = true,
						Sequence = p.sequence,
						Span = p.span,
						TimeStamp = p.timestamp,
						Data = new byte[p.len]
					};

					Array.Copy (buffer, sp.Data, p.len);

					Tick();

					return sp;

				default:
					var d = UpdateDelay (span * 2);
					Tick();
					return d;
			}		
		}

		public void Tick()
		{
			lock (sync)
			{
				jitter_buffer_tick (this.state);
			}
		}

		public unsafe SpeexJitterBufferPacket UpdateDelay (int span)
		{
			SpeexJitterBufferPacket packet = new SpeexJitterBufferPacket();

			JitterBufferPacket p = new JitterBufferPacket();
			p.span = (uint)span;
			lock (sync)
			{
			    jitter_buffer_update_delay (this.state, &p, IntPtr.Zero);
			}

			packet.Data = new byte[span];
			packet.Encoded = false;
			packet.Sequence = p.sequence;
			packet.Span = p.span;
			packet.TimeStamp = p.timestamp;

			return packet;
		}

		#region IDisposable Members
		public void Dispose ()
		{
			GC.SuppressFinalize (this);
			Dispose (true);
		}
{'fraction_non_alphanumeric': 0.10551020408163266, 'fraction_numerical': 0.0020408163265306124, 'mean_word_length': 2.775808936825886, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3213441', 'n_tokens_mistral': 2127, 'n_tokens_neox': 1631, 'n_words': 385}