Decompiled source of ManagedBass v3.1.101

BepInEx/core/ManagedBass/netstandard1.4/ManagedBass.dll

Decompiled 2 days ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v1.4", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MathewSachin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription(".Net wrapper for un4seen BASS audio library")]
[assembly: AssemblyFileVersion("3.1.1.0")]
[assembly: AssemblyInformationalVersion("3.1.1")]
[assembly: AssemblyProduct("ManagedBass")]
[assembly: AssemblyTitle("ManagedBass")]
[assembly: AssemblyVersion("3.1.1.0")]
namespace ManagedBass
{
	public enum DSInterface
	{
		IDirectSound = 1,
		IDirectSound3DListener
	}
	public enum EAXEnvironment
	{
		LeaveCurrent = -1,
		Generic,
		PaddedCell,
		Room,
		Bathroom,
		Livingroom,
		Stoneroom,
		Auditorium,
		ConcertHall,
		Cave,
		Arena,
		Hangar,
		CarpetedHallway,
		Hallway,
		StoneCorridor,
		Alley,
		Forest,
		City,
		Mountains,
		Quarry,
		Plain,
		ParkingLot,
		SewerPipe,
		Underwater,
		Drugged,
		Dizzy,
		Psychotic,
		Count
	}
	public abstract class Effect<T> : INotifyPropertyChanged, IDisposable where T : class, IEffectParameter, new()
	{
		private int _channel;

		private int _effectHandle;

		private int _hfsync;

		private GCHandle _gch;

		private int _priority;

		protected T Parameters { get; private set; } = new T();


		public int Priority
		{
			get
			{
				return _priority;
			}
			set
			{
				if (IsActive && Bass.FXSetPriority(_effectHandle, value))
				{
					_priority = value;
				}
			}
		}

		public bool IsActive
		{
			get
			{
				if (_channel != 0)
				{
					return _effectHandle != 0;
				}
				return false;
			}
			set
			{
				if (_channel != 0)
				{
					if (value && !IsActive)
					{
						_effectHandle = Bass.ChannelSetFX(_channel, Parameters.FXType, 1);
					}
					else if (!value && IsActive && Bass.ChannelRemoveFX(_channel, _effectHandle))
					{
						_effectHandle = 0;
					}
					OnPropertyChanged("IsActive");
				}
			}
		}

		public event PropertyChangedEventHandler PropertyChanged;

		public void ApplyOn(int Channel, int Priority = 0)
		{
			_channel = Channel;
			_priority = Priority;
			if (!_gch.IsAllocated)
			{
				_gch = GCHandle.Alloc(Parameters, GCHandleType.Pinned);
			}
			_hfsync = Bass.ChannelSetSync(Channel, SyncFlags.Free, 0L, delegate
			{
				Dispose();
			}, (IntPtr)0);
		}

		public void Dispose()
		{
			Bass.ChannelRemoveSync(_channel, _hfsync);
			_channel = (_effectHandle = 0);
			if (_gch.IsAllocated)
			{
				_gch.Free();
			}
		}

		public void Default()
		{
			_gch.Free();
			Parameters = new T();
			_gch = GCHandle.Alloc(Parameters, GCHandleType.Pinned);
			OnPreset();
		}

		protected void OnPreset()
		{
			OnPropertyChanged("");
		}

		protected virtual void OnPropertyChanged([CallerMemberName] string PropertyName = null)
		{
			this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
		}
	}
	public class GCPin : IDisposable
	{
		private GCHandle _gcHandle;

		public IntPtr Pointer => _gcHandle.AddrOfPinnedObject();

		public GCPin(object Item)
		{
			_gcHandle = GCHandle.Alloc(Item, GCHandleType.Pinned);
		}

		public static int CreateStreamHelper(Func<IntPtr, int> Function, object Memory)
		{
			GCHandle GCPin = GCHandle.Alloc(Memory, GCHandleType.Pinned);
			int num = Function(GCPin.AddrOfPinnedObject());
			if (num == 0)
			{
				GCPin.Free();
			}
			else
			{
				Bass.ChannelSetSync(num, SyncFlags.Free, 0L, delegate
				{
					GCPin.Free();
				}, (IntPtr)0);
			}
			return num;
		}

		public void Dispose()
		{
			_gcHandle.Free();
		}
	}
	public class BassException : Exception
	{
		public Errors ErrorCode { get; }

		public BassException()
			: this(Bass.LastError)
		{
		}

		public BassException(Errors ErrorCode)
			: base($"Error: {ErrorCode}")
		{
			this.ErrorCode = ErrorCode;
		}
	}
	public delegate void DownloadProcedure(IntPtr Buffer, int Length, IntPtr User);
	public delegate void DSPProcedure(int Handle, int Channel, IntPtr Buffer, int Length, IntPtr User);
	public delegate void FileCloseProcedure(IntPtr User);
	public delegate long FileLengthProcedure(IntPtr User);
	public delegate int FileReadProcedure(IntPtr Buffer, int Length, IntPtr User);
	public delegate bool FileSeekProcedure(long Offset, IntPtr User);
	public delegate bool RecordProcedure(int Handle, IntPtr Buffer, int Length, IntPtr User);
	public delegate int StreamProcedure(int Handle, IntPtr Buffer, int Length, IntPtr User);
	public delegate void SyncProcedure(int Handle, int Channel, int Data, IntPtr User);
	public enum Algorithm3D
	{
		Default,
		Off,
		Full,
		Light
	}
	[Flags]
	public enum BassFlags : uint
	{
		Default = 0u,
		Byte = 1u,
		Mono = 2u,
		Loop = 4u,
		Bass3D = 8u,
		SoftwareMixing = 0x10u,
		FX = 0x80u,
		Float = 0x100u,
		Prescan = 0x20000u,
		AutoFree = 0x40000u,
		RestrictDownloadRate = 0x80000u,
		StreamDownloadBlocks = 0x100000u,
		Decode = 0x200000u,
		StreamStatus = 0x800000u,
		AsyncFile = 0x40000000u,
		Unicode = 0x80000000u,
		FxBpmBackground = 1u,
		FXBpmMult2 = 2u,
		FxTempoAlgorithmLinear = 0x200u,
		FxTempoAlgorithmCubic = 0x400u,
		FxTempoAlgorithmShannon = 0x800u,
		FxFreeSource = 0x10000u,
		MidiNoHeader = 1u,
		Midi16Bit = 2u,
		MidiNoSystemReset = 0x800u,
		MidiDecayEnd = 0x1000u,
		MidiNoFx = 0x2000u,
		MidiDecaySeek = 0x4000u,
		MidiNoCrop = 0x8000u,
		MidiNoteOff1 = 0x10000u,
		MidiFontMemoryMap = 0x20000u,
		MidiFontXGDRUMS = 0x40000u,
		SincInterpolation = 0x800000u,
		MusicRamp = 0x200u,
		MusicSensitiveRamping = 0x400u,
		MusicSurround = 0x800u,
		MusicSurround2 = 0x1000u,
		MusicFT2Mod = 0x2000u,
		MusicFT2PAN = 0x2000u,
		MusicPT1Mod = 0x4000u,
		MusicPositionReset = 0x8000u,
		MusicNonInterpolated = 0x10000u,
		MusicStopBack = 0x80000u,
		MusicNoSample = 0x100000u,
		MusicPositionResetEx = 0x400000u,
		MuteMax = 0x20u,
		VAM = 0x40u,
		SampleOverrideLowestVolume = 0x10000u,
		SampleOverrideLongestPlaying = 0x20000u,
		SampleOverrideDistance = 0x30000u,
		SampleChannelNew = 1u,
		SampleChannelStream = 2u,
		CDSubChannel = 0x200u,
		CDSubchannelNoHW = 0x400u,
		CdC2Errors = 0x800u,
		MixerChanAbsolute = 0x1000u,
		SplitSlave = 0x1000u,
		SplitPosition = 0x2000u,
		MixerResume = 0x1000u,
		MixerPositionEx = 0x2000u,
		MixerChanBuffer = 0x2000u,
		[Obsolete("Renamed to MixerChanBuffer for clarity.")]
		MixerBuffer = 0x2000u,
		MixerChanLimit = 0x4000u,
		[Obsolete("Renamed to MixerChanLimit for clarity.")]
		MixerLimit = 0x4000u,
		MixerEnd = 0x10000u,
		MixerChanMatrix = 0x10000u,
		[Obsolete("Renamed to MixerChanMatrix for clarity.")]
		MixerMatrix = 0x10000u,
		MixerNonStop = 0x20000u,
		MixerChanPause = 0x20000u,
		[Obsolete("Renamed to MixerChanPause for clarity.")]
		MixerPause = 0x20000u,
		MixerChanDownMix = 0x400000u,
		[Obsolete("Renamed to MixerChanDownMix for clarity.")]
		MixerDownMix = 0x400000u,
		MixerChanNoRampin = 0x800000u,
		[Obsolete("Renamed to MixerChanNoRampin for clarity.")]
		MixerNoRampin = 0x800000u,
		RecordPause = 0x8000u,
		RecordEchoCancel = 0x2000u,
		RecordAGC = 0x4000u,
		SpeakerFront = 0x1000000u,
		SpeakerRear = 0x2000000u,
		SpeakerCenterLFE = 0x3000000u,
		SpeakerRearCenter = 0x4000000u,
		SpeakerPair1 = 0x1000000u,
		SpeakerPair2 = 0x2000000u,
		SpeakerPair3 = 0x3000000u,
		SpeakerPair4 = 0x4000000u,
		SpeakerPair5 = 0x5000000u,
		SpeakerPair6 = 0x6000000u,
		SpeakerPair7 = 0x7000000u,
		SpeakerPair8 = 0x8000000u,
		SpeakerPair9 = 0x9000000u,
		SpeakerPair10 = 0xA000000u,
		SpeakerPair11 = 0xB000000u,
		SpeakerPair12 = 0xC000000u,
		SpeakerPair13 = 0xD000000u,
		SpeakerPair14 = 0xE000000u,
		SpeakerPair15 = 0xF000000u,
		SpeakerLeft = 0x10000000u,
		SpeakerRight = 0x20000000u,
		SpeakerFrontLeft = 0x11000000u,
		SpeakerRearLeft = 0x12000000u,
		SpeakerCenter = 0x13000000u,
		SpeakerRearCenterLeft = 0x14000000u,
		SpeakerFrontRight = 0x21000000u,
		SpeakerRearRight = 0x22000000u,
		SpeakerLFE = 0x23000000u,
		SpeakerRearCenterRight = 0x24000000u,
		AacFrame960 = 0x1000u,
		AacStereo = 0x400000u,
		DSDOverPCM = 0x400u,
		DSDRaw = 0x200u,
		Ac3DownmixStereo = 0x200u,
		Ac3DownmixQuad = 0x400u,
		Ac3DownmixDolby = 0x600u,
		Ac3DRC = 0x800u,
		DShowNoAudioProcessing = 0x80000u,
		DShowStreamMix = 0x1000000u,
		DShowAutoDVD = 0x4000000u,
		DShowLoop = 0x8000000u,
		DShowVideoProcessing = 0x20000u,
		WVStereo = 0x400000u
	}
	[Flags]
	internal enum BASSInfoFlags
	{
		None = 0,
		ContinuousRate = 0x10,
		EmulatedDrivers = 0x20,
		Certified = 0x40,
		Mono = 0x100,
		Stereo = 0x200,
		Secondary8Bit = 0x400,
		Secondary16Bit = 0x800
	}
	public enum ChannelAttribute
	{
		Frequency = 1,
		Volume = 2,
		Pan = 3,
		EaxMix = 4,
		NoBuffer = 5,
		CPUUsage = 7,
		SampleRateConversion = 8,
		NetworkResumeBufferLevel = 9,
		ScannedInfo = 10,
		NoRamp = 11,
		Bitrate = 12,
		Buffer = 13,
		Granule = 14,
		MusicAmplify = 256,
		MusicPanSeparation = 257,
		MusicPositionScaler = 258,
		MusicBPM = 259,
		MusicSpeed = 260,
		MusicVolumeGlobal = 261,
		MusicActiveChannelCount = 262,
		MusicVolumeChannel = 512,
		MusicVolumeInstrument = 768,
		Tempo = 65536,
		Pitch = 65537,
		TempoFrequency = 65538,
		TempoUseAAFilter = 65552,
		TempoAAFilterLength = 65553,
		TempoUseQuickAlgorithm = 65554,
		TempoSequenceMilliseconds = 65555,
		TempoSeekWindowMilliseconds = 65556,
		TempoOverlapMilliseconds = 65557,
		TempoPreventClick = 65558,
		ReverseDirection = 69632,
		MidiPPQN = 73728,
		MidiCPU = 73729,
		MidiChannels = 73730,
		MidiVoices = 73731,
		MidiVoicesActive = 73732,
		MidiState = 73733,
		MidiSRC = 73734,
		MidiKill = 73735,
		MidiTrackVolume = 73984,
		OpusOriginalFrequency = 77824,
		DSDGain = 81920,
		DSDRate = 81921,
		MixerLatency = 86016,
		SplitAsyncBuffer = 86032,
		SplitAsyncPeriod = 86033
	}
	[Flags]
	public enum ChannelType
	{
		Unknown = 0,
		Sample = 1,
		Recording = 2,
		MO3 = 0x100,
		ZXTune = -820183040,
		Stream = 0x10000,
		OGG = 0x10002,
		MP1 = 0x10003,
		MP2 = 0x10004,
		MP3 = 0x10005,
		AIFF = 0x10006,
		CA = 0x10007,
		MF = 0x10008,
		CD = 0x10200,
		WMA = 0x10300,
		WMA_MP3 = 0x10301,
		WINAMP = 0x10400,
		WV = 0x10500,
		WV_H = 0x10501,
		WV_L = 0x10502,
		WV_LH = 0x10503,
		OFR = 0x10600,
		APE = 0x10700,
		Mixer = 0x10800,
		Split = 0x10801,
		FLAC = 0x10900,
		FLAC_OGG = 0x10901,
		MPC = 0x10A00,
		AAC = 0x10B00,
		MP4 = 0x10B01,
		SPX = 0x10C00,
		MIDI = 0x10D00,
		ALAC = 0x10E00,
		TTA = 0x10F00,
		AC3 = 0x11000,
		Video = 0x11100,
		OPUS = 0x11200,
		DSD = 0x11700,
		ADX = 0x1F000,
		AIX = 0x1F001,
		Tempo = 0x1F200,
		Reverse = 0x1F201,
		MOD = 0x20000,
		MTM = 0x20001,
		S3M = 0x20002,
		XM = 0x20003,
		IT = 0x20004,
		Wave = 0x40000,
		WavePCM = 0x50001,
		WaveFloat = 0x50003,
		Dummy = 0x18000,
		Device = 0x18001
	}
	public enum Configuration
	{
		PlaybackBufferLength = 0,
		UpdatePeriod = 1,
		GlobalSampleVolume = 4,
		GlobalStreamVolume = 5,
		GlobalMusicVolume = 6,
		LogarithmicVolumeCurve = 7,
		LogarithmicPanCurve = 8,
		FloatDSP = 9,
		Algorithm3D = 10,
		NetTimeOut = 11,
		NetBufferLength = 12,
		PauseNoPlay = 13,
		NetPreBuffer = 15,
		NetAgent = 16,
		NetProxy = 17,
		NetPassive = 18,
		RecordingBufferLength = 19,
		NetPlaylist = 21,
		MusicVirtual = 22,
		FileVerificationBytes = 23,
		UpdateThreads = 24,
		DeviceBufferLength = 27,
		LoopbackRecording = 28,
		NoTimerResolution = 29,
		TruePlayPosition = 30,
		IOSMixAudio = 34,
		IOSSession = 34,
		SuppressMP3ErrorCorruptionSilence = 35,
		IncludeDefaultDevice = 36,
		NetReadTimeOut = 37,
		VistaSpeakerAssignment = 38,
		IOSSpeaker = 39,
		MFDisable = 40,
		HandleCount = 41,
		UnicodeDeviceInformation = 42,
		SRCQuality = 43,
		SampleSRCQuality = 44,
		AsyncFileBufferLength = 45,
		IOSNotify = 46,
		OggPreScan = 47,
		MFVideo = 48,
		Airplay = 49,
		DevNonStop = 50,
		IOSNoCategory = 51,
		NetVerificationBytes = 52,
		DevicePeriod = 53,
		Float = 54,
		AndroidSessionId = 62,
		AndroidAAudio = 67,
		AC3DynamicRangeCompression = 65537,
		WmaNetPreBuffer = 65793,
		WmaBassFileHandling = 65795,
		WmaNetSeek = 65796,
		WmaVideo = 65797,
		WmaAsync = 65807,
		CDFreeOld = 66048,
		CDRetry = 66049,
		CDAutoSpeed = 66050,
		CDSkipError = 66051,
		CDDBServer = 66052,
		EncodePriority = 66304,
		EncodeQueue = 66305,
		EncodeACMLoad = 66306,
		EncodeCastTimeout = 66320,
		EncodeCastProxy = 66321,
		MidiCompact = 66560,
		MidiVoices = 66561,
		MidiAutoFont = 66562,
		MidiDefaultFont = 66563,
		MidiInputPorts = 66564,
		MixerBufferLength = 67073,
		MixerPositionEx = 67074,
		SplitBufferLength = 67088,
		PlayAudioFromMp4 = 67328,
		AacSupportMp4 = 67329,
		DSDFrequency = 67584,
		WinampInputTimeout = 67584,
		DSDGain = 67585,
		ZXTuneMaxFileSize = -820182784
	}
	[Flags]
	public enum DataFlags
	{
		Available = 0,
		FFTIndividual = 0x10,
		FFTNoWindow = 0x20,
		FFTRemoveDC = 0x40,
		FFTComplex = 0x80,
		Fixed = 0x20000000,
		Float = 0x40000000,
		FFT256 = int.MinValue,
		FFT512 = -2147483647,
		FFT1024 = -2147483646,
		FFT2048 = -2147483645,
		FFT4096 = -2147483644,
		FFT8192 = -2147483643,
		FFT16384 = -2147483642,
		FFT32768 = -2147483641
	}
	[Flags]
	public enum DeviceInfoFlags
	{
		None = 0,
		Enabled = 1,
		Default = 2,
		Initialized = 4,
		Loopback = 8,
		TypeMask = -16777216
	}
	[Flags]
	public enum DeviceInitFlags
	{
		Default = 0,
		Byte = 1,
		Mono = 2,
		Device3D = 4,
		Bits16 = 8,
		Latency = 0x100,
		CPSpeakers = 0x400,
		ForcedSpeakerAssignment = 0x800,
		NoSpeakerAssignment = 0x1000,
		DMix = 0x2000,
		Frequency = 0x4000,
		Stereo = 0x8000,
		Hog = 0x10000,
		AudioTrack = 0x20000,
		DirectSound = 0x40000
	}
	public enum DeviceType
	{
		Network = 16777216,
		Speakers = 33554432,
		Line = 50331648,
		Headphones = 67108864,
		Microphone = 83886080,
		Headset = 100663296,
		Handset = 117440512,
		Digital = 134217728,
		SPDIF = 150994944,
		HDMI = 167772160,
		DisplayPort = 1073741824
	}
	public enum DXPhase
	{
		Negative180,
		Negative90,
		Zero,
		Positive90,
		Positive180
	}
	public enum DXWaveform
	{
		Triangle,
		Sine
	}
	public enum EffectType
	{
		DXChorus = 0,
		DXDistortion = 1,
		DXEcho = 2,
		DXFlanger = 3,
		DXCompressor = 4,
		DXGargle = 5,
		DX_I3DL2Reverb = 6,
		DXParamEQ = 7,
		DXReverb = 8,
		Rotate = 65536,
		Volume = 65539,
		PeakEQ = 65540,
		Mix = 65543,
		Damp = 65544,
		AutoWah = 65545,
		Phaser = 65547,
		Chorus = 65549,
		Distortion = 65552,
		Compressor = 65553,
		VolumeEnvelope = 65554,
		BQF = 65555,
		Echo = 65556,
		PitchShift = 65557,
		Freeverb = 65558
	}
	public enum FileStreamPosition
	{
		Current = 0,
		Download = 1,
		End = 2,
		Start = 3,
		Connected = 4,
		Buffer = 5,
		Socket = 6,
		AsyncBuffer = 7,
		WmaBuffer = 1000,
		HlsSegment = 65536
	}
	[Flags]
	public enum FXChannelFlags
	{
		All = -1,
		None = 0,
		Channel1 = 1,
		Channel2 = 2,
		Channel3 = 4,
		Channel4 = 8,
		Channel5 = 0x10,
		Channel6 = 0x20,
		Channel7 = 0x40,
		Channel8 = 0x80,
		Channel9 = 0x100,
		Channel10 = 0x200,
		Channel11 = 0x400,
		Channel12 = 0x800,
		Channel13 = 0x1000,
		Channel14 = 0x2000,
		Channel15 = 0x4000,
		Channel16 = 0x8000,
		Channel17 = 0x10000,
		Channel18 = 0x20000,
		Channel19 = 0x40000,
		Channel20 = 0x80000,
		Channel21 = 0x100000,
		Channel22 = 0x200000,
		Channel23 = 0x400000,
		Channel24 = 0x800000,
		Channel25 = 0x1000000,
		Channel26 = 0x2000000,
		Channel27 = 0x4000000,
		Channel28 = 0x8000000,
		Channel29 = 0x10000000,
		Channel30 = 0x20000000
	}
	[Flags]
	public enum InputFlags
	{
		None = 0,
		Off = 0x10000,
		On = 0x20000
	}
	[Flags]
	public enum InputTypeFlags
	{
		InputTypeMask = -16777216,
		Error = -1,
		Undefined = 0,
		Digital = 0x1000000,
		Line = 0x2000000,
		Microphone = 0x3000000,
		MIDISynthesizer = 0x4000000,
		AnalogCD = 0x5000000,
		Phone = 0x6000000,
		Speaker = 0x7000000,
		Wave = 0x8000000,
		Auxiliary = 0x9000000,
		Analog = 0xA000000
	}
	[Flags]
	public enum LevelRetrievalFlags
	{
		All = 0,
		Mono = 1,
		Stereo = 2,
		RMS = 4,
		VolPan = 8
	}
	public enum Mode3D
	{
		LeaveCurrent = -1,
		Normal,
		Relative,
		Off
	}
	public enum PlaybackState
	{
		Stopped,
		Playing,
		Stalled,
		Paused
	}
	[Flags]
	public enum PositionFlags
	{
		Bytes = 0,
		MusicOrders = 1,
		MIDITick = 2,
		OGG = 3,
		CDTrack = 4,
		ZXTuneSubCount = 0xF10000,
		ZXTuneSubLength = 0xF20000,
		MIDIDecaySeek = 0x4000,
		MixerReset = 0x10000,
		MusicPositionReset = 0x8000,
		MusicPositionResetEx = 0x400000,
		MixerNoRampIn = 0x800000,
		Inexact = 0x8000000,
		Relative = 0x4000000,
		Decode = 0x10000000,
		DecodeTo = 0x20000000,
		Scan = 0x40000000,
		HlsSegment = 0x10000
	}
	[Flags]
	public enum RecordFormatFlags
	{
		Unknown = 0,
		WF1M08 = 1,
		WF1S08 = 2,
		WF1M16 = 4,
		WF1S16 = 8,
		WF2M08 = 0x10,
		WF2S08 = 0x20,
		WF2M16 = 0x40,
		WF2S16 = 0x80,
		WF4M08 = 0x100,
		WF4S08 = 0x200,
		WF4M16 = 0x400,
		WF4S16 = 0x800,
		WF48M08 = 0x1000,
		WF48S08 = 0x2000,
		WF48M16 = 0x4000,
		WF48S16 = 0x8000,
		WF96M08 = 0x10000,
		WF96S08 = 0x20000,
		WF96M16 = 0x40000,
		WF96S16 = 0x80000
	}
	[Flags]
	internal enum RecordInfoFlags
	{
		None = 0,
		EmulatedDrivers = 0x20,
		Certified = 0x40
	}
	public enum StreamProcedureType
	{
		End = int.MinValue,
		Push = -1,
		Dummy = 0,
		Device = -2
	}
	public enum StreamSystem
	{
		NoBuffer,
		Buffer,
		BufferPush
	}
	[Flags]
	public enum SyncFlags
	{
		Onetime = int.MinValue,
		Mixtime = 0x40000000,
		Thread = 0x20000000,
		Position = 0,
		MusicInstrument = 1,
		End = 2,
		MusicFx = 3,
		MetadataReceived = 4,
		Slided = 5,
		Stalled = 6,
		Downloaded = 7,
		Free = 8,
		MusicPosition = 0xA,
		Seeking = 0xB,
		OggChange = 0xC,
		Stop = 0xE,
		WinampBitRate = 0x64,
		CDError = 0x3E8,
		CDSpeed = 0x3EA,
		MidiMarker = 0x10000,
		MidiCue = 0x10001,
		MidiLyric = 0x10002,
		MidiText = 0x10003,
		MidiEvent = 0x10004,
		MidiTick = 0x10005,
		MidiTimeSignature = 0x10006,
		MidiKeySignature = 0x10007,
		WmaChange = 0x10100,
		WmaMeta = 0x10101,
		MixerEnvelope = 0x10200,
		MixerEnvelopeNode = 0x10201,
		HlsSegement = 0x10300
	}
	public enum TagType
	{
		ID3 = 0,
		ID3v2 = 1,
		OGG = 2,
		HTTP = 3,
		ICY = 4,
		META = 5,
		APE = 6,
		MP4 = 7,
		WMA = 8,
		OggEncoder = 9,
		Lyrics3v2 = 10,
		WmaMeta = 11,
		CoreAudioCodec = 11,
		WmaCodec = 12,
		FlacCue = 12,
		MF = 13,
		WaveFormat = 14,
		ZXTuneSuOgg = 15794176,
		RiffInfo = 256,
		RiffBext = 257,
		RiffCart = 258,
		RiffDISP = 259,
		ApeBinary = 4096,
		MusicName = 65536,
		MusicMessage = 65537,
		MusicOrders = 65538,
		MusicAuth = 65539,
		MusicInstrument = 65792,
		MusicSample = 66304,
		MidiTrack = 69632,
		FlacPicture = 73728,
		AdxLoop = 73728,
		DSDArtist = 77824,
		DSDTitle = 77825,
		DSDComment = 78080,
		HlsExtInf = 81920,
		HlsStreamInf = 81921,
		HlsDate = 81922
	}
	[Flags]
	public enum VAMMode
	{
		Hardware = 1,
		Software = 2,
		TerminateTime = 4,
		TerminateDistance = 8,
		TerminatePriority = 0x10
	}
	public enum WaveFormatTag : short
	{
		Extensible = -2,
		Unknown = 0,
		Pcm = 1,
		Adpcm = 2,
		IeeeFloat = 3,
		Vselp = 4,
		IbmCvsd = 5,
		ALaw = 6,
		MuLaw = 7,
		Dts = 8,
		Drm = 9,
		WmaVoice9 = 10,
		OkiAdpcm = 16,
		DviAdpcm = 17,
		ImaAdpcm = 17,
		MediaspaceAdpcm = 18,
		SierraAdpcm = 19,
		G723Adpcm = 20,
		DigiStd = 21,
		DigiFix = 22,
		DialogicOkiAdpcm = 23,
		MediaVisionAdpcm = 24,
		CUCodec = 25,
		YamahaAdpcm = 32,
		SonarC = 33,
		DspGroupTrueSpeech = 34,
		EchoSpeechCorporation1 = 35,
		AudioFileAf36 = 36,
		Aptx = 37,
		AudioFileAf10 = 38,
		Prosody1612 = 39,
		Lrc = 40,
		DolbyAc2 = 48,
		Gsm610 = 49,
		MsnAudio = 50,
		AntexAdpcme = 51,
		ControlResVqlpc = 52,
		DigiReal = 53,
		DigiAdpcm = 54,
		ControlResCr10 = 55,
		NMS_VBXADPCM = 56,
		CS_IMAADPCM = 57,
		ECHOSC3 = 58,
		ROCKWELL_ADPCM = 59,
		ROCKWELL_DIGITALK = 60,
		XEBEC = 61,
		G721_ADPCM = 64,
		G728_CELP = 65,
		MSG723 = 66,
		Mpeg = 80,
		RT24 = 82,
		PAC = 83,
		Mp3 = 85,
		LUCENT_G723 = 89,
		CIRRUS = 96,
		ESPCM = 97,
		VOXWARE = 98,
		CANOPUS_ATRAC = 99,
		G726_ADPCM = 100,
		G722_ADPCM = 101,
		DSAT_DISPLAY = 103,
		VOXWARE_BYTE_ALIGNED = 105,
		VOXWARE_AC8 = 112,
		VOXWARE_AC10 = 113,
		VOXWARE_AC16 = 114,
		VOXWARE_AC20 = 115,
		VOXWARE_RT24 = 116,
		VOXWARE_RT29 = 117,
		VOXWARE_RT29HW = 118,
		VOXWARE_VR12 = 119,
		VOXWARE_VR18 = 120,
		VOXWARE_TQ40 = 121,
		SOFTSOUND = 128,
		VOXWARE_TQ60 = 129,
		MSRT24 = 130,
		G729A = 131,
		MVI_MVI2 = 132,
		DF_G726 = 133,
		DF_GSM610 = 134,
		ISIAUDIO = 136,
		ONLIVE = 137,
		SBC24 = 145,
		DOLBY_AC3_SPDIF = 146,
		MEDIASONIC_G723 = 147,
		PROSODY_8KBPS = 148,
		ZYXEL_ADPCM = 151,
		PHILIPS_LPCBB = 152,
		PACKED = 153,
		MALDEN_PHONYTALK = 160,
		Gsm = 161,
		G729 = 162,
		G723 = 163,
		Acelp = 164,
		RawAac = 255,
		RHETOREX_ADPCM = 256,
		IRAT = 257,
		VIVO_G723 = 273,
		VIVO_SIREN = 274,
		DIGITAL_G723 = 291,
		SANYO_LD_ADPCM = 293,
		SIPROLAB_ACEPLNET = 304,
		SIPROLAB_ACELP4800 = 305,
		SIPROLAB_ACELP8V3 = 306,
		SIPROLAB_G729 = 307,
		SIPROLAB_G729A = 308,
		SIPROLAB_KELVIN = 309,
		G726ADPCM = 320,
		QUALCOMM_PUREVOICE = 336,
		QUALCOMM_HALFRATE = 337,
		TUBGSM = 341,
		MSAUDIO1 = 352,
		WMA = 353,
		WMAProfessional = 354,
		WMALosseless = 355,
		WMA_SPDIF = 356,
		UNISYS_NAP_ADPCM = 368,
		UNISYS_NAP_ULAW = 369,
		UNISYS_NAP_ALAW = 370,
		UNISYS_NAP_16K = 371,
		CREATIVE_ADPCM = 512,
		CREATIVE_FASTSPEECH8 = 514,
		CREATIVE_FASTSPEECH10 = 515,
		UHER_ADPCM = 528,
		QUARTERDECK = 544,
		ILINK_VC = 560,
		RAW_SPORT = 576,
		ESST_AC3 = 577,
		IPI_HSX = 592,
		IPI_RPELP = 593,
		CS2 = 608,
		SONY_SCX = 624,
		FM_TOWNS_SND = 768,
		BTV_DIGITAL = 1024,
		QDESIGN_MUSIC = 1104,
		VME_VMPCM = 1664,
		TPC = 1665,
		OLIGSM = 4096,
		OLIADPCM = 4097,
		OLICELP = 4098,
		OLISBC = 4099,
		OLIOPR = 4100,
		LH_CODEC = 4352,
		NORRIS = 5120,
		SOUNDSPACE_MUSICOMPRESS = 5376,
		MPEG_ADTS_AAC = 5632,
		MPEG_RAW_AAC = 5633,
		MPEG_LOAS = 5634,
		NOKIA_MPEG_ADTS_AAC = 5640,
		NOKIA_MPEG_RAW_AAC = 5641,
		VODAFONE_MPEG_ADTS_AAC = 5642,
		VODAFONE_MPEG_RAW_AAC = 5643,
		MPEG_HEAAC = 5648,
		DVM = 8192,
		Vorbis1 = 26447,
		Vorbis2 = 26448,
		Vorbis3 = 26449,
		Vorbis1P = 26479,
		Vorbis2P = 26480,
		Vorbis3P = 26481
	}
	public static class Bass
	{
		private const string DllName = "bass";

		private const int SlideLog = 16777216;

		public const int NoSoundDevice = 0;

		public const int DefaultDevice = -1;

		public static Algorithm3D Algorithm3D
		{
			get
			{
				return (Algorithm3D)GetConfig(Configuration.Algorithm3D);
			}
			set
			{
				Configure(Configuration.Algorithm3D, (int)value);
			}
		}

		public static string SupportedFormats => "*.mp3;*.mp2;*.mp1;*.ogg;*.wav;*.aif";

		public static double CPUUsage => BASS_GetCPU();

		public static Version Version => Extensions.GetVersion(BASS_GetVersion());

		public static Errors LastError => BASS_ErrorGetCode();

		public static bool Float => GetConfigBool(Configuration.Float);

		public static int PlaybackBufferLength
		{
			get
			{
				return GetConfig(Configuration.PlaybackBufferLength);
			}
			set
			{
				Configure(Configuration.PlaybackBufferLength, value);
			}
		}

		public static int UpdatePeriod
		{
			get
			{
				return GetConfig(Configuration.UpdatePeriod);
			}
			set
			{
				Configure(Configuration.UpdatePeriod, value);
			}
		}

		public static int GlobalSampleVolume
		{
			get
			{
				return GetConfig(Configuration.GlobalSampleVolume);
			}
			set
			{
				Configure(Configuration.GlobalSampleVolume, value);
			}
		}

		public static int GlobalStreamVolume
		{
			get
			{
				return GetConfig(Configuration.GlobalStreamVolume);
			}
			set
			{
				Configure(Configuration.GlobalStreamVolume, value);
			}
		}

		public static int GlobalMusicVolume
		{
			get
			{
				return GetConfig(Configuration.GlobalMusicVolume);
			}
			set
			{
				Configure(Configuration.GlobalMusicVolume, value);
			}
		}

		public static bool LogarithmicVolumeCurve
		{
			get
			{
				return GetConfigBool(Configuration.LogarithmicVolumeCurve);
			}
			set
			{
				Configure(Configuration.LogarithmicVolumeCurve, value);
			}
		}

		public static bool LogarithmicPanningCurve
		{
			get
			{
				return GetConfigBool(Configuration.LogarithmicPanCurve);
			}
			set
			{
				Configure(Configuration.LogarithmicPanCurve, value);
			}
		}

		public static bool FloatingPointDSP
		{
			get
			{
				return GetConfigBool(Configuration.FloatDSP);
			}
			set
			{
				Configure(Configuration.FloatDSP, value);
			}
		}

		public static int UpdateThreads
		{
			get
			{
				return GetConfig(Configuration.UpdateThreads);
			}
			set
			{
				Configure(Configuration.UpdateThreads, value);
			}
		}

		public static int AsyncFileBufferLength
		{
			get
			{
				return GetConfig(Configuration.AsyncFileBufferLength);
			}
			set
			{
				Configure(Configuration.AsyncFileBufferLength, value);
			}
		}

		public static int HandleCount => GetConfig(Configuration.HandleCount);

		public static int NetTimeOut
		{
			get
			{
				return GetConfig(Configuration.NetTimeOut);
			}
			set
			{
				Configure(Configuration.NetTimeOut, value);
			}
		}

		public static int NetReadTimeOut
		{
			get
			{
				return GetConfig(Configuration.NetReadTimeOut);
			}
			set
			{
				Configure(Configuration.NetReadTimeOut, value);
			}
		}

		public static int NetBufferLength
		{
			get
			{
				return GetConfig(Configuration.NetBufferLength);
			}
			set
			{
				Configure(Configuration.NetBufferLength, value);
			}
		}

		public static int PauseNoPlay
		{
			get
			{
				return GetConfig(Configuration.PauseNoPlay);
			}
			set
			{
				Configure(Configuration.PauseNoPlay, value);
			}
		}

		public static int NetPreBuffer
		{
			get
			{
				return GetConfig(Configuration.NetPreBuffer);
			}
			set
			{
				Configure(Configuration.NetPreBuffer, value);
			}
		}

		public static bool FTPPassive
		{
			get
			{
				return GetConfigBool(Configuration.NetPassive);
			}
			set
			{
				Configure(Configuration.NetPassive, value);
			}
		}

		public static int NetPlaylist
		{
			get
			{
				return GetConfig(Configuration.NetPlaylist);
			}
			set
			{
				Configure(Configuration.NetPlaylist, value);
			}
		}

		public static string NetAgent
		{
			get
			{
				return Marshal.PtrToStringAnsi(GetConfigPtr(Configuration.NetAgent));
			}
			set
			{
				IntPtr intPtr = Marshal.StringToHGlobalAnsi(value);
				Configure(Configuration.NetAgent, intPtr);
				Marshal.FreeHGlobal(intPtr);
			}
		}

		public static string NetProxy
		{
			get
			{
				return Marshal.PtrToStringAnsi(GetConfigPtr(Configuration.NetProxy));
			}
			set
			{
				IntPtr intPtr = Marshal.StringToHGlobalAnsi(value);
				Configure(Configuration.NetProxy, intPtr);
				Marshal.FreeHGlobal(intPtr);
			}
		}

		public static int MusicVirtial
		{
			get
			{
				return GetConfig(Configuration.MusicVirtual);
			}
			set
			{
				Configure(Configuration.MusicVirtual, value);
			}
		}

		public static int FileVerificationBytes
		{
			get
			{
				return GetConfig(Configuration.FileVerificationBytes);
			}
			set
			{
				Configure(Configuration.FileVerificationBytes, value);
			}
		}

		public static int NetVerificationBytes
		{
			get
			{
				return GetConfig(Configuration.NetVerificationBytes);
			}
			set
			{
				Configure(Configuration.NetVerificationBytes, value);
			}
		}

		public static int DeviceBufferLength
		{
			get
			{
				return GetConfig(Configuration.DeviceBufferLength);
			}
			set
			{
				Configure(Configuration.DeviceBufferLength, value);
			}
		}

		public static bool SuppressMP3ErrorCorruptionSilence
		{
			get
			{
				return GetConfigBool(Configuration.SuppressMP3ErrorCorruptionSilence);
			}
			set
			{
				Configure(Configuration.SuppressMP3ErrorCorruptionSilence, value);
			}
		}

		public static int SRCQuality
		{
			get
			{
				return GetConfig(Configuration.SRCQuality);
			}
			set
			{
				Configure(Configuration.SRCQuality, value);
			}
		}

		public static int SampleSRCQuality
		{
			get
			{
				return GetConfig(Configuration.SampleSRCQuality);
			}
			set
			{
				Configure(Configuration.SampleSRCQuality, value);
			}
		}

		public static bool OggPreScan
		{
			get
			{
				return GetConfigBool(Configuration.OggPreScan);
			}
			set
			{
				Configure(Configuration.OggPreScan, value);
			}
		}

		public static bool DeviceNonStop
		{
			get
			{
				return GetConfigBool(Configuration.DevNonStop);
			}
			set
			{
				Configure(Configuration.DevNonStop, value);
			}
		}

		public static int DeviceCount
		{
			get
			{
				int i;
				DeviceInfo Info;
				for (i = 0; GetDeviceInfo(i, out Info); i++)
				{
				}
				return i;
			}
		}

		public static double Volume
		{
			get
			{
				return BASS_GetVolume();
			}
			set
			{
				if (!BASS_SetVolume((float)value))
				{
					throw new BassException();
				}
			}
		}

		public static int CurrentDevice
		{
			get
			{
				return BASS_GetDevice();
			}
			set
			{
				if (!BASS_SetDevice(value))
				{
					throw new BassException();
				}
			}
		}

		public static BassInfo Info
		{
			get
			{
				if (!GetInfo(out var Info))
				{
					throw new BassException();
				}
				return Info;
			}
		}

		public static int CurrentRecordingDevice
		{
			get
			{
				return BASS_RecordGetDevice();
			}
			set
			{
				if (!BASS_RecordSetDevice(value))
				{
					throw new BassException();
				}
			}
		}

		public static RecordInfo RecordingInfo
		{
			get
			{
				if (!RecordGetInfo(out var info))
				{
					throw new BassException();
				}
				return info;
			}
		}

		public static int RecordingBufferLength
		{
			get
			{
				return GetConfig(Configuration.RecordingBufferLength);
			}
			set
			{
				Configure(Configuration.RecordingBufferLength, value);
			}
		}

		public static int RecordingDeviceCount
		{
			get
			{
				int i;
				DeviceInfo Info;
				for (i = 0; RecordGetDeviceInfo(i, out Info); i++)
				{
				}
				return i;
			}
		}

		[DllImport("bass", EntryPoint = "BASS_Apply3D")]
		public static extern void Apply3D();

		[DllImport("bass", EntryPoint = "BASS_Get3DFactors")]
		public static extern bool Get3DFactors(ref float Distance, ref float RollOff, ref float Doppler);

		[DllImport("bass", EntryPoint = "BASS_Set3DFactors")]
		public static extern bool Set3DFactors(float Distance, float RollOff, float Doppler);

		[DllImport("bass", EntryPoint = "BASS_Get3DPosition")]
		public static extern bool Get3DPosition(ref Vector3D Position, ref Vector3D Velocity, ref Vector3D Front, ref Vector3D Top);

		[DllImport("bass", EntryPoint = "BASS_Set3DPosition")]
		public static extern bool Set3DPosition(Vector3D Position, Vector3D Velocity, Vector3D Front, Vector3D Top);

		[DllImport("bass", EntryPoint = "BASS_ChannelGet3DAttributes")]
		public static extern bool ChannelGet3DAttributes(int Handle, ref Mode3D Mode, ref float Min, ref float Max, ref int iAngle, ref int oAngle, ref float OutVol);

		[DllImport("bass", EntryPoint = "BASS_ChannelSet3DAttributes")]
		public static extern bool ChannelSet3DAttributes(int Handle, Mode3D Mode, float Min, float Max, int iAngle, int oAngle, float OutVol);

		[DllImport("bass", EntryPoint = "BASS_ChannelGet3DPosition")]
		public static extern bool ChannelGet3DPosition(int Handle, ref Vector3D Position, ref Vector3D Orientation, ref Vector3D Velocity);

		[DllImport("bass", EntryPoint = "BASS_ChannelSet3DPosition")]
		public static extern bool ChannelSet3DPosition(int Handle, Vector3D Position, Vector3D Orientation, Vector3D Velocity);

		[DllImport("bass", EntryPoint = "BASS_Update")]
		public static extern bool Update(int Length);

		[DllImport("bass")]
		private static extern float BASS_GetCPU();

		[DllImport("bass")]
		private static extern int BASS_GetVersion();

		[DllImport("bass")]
		private static extern Errors BASS_ErrorGetCode();

		[DllImport("bass", EntryPoint = "BASS_ChannelGetInfo")]
		public static extern bool ChannelGetInfo(int Handle, out ChannelInfo Info);

		public static ChannelInfo ChannelGetInfo(int Handle)
		{
			if (!ChannelGetInfo(Handle, out var Info))
			{
				throw new BassException();
			}
			return Info;
		}

		[DllImport("bass")]
		private static extern int BASS_ChannelSetDSP(int Handle, DSPProcedure Procedure, IntPtr User, int Priority);

		public static int ChannelSetDSP(int Handle, DSPProcedure Procedure, IntPtr User = default(IntPtr), int Priority = 0)
		{
			int num = BASS_ChannelSetDSP(Handle, Procedure, User, Priority);
			if (num != 0)
			{
				ChannelReferences.Add(Handle, num, Procedure);
			}
			return num;
		}

		[DllImport("bass")]
		private static extern bool BASS_ChannelRemoveDSP(int Handle, int DSP);

		public static bool ChannelRemoveDSP(int Handle, int DSP)
		{
			bool num = BASS_ChannelRemoveDSP(Handle, DSP);
			if (num)
			{
				ChannelReferences.Remove(Handle, DSP);
			}
			return num;
		}

		[DllImport("bass")]
		private static extern int BASS_ChannelSetSync(int Handle, SyncFlags Type, long Parameter, SyncProcedure Procedure, IntPtr User);

		public static int ChannelSetSync(int Handle, SyncFlags Type, long Parameter, SyncProcedure Procedure, IntPtr User = default(IntPtr))
		{
			SyncProcedure syncProcedure = (Type.HasFlag(SyncFlags.Onetime) ? ((SyncProcedure)delegate(int I, int Channel, int Data, IntPtr Ptr)
			{
				Procedure(I, Channel, Data, Ptr);
				ChannelReferences.Remove(Channel, I);
			}) : Procedure);
			int num = BASS_ChannelSetSync(Handle, Type, Parameter, syncProcedure, User);
			if (num != 0)
			{
				ChannelReferences.Add(Handle, num, syncProcedure);
			}
			return num;
		}

		[DllImport("bass")]
		private static extern bool BASS_ChannelRemoveSync(int Handle, int Sync);

		public static bool ChannelRemoveSync(int Handle, int Sync)
		{
			bool num = BASS_ChannelRemoveSync(Handle, Sync);
			if (num)
			{
				ChannelReferences.Remove(Handle, Sync);
			}
			return num;
		}

		[DllImport("bass", EntryPoint = "BASS_ChannelPlay")]
		public static extern bool ChannelPlay(int Handle, bool Restart = false);

		[DllImport("bass", EntryPoint = "BASS_ChannelPause")]
		public static extern bool ChannelPause(int Handle);

		[DllImport("bass", EntryPoint = "BASS_ChannelStop")]
		public static extern bool ChannelStop(int Handle);

		[DllImport("bass", EntryPoint = "BASS_ChannelLock")]
		public static extern bool ChannelLock(int Handle, bool Lock = true);

		[DllImport("bass", EntryPoint = "BASS_ChannelIsActive")]
		public static extern PlaybackState ChannelIsActive(int Handle);

		[DllImport("bass", EntryPoint = "BASS_ChannelSetLink")]
		public static extern bool ChannelSetLink(int Handle, int Channel);

		[DllImport("bass", EntryPoint = "BASS_ChannelRemoveLink")]
		public static extern bool ChannelRemoveLink(int Handle, int Channel);

		[DllImport("bass", EntryPoint = "BASS_ChannelFlags")]
		public static extern BassFlags ChannelFlags(int Handle, BassFlags Flags, BassFlags Mask);

		public static bool ChannelHasFlag(int Handle, BassFlags Flag)
		{
			return ChannelFlags(Handle, BassFlags.Default, BassFlags.Default).HasFlag(Flag);
		}

		public static bool ChannelAddFlag(int Handle, BassFlags Flag)
		{
			return ChannelFlags(Handle, Flag, Flag).HasFlag(Flag);
		}

		public static bool ChannelRemoveFlag(int Handle, BassFlags Flag)
		{
			return !ChannelFlags(Handle, BassFlags.Default, Flag).HasFlag(Flag);
		}

		[DllImport("bass", EntryPoint = "BASS_ChannelGetAttribute")]
		public static extern bool ChannelGetAttribute(int Handle, ChannelAttribute Attribute, out float Value);

		public static double ChannelGetAttribute(int Handle, ChannelAttribute Attribute)
		{
			ChannelGetAttribute(Handle, Attribute, out var Value);
			return Value;
		}

		[DllImport("bass", EntryPoint = "BASS_ChannelGetAttributeEx")]
		public static extern int ChannelGetAttribute(int Handle, ChannelAttribute Attribute, IntPtr Value, int Size);

		[DllImport("bass", EntryPoint = "BASS_ChannelSetAttribute")]
		public static extern bool ChannelSetAttribute(int Handle, ChannelAttribute Attribute, float Value);

		public static bool ChannelSetAttribute(int Handle, ChannelAttribute Attribute, double Value)
		{
			return ChannelSetAttribute(Handle, Attribute, (float)Value);
		}

		[DllImport("bass", EntryPoint = "BASS_ChannelSetAttributeEx")]
		public static extern bool ChannelSetAttribute(int Handle, ChannelAttribute Attribute, IntPtr Value, int Size);

		[DllImport("bass", EntryPoint = "BASS_ChannelGetTags")]
		public static extern IntPtr ChannelGetTags(int Handle, TagType Tags);

		[DllImport("bass", EntryPoint = "BASS_ChannelGetLength")]
		public static extern long ChannelGetLength(int Handle, PositionFlags Mode = PositionFlags.Bytes);

		[DllImport("bass", EntryPoint = "BASS_ChannelBytes2Seconds")]
		public static extern double ChannelBytes2Seconds(int Handle, long Position);

		[DllImport("bass", EntryPoint = "BASS_ChannelSeconds2Bytes")]
		public static extern long ChannelSeconds2Bytes(int Handle, double Position);

		[DllImport("bass", EntryPoint = "BASS_ChannelGetPosition")]
		public static extern long ChannelGetPosition(int Handle, PositionFlags Mode = PositionFlags.Bytes);

		[DllImport("bass", EntryPoint = "BASS_ChannelSetPosition")]
		public static extern bool ChannelSetPosition(int Handle, long Position, PositionFlags Mode = PositionFlags.Bytes);

		[DllImport("bass", EntryPoint = "BASS_ChannelIsSliding")]
		public static extern bool ChannelIsSliding(int Handle, ChannelAttribute Attribute);

		[DllImport("bass")]
		private static extern bool BASS_ChannelSlideAttribute(int Handle, int Attribute, float Value, int Time);

		public static bool ChannelSlideAttribute(int Handle, ChannelAttribute Attribute, float Value, int Time, bool Logarithmic = false)
		{
			int num = (int)Attribute;
			if (Logarithmic)
			{
				num |= 0x1000000;
			}
			return BASS_ChannelSlideAttribute(Handle, num, Value, Time);
		}

		[DllImport("bass", EntryPoint = "BASS_ChannelGetLevel")]
		public static extern int ChannelGetLevel(int Handle);

		public static int ChannelGetLevelLeft(int Handle)
		{
			int num = ChannelGetLevel(Handle);
			if (num == -1)
			{
				return -1;
			}
			return num.LoWord();
		}

		public static int ChannelGetLevelRight(int Handle)
		{
			int num = ChannelGetLevel(Handle);
			if (num == -1)
			{
				return -1;
			}
			return num.HiWord();
		}

		[DllImport("bass", EntryPoint = "BASS_ChannelGetLevelEx")]
		public static extern bool ChannelGetLevel(int Handle, [In][Out] float[] Levels, float Length, LevelRetrievalFlags Flags);

		public static float[] ChannelGetLevel(int Handle, float Length, LevelRetrievalFlags Flags)
		{
			int num = ChannelGetInfo(Handle).Channels;
			if (Flags.HasFlag(LevelRetrievalFlags.Mono))
			{
				num = 1;
			}
			else if (Flags.HasFlag(LevelRetrievalFlags.Stereo))
			{
				num = 2;
			}
			float[] array = new float[num];
			if (!ChannelGetLevel(Handle, array, Length, Flags))
			{
				return null;
			}
			return array;
		}

		[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
		public static extern int ChannelGetData(int Handle, IntPtr Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
		public static extern int ChannelGetData(int Handle, [In][Out] byte[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
		public static extern int ChannelGetData(int Handle, [In][Out] short[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
		public static extern int ChannelGetData(int Handle, [In][Out] int[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
		public static extern int ChannelGetData(int Handle, [In][Out] float[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_ChannelUpdate")]
		public static extern bool ChannelUpdate(int Handle, int Length);

		[DllImport("bass", EntryPoint = "BASS_SetConfig")]
		public static extern bool Configure(Configuration Option, bool NewValue);

		[DllImport("bass", EntryPoint = "BASS_SetConfig")]
		public static extern bool Configure(Configuration Option, int NewValue);

		[DllImport("bass", EntryPoint = "BASS_SetConfigPtr")]
		public static extern bool Configure(Configuration Option, IntPtr NewValue);

		[DllImport("bass", EntryPoint = "BASS_GetConfig")]
		public static extern int GetConfig(Configuration Option);

		[DllImport("bass", EntryPoint = "BASS_GetConfigPtr")]
		public static extern IntPtr GetConfigPtr(Configuration Option);

		public static bool GetConfigBool(Configuration Option)
		{
			int config = GetConfig(Option);
			if (config != -1)
			{
				return config != 0;
			}
			return false;
		}

		[DllImport("bass", CharSet = CharSet.Unicode)]
		private static extern int BASS_StreamCreateFile(bool mem, string file, long offset, long length, BassFlags flags);

		[DllImport("bass")]
		private static extern int BASS_StreamCreateFile(bool mem, IntPtr file, long offset, long length, BassFlags flags);

		public static int CreateStream(string File, long Offset = 0L, long Length = 0L, BassFlags Flags = BassFlags.Default)
		{
			return BASS_StreamCreateFile(mem: false, File, Offset, Length, Flags | BassFlags.Unicode);
		}

		public static int CreateStream(IntPtr Memory, long Offset, long Length, BassFlags Flags = BassFlags.Default)
		{
			return BASS_StreamCreateFile(mem: true, new IntPtr(Memory.ToInt64() + Offset), 0L, Length, Flags);
		}

		public static int CreateStream(byte[] Memory, long Offset, long Length, BassFlags Flags)
		{
			return GCPin.CreateStreamHelper((IntPtr Pointer) => CreateStream(Pointer, Offset, Length, Flags), Memory);
		}

		[DllImport("bass")]
		private static extern int BASS_StreamCreateFileUser(StreamSystem system, BassFlags flags, [In][Out] FileProcedures procs, IntPtr user);

		public static int CreateStream(StreamSystem System, BassFlags Flags, FileProcedures Procedures, IntPtr User = default(IntPtr))
		{
			int num = BASS_StreamCreateFileUser(System, Flags, Procedures, User);
			if (num != 0)
			{
				ChannelReferences.Add(num, 0, Procedures);
			}
			return num;
		}

		[DllImport("bass", CharSet = CharSet.Unicode)]
		private static extern int BASS_StreamCreateURL(string Url, int Offset, BassFlags Flags, DownloadProcedure Procedure, IntPtr User);

		public static int CreateStream(string Url, int Offset, BassFlags Flags, DownloadProcedure Procedure, IntPtr User = default(IntPtr))
		{
			int num = BASS_StreamCreateURL(Url, Offset, Flags | BassFlags.Unicode, Procedure, User);
			if (num != 0)
			{
				ChannelReferences.Add(num, 0, Procedure);
			}
			return num;
		}

		[DllImport("bass", EntryPoint = "BASS_Init")]
		public static extern bool Init(int Device = -1, int Frequency = 44100, DeviceInitFlags Flags = DeviceInitFlags.Default, IntPtr Win = default(IntPtr), IntPtr ClsID = default(IntPtr));

		[DllImport("bass", EntryPoint = "BASS_Start")]
		public static extern bool Start();

		[DllImport("bass", EntryPoint = "BASS_Pause")]
		public static extern bool Pause();

		[DllImport("bass", EntryPoint = "BASS_Stop")]
		public static extern bool Stop();

		[DllImport("bass", EntryPoint = "BASS_Free")]
		public static extern bool Free();

		[DllImport("bass", EntryPoint = "BASS_ChannelGetDevice")]
		public static extern int ChannelGetDevice(int Handle);

		[DllImport("bass", EntryPoint = "BASS_ChannelSetDevice")]
		public static extern bool ChannelSetDevice(int Handle, int Device);

		[DllImport("bass")]
		private static extern float BASS_GetVolume();

		[DllImport("bass")]
		private static extern bool BASS_SetVolume(float volume);

		[DllImport("bass")]
		private static extern int BASS_GetDevice();

		[DllImport("bass")]
		private static extern bool BASS_SetDevice(int Device);

		[DllImport("bass", EntryPoint = "BASS_GetDeviceInfo")]
		public static extern bool GetDeviceInfo(int Device, out DeviceInfo Info);

		public static DeviceInfo GetDeviceInfo(int Device)
		{
			if (!GetDeviceInfo(Device, out var Info))
			{
				throw new BassException();
			}
			return Info;
		}

		[DllImport("bass", EntryPoint = "BASS_GetInfo")]
		public static extern bool GetInfo(out BassInfo Info);

		[DllImport("bass", EntryPoint = "BASS_FXSetParameters")]
		public static extern bool FXSetParameters(int Handle, IntPtr Parameters);

		public static bool FXSetParameters(int Handle, IEffectParameter Parameters)
		{
			using GCPin gCPin = new GCPin(Parameters);
			return FXSetParameters(Handle, gCPin.Pointer);
		}

		[DllImport("bass", EntryPoint = "BASS_FXGetParameters")]
		public static extern bool FXGetParameters(int Handle, IntPtr Parameters);

		public static bool FXGetParameters(int Handle, IEffectParameter Parameters)
		{
			using GCPin gCPin = new GCPin(Parameters);
			return FXGetParameters(Handle, gCPin.Pointer);
		}

		[DllImport("bass", EntryPoint = "BASS_FXReset")]
		public static extern bool FXReset(int Handle);

		[DllImport("bass", EntryPoint = "BASS_ChannelSetFX")]
		public static extern int ChannelSetFX(int Handle, EffectType Type, int Priority);

		[DllImport("bass", EntryPoint = "BASS_ChannelRemoveFX")]
		public static extern bool ChannelRemoveFX(int Handle, int FX);

		[DllImport("bass", EntryPoint = "BASS_FXSetPriority")]
		public static extern bool FXSetPriority(int Handle, int Priority);

		[DllImport("bass", EntryPoint = "BASS_MusicFree")]
		public static extern bool MusicFree(int Handle);

		[DllImport("bass", CharSet = CharSet.Unicode)]
		private static extern int BASS_MusicLoad(bool mem, string file, long offset, int Length, BassFlags flags, int freq);

		[DllImport("bass")]
		private static extern int BASS_MusicLoad(bool mem, IntPtr file, long offset, int Length, BassFlags flags, int freq);

		public static int MusicLoad(string File, long Offset = 0L, int Length = 0, BassFlags Flags = BassFlags.Default, int Frequency = 0)
		{
			return BASS_MusicLoad(mem: false, File, Offset, Length, Flags | BassFlags.Unicode, Frequency);
		}

		public static int MusicLoad(IntPtr Memory, long Offset, int Length, BassFlags Flags = BassFlags.Default, int Frequency = 0)
		{
			return BASS_MusicLoad(mem: true, new IntPtr(Memory.ToInt64() + Offset), 0L, Length, Flags, Frequency);
		}

		public static int MusicLoad(byte[] Memory, long Offset, int Length, BassFlags Flags = BassFlags.Default, int Frequency = 0)
		{
			return GCPin.CreateStreamHelper((IntPtr Pointer) => MusicLoad(Pointer, Offset, Length, Flags), Memory);
		}

		[DllImport("bass")]
		private static extern IntPtr BASS_PluginGetInfo(int Handle);

		public static PluginInfo PluginGetInfo(int Handle)
		{
			return Marshal.PtrToStructure<PluginInfo>(BASS_PluginGetInfo(Handle));
		}

		[DllImport("bass", CharSet = CharSet.Unicode)]
		private static extern int BASS_PluginLoad(string FileName, BassFlags Flags = BassFlags.Unicode);

		public static int PluginLoad(string FilePath)
		{
			if (Path.HasExtension(FilePath))
			{
				return BASS_PluginLoad(FilePath);
			}
			string directoryName = Path.GetDirectoryName(FilePath);
			string fileName = Path.GetFileName(FilePath);
			string[] array = new string[3]
			{
				Path.Combine(directoryName, fileName + ".dll"),
				Path.Combine(directoryName, "lib" + fileName + ".so"),
				Path.Combine(directoryName, "lib" + fileName + ".dylib")
			};
			foreach (string text in array)
			{
				if (File.Exists(text))
				{
					int num = BASS_PluginLoad(text);
					if (num != 0 || LastError == Errors.Already)
					{
						return num;
					}
				}
			}
			return BASS_PluginLoad(FilePath);
		}

		[DllImport("bass", EntryPoint = "BASS_PluginFree")]
		public static extern bool PluginFree(int Handle);

		[DllImport("bass", EntryPoint = "BASS_RecordInit")]
		public static extern bool RecordInit(int Device = -1);

		[DllImport("bass", EntryPoint = "BASS_RecordFree")]
		public static extern bool RecordFree();

		[DllImport("bass")]
		private static extern int BASS_RecordStart(int freq, int chans, BassFlags flags, RecordProcedure proc, IntPtr User);

		public static int RecordStart(int Frequency, int Channels, BassFlags Flags, RecordProcedure Procedure, IntPtr User = default(IntPtr))
		{
			int num = BASS_RecordStart(Frequency, Channels, Flags, Procedure, User);
			if (num != 0)
			{
				ChannelReferences.Add(num, 0, Procedure);
			}
			return num;
		}

		public static int RecordStart(int Frequency, int Channels, BassFlags Flags, int Period, RecordProcedure Procedure, IntPtr User = default(IntPtr))
		{
			return RecordStart(Frequency, Channels, (BassFlags)BitHelper.MakeLong((short)Flags, (short)Period), Procedure, User);
		}

		[DllImport("bass")]
		private static extern int BASS_RecordGetDevice();

		[DllImport("bass")]
		private static extern bool BASS_RecordSetDevice(int Device);

		[DllImport("bass", EntryPoint = "BASS_RecordGetDeviceInfo")]
		public static extern bool RecordGetDeviceInfo(int Device, out DeviceInfo Info);

		public static DeviceInfo RecordGetDeviceInfo(int Device)
		{
			if (!RecordGetDeviceInfo(Device, out var Info))
			{
				throw new BassException();
			}
			return Info;
		}

		[DllImport("bass", EntryPoint = "BASS_RecordGetInfo")]
		public static extern bool RecordGetInfo(out RecordInfo info);

		[DllImport("bass", EntryPoint = "BASS_RecordGetInput")]
		public static extern int RecordGetInput(int Input, out float Volume);

		[DllImport("bass")]
		private static extern int BASS_RecordGetInput(int Input, IntPtr Volume);

		public static int RecordGetInput(int Input)
		{
			return BASS_RecordGetInput(Input, IntPtr.Zero);
		}

		[DllImport("bass")]
		private static extern IntPtr BASS_RecordGetInputName(int input);

		public static string RecordGetInputName(int Input)
		{
			IntPtr intPtr = BASS_RecordGetInputName(Input);
			if (intPtr == IntPtr.Zero)
			{
				return null;
			}
			return GetConfig(Configuration.UnicodeDeviceInformation) switch
			{
				-1 => Extensions.PtrToStringUtf8(intPtr), 
				0 => Marshal.PtrToStringAnsi(intPtr), 
				_ => Extensions.PtrToStringUtf8(intPtr), 
			};
		}

		[DllImport("bass", EntryPoint = "BASS_RecordSetInput")]
		public static extern bool RecordSetInput(int Input, InputFlags Setting, float Volume);

		public static int SampleGetChannel(int Sample, bool OnlyNew = false)
		{
			return SampleGetChannel(Sample, OnlyNew ? BassFlags.Byte : BassFlags.Default);
		}

		[DllImport("bass", EntryPoint = "BASS_SampleGetChannel")]
		public static extern int SampleGetChannel(int Sample, BassFlags Flags);

		[DllImport("bass", EntryPoint = "BASS_SampleFree")]
		public static extern bool SampleFree(int Handle);

		[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
		public static extern bool SampleSetData(int Handle, IntPtr Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
		public static extern bool SampleSetData(int Handle, byte[] Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
		public static extern bool SampleSetData(int Handle, int[] Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
		public static extern bool SampleSetData(int Handle, short[] Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
		public static extern bool SampleSetData(int Handle, float[] Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleCreate")]
		public static extern int CreateSample(int Length, int Frequency, int Channels, int Max, BassFlags Flags);

		[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
		public static extern bool SampleGetData(int Handle, IntPtr Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
		public static extern bool SampleGetData(int Handle, [In][Out] byte[] Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
		public static extern bool SampleGetData(int Handle, [In][Out] short[] Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
		public static extern bool SampleGetData(int Handle, [In][Out] int[] Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
		public static extern bool SampleGetData(int Handle, [In][Out] float[] Buffer);

		[DllImport("bass", EntryPoint = "BASS_SampleGetInfo")]
		public static extern bool SampleGetInfo(int Handle, [In][Out] SampleInfo Info);

		public static SampleInfo SampleGetInfo(int Handle)
		{
			SampleInfo sampleInfo = new SampleInfo();
			if (!SampleGetInfo(Handle, sampleInfo))
			{
				throw new BassException();
			}
			return sampleInfo;
		}

		[DllImport("bass", EntryPoint = "BASS_SampleSetInfo")]
		public static extern bool SampleSetInfo(int Handle, SampleInfo Info);

		[DllImport("bass")]
		private static extern int BASS_SampleGetChannels(int handle, [In][Out] int[] channels);

		public static int[] SampleGetChannels(int Handle)
		{
			int num = BASS_SampleGetChannels(Handle, null);
			if (num < 0)
			{
				return null;
			}
			int[] array = new int[num];
			num = BASS_SampleGetChannels(Handle, array);
			if (num >= 0)
			{
				return array;
			}
			return null;
		}

		[DllImport("bass", EntryPoint = "BASS_SampleStop")]
		public static extern bool SampleStop(int Handle);

		[DllImport("bass", CharSet = CharSet.Unicode)]
		private static extern int BASS_SampleLoad(bool mem, string file, long offset, int Length, int max, BassFlags flags);

		[DllImport("bass")]
		private static extern int BASS_SampleLoad(bool mem, IntPtr file, long offset, int Length, int max, BassFlags flags);

		public static int SampleLoad(string File, long Offset, int Length, int MaxNoOfPlaybacks, BassFlags Flags)
		{
			return BASS_SampleLoad(mem: false, File, Offset, Length, MaxNoOfPlaybacks, Flags | BassFlags.Unicode);
		}

		public static int SampleLoad(IntPtr Memory, long Offset, int Length, int MaxNoOfPlaybacks, BassFlags Flags)
		{
			return BASS_SampleLoad(mem: true, new IntPtr(Memory.ToInt64() + Offset), 0L, Length, MaxNoOfPlaybacks, Flags);
		}

		public static int SampleLoad(byte[] Memory, long Offset, int Length, int MaxNoOfPlaybacks, BassFlags Flags)
		{
			return GCPin.CreateStreamHelper((IntPtr Pointer) => SampleLoad(Pointer, Offset, Length, MaxNoOfPlaybacks, Flags), Memory);
		}

		[DllImport("bass", EntryPoint = "BASS_StreamGetFilePosition")]
		public static extern long StreamGetFilePosition(int Handle, FileStreamPosition Mode = FileStreamPosition.Current);

		[DllImport("bass")]
		private static extern int BASS_StreamCreate(int Frequency, int Channels, BassFlags Flags, StreamProcedure Procedure, IntPtr User);

		public static int CreateStream(int Frequency, int Channels, BassFlags Flags, StreamProcedure Procedure, IntPtr User = default(IntPtr))
		{
			int num = BASS_StreamCreate(Frequency, Channels, Flags, Procedure, User);
			if (num != 0)
			{
				ChannelReferences.Add(num, 0, Procedure);
			}
			return num;
		}

		[DllImport("bass")]
		private static extern int BASS_StreamCreate(int Frequency, int Channels, BassFlags Flags, IntPtr ProcedureType, IntPtr User = default(IntPtr));

		public static int CreateStream(int Frequency, int Channels, BassFlags Flags, StreamProcedureType ProcedureType)
		{
			return BASS_StreamCreate(Frequency, Channels, Flags, new IntPtr((int)ProcedureType), (IntPtr)0);
		}

		[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
		public static extern int StreamPutData(int Handle, IntPtr Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
		public static extern int StreamPutData(int Handle, byte[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
		public static extern int StreamPutData(int Handle, short[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
		public static extern int StreamPutData(int Handle, int[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
		public static extern int StreamPutData(int Handle, float[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
		public static extern int StreamPutFileData(int Handle, IntPtr Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
		public static extern int StreamPutFileData(int Handle, byte[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
		public static extern int StreamPutFileData(int Handle, short[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
		public static extern int StreamPutFileData(int Handle, int[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
		public static extern int StreamPutFileData(int Handle, float[] Buffer, int Length);

		[DllImport("bass", EntryPoint = "BASS_StreamFree")]
		public static extern bool StreamFree(int Handle);
	}
	public struct BassInfo
	{
		private BASSInfoFlags flags;

		private int hwsize;

		private int hwfree;

		private int freesam;

		private int free3d;

		private int minrate;

		private int maxrate;

		private bool eax;

		private int minbuf;

		private int dsver;

		private int latency;

		private DeviceInitFlags initFlags;

		private int speakers;

		private int freq;

		public int TotalHardwareMemory => hwsize;

		public int FreeHardwareMemory => hwsize;

		public int FreeSampleSlots => freesam;

		public int Free3DSampleSlots => free3d;

		public int MinSampleRate => minrate;

		public int MaxSampleRate => maxrate;

		public bool EAXEnabled => eax;

		public int MinBufferLength => minbuf;

		public int DSVersion => dsver;

		public int Latency => latency;

		public DeviceInitFlags InitFlags => initFlags;

		public int SpeakerCount => speakers;

		public int SampleRate => freq;

		public bool IsCertified => flags.HasFlag(BASSInfoFlags.Certified);

		public bool Supports16BitSamples => flags.HasFlag(BASSInfoFlags.Secondary16Bit);

		public bool Supports8BitSamples => flags.HasFlag(BASSInfoFlags.Secondary8Bit);

		public bool SupportsContinuousRate => flags.HasFlag(BASSInfoFlags.ContinuousRate);

		public bool SupportsDirectSound => !flags.HasFlag(BASSInfoFlags.EmulatedDrivers);

		public bool SupportsMonoSamples => flags.HasFlag(BASSInfoFlags.Mono);

		public bool SupportsStereoSamples => flags.HasFlag(BASSInfoFlags.Stereo);
	}
	public struct ChannelInfo
	{
		private int freq;

		private int chans;

		private BassFlags flags;

		private ChannelType ctype;

		private int origres;

		private int plugin;

		private int sample;

		private IntPtr filename;

		public int Frequency => freq;

		public int Channels => chans;

		public BassFlags Flags => flags;

		public ChannelType ChannelType => ctype;

		public int Plugin => plugin;

		public int Sample => sample;

		public Resolution Resolution
		{
			get
			{
				if (flags.HasFlag(BassFlags.Byte))
				{
					return Resolution.Byte;
				}
				if (!flags.HasFlag(BassFlags.Float))
				{
					return Resolution.Short;
				}
				return Resolution.Float;
			}
		}

		public int OriginalResolution => origres;

		public string FileName
		{
			get
			{
				if (!(filename == IntPtr.Zero))
				{
					return Marshal.PtrToStringAnsi(filename);
				}
				return null;
			}
		}

		public bool IsDecodingChannel => flags.HasFlag(BassFlags.Decode);
	}
	public struct DeviceInfo
	{
		private IntPtr name;

		private IntPtr driver;

		private DeviceInfoFlags flags;

		public string Name => PtrToString(name);

		public string Driver => PtrToString(driver);

		public bool IsDefault => flags.HasFlag(DeviceInfoFlags.Default);

		public bool IsEnabled => flags.HasFlag(DeviceInfoFlags.Enabled);

		public bool IsInitialized => flags.HasFlag(DeviceInfoFlags.Initialized);

		public bool IsLoopback => flags.HasFlag(DeviceInfoFlags.Loopback);

		public DeviceType Type => (DeviceType)(flags & DeviceInfoFlags.TypeMask);

		private static string PtrToString(IntPtr ptr)
		{
			if (ptr == IntPtr.Zero)
			{
				return null;
			}
			return Bass.GetConfig(Configuration.UnicodeDeviceInformation) switch
			{
				-1 => Extensions.PtrToStringUtf8(ptr), 
				0 => Marshal.PtrToStringAnsi(ptr), 
				_ => Extensions.PtrToStringUtf8(ptr), 
			};
		}
	}
	[StructLayout(LayoutKind.Sequential)]
	public class FileProcedures
	{
		public FileCloseProcedure Close;

		public FileLengthProcedure Length;

		public FileReadProcedure Read;

		public FileSeekProcedure Seek;
	}
	public struct PluginFormat
	{
		private ChannelType ctype;

		private IntPtr name;

		private IntPtr exts;

		public ChannelType ChannelType => ctype;

		public string Name
		{
			get
			{
				if (!(name == IntPtr.Zero))
				{
					return Marshal.PtrToStringAnsi(name);
				}
				return null;
			}
		}

		public string FileExtensions
		{
			get
			{
				if (!(exts == IntPtr.Zero))
				{
					return Marshal.PtrToStringAnsi(exts);
				}
				return null;
			}
		}
	}
	public struct PluginInfo
	{
		private int version;

		private int formatc;

		private IntPtr formats;

		public Version Version => Extensions.GetVersion(version);

		public PluginFormat[] Formats
		{
			get
			{
				PluginFormat[] array = new PluginFormat[formatc];
				int num = Marshal.SizeOf<PluginFormat>();
				int num2 = 0;
				while (num2 < formatc)
				{
					array[num2] = Marshal.PtrToStructure<PluginFormat>(formats);
					num2++;
					formats += num;
				}
				return array;
			}
		}
	}
	public struct RecordInfo
	{
		private RecordInfoFlags flags;

		private int formats;

		private int inputs;

		private bool singlein;

		private int freq;

		public RecordFormatFlags SupportedFormats => (RecordFormatFlags)(formats & 0xFFFFFF);

		public int Inputs => inputs;

		public bool SingleInput => singlein;

		public int Frequency => freq;

		public int Channels => formats >> 24;

		public bool IsCertified => flags.HasFlag(RecordInfoFlags.Certified);

		public bool SupportsDirectSound => flags.HasFlag(RecordInfoFlags.EmulatedDrivers);
	}
	[StructLayout(LayoutKind.Sequential)]
	public class SampleInfo
	{
		public int Frequency = 44100;

		public float Volume = 1f;

		public float Pan;

		public BassFlags Flags;

		public int Length;

		public int Max = 1;

		public int OriginalResolution;

		public int Channels = 2;

		public int MinGap;

		public Mode3D Mode3D;

		public float MinDistance;

		public float MaxDistance;

		public int InsideAngle;

		public int OutsideAngle;

		public float OutsideVolume = 1f;

		public VAMMode VAM = VAMMode.Hardware;

		public int Priority;
	}
	[StructLayout(LayoutKind.Sequential)]
	public class Vector3D
	{
		public float X;

		public float Y;

		public float Z;

		public Vector3D()
		{
		}

		public Vector3D(float X, float Y, float Z)
		{
			this.X = X;
			this.Y = Y;
			this.Z = Z;
		}

		public override string ToString()
		{
			return $"({X}, {Y}, {Z})";
		}
	}
	public static class BitHelper
	{
		public static long HiDword(this long DWord)
		{
			return DWord >>> 32;
		}

		public static long LoDword(this long DWord)
		{
			return DWord & 0xFFFFFFFFu;
		}

		public static int HiWord(this int DWord)
		{
			return DWord >>> 16;
		}

		public static int LoWord(this int DWord)
		{
			return DWord & 0xFFFF;
		}

		public static byte HiByte(this short Word)
		{
			return (byte)(Word >> 8);
		}

		public static byte LoByte(this short Word)
		{
			return (byte)((uint)Word & 0xFFu);
		}

		public static short MakeWord(byte Low, byte High)
		{
			return (short)(Low | (ushort)(High << 8));
		}

		public static int MakeLong(short Low, short High)
		{
			return (ushort)Low | (High << 16);
		}
	}
	public enum Errors
	{
		Unknown = -1,
		OK = 0,
		Memory = 1,
		FileOpen = 2,
		Driver = 3,
		BufferLost = 4,
		Handle = 5,
		SampleFormat = 6,
		Position = 7,
		Init = 8,
		Start = 9,
		[Obsolete("Use SSL instead.")]
		SLL = 10,
		SSL = 10,
		NoCD = 12,
		CDTrack = 13,
		Already = 14,
		NotPaused = 16,
		NotAudioTrack = 17,
		NoChannel = 18,
		Type = 19,
		Parameter = 20,
		No3D = 21,
		NoEAX = 22,
		Device = 23,
		NotPlaying = 24,
		SampleRate = 25,
		NotFile = 27,
		NoHW = 29,
		Empty = 31,
		NoInternet = 32,
		Create = 33,
		NoFX = 34,
		Playing = 35,
		NotAvailable = 37,
		Decode = 38,
		DirectX = 39,
		Timeout = 40,
		FileFormat = 41,
		Speaker = 42,
		Version = 43,
		Codec = 44,
		Ended = 45,
		Busy = 46,
		Unstreamable = 47,
		WmaLicense = 1000,
		WM9 = 1001,
		WmaAccesDenied = 1002,
		WmaCodec = 1003,
		WmaIndividual = 1004,
		Wasapi = 5000,
		AcmCancel = 2000,
		CastDenied = 2100,
		Mp4NoStream = 6000
	}
	public static class Extensions
	{
		private static bool? _floatable;

		public static bool SupportsFloatingPoint
		{
			get
			{
				if (_floatable.HasValue)
				{
					return _floatable.Value;
				}
				int num = Bass.CreateStream(44100, 1, BassFlags.Float, StreamProcedureType.Dummy);
				_floatable = num != 0;
				if (_floatable.Value)
				{
					Bass.StreamFree(num);
				}
				return _floatable.Value;
			}
		}

		public static StreamProcedure SilenceStreamProcedure { get; } = delegate(int Handle, IntPtr Buffer, int Length, IntPtr User)
		{
			for (int i = 0; i < Length; i++)
			{
				Marshal.WriteByte(Buffer, i, 0);
			}
			return Length;
		};


		public static T Clip<T>(this T Item, T MinValue, T MaxValue) where T : IComparable<T>
		{
			if (Item.CompareTo(MaxValue) > 0)
			{
				return MaxValue;
			}
			if (Item.CompareTo(MinValue) >= 0)
			{
				return Item;
			}
			return MinValue;
		}

		public static BassFlags ToBassFlag(this Resolution Resolution)
		{
			return Resolution switch
			{
				Resolution.Byte => BassFlags.Byte, 
				Resolution.Float => BassFlags.Float, 
				_ => BassFlags.Default, 
			};
		}

		public static BassFlags SpeakerN(int N)
		{
			return (BassFlags)(N << 24);
		}

		public static Version GetVersion(int Num)
		{
			return new Version((Num >> 24) & 0xFF, (Num >> 16) & 0xFF, (Num >> 8) & 0xFF, Num & 0xFF);
		}

		public static string ChannelCountToString(int Channels)
		{
			switch (Channels)
			{
			case 1:
				return "Mono";
			case 2:
				return "Stereo";
			case 3:
				return "2.1";
			case 4:
				return "Quad";
			case 5:
				return "4.1";
			case 6:
				return "5.1";
			case 7:
				return "6.1";
			default:
				if (Channels < 1)
				{
					throw new ArgumentException("Channels must be greater than Zero.");
				}
				return Channels + " Channels";
			}
		}

		public static string[] ExtractMultiStringAnsi(IntPtr Ptr)
		{
			List<string> list = new List<string>();
			while (true)
			{
				string text = ((Ptr == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(Ptr));
				if (string.IsNullOrEmpty(text))
				{
					break;
				}
				list.Add(text);
				Ptr += text.Length + 1;
			}
			return list.ToArray();
		}

		public static string[] ExtractMultiStringUtf8(IntPtr Ptr)
		{
			List<string> list = new List<string>();
			while (true)
			{
				int Size;
				string text = PtrToStringUtf8(Ptr, out Size);
				if (string.IsNullOrEmpty(text))
				{
					break;
				}
				list.Add(text);
				Ptr += Size + 1;
			}
			return list.ToArray();
		}

		private unsafe static string PtrToStringUtf8(IntPtr Ptr, out int Size)
		{
			Size = 0;
			byte* ptr = (byte*)Ptr.ToPointer();
			if (Ptr == IntPtr.Zero || *ptr == 0)
			{
				return null;
			}
			while (ptr[Size] != 0)
			{
				Size++;
			}
			byte[] array = new byte[Size];
			Marshal.Copy(Ptr, array, 0, Size);
			return Encoding.UTF8.GetString(array, 0, array.Length);
		}

		public static string PtrToStringUtf8(IntPtr Ptr)
		{
			int Size;
			return PtrToStringUtf8(Ptr, out Size);
		}

		public static FileProcedures StreamFileProcedures(Stream InputStream)
		{
			return new StreamFileProcedures(InputStream);
		}

		public static void ApplyOn<T>(this Effect<T> Effect, MediaPlayer Player, int Priority = 0) where T : class, IEffectParameter, new()
		{
			Effect.ApplyOn(Player.Handle, Priority);
			Player.MediaLoaded += delegate(int NewHandle)
			{
				Effect.Dispose();
				Effect.ApplyOn(NewHandle, Priority);
			};
		}
	}
	public interface IEffectParameter
	{
		EffectType FXType { get; }
	}
	public class MediaPlayer : INotifyPropertyChanged, IDisposable
	{
		private readonly SynchronizationContext _syncContext;

		private int _handle;

		private bool _restartOnNextPlayback;

		private double _freq = 44100.0;

		private double _pan;

		private int _dev = -1;

		private double _vol = 0.5;

		private bool _loop;

		private string _title = "";

		private string _artist = "";

		private string _album = "";

		protected internal int Handle
		{
			get
			{
				return _handle;
			}
			private set
			{
				if (!Bass.ChannelGetInfo(value, out var _))
				{
					throw new ArgumentException("Invalid Channel Handle: " + value);
				}
				_handle = value;
				Bass.ChannelSetSync(Handle, SyncFlags.Free, 0L, GetSyncProcedure(delegate
				{
					this.Disposed?.Invoke(this, EventArgs.Empty);
				}), (IntPtr)0);
				Bass.ChannelSetSync(Handle, SyncFlags.Stop, 0L, GetSyncProcedure(delegate
				{
					this.MediaFailed?.Invoke(this, EventArgs.Empty);
				}), (IntPtr)0);
				Bass.ChannelSetSync(Handle, SyncFlags.End, 0L, GetSyncProcedure(delegate
				{
					try
					{
						if (!Bass.ChannelHasFlag(Handle, BassFlags.Loop))
						{
							this.MediaEnded?.Invoke(this, EventArgs.Empty);
						}
					}
					finally
					{
						OnStateChanged();
					}
				}), (IntPtr)0);
			}
		}

		public double Frequency
		{
			get
			{
				return _freq;
			}
			set
			{
				if (Bass.ChannelSetAttribute(Handle, ChannelAttribute.Frequency, value))
				{
					_freq = value;
					OnPropertyChanged("Frequency");
				}
			}
		}

		public double Balance
		{
			get
			{
				return _pan;
			}
			set
			{
				if (Bass.ChannelSetAttribute(Handle, ChannelAttribute.Pan, value))
				{
					_pan = value;
					OnPropertyChanged("Balance");
				}
			}
		}

		public int Device
		{
			get
			{
				return _dev = ((_dev == -1) ? Bass.ChannelGetDevice(Handle) : _dev);
			}
			set
			{
				if ((Bass.GetDeviceInfo(value).IsInitialized || Bass.Init(value, 44100, DeviceInitFlags.Default, (IntPtr)0, (IntPtr)0)) && Bass.ChannelSetDevice(Handle, value))
				{
					_dev = value;
					OnPropertyChanged("Device");
				}
			}
		}

		public double Volume
		{
			get
			{
				return _vol;
			}
			set
			{
				if (Bass.ChannelSetAttribute(Handle, ChannelAttribute.Volume, value))
				{
					_vol = value;
					OnPropertyChanged("Volume");
				}
			}
		}

		public bool Loop
		{
			get
			{
				return _loop;
			}
			set
			{
				if (!(value ? (!Bass.ChannelAddFlag(Handle, BassFlags.Loop)) : (!Bass.ChannelRemoveFlag(Handle, BassFlags.Loop))))
				{
					_loop = value;
					OnPropertyChanged("Loop");
				}
			}
		}

		public string Title
		{
			get
			{
				return _title;
			}
			private set
			{
				_title = value;
				OnPropertyChanged("Title");
			}
		}

		public string Artist
		{
			get
			{
				return _artist;
			}
			private set
			{
				_artist = value;
				OnPropertyChanged("Artist");
			}
		}

		public string Album
		{
			get
			{
				return _album;
			}
			private set
			{
				_album = value;
				OnPropertyChanged("Album");
			}
		}

		public PlaybackState State
		{
			get
			{
				if (Handle != 0)
				{
					return Bass.ChannelIsActive(Handle);
				}
				return PlaybackState.Stopped;
			}
		}

		public TimeSpan Duration => TimeSpan.FromSeconds(Bass.ChannelBytes2Seconds(Handle, Bass.ChannelGetLength(Handle)));

		public TimeSpan Position
		{
			get
			{
				return TimeSpan.FromSeconds(Bass.ChannelBytes2Seconds(Handle, Bass.ChannelGetPosition(Handle)));
			}
			set
			{
				Bass.ChannelSetPosition(Handle, Bass.ChannelSeconds2Bytes(Handle, value.TotalSeconds));
			}
		}

		public event EventHandler Disposed;

		public event EventHandler MediaEnded;

		public event EventHandler MediaFailed;

		public event Action<int> MediaLoaded;

		public event PropertyChangedEventHandler PropertyChanged;

		private SyncProcedure GetSyncProcedure(Action Handler)
		{
			return delegate
			{
				if (Handler != null)
				{
					if (_syncContext == null)
					{
						Handler();
					}
					else
					{
						_syncContext.Post(delegate
						{
							Handler();
						}, null);
					}
				}
			};
		}

		static MediaPlayer()
		{
			int currentDevice = Bass.CurrentDevice;
			if (currentDevice == -1 || !Bass.GetDeviceInfo(Bass.CurrentDevice).IsInitialized)
			{
				Bass.Init(currentDevice, 44100, DeviceInitFlags.Default, (IntPtr)0, (IntPtr)0);
			}
		}

		public MediaPlayer()
		{
			_syncContext = SynchronizationContext.Current;
		}

		protected virtual int OnLoad(string FileName)
		{
			return Bass.CreateStream(FileName, 0L, 0L);
		}

		public bool Play()
		{
			try
			{
				bool num = Bass.ChannelPlay(Handle, _restartOnNextPlayback);
				if (num)
				{
					_restartOnNextPlayback = false;
				}
				return num;
			}
			finally
			{
				OnStateChanged();
			}
		}

		public bool Pause()
		{
			try
			{
				return Bass.ChannelPause(Handle);
			}
			finally
			{
				OnStateChanged();
			}
		}

		public bool Stop()
		{
			try
			{
				_restartOnNextPlayback = true;
				return Bass.ChannelStop(Handle);
			}
			finally
			{
				OnStateChanged();
			}
		}

		public async Task<bool> LoadAsync(string FileName)
		{
			try
			{
				if (Handle != 0)
				{
					Bass.StreamFree(Handle);
				}
			}
			catch
			{
			}
			if (_dev != -1)
			{
				Bass.CurrentDevice = _dev;
			}
			int currentDevice = Bass.CurrentDevice;
			if (currentDevice == -1 || !Bass.GetDeviceInfo(Bass.CurrentDevice).IsInitialized)
			{
				Bass.Init(currentDevice, 44100, DeviceInitFlags.Default, (IntPtr)0, (IntPtr)0);
			}
			int num = await Task.Run(() => OnLoad(FileName));
			if (num == 0)
			{
				return false;
			}
			Handle = num;
			TagReader tagReader = TagReader.Read(Handle);
			Title = ((!string.IsNullOrWhiteSpace(tagReader.Title)) ? tagReader.Title : Path.GetFileNameWithoutExtension(FileName));
			Artist = tagReader.Artist;
			Album = tagReader.Album;
			InitProperties();
			this.MediaLoaded?.Invoke(num);
			OnPropertyChanged("");
			return true;
		}

		public virtual void Dispose()
		{
			try
			{
				if (Bass.StreamFree(Handle))
				{
					_handle = 0;
				}
			}
			finally
			{
				OnStateChanged();
			}
		}

		protected virtual void InitProperties()
		{
			Frequency = _freq;
			Balance = _pan;
			Volume = _vol;
			Loop = _loop;
		}

		private void OnStateChanged()
		{
			OnPropertyChanged("State");
		}

		protected virtual void OnPropertyChanged([CallerMemberName] string PropertyName = null)
		{
			Action f = delegate
			{
				this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
			};
			if (_syncContext == null)
			{
				f();
				return;
			}
			_syncContext.Post(delegate
			{
				f();
			}, null);
		}
	}
	public static class ChannelReferences
	{
		private static readonly ConcurrentDictionary<Tuple<int, int>, object> Procedures = new ConcurrentDictionary<Tuple<int, int>, object>();

		private static readonly SyncProcedure Freeproc = Callback;

		public static void Add(int Handle, int SpecificHandle, object proc)
		{
			if (proc != null && !proc.Equals(Freeproc))
			{
				Tuple<int, int> key = Tuple.Create(Handle, SpecificHandle);
				bool num = Procedures.ContainsKey(key);
				if (Freeproc != null && Procedures.All((KeyValuePair<Tuple<int, int>, object> pair) => pair.Key.Item1 != Handle))
				{
					Bass.ChannelSetSync(Handle, SyncFlags.Free, 0L, Freeproc, (IntPtr)0);
				}
				if (num)
				{
					Procedures[key] = proc;
				}
				else
				{
					Procedures.TryAdd(key, proc);
				}
			}
		}

		public static void Remove(int Handle, int SpecialHandle)
		{
			Tuple<int, int> key = Tuple.Create(Handle, SpecialHandle);
			Procedures.TryRemove(key, out var _);
		}

		private static void Callback(int Handle, int Channel, int Data, IntPtr User)
		{
			Tuple<int, int>[] array = (from Pair in Procedures
				where Pair.Key.Item1 == Channel
				select Pair.Key).ToArray();
			foreach (Tuple<int, int> key in array)
			{
				Procedures.TryRemove(key, out var _);
			}
		}
	}
	public enum Resolution
	{
		Short,
		Byte,
		Float
	}
	internal class StreamFileProcedures : FileProcedures
	{
		private readonly Stream _stream;

		private byte[] b;

		public StreamFileProcedures(Stream InputStream)
		{
			_stream = InputStream;
			if (!_stream.CanRead)
			{
				throw new ArgumentException("Provide a readable stream", "InputStream");
			}
			Close = delegate
			{
				_stream.Dispose();
			};
			Length = (IntPtr M) => _stream.Length;
			Read = ReadProc;
			Seek = SeekProc;
		}

		private int ReadProc(IntPtr Buffer, int Length, IntPtr User)
		{
			try
			{
				if (b == null || b.Length < Length)
				{
					b = new byte[Length];
				}
				int num = _stream.Read(b, 0, Length);
				Marshal.Copy(b, 0, Buffer, num);
				return num;
			}
			catch
			{
				return 0;
			}
		}

		private bool SeekProc(long Offset, IntPtr User)
		{
			if (!_stream.CanSeek)
			{
				return false;
			}
			try
			{
				_stream.Seek(Offset, SeekOrigin.Current);
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
	public class ID3v2Tag
	{
		private enum TextEncodings
		{
			Ascii,
			Utf16,
			Utf16Be,
			Utf8
		}

		private IntPtr _ptr;

		private readonly Version _versionInfo;

		public Dictionary<string, string> TextFrames { get; } = new Dictionary<string, string>();


		public List<PictureTag> PictureFrames { get; } = new List<PictureTag>();


		public ID3v2Tag(IntPtr Pointer)
		{
			_ptr = Pointer;
			if (ReadText(3, TextEncodings.Ascii) != "ID3")
			{
				throw new DataMisalignedException("ID3v2 info not found");
			}
			_versionInfo = new Version(2, ReadByte(), ReadByte());
			_ptr += 1;
			ReadAllFrames(ReadSize());
		}

		public ID3v2Tag(int Channel)
			: this(Bass.ChannelGetTags(Channel, TagType.ID3v2))
		{
		}

		private void ReadAllFrames(int Length)
		{
			int num = ((_versionInfo.Minor == 2) ? 3 : 4);
			while (Length > 10)
			{
				if (ReadByte() == 0)
				{
					Length--;
					continue;
				}
				_ptr -= 1;
				string frameID = ReadText(num, TextEncodings.Ascii);
				int val = Convert.ToInt32(ReadUInt(num));
				if (num == 4)
				{
					ReadUInt(2);
				}
				val = Math.Min(val, Length - 10);
				if (!AddFrame(frameID, val))
				{
					_ptr += val;
				}
				Length -= val + 10;
			}
		}

		private bool AddFrame(string FrameID, int Length)
		{
			if (FrameID == null || !IsValidFrameID(FrameID))
			{
				return false;
			}
			if (FrameID[0] == 'T' || FrameID[0] == 'W')
			{
				TextEncodings textEncodings;
				if (FrameID[0] == 'W')
				{
					textEncodings = TextEncodings.Ascii;
				}
				else
				{
					textEncodings = (TextEncodings)ReadByte();
					Length--;
					if (!Enum.IsDefined(typeof(TextEncodings), textEncodings))
					{
						return false;
					}
				}
				string value = ReadText(Length, textEncodings);
				AddTextFrame(FrameID, value);
				return true;
			}
			switch (FrameID)
			{
			case "POPM":
			{
				ReadText(Length, TextEncodings.Ascii, ref Length, DetectEncoding: true);
				string value2 = ReadByte().ToString();
				if (--Length > 8)
				{
					return false;
				}
				_ptr += Length;
				AddTextFrame("POPM", value2);
				return true;
			}
			case "COM":
			case "COMM":
			{
				TextEncodings textEncodings3 = (TextEncodings)ReadByte();
				Length--;
				if (!Enum.IsDefined(typeof(TextEncodings), textEncodings3))
				{
					return false;
				}
				_ptr += 3;
				Length -= 3;
				ReadText(Length, textEncodings3, ref Length, DetectEncoding: true);
				AddTextFrame("COMM", ReadText(Length, textEncodings3));
				return true;
			}
			case "APIC":
			{
				TextEncodings textEncodings2 = (TextEncodings)ReadByte();
				Length--;
				if (!Enum.IsDefined(typeof(TextEncodings), textEncodings2))
				{
					return false;
				}
				string mimeType = ReadText(Length, TextEncodings.Ascii, ref Length, DetectEncoding: true);
				PictureTypes pictureType = (PictureTypes)ReadByte();
				Length--;
				ReadText(Length, textEncodings2, ref Length, DetectEncoding: true);
				byte[] array = new byte[Length];
				Read(array, 0, Length);
				PictureFrames.Add(new PictureTag
				{
					Data = array,
					MimeType = mimeType,
					PictureType = pictureType
				});
				return true;
			}
			default:
				return false;
			}
		}

		private static bool IsValidFrameID(string FrameID)
		{
			if (FrameID == null || (FrameID.Length != 3 && FrameID.Length != 4))
			{
				return false;
			}
			return FrameID.Cast<char>().All((char ch) => char.IsUpper(ch) || char.IsDigit(ch));
		}

		private void AddTextFrame(string Key, string Value)
		{
			if (TextFrames.ContainsKey(Key))
			{
				Dictionary<string, string> textFrames = TextFrames;
				textFrames[Key] = textFrames[Key] + ";" + Value;
			}
			else
			{
				TextFrames.Add(Key, Value);
			}
		}

		private string ReadText(int MaxLength, TextEncodings TEncoding)
		{
			int ReadedLength = 0;
			return ReadText(MaxLength, TEncoding, ref ReadedLength, DetectEncoding: false);
		}

		private string ReadText(int MaxLength, TextEncodings TEncoding, ref int ReadedLength, bool DetectEncoding)
		{
			if (MaxLength <= 0)
			{
				return "";
			}
			int num = 0;
			using MemoryStream memoryStream = new MemoryStream();
			if (DetectEncoding && MaxLength >= 3)
			{
				byte[] array = new byte[3];
				Read(array, 0, array.Length);
				if (array[0] == byte.MaxValue && array[1] == 254)
				{
					TEncoding = TextEncodings.Utf16;
					_ptr -= 1;
					num++;
					MaxLength -= 2;
				}
				else if (array[0] == 254 && array[1] == byte.MaxValue)
				{
					TEncoding = TextEncodings.Utf16Be;
					_ptr -= 1;
					num++;
					MaxLength -= 2;
				}
				else if (array[0] == 239 && array[1] == 187 && array[2] == 191)
				{
					TEncoding = TextEncodings.Utf8;
					MaxLength -= 3;
				}
				_ptr -= 3;
				num += 3;
			}
			bool flag = TEncoding == TextEncodings.Utf16 || TEncoding == TextEncodings.Utf16Be;
			while (MaxLength > 0)
			{
				byte b = ReadByte();
				if (b != 0)
				{
					memoryStream.WriteByte(b);
				}
				else
				{
					if (!flag)
					{
						break;
					}
					byte b2 = ReadByte();
					if (b2 == 0)
					{
						break;
					}
					memoryStream.WriteByte(b);
					memoryStream.WriteByte(b2);
					MaxLength--;
				}
				MaxLength--;
			}
			if (MaxLength < 0)
			{
				_ptr += MaxLength;
			}
			ReadedLength -= num;
			return GetEncoding(TEncoding).GetString(memoryStream.ToArray(), 0, (int)memoryStream.Length);
		}

		private byte ReadByte()
		{
			byte[] array = new byte[1];
			Read(array, 0, 1);
			return array[0];
		}

		private uint ReadUInt(int Length)
		{
			if (Length > 4 || Length < 1)
			{
				throw new ArgumentOutOfRangeException("Length", "ReadUInt method can read 1-4 byte(s)");
			}
			byte[] array = new byte[Length];
			byte[] array2 = new byte[4];
			Read(array, 0, Length);
			array.CopyTo(array2, 4 - array.Length);
			Array.Reverse((Array)array2);
			return BitConverter.ToUInt32(array2, 0);
		}

		private int ReadSize()
		{
			return ReadByte() * 2097152 + ReadByte() * 16384 + ReadByte() * 128 + ReadByte();
		}

		private static Encoding GetEncoding(TextEncodings TEncoding)
		{
			return TEncoding switch
			{
				TextEncodings.Utf16 => Encoding.Unicode, 
				TextEncodings.Utf16Be => Encoding.GetEncoding("UTF-16BE"), 
				_ => Encoding.UTF8, 
			};
		}

		private void Read(byte[] Buffer, int Offset, int Count)
		{
			Marshal.Copy(_ptr, Buffer, Offset, Count);
			_ptr += Count;
		}
	}
	public class PictureTag
	{
		public string MimeType;

		public PictureTypes PictureType;

		public byte[] Data;
	}
	public enum PictureTypes
	{
		Other,
		FileIcon,
		OtherFileIcon,
		FrontCover,
		BackCover,
		LeafletPage,
		Media,
		Soloist,
		Artist,
		Conductor,
		Band,
		Composer,
		Lyricist,
		RecordingLocation,
		DuringRecording,
		DuringPerformance,
		Movie,
		ABrightColouredFish,
		Illustration,
		BandLogo,
		PublisherLogo
	}
	internal static class LookupTables
	{
		public static readonly TagProperties<IEnumerable<string>> Ape = new TagProperties<IEnumerable<string>>
		{
			Title = new string[1] { "title" },
			Artist = new string[1] { "artist" },
			Album = new string[1] { "album" },
			AlbumArtist = new string[1] { "album artist" },
			Track = new string[1] { "track" },
			Year = new string[1] { "year" },
			Genre = new string[1] { "genre" },
			Copyright = new string[1] { "copyright" },
			Encoder = new string[1] { "encodedby" },
			Publisher = new string[1] { "label" },
			Composer = new string[1] { "composer" },
			Conductor = new string[1] { "conductor" },
			Lyricist = new string[1] { "lyricist" },
			Remixer = new string[1] { "remixer" },
			Producer = new string[1] { "producer" },
			Comment = new string[1] { "comment" },
			Grouping = new string[1] { "grouping" },
			Mood = new string[1] { "mood" },
			Rating = new string[1] { "rating" },
			ISRC = new string[1] { "isrc" },
			BPM = new string[1] { "bpm" }
		};

		public static readonly TagProperties<IEnumerable<string>> Ogg = new TagProperties<IEnumerable<string>>
		{
			Title = new string[1] { "title" },
			Artist = new string[1] { "artist" },
			Album = new string[1] { "album" },
			AlbumArtist = new string[1] { "albumartist" },
			Track = new string[1] { "tracknumber" },
			Year = new string[1] { "date" },
			Genre = new string[1] { "genre" },
			Copyright = new string[1] { "copyright" },
			Encoder = new string[1] { "encodedby" },
			Publisher = new string[1] { "label" },
			Composer = new string[1] { "composer" },
			Conductor = new string[1] { "conductor" },
			Lyricist = new string[1] { "lyricist" },
			Remixer = new string[1] { "remixer" },
			Producer = new string[1] { "producer" },
			Comment = new string[1] { "comment" },
			Grouping = new string[1] { "grouping" },
			Mood = new string[1] { "mood" },
			Rating = new string[1] { "rating" },
			ISRC = new string[1] { "isrc" },
			BPM = new string[1] { "bpm" }
		};

		public static readonly TagProperties<IEnumerable<string>> RiffInfo = new TagProperties<IEnumerable<string>>
		{
			Title = new string[1] { "inam" },
			Artist = new string[1] { "iart" },
			Album = new string[1] { "iprd" },
			AlbumArtist = new string[1] { "isbj" },
			Track = new string[2] { "itrk", "iprt" },
			Year = new string[1] { "icrd" },
			Genre = new string[1] { "ignr" },
			Copyright = new string[1] { "icop" },
			Encoder = new string[1] { "isft" },
			Publisher = new string[1] { "icms" },
			Composer = new string[1] { "ieng" },
			Conductor = new string[1] { "itch" },
			Lyricist = new string[1] { "iwri" },
			Remixer = new string[1] { "iedt" },
			Producer = new string[1] { "ipro" },
			Comment = new string[1] { "icmt" },
			Grouping = new string[1] { "isrf" },
			Mood = new string[1] { "ikey" },
			Rating = new string[1] { "ishp" },
			ISRC = new string[1] { "isrc" },
			BPM = new string[1] { "ibpm" }
		};

		public static readonly TagProperties<IEnumerable<string>> Mp4 = new TagProperties<IEnumerable<string>>
		{
			Title = new string[1] { "©nam" },
			Artist = new string[1] { "©art" },
			Album = new string[1] { "©alb" },
			AlbumArtist = new string[1] { "aart" },
			Track = new string[1] { "trkn" },
			Year = new string[1] { "©day" },
			Genre = new string[1] { "©gen" },
			Copyright = new string[1] { "cprt" },
			Encoder = new string[1] { "©too" },
			Composer = new string[1] { "©wrt" },
			Comment = new string[1] { "©cmt" },
			Grouping = new string[1] { "©grp" },
			Rating = new string[1] { "rtng" }
		};

		public static readonly TagProperties<IEnumerable<string>> Id3v2 = new TagProperties<IEnumerable<string>>
		{
			Title = new string[2] { "TIT2", "TT2" },
			Artist = new string[2] { "TPE1", "TP1" },
			Album = new string[2] { "TALB", "TAL" },
			AlbumArtist = new string[2] { "TPE2", "TP2" },
			Subtitle = new string[2] { "TIT3", "TT3" },
			Track = new string[2] { "TRK", "TRCK" },
			Year = new string[2] { "TYER", "TYE" },
			Genre = new string[2] { "TCON", "TCO" },
			Copyright = new string[2] { "TCOP", "TCR" },
			Encoder = new string[2] { "TENC", "TEN" },
			Publisher = new string[2] { "TPUB", "TPB" },
			Composer = new string[2] { "TCOM", "TCM" },
			Conductor = new string[2] { "TPE3", "TP3" },
			Lyricist = new string[2] { "TEXT", "TXT" },
			Remixer = new string[2] { "TPE4", "TP4" },
			Producer = new string[1] { "TIPL" },
			Comment = new string[2] { "COMM", "COM" },
			Grouping = new string[2] { "TIT1", "TT1" },
			Mood = new string[1] { "TMOO" },
			Rating = new string[1] { "POPM" },
			ISRC = new string[1] { "TSCR" },
			BPM = new string[2] { "TBPM", "TBP" }
		};
	}
	public class TagProperties<T>
	{
		public T Title { get; set; }

		public T Artist { get; set; }

		public T Album { get; set; }

		public T AlbumArtist { get; set; }

		public T Subtitle { get; set; }

		public T BPM { get; set; }

		public T Composer { get; set; }

		public T Copyright { get; set; }

		public T Genre { get; set; }

		public T Grouping { get; set; }

		public T Publisher { get; set; }

		public T Encoder { get; set; }

		public T Lyricist { get; set; }

		public T Year { get; set; }

		public T Conductor { get; set; }

		public T Track { get; set; }

		public T Producer { get; set; }

		public T Comment { get; set; }

		public T Mood { get; set; }

		public T Rating { get; set; }

		public T ISRC { get; set; }

		public T Remixer { get; set; }
	}
	public sealed class TagReader : TagProperties<string>
	{
		public Dictionary<string, string> Other { get; } = new Dictionary<string, string>();


		public List<PictureTag> Pictures { get; } = new List<PictureTag>();


		public string Lyrics { get; set; }

		public static TagReader Read(string FileName)
		{
			Bass.Init(-1, 44100, DeviceInitFlags.Default, (IntPtr)0, (IntPtr)0);
			int num = Bass.CreateStream(FileName, 0L, 0L, BassFlags.Prescan);
			TagReader tagReader = null;
			if (num != 0)
			{
				tagReader = Read(num);
				Bass.StreamFree(num);
			}
			else
			{
				num = Bass.MusicLoad(FileName, 0L, 0, BassFlags.Prescan);
				if (num != 0)
				{
					tagReader = Read(num);
					Bass.MusicFree(num);
				}
			}
			if (!string.IsNullOrWhiteSpace(tagReader?.Title))
			{
				tagReader.Title = Path.GetFileNameWithoutExtension(FileName);
			}
			return tagReader;
		}

		public static TagReader Read(int Channel)
		{
			TagReader tagReader = new TagReader();
			switch (Bass.ChannelGetInfo(Channel).ChannelType)
			{
			case ChannelType.MP1:
			case ChannelType.MP2:
			case ChannelType.MP3:
				if (!tagReader.ReadID3v2(Channel) && !tagReader.ReadID3v1(Channel) && !tagReader.ReadApe(Channel) && !tagReader.ReadBWF(Channel))
				{
				}
				break;
			case ChannelType.OGG:
				if (!tagReader.ReadOgg(Channel) && !tagReader.ReadApe(Channel))
				{
				}
				break;
			case ChannelType.AAC:
			case ChannelType.MP4:
				if (!tagReader.ReadMp4(Channel) && !tagReader.ReadID3v2(Channel) && !tagReader.ReadApe(Channel) && !tagReader.ReadOgg(Channel))
				{
				}
				break;
			case ChannelType.Wave:
			case ChannelType.WavePCM:
			case ChannelType.WaveFloat:
				if (!tagReader.ReadRiffInfo(Channel) && !tagReader.ReadBWF(Channel) && !tagReader.ReadID3v2(Channel))
				{
				}
				break;
			case ChannelType.DSD:
				tagReader.Title = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.DSDTitle));
				tagReader.Artist = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.DSDArtist));
				break;
			case ChannelType.MOD:
				tagReader.Title = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.MusicName));
				tagReader.Artist = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.MusicAuth));
				tagReader.Comment = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.MusicMessage));
				break;
			default:
				if (!tagReader.ReadApe(Channel) && !tagReader.ReadOgg(Channel) && !tagReader.ReadID3v2(Channel))
				{
					tagReader.ReadID3v1(Channel);
				}
				break;
			}
			if (string.IsNullOrWhiteSpace(tagReader.Lyrics))
			{
				IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.Lyrics3v2);
				if (intPtr != IntPtr.Zero)
				{
					tagReader.Lyrics = Marshal.PtrToStringAnsi(intPtr);
				}
			}
			return tagReader;
		}

		private IEnumerable<KeyValuePair<string, string>> ReadUsingLookupTable(IEnumerable<string> Tags, TagProperties<IEnumerable<string>> LookupTable, char Separator)
		{
			foreach (string Tag in Tags)
			{
				string[] array = Tag.Split(new char[1] { Separator });
				string key = array[0].ToLower();
				string value = array[1];
				if (!SetTagUsingLookupTable(key, value, LookupTable))
				{
					yield return new KeyValuePair<string, string>(array[0], value);
				}
			}
		}

		private bool SetTagUsingLookupTable(string Key, string Value, TagProperties<IEnumerable<string>> LookupTable)
		{
			if (LookupTable.Title != null && LookupTable.Title.Contains(Key))
			{
				base.Title = Value;
			}
			else if (LookupTable.Artist != null && LookupTable.Artist.Contains(Key))
			{
				base.Artist = Value;
			}
			else if (LookupTable.Album != null && LookupTable.Album.Contains(Key))
			{
				base.Album = Value;
			}
			else if (LookupTable.AlbumArtist != null && LookupTable.AlbumArtist.Contains(Key))
			{
				base.AlbumArtist = Value;
			}
			else if (LookupTable.Subtitle != null && LookupTable.Subtitle.Contains(Key))
			{
				base.Subtitle = Value;
			}
			else if (LookupTable.BPM != null && LookupTable.BPM.Contains(Key))
			{
				base.BPM = Value;
			}
			else if (LookupTable.Composer != null && LookupTable.Composer.Contains(Key))
			{
				base.Composer = Value;
			}
			else if (LookupTable.Copyright != null && LookupTable.Copyright.Contains(Key))
			{
				base.Copyright = Value;
			}
			else if (LookupTable.Genre != null && LookupTable.Genre.Contains(Key))
			{
				base.Genre = Value;
			}
			else if (LookupTable.Grouping != null && LookupTable.Grouping.Contains(Key))
			{
				base.Grouping = Value;
			}
			else if (LookupTable.Publisher != null && LookupTable.Publisher.Contains(Key))
			{
				base.Publisher = Value;
			}
			else if (LookupTable.Encoder != null && LookupTable.Encoder.Contains(Key))
			{
				base.Encoder = Value;
			}
			else if (LookupTable.Lyricist != null && LookupTable.Lyricist.Contains(Key))
			{
				base.Lyricist = Value;
			}
			else if (LookupTable.Year != null && LookupTable.Year.Contains(Key))
			{
				base.Year = Value;
			}
			else if (LookupTable.Conductor != null && LookupTable.Conductor.Contains(Key))
			{
				base.Conductor = Value;
			}
			else if (LookupTable.Track != null && LookupTable.Track.Contains(Key))
			{
				base.Track = Value;
			}
			else if (LookupTable.Producer != null && LookupTable.Producer.Contains(Key))
			{
				base.Producer = Value;
			}
			else if (LookupTable.Comment != null && LookupTable.Comment.Contains(Key))
			{
				base.Comment = Value;
			}
			else if (LookupTable.Mood != null && LookupTable.Mood.Contains(Key))
			{
				base.Mood = Value;
			}
			else if (LookupTable.Rating != null && LookupTable.Rating.Contains(Key))
			{
				base.Rating = Value;
			}
			else if (LookupTable.ISRC != null && LookupTable.ISRC.Contains(Key))
			{
				base.ISRC = Value;
			}
			else
			{
				if (LookupTable.Remixer == null || !LookupTable.Remixer.Contains(Key))
				{
					return false;
				}
				base.Remixer = Value;
			}
			return true;
		}

		public bool ReadApe(int Channel)
		{
			IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.APE);
			if (intPtr == IntPtr.Zero)
			{
				return false;
			}
			foreach (KeyValuePair<string, string> item in ReadUsingLookupTable(Extensions.ExtractMultiStringUtf8(intPtr), LookupTables.Ape, '='))
			{
				Other.Add(item.Key, item.Value);
			}
			return true;
		}

		public bool ReadOgg(int Channel)
		{
			IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.OGG);
			if (intPtr == IntPtr.Zero)
			{
				return false;
			}
			foreach (KeyValuePair<string, string> item in ReadUsingLookupTable(Extensions.ExtractMultiStringUtf8(intPtr), LookupTables.Ogg, '='))
			{
				Other.Add(item.Key, item.Value);
			}
			if (string.IsNullOrWhiteSpace(base.Encoder))
			{
				IntPtr intPtr2 = Bass.ChannelGetTags(Channel, TagType.OggEncoder);
				if (intPtr2 != IntPtr.Zero)
				{
					base.Encoder = Extensions.PtrToStringUtf8(intPtr2);
				}
			}
			return true;
		}

		public bool ReadRiffInfo(int Channel)
		{
			IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.RiffInfo);
			if (intPtr == IntPtr.Zero)
			{
				return false;
			}
			foreach (KeyValuePair<string, string> item in ReadUsingLookupTable(Extensions.ExtractMultiStringAnsi(intPtr), LookupTables.RiffInfo, '='))
			{
				Other.Add(item.Key, item.Value);
			}
			return true;
		}

		public bool ReadMp4(int Channel)
		{
			IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.MP4);
			if (intPtr == IntPtr.Zero)
			{
				return false;
			}
			foreach (KeyValuePair<string, string> item in ReadUsingLookupTable(Extensions.ExtractMultiStringUtf8(intPtr), LookupTables.Mp4, '='))
			{
				Other.Add(item.Key, item.Value);
			}
			return true;
		}

		public bool ReadID3v1(int Channel)
		{
			IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.ID3);
			if (intPtr == IntPtr.Zero)
			{
				return false;
			}
			ID3v1Tag iD3v1Tag = Marshal.PtrToStructure<ID3v1Tag>(intPtr);
			base.Title = iD3v1Tag.Title;
			base.Artist = iD3v1Tag.Artist;
			base.Album = iD3v1Tag.Album;
			base.Year = iD3v1Tag.Year;
			base.Genre = iD3v1Tag.Genre;
			base.Track = iD3v1Tag.TrackNo.ToString();
			base.Comment = iD3v1Tag.Comment;
			return true;
		}

		public bool ReadID3v2(int Channel)
		{
			IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.ID3v2);
			if (intPtr == IntPtr.Zero)
			{
				return false;
			}
			ID3v2Tag iD3v2Tag = new ID3v2Tag(intPtr);
			foreach (KeyValuePair<string, string> textFrame in iD3v2Tag.TextFrames)
			{
				if (!SetTagUsingLookupTable(textFrame.Key, textFrame.Value, LookupTables.Id3v2))
				{
					Other.Add(textFrame.Key, textFrame.Value);
				}
			}
			Pictures.AddRange(iD3v2Tag.PictureFrames);
			return true;
		}

		public bool ReadBWF(int Channel)
		{
			IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.RiffBext);
			if (intPtr == IntPtr.Zero)
			{
				return false;
			}
			BextTag bextTag = Marshal.PtrToStructure<BextTag>(intPtr);
			base.Title = bextTag.Description;
			base.Artist = bextTag.Originator;
			base.Encoder = bextTag.OriginatorReference;
			base.Year = bextTag.OriginationDate.Split(new char[1] { '-' })[0];
			return true;
		}
	}
	[StructLayout(LayoutKind.Sequential)]
	public class BextTag
	{
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
		public string Description;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		public string Originator;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		public string OriginatorReference;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
		public string OriginationDate;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
		public string OriginationTime;

		public long TimeReference;

		public short Version;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
		public byte[] UMID;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 190)]
		private byte[] reserved;

		private IntPtr codinghistory;

		public DateTime OriginationDateTime
		{
			get
			{
				int year = int.Parse(OriginationDate.Substring(0, 4));
				int month = int.Parse(OriginationDate.Substring(5, 2));
				int day = int.Parse(OriginationDate.Substring(8, 2));
				int hour = int.Parse(OriginationTime.Substring(0, 2));
				int minute = int.Parse(OriginationTime.Substring(3, 2));
				int second = int.Parse(OriginationTime.Substring(6, 2));
				return new DateTime(year, month, day, hour, minute, second);
			}
		}

		public string CodingHistory
		{
			get
			{
				if (!(codinghistory == IntPtr.Zero))
				{
					return Marshal.PtrToStringAnsi(codinghistory);
				}
				return null;
			}
		}

		public static BextTag Read(int Channel)
		{
			return Marshal.PtrToStructure<BextTag>(Bass.ChannelGetTags(Channel, TagType.RiffBext));
		}
	}
	[StructLayout(LayoutKind.Sequential)]
	public class CACodecTag
	{
		public int ftype;

		public int atype;

		private IntPtr name;

		public string Name
		{
			get
			{
				if (!(name == IntPtr.Zero))
				{
					return Marshal.PtrToStringAnsi(name);
				}
				return null;
			}
		}

		public static CACodecTag Read(int Channel)
		{
			return Marshal.PtrToStructure<CACodecTag>(Bass.ChannelGetTags(Channel, TagType.WmaMeta));
		}
	}
	[StructLayout(LayoutKind.Sequential)]
	public class CartTimer
	{
		public int Usage;

		public int Value;
	}
	[StructLayout(LayoutKind.Sequential)]
	public class CartTag
	{
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
		public string Version;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string Title;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string Artist;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string CutID;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string ClientID;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string Category;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string Classification;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string OutCue;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
		private string startDate;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
		private string startTime;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
		private string endDate;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
		private string endTime;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string ProducerAppID;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string ProducerAppVersion;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string UserDef;

		public int dwLevelReference;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
		public CartTimer[] PostTimer;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 276)]
		private char[] Reserved;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
		public string URL;

		private IntPtr tagText;

		public string TagText
		{
			get
			{
				if (!(tagText == IntPtr.Zero))
				{
					return Marshal.PtrToStringAnsi(tagText);
				}
				return null;
			}
		}

		public DateTime StartTime
		{
			get
			{
				string[] array = startDate.Split(new char[1] { '-' });
				string[] array2 = startTime.Split(new char[1] { ':' });
				return new DateTime(int.Parse(array[0]), int.Parse(array[1]), int.Parse(array[2]), int.Parse(array2[0]), int.Parse(array2[1]), int.Parse(array2[2]));
			}
		}

		public DateTime EndTime
		{
			get
			{
				string[] array = endDate.Split(new char[1] { '-' });
				string[] array2 = endTime.Split(new char[1] { ':' });
				return new DateTime(int.Parse(array[0]), int.Parse(array[1]), int.Parse(array[2]), int.Parse(array2[0]), int.Parse(array2[1]), int.Parse(array2[2]));
			}