Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ManagedBass v4.0.200
BepInEx/core/ManagedBass/netstandard2.0/ManagedBass.dll
Decompiled 5 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; 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.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("MathewSachin")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription(".Net wrapper for un4seen BASS audio library")] [assembly: AssemblyFileVersion("4.0.2.0")] [assembly: AssemblyInformationalVersion("4.0.2+ea1a86cd138f66f7fadbe4e7a822fe4ceba933c8")] [assembly: AssemblyProduct("ManagedBass")] [assembly: AssemblyTitle("ManagedBass")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ManagedBass/ManagedBass")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.0.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ManagedBass { 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, BassLoudnessCurrent = 0u, BassLoudnessIntegrated = 1u, BassLoudnessRange = 2u, BassLoudnessPeak = 4u, BassLoudnessTruePeak = 8u, BassLoudnessAutofree = 0x8000u, 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 DSInterface { IDirectSound = 1, IDirectSound3DListener } public enum DXPhase { Negative180, Negative90, Zero, Positive90, Positive180 } public enum DXWaveform { Triangle, Sine } 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 enum EffectType { DXChorus = 0, DXDistortion = 1, DXEcho = 2, DXFlanger = 3, DXCompressor = 4, DXGargle = 5, DX_I3DL2Reverb = 6, DXParamEQ = 7, DXReverb = 8, Volume = 9, Rotate = 65536, VolumeBfx = 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; private static readonly IOSNotifyProcedure iosnproc = delegate(IOSNotify status) { Bass._iosnotify?.Invoke(status); }; 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; } } public static IOSMixAudioFlags IOSMixAudio { get { return (IOSMixAudioFlags)GetConfig(Configuration.IOSMixAudio); } set { Configure(Configuration.IOSMixAudio, (int)value); } } public static bool IOSNoCategory { get { return GetConfigBool(Configuration.IOSNoCategory); } set { Configure(Configuration.IOSNoCategory, value); } } public static bool IOSSpeaker { get { return GetConfigBool(Configuration.IOSSpeaker); } set { Configure(Configuration.IOSSpeaker, value); } } public static bool VistaTruePlayPosition { get { return GetConfigBool(Configuration.TruePlayPosition); } set { Configure(Configuration.TruePlayPosition, value); } } public static bool IncludeDefaultDevice { get { return GetConfigBool(Configuration.IncludeDefaultDevice); } set { Configure(Configuration.IncludeDefaultDevice, value); } } public static bool VistaSpeakerAssignment { get { return GetConfigBool(Configuration.VistaSpeakerAssignment); } set { Configure(Configuration.VistaSpeakerAssignment, value); } } public static bool UnicodeDeviceInformation { get { return GetConfigBool(Configuration.UnicodeDeviceInformation); } set { Configure(Configuration.UnicodeDeviceInformation, value); } } public static bool MFVideo { get { return GetConfigBool(Configuration.MFVideo); } set { Configure(Configuration.MFVideo, value); } } public static bool NoTimerResolution { get { return GetConfigBool(Configuration.NoTimerResolution); } set { Configure(Configuration.NoTimerResolution, value); } } private static event IOSNotifyProcedure _iosnotify; public static event IOSNotifyProcedure IOSNotification { add { if (Bass._iosnotify == null) { Configure(Configuration.IOSNotify, Marshal.GetFunctionPointerForDelegate(iosnproc)); } _iosnotify += value; } remove { _iosnotify -= value; if (Bass._iosnotify == null) { Configure(Configuration.IOSNotify, IntPtr.Zero); } } } [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 BassMarshal.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); [DllImport("bass", EntryPoint = "BASS_GetDSoundObject")] public static extern IntPtr GetDSoundObject(DSInterface obj); [DllImport("bass", EntryPoint = "BASS_GetDSoundObject")] public static extern IntPtr GetDSoundObject(int Channel); [DllImport("bass", EntryPoint = "BASS_GetEAXParameters")] public static extern bool GetEAXParameters(ref EAXEnvironment Environment, ref float Volume, ref float Decay, ref float Damp); public static bool SetEAXPreset(EAXEnvironment Environment) { return Environment switch { EAXEnvironment.Generic => SetEAXParameters(Environment, 0.5f, 1.493f, 0.5f), EAXEnvironment.PaddedCell => SetEAXParameters(Environment, 0.25f, 0.1f, 0f), EAXEnvironment.Room => SetEAXParameters(Environment, 0.417f, 0.4f, 0.666f), EAXEnvironment.Bathroom => SetEAXParameters(Environment, 0.653f, 1.499f, 0.166f), EAXEnvironment.Livingroom => SetEAXParameters(Environment, 0.208f, 0.478f, 0f), EAXEnvironment.Stoneroom => SetEAXParameters(Environment, 0.5f, 2.309f, 0.888f), EAXEnvironment.Auditorium => SetEAXParameters(Environment, 0.403f, 4.279f, 0.5f), EAXEnvironment.ConcertHall => SetEAXParameters(Environment, 0.5f, 3.961f, 0.5f), EAXEnvironment.Cave => SetEAXParameters(Environment, 0.5f, 2.886f, 1.304f), EAXEnvironment.Arena => SetEAXParameters(Environment, 0.361f, 7.284f, 0.332f), EAXEnvironment.Hangar => SetEAXParameters(Environment, 0.5f, 10f, 0.3f), EAXEnvironment.CarpetedHallway => SetEAXParameters(Environment, 0.153f, 0.259f, 2f), EAXEnvironment.Hallway => SetEAXParameters(Environment, 0.361f, 1.493f, 0f), EAXEnvironment.StoneCorridor => SetEAXParameters(Environment, 0.444f, 2.697f, 0.638f), EAXEnvironment.Alley => SetEAXParameters(Environment, 0.25f, 1.752f, 0.776f), EAXEnvironment.Forest => SetEAXParameters(Environment, 0.111f, 3.145f, 0.472f), EAXEnvironment.City => SetEAXParameters(Environment, 0.111f, 2.767f, 0.224f), EAXEnvironment.Mountains => SetEAXParameters(Environment, 0.194f, 7.841f, 0.472f), EAXEnvironment.Quarry => SetEAXParameters(Environment, 1f, 1.499f, 0.5f), EAXEnvironment.Plain => SetEAXParameters(Environment, 0.097f, 2.767f, 0.224f), EAXEnvironment.ParkingLot => SetEAXParameters(Environment, 0.208f, 1.652f, 1.5f), EAXEnvironment.SewerPipe => SetEAXParameters(Environment, 0.652f, 2.886f, 0.25f), EAXEnvironment.Underwater => SetEAXParameters(Environment, 1f, 1.499f, 0f), EAXEnvironment.Drugged => SetEAXParameters(Environment, 0.875f, 8.392f, 1.388f), EAXEnvironment.Dizzy => SetEAXParameters(Environment, 0.139f, 17.234f, 0.666f), EAXEnvironment.Psychotic => SetEAXParameters(Environment, 0.486f, 7.563f, 0.806f), _ => false, }; } [DllImport("bass", EntryPoint = "BASS_SetEAXParameters")] public static extern bool SetEAXParameters(EAXEnvironment Environment, float Volume, float Decay, float Damp); } 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 = BassMarshal.SizeOf<PluginFormat>(); int num2 = 0; while (num2 < formatc) { array[num2] = BassMarshal.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 class BassException : Exception { public Errors ErrorCode { get; } public BassException() : this(Bass.LastError) { } public BassException(Errors ErrorCode) : base($"Error: {ErrorCode}") { this.ErrorCode = ErrorCode; } } public static class BassMarshal { public static T PtrToStructure<T>(IntPtr ptr) { return Marshal.PtrToStructure<T>(ptr); } public static int SizeOf<T>() { return Marshal.SizeOf<T>(); } public static int SizeOf(object obj) { return Marshal.SizeOf(obj); } } 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 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 (CrossPlatformHelper.IsDynamicCodeSupported && 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) { if (CrossPlatformHelper.IsDynamicCodeSupported) { 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 static class CrossPlatformHelper { public static bool IsDynamicCodeSupported => true; } 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 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 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 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); } } [Flags] public enum IOSMixAudioFlags { MixWithOthers = 1, OtherMixableAudioShouldDuck = 2, AmbientSound = 4, Speaker = 8, Disable = 0x10 } public enum IOSNotify { Interrupt = 1, InterruptEnd } public delegate void IOSNotifyProcedure(IOSNotify Status); 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> { [CompilerGenerated] private sealed class <ReadUsingLookupTable>d__12 : IEnumerable<KeyValuePair<string, string>>, IEnumerable, IEnumerator<KeyValuePair<string, string>>, IEnumerator, IDisposable { private int <>1__state; private KeyValuePair<string, string> <>2__current; private int <>l__initialThreadId; private IEnumerable<string> Tags; public IEnumerable<string> <>3__Tags; private char Separator; public char <>3__Separator; public TagReader <>4__this; private TagProperties<IEnumerable<string>> LookupTable; public TagProperties<IEnumerable<string>> <>3__LookupTable; private IEnumerator<string> <>7__wrap1; KeyValuePair<string, string> IEnumerator<KeyValuePair<string, string>>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ReadUsingLookupTable>d__12(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; TagReader tagReader = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = Tags.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap1.MoveNext()) { string[] array = <>7__wrap1.Current.Split(new char[1] { Separator }); string key = array[0].ToLower(); string value = array[1]; if (!tagReader.SetTagUsingLookupTable(key, value, LookupTable)) { <>2__current = new KeyValuePair<string, string>(array[0], value); <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator() { <ReadUsingLookupTable>d__12 <ReadUsingLookupTable>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <ReadUsingLookupTable>d__ = this; } else { <ReadUsingLookupTable>d__ = new <ReadUsingLookupTable>d__12(0) { <>4__this = <>4__this }; } <ReadUsingLookupTable>d__.Tags = <>3__Tags; <ReadUsingLookupTable>d__.LookupTable = <>3__LookupTable; <ReadUsingLookupTable>d__.Separator = <>3__Separator; return <ReadUsingLookupTable>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<KeyValuePair<string, string>>)this).GetEnumerator(); } } 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; } [IteratorStateMachine(typeof(<ReadUsingLookupTable>d__12))] private IEnumerable<KeyValuePair<string, string>> ReadUsingLookupTable(