Decompiled source of ManagedBass v3.1.101
BepInEx/core/ManagedBass/netstandard1.4/ManagedBass.dll
Decompiled 6 months ago
The result has been truncated due to the large size, download it to view full contents!
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])); }