using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v1.4", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MathewSachin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription(".Net wrapper for un4seen BASS audio library")]
[assembly: AssemblyFileVersion("3.1.1.0")]
[assembly: AssemblyInformationalVersion("3.1.1")]
[assembly: AssemblyProduct("ManagedBass")]
[assembly: AssemblyTitle("ManagedBass")]
[assembly: AssemblyVersion("3.1.1.0")]
namespace ManagedBass
{
public enum DSInterface
{
IDirectSound = 1,
IDirectSound3DListener
}
public enum EAXEnvironment
{
LeaveCurrent = -1,
Generic,
PaddedCell,
Room,
Bathroom,
Livingroom,
Stoneroom,
Auditorium,
ConcertHall,
Cave,
Arena,
Hangar,
CarpetedHallway,
Hallway,
StoneCorridor,
Alley,
Forest,
City,
Mountains,
Quarry,
Plain,
ParkingLot,
SewerPipe,
Underwater,
Drugged,
Dizzy,
Psychotic,
Count
}
public abstract class Effect<T> : INotifyPropertyChanged, IDisposable where T : class, IEffectParameter, new()
{
private int _channel;
private int _effectHandle;
private int _hfsync;
private GCHandle _gch;
private int _priority;
protected T Parameters { get; private set; } = new T();
public int Priority
{
get
{
return _priority;
}
set
{
if (IsActive && Bass.FXSetPriority(_effectHandle, value))
{
_priority = value;
}
}
}
public bool IsActive
{
get
{
if (_channel != 0)
{
return _effectHandle != 0;
}
return false;
}
set
{
if (_channel != 0)
{
if (value && !IsActive)
{
_effectHandle = Bass.ChannelSetFX(_channel, Parameters.FXType, 1);
}
else if (!value && IsActive && Bass.ChannelRemoveFX(_channel, _effectHandle))
{
_effectHandle = 0;
}
OnPropertyChanged("IsActive");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void ApplyOn(int Channel, int Priority = 0)
{
_channel = Channel;
_priority = Priority;
if (!_gch.IsAllocated)
{
_gch = GCHandle.Alloc(Parameters, GCHandleType.Pinned);
}
_hfsync = Bass.ChannelSetSync(Channel, SyncFlags.Free, 0L, delegate
{
Dispose();
}, (IntPtr)0);
}
public void Dispose()
{
Bass.ChannelRemoveSync(_channel, _hfsync);
_channel = (_effectHandle = 0);
if (_gch.IsAllocated)
{
_gch.Free();
}
}
public void Default()
{
_gch.Free();
Parameters = new T();
_gch = GCHandle.Alloc(Parameters, GCHandleType.Pinned);
OnPreset();
}
protected void OnPreset()
{
OnPropertyChanged("");
}
protected virtual void OnPropertyChanged([CallerMemberName] string PropertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
}
public class GCPin : IDisposable
{
private GCHandle _gcHandle;
public IntPtr Pointer => _gcHandle.AddrOfPinnedObject();
public GCPin(object Item)
{
_gcHandle = GCHandle.Alloc(Item, GCHandleType.Pinned);
}
public static int CreateStreamHelper(Func<IntPtr, int> Function, object Memory)
{
GCHandle GCPin = GCHandle.Alloc(Memory, GCHandleType.Pinned);
int num = Function(GCPin.AddrOfPinnedObject());
if (num == 0)
{
GCPin.Free();
}
else
{
Bass.ChannelSetSync(num, SyncFlags.Free, 0L, delegate
{
GCPin.Free();
}, (IntPtr)0);
}
return num;
}
public void Dispose()
{
_gcHandle.Free();
}
}
public class BassException : Exception
{
public Errors ErrorCode { get; }
public BassException()
: this(Bass.LastError)
{
}
public BassException(Errors ErrorCode)
: base($"Error: {ErrorCode}")
{
this.ErrorCode = ErrorCode;
}
}
public delegate void DownloadProcedure(IntPtr Buffer, int Length, IntPtr User);
public delegate void DSPProcedure(int Handle, int Channel, IntPtr Buffer, int Length, IntPtr User);
public delegate void FileCloseProcedure(IntPtr User);
public delegate long FileLengthProcedure(IntPtr User);
public delegate int FileReadProcedure(IntPtr Buffer, int Length, IntPtr User);
public delegate bool FileSeekProcedure(long Offset, IntPtr User);
public delegate bool RecordProcedure(int Handle, IntPtr Buffer, int Length, IntPtr User);
public delegate int StreamProcedure(int Handle, IntPtr Buffer, int Length, IntPtr User);
public delegate void SyncProcedure(int Handle, int Channel, int Data, IntPtr User);
public enum Algorithm3D
{
Default,
Off,
Full,
Light
}
[Flags]
public enum BassFlags : uint
{
Default = 0u,
Byte = 1u,
Mono = 2u,
Loop = 4u,
Bass3D = 8u,
SoftwareMixing = 0x10u,
FX = 0x80u,
Float = 0x100u,
Prescan = 0x20000u,
AutoFree = 0x40000u,
RestrictDownloadRate = 0x80000u,
StreamDownloadBlocks = 0x100000u,
Decode = 0x200000u,
StreamStatus = 0x800000u,
AsyncFile = 0x40000000u,
Unicode = 0x80000000u,
FxBpmBackground = 1u,
FXBpmMult2 = 2u,
FxTempoAlgorithmLinear = 0x200u,
FxTempoAlgorithmCubic = 0x400u,
FxTempoAlgorithmShannon = 0x800u,
FxFreeSource = 0x10000u,
MidiNoHeader = 1u,
Midi16Bit = 2u,
MidiNoSystemReset = 0x800u,
MidiDecayEnd = 0x1000u,
MidiNoFx = 0x2000u,
MidiDecaySeek = 0x4000u,
MidiNoCrop = 0x8000u,
MidiNoteOff1 = 0x10000u,
MidiFontMemoryMap = 0x20000u,
MidiFontXGDRUMS = 0x40000u,
SincInterpolation = 0x800000u,
MusicRamp = 0x200u,
MusicSensitiveRamping = 0x400u,
MusicSurround = 0x800u,
MusicSurround2 = 0x1000u,
MusicFT2Mod = 0x2000u,
MusicFT2PAN = 0x2000u,
MusicPT1Mod = 0x4000u,
MusicPositionReset = 0x8000u,
MusicNonInterpolated = 0x10000u,
MusicStopBack = 0x80000u,
MusicNoSample = 0x100000u,
MusicPositionResetEx = 0x400000u,
MuteMax = 0x20u,
VAM = 0x40u,
SampleOverrideLowestVolume = 0x10000u,
SampleOverrideLongestPlaying = 0x20000u,
SampleOverrideDistance = 0x30000u,
SampleChannelNew = 1u,
SampleChannelStream = 2u,
CDSubChannel = 0x200u,
CDSubchannelNoHW = 0x400u,
CdC2Errors = 0x800u,
MixerChanAbsolute = 0x1000u,
SplitSlave = 0x1000u,
SplitPosition = 0x2000u,
MixerResume = 0x1000u,
MixerPositionEx = 0x2000u,
MixerChanBuffer = 0x2000u,
[Obsolete("Renamed to MixerChanBuffer for clarity.")]
MixerBuffer = 0x2000u,
MixerChanLimit = 0x4000u,
[Obsolete("Renamed to MixerChanLimit for clarity.")]
MixerLimit = 0x4000u,
MixerEnd = 0x10000u,
MixerChanMatrix = 0x10000u,
[Obsolete("Renamed to MixerChanMatrix for clarity.")]
MixerMatrix = 0x10000u,
MixerNonStop = 0x20000u,
MixerChanPause = 0x20000u,
[Obsolete("Renamed to MixerChanPause for clarity.")]
MixerPause = 0x20000u,
MixerChanDownMix = 0x400000u,
[Obsolete("Renamed to MixerChanDownMix for clarity.")]
MixerDownMix = 0x400000u,
MixerChanNoRampin = 0x800000u,
[Obsolete("Renamed to MixerChanNoRampin for clarity.")]
MixerNoRampin = 0x800000u,
RecordPause = 0x8000u,
RecordEchoCancel = 0x2000u,
RecordAGC = 0x4000u,
SpeakerFront = 0x1000000u,
SpeakerRear = 0x2000000u,
SpeakerCenterLFE = 0x3000000u,
SpeakerRearCenter = 0x4000000u,
SpeakerPair1 = 0x1000000u,
SpeakerPair2 = 0x2000000u,
SpeakerPair3 = 0x3000000u,
SpeakerPair4 = 0x4000000u,
SpeakerPair5 = 0x5000000u,
SpeakerPair6 = 0x6000000u,
SpeakerPair7 = 0x7000000u,
SpeakerPair8 = 0x8000000u,
SpeakerPair9 = 0x9000000u,
SpeakerPair10 = 0xA000000u,
SpeakerPair11 = 0xB000000u,
SpeakerPair12 = 0xC000000u,
SpeakerPair13 = 0xD000000u,
SpeakerPair14 = 0xE000000u,
SpeakerPair15 = 0xF000000u,
SpeakerLeft = 0x10000000u,
SpeakerRight = 0x20000000u,
SpeakerFrontLeft = 0x11000000u,
SpeakerRearLeft = 0x12000000u,
SpeakerCenter = 0x13000000u,
SpeakerRearCenterLeft = 0x14000000u,
SpeakerFrontRight = 0x21000000u,
SpeakerRearRight = 0x22000000u,
SpeakerLFE = 0x23000000u,
SpeakerRearCenterRight = 0x24000000u,
AacFrame960 = 0x1000u,
AacStereo = 0x400000u,
DSDOverPCM = 0x400u,
DSDRaw = 0x200u,
Ac3DownmixStereo = 0x200u,
Ac3DownmixQuad = 0x400u,
Ac3DownmixDolby = 0x600u,
Ac3DRC = 0x800u,
DShowNoAudioProcessing = 0x80000u,
DShowStreamMix = 0x1000000u,
DShowAutoDVD = 0x4000000u,
DShowLoop = 0x8000000u,
DShowVideoProcessing = 0x20000u,
WVStereo = 0x400000u
}
[Flags]
internal enum BASSInfoFlags
{
None = 0,
ContinuousRate = 0x10,
EmulatedDrivers = 0x20,
Certified = 0x40,
Mono = 0x100,
Stereo = 0x200,
Secondary8Bit = 0x400,
Secondary16Bit = 0x800
}
public enum ChannelAttribute
{
Frequency = 1,
Volume = 2,
Pan = 3,
EaxMix = 4,
NoBuffer = 5,
CPUUsage = 7,
SampleRateConversion = 8,
NetworkResumeBufferLevel = 9,
ScannedInfo = 10,
NoRamp = 11,
Bitrate = 12,
Buffer = 13,
Granule = 14,
MusicAmplify = 256,
MusicPanSeparation = 257,
MusicPositionScaler = 258,
MusicBPM = 259,
MusicSpeed = 260,
MusicVolumeGlobal = 261,
MusicActiveChannelCount = 262,
MusicVolumeChannel = 512,
MusicVolumeInstrument = 768,
Tempo = 65536,
Pitch = 65537,
TempoFrequency = 65538,
TempoUseAAFilter = 65552,
TempoAAFilterLength = 65553,
TempoUseQuickAlgorithm = 65554,
TempoSequenceMilliseconds = 65555,
TempoSeekWindowMilliseconds = 65556,
TempoOverlapMilliseconds = 65557,
TempoPreventClick = 65558,
ReverseDirection = 69632,
MidiPPQN = 73728,
MidiCPU = 73729,
MidiChannels = 73730,
MidiVoices = 73731,
MidiVoicesActive = 73732,
MidiState = 73733,
MidiSRC = 73734,
MidiKill = 73735,
MidiTrackVolume = 73984,
OpusOriginalFrequency = 77824,
DSDGain = 81920,
DSDRate = 81921,
MixerLatency = 86016,
SplitAsyncBuffer = 86032,
SplitAsyncPeriod = 86033
}
[Flags]
public enum ChannelType
{
Unknown = 0,
Sample = 1,
Recording = 2,
MO3 = 0x100,
ZXTune = -820183040,
Stream = 0x10000,
OGG = 0x10002,
MP1 = 0x10003,
MP2 = 0x10004,
MP3 = 0x10005,
AIFF = 0x10006,
CA = 0x10007,
MF = 0x10008,
CD = 0x10200,
WMA = 0x10300,
WMA_MP3 = 0x10301,
WINAMP = 0x10400,
WV = 0x10500,
WV_H = 0x10501,
WV_L = 0x10502,
WV_LH = 0x10503,
OFR = 0x10600,
APE = 0x10700,
Mixer = 0x10800,
Split = 0x10801,
FLAC = 0x10900,
FLAC_OGG = 0x10901,
MPC = 0x10A00,
AAC = 0x10B00,
MP4 = 0x10B01,
SPX = 0x10C00,
MIDI = 0x10D00,
ALAC = 0x10E00,
TTA = 0x10F00,
AC3 = 0x11000,
Video = 0x11100,
OPUS = 0x11200,
DSD = 0x11700,
ADX = 0x1F000,
AIX = 0x1F001,
Tempo = 0x1F200,
Reverse = 0x1F201,
MOD = 0x20000,
MTM = 0x20001,
S3M = 0x20002,
XM = 0x20003,
IT = 0x20004,
Wave = 0x40000,
WavePCM = 0x50001,
WaveFloat = 0x50003,
Dummy = 0x18000,
Device = 0x18001
}
public enum Configuration
{
PlaybackBufferLength = 0,
UpdatePeriod = 1,
GlobalSampleVolume = 4,
GlobalStreamVolume = 5,
GlobalMusicVolume = 6,
LogarithmicVolumeCurve = 7,
LogarithmicPanCurve = 8,
FloatDSP = 9,
Algorithm3D = 10,
NetTimeOut = 11,
NetBufferLength = 12,
PauseNoPlay = 13,
NetPreBuffer = 15,
NetAgent = 16,
NetProxy = 17,
NetPassive = 18,
RecordingBufferLength = 19,
NetPlaylist = 21,
MusicVirtual = 22,
FileVerificationBytes = 23,
UpdateThreads = 24,
DeviceBufferLength = 27,
LoopbackRecording = 28,
NoTimerResolution = 29,
TruePlayPosition = 30,
IOSMixAudio = 34,
IOSSession = 34,
SuppressMP3ErrorCorruptionSilence = 35,
IncludeDefaultDevice = 36,
NetReadTimeOut = 37,
VistaSpeakerAssignment = 38,
IOSSpeaker = 39,
MFDisable = 40,
HandleCount = 41,
UnicodeDeviceInformation = 42,
SRCQuality = 43,
SampleSRCQuality = 44,
AsyncFileBufferLength = 45,
IOSNotify = 46,
OggPreScan = 47,
MFVideo = 48,
Airplay = 49,
DevNonStop = 50,
IOSNoCategory = 51,
NetVerificationBytes = 52,
DevicePeriod = 53,
Float = 54,
AndroidSessionId = 62,
AndroidAAudio = 67,
AC3DynamicRangeCompression = 65537,
WmaNetPreBuffer = 65793,
WmaBassFileHandling = 65795,
WmaNetSeek = 65796,
WmaVideo = 65797,
WmaAsync = 65807,
CDFreeOld = 66048,
CDRetry = 66049,
CDAutoSpeed = 66050,
CDSkipError = 66051,
CDDBServer = 66052,
EncodePriority = 66304,
EncodeQueue = 66305,
EncodeACMLoad = 66306,
EncodeCastTimeout = 66320,
EncodeCastProxy = 66321,
MidiCompact = 66560,
MidiVoices = 66561,
MidiAutoFont = 66562,
MidiDefaultFont = 66563,
MidiInputPorts = 66564,
MixerBufferLength = 67073,
MixerPositionEx = 67074,
SplitBufferLength = 67088,
PlayAudioFromMp4 = 67328,
AacSupportMp4 = 67329,
DSDFrequency = 67584,
WinampInputTimeout = 67584,
DSDGain = 67585,
ZXTuneMaxFileSize = -820182784
}
[Flags]
public enum DataFlags
{
Available = 0,
FFTIndividual = 0x10,
FFTNoWindow = 0x20,
FFTRemoveDC = 0x40,
FFTComplex = 0x80,
Fixed = 0x20000000,
Float = 0x40000000,
FFT256 = int.MinValue,
FFT512 = -2147483647,
FFT1024 = -2147483646,
FFT2048 = -2147483645,
FFT4096 = -2147483644,
FFT8192 = -2147483643,
FFT16384 = -2147483642,
FFT32768 = -2147483641
}
[Flags]
public enum DeviceInfoFlags
{
None = 0,
Enabled = 1,
Default = 2,
Initialized = 4,
Loopback = 8,
TypeMask = -16777216
}
[Flags]
public enum DeviceInitFlags
{
Default = 0,
Byte = 1,
Mono = 2,
Device3D = 4,
Bits16 = 8,
Latency = 0x100,
CPSpeakers = 0x400,
ForcedSpeakerAssignment = 0x800,
NoSpeakerAssignment = 0x1000,
DMix = 0x2000,
Frequency = 0x4000,
Stereo = 0x8000,
Hog = 0x10000,
AudioTrack = 0x20000,
DirectSound = 0x40000
}
public enum DeviceType
{
Network = 16777216,
Speakers = 33554432,
Line = 50331648,
Headphones = 67108864,
Microphone = 83886080,
Headset = 100663296,
Handset = 117440512,
Digital = 134217728,
SPDIF = 150994944,
HDMI = 167772160,
DisplayPort = 1073741824
}
public enum DXPhase
{
Negative180,
Negative90,
Zero,
Positive90,
Positive180
}
public enum DXWaveform
{
Triangle,
Sine
}
public enum EffectType
{
DXChorus = 0,
DXDistortion = 1,
DXEcho = 2,
DXFlanger = 3,
DXCompressor = 4,
DXGargle = 5,
DX_I3DL2Reverb = 6,
DXParamEQ = 7,
DXReverb = 8,
Rotate = 65536,
Volume = 65539,
PeakEQ = 65540,
Mix = 65543,
Damp = 65544,
AutoWah = 65545,
Phaser = 65547,
Chorus = 65549,
Distortion = 65552,
Compressor = 65553,
VolumeEnvelope = 65554,
BQF = 65555,
Echo = 65556,
PitchShift = 65557,
Freeverb = 65558
}
public enum FileStreamPosition
{
Current = 0,
Download = 1,
End = 2,
Start = 3,
Connected = 4,
Buffer = 5,
Socket = 6,
AsyncBuffer = 7,
WmaBuffer = 1000,
HlsSegment = 65536
}
[Flags]
public enum FXChannelFlags
{
All = -1,
None = 0,
Channel1 = 1,
Channel2 = 2,
Channel3 = 4,
Channel4 = 8,
Channel5 = 0x10,
Channel6 = 0x20,
Channel7 = 0x40,
Channel8 = 0x80,
Channel9 = 0x100,
Channel10 = 0x200,
Channel11 = 0x400,
Channel12 = 0x800,
Channel13 = 0x1000,
Channel14 = 0x2000,
Channel15 = 0x4000,
Channel16 = 0x8000,
Channel17 = 0x10000,
Channel18 = 0x20000,
Channel19 = 0x40000,
Channel20 = 0x80000,
Channel21 = 0x100000,
Channel22 = 0x200000,
Channel23 = 0x400000,
Channel24 = 0x800000,
Channel25 = 0x1000000,
Channel26 = 0x2000000,
Channel27 = 0x4000000,
Channel28 = 0x8000000,
Channel29 = 0x10000000,
Channel30 = 0x20000000
}
[Flags]
public enum InputFlags
{
None = 0,
Off = 0x10000,
On = 0x20000
}
[Flags]
public enum InputTypeFlags
{
InputTypeMask = -16777216,
Error = -1,
Undefined = 0,
Digital = 0x1000000,
Line = 0x2000000,
Microphone = 0x3000000,
MIDISynthesizer = 0x4000000,
AnalogCD = 0x5000000,
Phone = 0x6000000,
Speaker = 0x7000000,
Wave = 0x8000000,
Auxiliary = 0x9000000,
Analog = 0xA000000
}
[Flags]
public enum LevelRetrievalFlags
{
All = 0,
Mono = 1,
Stereo = 2,
RMS = 4,
VolPan = 8
}
public enum Mode3D
{
LeaveCurrent = -1,
Normal,
Relative,
Off
}
public enum PlaybackState
{
Stopped,
Playing,
Stalled,
Paused
}
[Flags]
public enum PositionFlags
{
Bytes = 0,
MusicOrders = 1,
MIDITick = 2,
OGG = 3,
CDTrack = 4,
ZXTuneSubCount = 0xF10000,
ZXTuneSubLength = 0xF20000,
MIDIDecaySeek = 0x4000,
MixerReset = 0x10000,
MusicPositionReset = 0x8000,
MusicPositionResetEx = 0x400000,
MixerNoRampIn = 0x800000,
Inexact = 0x8000000,
Relative = 0x4000000,
Decode = 0x10000000,
DecodeTo = 0x20000000,
Scan = 0x40000000,
HlsSegment = 0x10000
}
[Flags]
public enum RecordFormatFlags
{
Unknown = 0,
WF1M08 = 1,
WF1S08 = 2,
WF1M16 = 4,
WF1S16 = 8,
WF2M08 = 0x10,
WF2S08 = 0x20,
WF2M16 = 0x40,
WF2S16 = 0x80,
WF4M08 = 0x100,
WF4S08 = 0x200,
WF4M16 = 0x400,
WF4S16 = 0x800,
WF48M08 = 0x1000,
WF48S08 = 0x2000,
WF48M16 = 0x4000,
WF48S16 = 0x8000,
WF96M08 = 0x10000,
WF96S08 = 0x20000,
WF96M16 = 0x40000,
WF96S16 = 0x80000
}
[Flags]
internal enum RecordInfoFlags
{
None = 0,
EmulatedDrivers = 0x20,
Certified = 0x40
}
public enum StreamProcedureType
{
End = int.MinValue,
Push = -1,
Dummy = 0,
Device = -2
}
public enum StreamSystem
{
NoBuffer,
Buffer,
BufferPush
}
[Flags]
public enum SyncFlags
{
Onetime = int.MinValue,
Mixtime = 0x40000000,
Thread = 0x20000000,
Position = 0,
MusicInstrument = 1,
End = 2,
MusicFx = 3,
MetadataReceived = 4,
Slided = 5,
Stalled = 6,
Downloaded = 7,
Free = 8,
MusicPosition = 0xA,
Seeking = 0xB,
OggChange = 0xC,
Stop = 0xE,
WinampBitRate = 0x64,
CDError = 0x3E8,
CDSpeed = 0x3EA,
MidiMarker = 0x10000,
MidiCue = 0x10001,
MidiLyric = 0x10002,
MidiText = 0x10003,
MidiEvent = 0x10004,
MidiTick = 0x10005,
MidiTimeSignature = 0x10006,
MidiKeySignature = 0x10007,
WmaChange = 0x10100,
WmaMeta = 0x10101,
MixerEnvelope = 0x10200,
MixerEnvelopeNode = 0x10201,
HlsSegement = 0x10300
}
public enum TagType
{
ID3 = 0,
ID3v2 = 1,
OGG = 2,
HTTP = 3,
ICY = 4,
META = 5,
APE = 6,
MP4 = 7,
WMA = 8,
OggEncoder = 9,
Lyrics3v2 = 10,
WmaMeta = 11,
CoreAudioCodec = 11,
WmaCodec = 12,
FlacCue = 12,
MF = 13,
WaveFormat = 14,
ZXTuneSuOgg = 15794176,
RiffInfo = 256,
RiffBext = 257,
RiffCart = 258,
RiffDISP = 259,
ApeBinary = 4096,
MusicName = 65536,
MusicMessage = 65537,
MusicOrders = 65538,
MusicAuth = 65539,
MusicInstrument = 65792,
MusicSample = 66304,
MidiTrack = 69632,
FlacPicture = 73728,
AdxLoop = 73728,
DSDArtist = 77824,
DSDTitle = 77825,
DSDComment = 78080,
HlsExtInf = 81920,
HlsStreamInf = 81921,
HlsDate = 81922
}
[Flags]
public enum VAMMode
{
Hardware = 1,
Software = 2,
TerminateTime = 4,
TerminateDistance = 8,
TerminatePriority = 0x10
}
public enum WaveFormatTag : short
{
Extensible = -2,
Unknown = 0,
Pcm = 1,
Adpcm = 2,
IeeeFloat = 3,
Vselp = 4,
IbmCvsd = 5,
ALaw = 6,
MuLaw = 7,
Dts = 8,
Drm = 9,
WmaVoice9 = 10,
OkiAdpcm = 16,
DviAdpcm = 17,
ImaAdpcm = 17,
MediaspaceAdpcm = 18,
SierraAdpcm = 19,
G723Adpcm = 20,
DigiStd = 21,
DigiFix = 22,
DialogicOkiAdpcm = 23,
MediaVisionAdpcm = 24,
CUCodec = 25,
YamahaAdpcm = 32,
SonarC = 33,
DspGroupTrueSpeech = 34,
EchoSpeechCorporation1 = 35,
AudioFileAf36 = 36,
Aptx = 37,
AudioFileAf10 = 38,
Prosody1612 = 39,
Lrc = 40,
DolbyAc2 = 48,
Gsm610 = 49,
MsnAudio = 50,
AntexAdpcme = 51,
ControlResVqlpc = 52,
DigiReal = 53,
DigiAdpcm = 54,
ControlResCr10 = 55,
NMS_VBXADPCM = 56,
CS_IMAADPCM = 57,
ECHOSC3 = 58,
ROCKWELL_ADPCM = 59,
ROCKWELL_DIGITALK = 60,
XEBEC = 61,
G721_ADPCM = 64,
G728_CELP = 65,
MSG723 = 66,
Mpeg = 80,
RT24 = 82,
PAC = 83,
Mp3 = 85,
LUCENT_G723 = 89,
CIRRUS = 96,
ESPCM = 97,
VOXWARE = 98,
CANOPUS_ATRAC = 99,
G726_ADPCM = 100,
G722_ADPCM = 101,
DSAT_DISPLAY = 103,
VOXWARE_BYTE_ALIGNED = 105,
VOXWARE_AC8 = 112,
VOXWARE_AC10 = 113,
VOXWARE_AC16 = 114,
VOXWARE_AC20 = 115,
VOXWARE_RT24 = 116,
VOXWARE_RT29 = 117,
VOXWARE_RT29HW = 118,
VOXWARE_VR12 = 119,
VOXWARE_VR18 = 120,
VOXWARE_TQ40 = 121,
SOFTSOUND = 128,
VOXWARE_TQ60 = 129,
MSRT24 = 130,
G729A = 131,
MVI_MVI2 = 132,
DF_G726 = 133,
DF_GSM610 = 134,
ISIAUDIO = 136,
ONLIVE = 137,
SBC24 = 145,
DOLBY_AC3_SPDIF = 146,
MEDIASONIC_G723 = 147,
PROSODY_8KBPS = 148,
ZYXEL_ADPCM = 151,
PHILIPS_LPCBB = 152,
PACKED = 153,
MALDEN_PHONYTALK = 160,
Gsm = 161,
G729 = 162,
G723 = 163,
Acelp = 164,
RawAac = 255,
RHETOREX_ADPCM = 256,
IRAT = 257,
VIVO_G723 = 273,
VIVO_SIREN = 274,
DIGITAL_G723 = 291,
SANYO_LD_ADPCM = 293,
SIPROLAB_ACEPLNET = 304,
SIPROLAB_ACELP4800 = 305,
SIPROLAB_ACELP8V3 = 306,
SIPROLAB_G729 = 307,
SIPROLAB_G729A = 308,
SIPROLAB_KELVIN = 309,
G726ADPCM = 320,
QUALCOMM_PUREVOICE = 336,
QUALCOMM_HALFRATE = 337,
TUBGSM = 341,
MSAUDIO1 = 352,
WMA = 353,
WMAProfessional = 354,
WMALosseless = 355,
WMA_SPDIF = 356,
UNISYS_NAP_ADPCM = 368,
UNISYS_NAP_ULAW = 369,
UNISYS_NAP_ALAW = 370,
UNISYS_NAP_16K = 371,
CREATIVE_ADPCM = 512,
CREATIVE_FASTSPEECH8 = 514,
CREATIVE_FASTSPEECH10 = 515,
UHER_ADPCM = 528,
QUARTERDECK = 544,
ILINK_VC = 560,
RAW_SPORT = 576,
ESST_AC3 = 577,
IPI_HSX = 592,
IPI_RPELP = 593,
CS2 = 608,
SONY_SCX = 624,
FM_TOWNS_SND = 768,
BTV_DIGITAL = 1024,
QDESIGN_MUSIC = 1104,
VME_VMPCM = 1664,
TPC = 1665,
OLIGSM = 4096,
OLIADPCM = 4097,
OLICELP = 4098,
OLISBC = 4099,
OLIOPR = 4100,
LH_CODEC = 4352,
NORRIS = 5120,
SOUNDSPACE_MUSICOMPRESS = 5376,
MPEG_ADTS_AAC = 5632,
MPEG_RAW_AAC = 5633,
MPEG_LOAS = 5634,
NOKIA_MPEG_ADTS_AAC = 5640,
NOKIA_MPEG_RAW_AAC = 5641,
VODAFONE_MPEG_ADTS_AAC = 5642,
VODAFONE_MPEG_RAW_AAC = 5643,
MPEG_HEAAC = 5648,
DVM = 8192,
Vorbis1 = 26447,
Vorbis2 = 26448,
Vorbis3 = 26449,
Vorbis1P = 26479,
Vorbis2P = 26480,
Vorbis3P = 26481
}
public static class Bass
{
private const string DllName = "bass";
private const int SlideLog = 16777216;
public const int NoSoundDevice = 0;
public const int DefaultDevice = -1;
public static Algorithm3D Algorithm3D
{
get
{
return (Algorithm3D)GetConfig(Configuration.Algorithm3D);
}
set
{
Configure(Configuration.Algorithm3D, (int)value);
}
}
public static string SupportedFormats => "*.mp3;*.mp2;*.mp1;*.ogg;*.wav;*.aif";
public static double CPUUsage => BASS_GetCPU();
public static Version Version => Extensions.GetVersion(BASS_GetVersion());
public static Errors LastError => BASS_ErrorGetCode();
public static bool Float => GetConfigBool(Configuration.Float);
public static int PlaybackBufferLength
{
get
{
return GetConfig(Configuration.PlaybackBufferLength);
}
set
{
Configure(Configuration.PlaybackBufferLength, value);
}
}
public static int UpdatePeriod
{
get
{
return GetConfig(Configuration.UpdatePeriod);
}
set
{
Configure(Configuration.UpdatePeriod, value);
}
}
public static int GlobalSampleVolume
{
get
{
return GetConfig(Configuration.GlobalSampleVolume);
}
set
{
Configure(Configuration.GlobalSampleVolume, value);
}
}
public static int GlobalStreamVolume
{
get
{
return GetConfig(Configuration.GlobalStreamVolume);
}
set
{
Configure(Configuration.GlobalStreamVolume, value);
}
}
public static int GlobalMusicVolume
{
get
{
return GetConfig(Configuration.GlobalMusicVolume);
}
set
{
Configure(Configuration.GlobalMusicVolume, value);
}
}
public static bool LogarithmicVolumeCurve
{
get
{
return GetConfigBool(Configuration.LogarithmicVolumeCurve);
}
set
{
Configure(Configuration.LogarithmicVolumeCurve, value);
}
}
public static bool LogarithmicPanningCurve
{
get
{
return GetConfigBool(Configuration.LogarithmicPanCurve);
}
set
{
Configure(Configuration.LogarithmicPanCurve, value);
}
}
public static bool FloatingPointDSP
{
get
{
return GetConfigBool(Configuration.FloatDSP);
}
set
{
Configure(Configuration.FloatDSP, value);
}
}
public static int UpdateThreads
{
get
{
return GetConfig(Configuration.UpdateThreads);
}
set
{
Configure(Configuration.UpdateThreads, value);
}
}
public static int AsyncFileBufferLength
{
get
{
return GetConfig(Configuration.AsyncFileBufferLength);
}
set
{
Configure(Configuration.AsyncFileBufferLength, value);
}
}
public static int HandleCount => GetConfig(Configuration.HandleCount);
public static int NetTimeOut
{
get
{
return GetConfig(Configuration.NetTimeOut);
}
set
{
Configure(Configuration.NetTimeOut, value);
}
}
public static int NetReadTimeOut
{
get
{
return GetConfig(Configuration.NetReadTimeOut);
}
set
{
Configure(Configuration.NetReadTimeOut, value);
}
}
public static int NetBufferLength
{
get
{
return GetConfig(Configuration.NetBufferLength);
}
set
{
Configure(Configuration.NetBufferLength, value);
}
}
public static int PauseNoPlay
{
get
{
return GetConfig(Configuration.PauseNoPlay);
}
set
{
Configure(Configuration.PauseNoPlay, value);
}
}
public static int NetPreBuffer
{
get
{
return GetConfig(Configuration.NetPreBuffer);
}
set
{
Configure(Configuration.NetPreBuffer, value);
}
}
public static bool FTPPassive
{
get
{
return GetConfigBool(Configuration.NetPassive);
}
set
{
Configure(Configuration.NetPassive, value);
}
}
public static int NetPlaylist
{
get
{
return GetConfig(Configuration.NetPlaylist);
}
set
{
Configure(Configuration.NetPlaylist, value);
}
}
public static string NetAgent
{
get
{
return Marshal.PtrToStringAnsi(GetConfigPtr(Configuration.NetAgent));
}
set
{
IntPtr intPtr = Marshal.StringToHGlobalAnsi(value);
Configure(Configuration.NetAgent, intPtr);
Marshal.FreeHGlobal(intPtr);
}
}
public static string NetProxy
{
get
{
return Marshal.PtrToStringAnsi(GetConfigPtr(Configuration.NetProxy));
}
set
{
IntPtr intPtr = Marshal.StringToHGlobalAnsi(value);
Configure(Configuration.NetProxy, intPtr);
Marshal.FreeHGlobal(intPtr);
}
}
public static int MusicVirtial
{
get
{
return GetConfig(Configuration.MusicVirtual);
}
set
{
Configure(Configuration.MusicVirtual, value);
}
}
public static int FileVerificationBytes
{
get
{
return GetConfig(Configuration.FileVerificationBytes);
}
set
{
Configure(Configuration.FileVerificationBytes, value);
}
}
public static int NetVerificationBytes
{
get
{
return GetConfig(Configuration.NetVerificationBytes);
}
set
{
Configure(Configuration.NetVerificationBytes, value);
}
}
public static int DeviceBufferLength
{
get
{
return GetConfig(Configuration.DeviceBufferLength);
}
set
{
Configure(Configuration.DeviceBufferLength, value);
}
}
public static bool SuppressMP3ErrorCorruptionSilence
{
get
{
return GetConfigBool(Configuration.SuppressMP3ErrorCorruptionSilence);
}
set
{
Configure(Configuration.SuppressMP3ErrorCorruptionSilence, value);
}
}
public static int SRCQuality
{
get
{
return GetConfig(Configuration.SRCQuality);
}
set
{
Configure(Configuration.SRCQuality, value);
}
}
public static int SampleSRCQuality
{
get
{
return GetConfig(Configuration.SampleSRCQuality);
}
set
{
Configure(Configuration.SampleSRCQuality, value);
}
}
public static bool OggPreScan
{
get
{
return GetConfigBool(Configuration.OggPreScan);
}
set
{
Configure(Configuration.OggPreScan, value);
}
}
public static bool DeviceNonStop
{
get
{
return GetConfigBool(Configuration.DevNonStop);
}
set
{
Configure(Configuration.DevNonStop, value);
}
}
public static int DeviceCount
{
get
{
int i;
DeviceInfo Info;
for (i = 0; GetDeviceInfo(i, out Info); i++)
{
}
return i;
}
}
public static double Volume
{
get
{
return BASS_GetVolume();
}
set
{
if (!BASS_SetVolume((float)value))
{
throw new BassException();
}
}
}
public static int CurrentDevice
{
get
{
return BASS_GetDevice();
}
set
{
if (!BASS_SetDevice(value))
{
throw new BassException();
}
}
}
public static BassInfo Info
{
get
{
if (!GetInfo(out var Info))
{
throw new BassException();
}
return Info;
}
}
public static int CurrentRecordingDevice
{
get
{
return BASS_RecordGetDevice();
}
set
{
if (!BASS_RecordSetDevice(value))
{
throw new BassException();
}
}
}
public static RecordInfo RecordingInfo
{
get
{
if (!RecordGetInfo(out var info))
{
throw new BassException();
}
return info;
}
}
public static int RecordingBufferLength
{
get
{
return GetConfig(Configuration.RecordingBufferLength);
}
set
{
Configure(Configuration.RecordingBufferLength, value);
}
}
public static int RecordingDeviceCount
{
get
{
int i;
DeviceInfo Info;
for (i = 0; RecordGetDeviceInfo(i, out Info); i++)
{
}
return i;
}
}
[DllImport("bass", EntryPoint = "BASS_Apply3D")]
public static extern void Apply3D();
[DllImport("bass", EntryPoint = "BASS_Get3DFactors")]
public static extern bool Get3DFactors(ref float Distance, ref float RollOff, ref float Doppler);
[DllImport("bass", EntryPoint = "BASS_Set3DFactors")]
public static extern bool Set3DFactors(float Distance, float RollOff, float Doppler);
[DllImport("bass", EntryPoint = "BASS_Get3DPosition")]
public static extern bool Get3DPosition(ref Vector3D Position, ref Vector3D Velocity, ref Vector3D Front, ref Vector3D Top);
[DllImport("bass", EntryPoint = "BASS_Set3DPosition")]
public static extern bool Set3DPosition(Vector3D Position, Vector3D Velocity, Vector3D Front, Vector3D Top);
[DllImport("bass", EntryPoint = "BASS_ChannelGet3DAttributes")]
public static extern bool ChannelGet3DAttributes(int Handle, ref Mode3D Mode, ref float Min, ref float Max, ref int iAngle, ref int oAngle, ref float OutVol);
[DllImport("bass", EntryPoint = "BASS_ChannelSet3DAttributes")]
public static extern bool ChannelSet3DAttributes(int Handle, Mode3D Mode, float Min, float Max, int iAngle, int oAngle, float OutVol);
[DllImport("bass", EntryPoint = "BASS_ChannelGet3DPosition")]
public static extern bool ChannelGet3DPosition(int Handle, ref Vector3D Position, ref Vector3D Orientation, ref Vector3D Velocity);
[DllImport("bass", EntryPoint = "BASS_ChannelSet3DPosition")]
public static extern bool ChannelSet3DPosition(int Handle, Vector3D Position, Vector3D Orientation, Vector3D Velocity);
[DllImport("bass", EntryPoint = "BASS_Update")]
public static extern bool Update(int Length);
[DllImport("bass")]
private static extern float BASS_GetCPU();
[DllImport("bass")]
private static extern int BASS_GetVersion();
[DllImport("bass")]
private static extern Errors BASS_ErrorGetCode();
[DllImport("bass", EntryPoint = "BASS_ChannelGetInfo")]
public static extern bool ChannelGetInfo(int Handle, out ChannelInfo Info);
public static ChannelInfo ChannelGetInfo(int Handle)
{
if (!ChannelGetInfo(Handle, out var Info))
{
throw new BassException();
}
return Info;
}
[DllImport("bass")]
private static extern int BASS_ChannelSetDSP(int Handle, DSPProcedure Procedure, IntPtr User, int Priority);
public static int ChannelSetDSP(int Handle, DSPProcedure Procedure, IntPtr User = default(IntPtr), int Priority = 0)
{
int num = BASS_ChannelSetDSP(Handle, Procedure, User, Priority);
if (num != 0)
{
ChannelReferences.Add(Handle, num, Procedure);
}
return num;
}
[DllImport("bass")]
private static extern bool BASS_ChannelRemoveDSP(int Handle, int DSP);
public static bool ChannelRemoveDSP(int Handle, int DSP)
{
bool num = BASS_ChannelRemoveDSP(Handle, DSP);
if (num)
{
ChannelReferences.Remove(Handle, DSP);
}
return num;
}
[DllImport("bass")]
private static extern int BASS_ChannelSetSync(int Handle, SyncFlags Type, long Parameter, SyncProcedure Procedure, IntPtr User);
public static int ChannelSetSync(int Handle, SyncFlags Type, long Parameter, SyncProcedure Procedure, IntPtr User = default(IntPtr))
{
SyncProcedure syncProcedure = (Type.HasFlag(SyncFlags.Onetime) ? ((SyncProcedure)delegate(int I, int Channel, int Data, IntPtr Ptr)
{
Procedure(I, Channel, Data, Ptr);
ChannelReferences.Remove(Channel, I);
}) : Procedure);
int num = BASS_ChannelSetSync(Handle, Type, Parameter, syncProcedure, User);
if (num != 0)
{
ChannelReferences.Add(Handle, num, syncProcedure);
}
return num;
}
[DllImport("bass")]
private static extern bool BASS_ChannelRemoveSync(int Handle, int Sync);
public static bool ChannelRemoveSync(int Handle, int Sync)
{
bool num = BASS_ChannelRemoveSync(Handle, Sync);
if (num)
{
ChannelReferences.Remove(Handle, Sync);
}
return num;
}
[DllImport("bass", EntryPoint = "BASS_ChannelPlay")]
public static extern bool ChannelPlay(int Handle, bool Restart = false);
[DllImport("bass", EntryPoint = "BASS_ChannelPause")]
public static extern bool ChannelPause(int Handle);
[DllImport("bass", EntryPoint = "BASS_ChannelStop")]
public static extern bool ChannelStop(int Handle);
[DllImport("bass", EntryPoint = "BASS_ChannelLock")]
public static extern bool ChannelLock(int Handle, bool Lock = true);
[DllImport("bass", EntryPoint = "BASS_ChannelIsActive")]
public static extern PlaybackState ChannelIsActive(int Handle);
[DllImport("bass", EntryPoint = "BASS_ChannelSetLink")]
public static extern bool ChannelSetLink(int Handle, int Channel);
[DllImport("bass", EntryPoint = "BASS_ChannelRemoveLink")]
public static extern bool ChannelRemoveLink(int Handle, int Channel);
[DllImport("bass", EntryPoint = "BASS_ChannelFlags")]
public static extern BassFlags ChannelFlags(int Handle, BassFlags Flags, BassFlags Mask);
public static bool ChannelHasFlag(int Handle, BassFlags Flag)
{
return ChannelFlags(Handle, BassFlags.Default, BassFlags.Default).HasFlag(Flag);
}
public static bool ChannelAddFlag(int Handle, BassFlags Flag)
{
return ChannelFlags(Handle, Flag, Flag).HasFlag(Flag);
}
public static bool ChannelRemoveFlag(int Handle, BassFlags Flag)
{
return !ChannelFlags(Handle, BassFlags.Default, Flag).HasFlag(Flag);
}
[DllImport("bass", EntryPoint = "BASS_ChannelGetAttribute")]
public static extern bool ChannelGetAttribute(int Handle, ChannelAttribute Attribute, out float Value);
public static double ChannelGetAttribute(int Handle, ChannelAttribute Attribute)
{
ChannelGetAttribute(Handle, Attribute, out var Value);
return Value;
}
[DllImport("bass", EntryPoint = "BASS_ChannelGetAttributeEx")]
public static extern int ChannelGetAttribute(int Handle, ChannelAttribute Attribute, IntPtr Value, int Size);
[DllImport("bass", EntryPoint = "BASS_ChannelSetAttribute")]
public static extern bool ChannelSetAttribute(int Handle, ChannelAttribute Attribute, float Value);
public static bool ChannelSetAttribute(int Handle, ChannelAttribute Attribute, double Value)
{
return ChannelSetAttribute(Handle, Attribute, (float)Value);
}
[DllImport("bass", EntryPoint = "BASS_ChannelSetAttributeEx")]
public static extern bool ChannelSetAttribute(int Handle, ChannelAttribute Attribute, IntPtr Value, int Size);
[DllImport("bass", EntryPoint = "BASS_ChannelGetTags")]
public static extern IntPtr ChannelGetTags(int Handle, TagType Tags);
[DllImport("bass", EntryPoint = "BASS_ChannelGetLength")]
public static extern long ChannelGetLength(int Handle, PositionFlags Mode = PositionFlags.Bytes);
[DllImport("bass", EntryPoint = "BASS_ChannelBytes2Seconds")]
public static extern double ChannelBytes2Seconds(int Handle, long Position);
[DllImport("bass", EntryPoint = "BASS_ChannelSeconds2Bytes")]
public static extern long ChannelSeconds2Bytes(int Handle, double Position);
[DllImport("bass", EntryPoint = "BASS_ChannelGetPosition")]
public static extern long ChannelGetPosition(int Handle, PositionFlags Mode = PositionFlags.Bytes);
[DllImport("bass", EntryPoint = "BASS_ChannelSetPosition")]
public static extern bool ChannelSetPosition(int Handle, long Position, PositionFlags Mode = PositionFlags.Bytes);
[DllImport("bass", EntryPoint = "BASS_ChannelIsSliding")]
public static extern bool ChannelIsSliding(int Handle, ChannelAttribute Attribute);
[DllImport("bass")]
private static extern bool BASS_ChannelSlideAttribute(int Handle, int Attribute, float Value, int Time);
public static bool ChannelSlideAttribute(int Handle, ChannelAttribute Attribute, float Value, int Time, bool Logarithmic = false)
{
int num = (int)Attribute;
if (Logarithmic)
{
num |= 0x1000000;
}
return BASS_ChannelSlideAttribute(Handle, num, Value, Time);
}
[DllImport("bass", EntryPoint = "BASS_ChannelGetLevel")]
public static extern int ChannelGetLevel(int Handle);
public static int ChannelGetLevelLeft(int Handle)
{
int num = ChannelGetLevel(Handle);
if (num == -1)
{
return -1;
}
return num.LoWord();
}
public static int ChannelGetLevelRight(int Handle)
{
int num = ChannelGetLevel(Handle);
if (num == -1)
{
return -1;
}
return num.HiWord();
}
[DllImport("bass", EntryPoint = "BASS_ChannelGetLevelEx")]
public static extern bool ChannelGetLevel(int Handle, [In][Out] float[] Levels, float Length, LevelRetrievalFlags Flags);
public static float[] ChannelGetLevel(int Handle, float Length, LevelRetrievalFlags Flags)
{
int num = ChannelGetInfo(Handle).Channels;
if (Flags.HasFlag(LevelRetrievalFlags.Mono))
{
num = 1;
}
else if (Flags.HasFlag(LevelRetrievalFlags.Stereo))
{
num = 2;
}
float[] array = new float[num];
if (!ChannelGetLevel(Handle, array, Length, Flags))
{
return null;
}
return array;
}
[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
public static extern int ChannelGetData(int Handle, IntPtr Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
public static extern int ChannelGetData(int Handle, [In][Out] byte[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
public static extern int ChannelGetData(int Handle, [In][Out] short[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
public static extern int ChannelGetData(int Handle, [In][Out] int[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_ChannelGetData")]
public static extern int ChannelGetData(int Handle, [In][Out] float[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_ChannelUpdate")]
public static extern bool ChannelUpdate(int Handle, int Length);
[DllImport("bass", EntryPoint = "BASS_SetConfig")]
public static extern bool Configure(Configuration Option, bool NewValue);
[DllImport("bass", EntryPoint = "BASS_SetConfig")]
public static extern bool Configure(Configuration Option, int NewValue);
[DllImport("bass", EntryPoint = "BASS_SetConfigPtr")]
public static extern bool Configure(Configuration Option, IntPtr NewValue);
[DllImport("bass", EntryPoint = "BASS_GetConfig")]
public static extern int GetConfig(Configuration Option);
[DllImport("bass", EntryPoint = "BASS_GetConfigPtr")]
public static extern IntPtr GetConfigPtr(Configuration Option);
public static bool GetConfigBool(Configuration Option)
{
int config = GetConfig(Option);
if (config != -1)
{
return config != 0;
}
return false;
}
[DllImport("bass", CharSet = CharSet.Unicode)]
private static extern int BASS_StreamCreateFile(bool mem, string file, long offset, long length, BassFlags flags);
[DllImport("bass")]
private static extern int BASS_StreamCreateFile(bool mem, IntPtr file, long offset, long length, BassFlags flags);
public static int CreateStream(string File, long Offset = 0L, long Length = 0L, BassFlags Flags = BassFlags.Default)
{
return BASS_StreamCreateFile(mem: false, File, Offset, Length, Flags | BassFlags.Unicode);
}
public static int CreateStream(IntPtr Memory, long Offset, long Length, BassFlags Flags = BassFlags.Default)
{
return BASS_StreamCreateFile(mem: true, new IntPtr(Memory.ToInt64() + Offset), 0L, Length, Flags);
}
public static int CreateStream(byte[] Memory, long Offset, long Length, BassFlags Flags)
{
return GCPin.CreateStreamHelper((IntPtr Pointer) => CreateStream(Pointer, Offset, Length, Flags), Memory);
}
[DllImport("bass")]
private static extern int BASS_StreamCreateFileUser(StreamSystem system, BassFlags flags, [In][Out] FileProcedures procs, IntPtr user);
public static int CreateStream(StreamSystem System, BassFlags Flags, FileProcedures Procedures, IntPtr User = default(IntPtr))
{
int num = BASS_StreamCreateFileUser(System, Flags, Procedures, User);
if (num != 0)
{
ChannelReferences.Add(num, 0, Procedures);
}
return num;
}
[DllImport("bass", CharSet = CharSet.Unicode)]
private static extern int BASS_StreamCreateURL(string Url, int Offset, BassFlags Flags, DownloadProcedure Procedure, IntPtr User);
public static int CreateStream(string Url, int Offset, BassFlags Flags, DownloadProcedure Procedure, IntPtr User = default(IntPtr))
{
int num = BASS_StreamCreateURL(Url, Offset, Flags | BassFlags.Unicode, Procedure, User);
if (num != 0)
{
ChannelReferences.Add(num, 0, Procedure);
}
return num;
}
[DllImport("bass", EntryPoint = "BASS_Init")]
public static extern bool Init(int Device = -1, int Frequency = 44100, DeviceInitFlags Flags = DeviceInitFlags.Default, IntPtr Win = default(IntPtr), IntPtr ClsID = default(IntPtr));
[DllImport("bass", EntryPoint = "BASS_Start")]
public static extern bool Start();
[DllImport("bass", EntryPoint = "BASS_Pause")]
public static extern bool Pause();
[DllImport("bass", EntryPoint = "BASS_Stop")]
public static extern bool Stop();
[DllImport("bass", EntryPoint = "BASS_Free")]
public static extern bool Free();
[DllImport("bass", EntryPoint = "BASS_ChannelGetDevice")]
public static extern int ChannelGetDevice(int Handle);
[DllImport("bass", EntryPoint = "BASS_ChannelSetDevice")]
public static extern bool ChannelSetDevice(int Handle, int Device);
[DllImport("bass")]
private static extern float BASS_GetVolume();
[DllImport("bass")]
private static extern bool BASS_SetVolume(float volume);
[DllImport("bass")]
private static extern int BASS_GetDevice();
[DllImport("bass")]
private static extern bool BASS_SetDevice(int Device);
[DllImport("bass", EntryPoint = "BASS_GetDeviceInfo")]
public static extern bool GetDeviceInfo(int Device, out DeviceInfo Info);
public static DeviceInfo GetDeviceInfo(int Device)
{
if (!GetDeviceInfo(Device, out var Info))
{
throw new BassException();
}
return Info;
}
[DllImport("bass", EntryPoint = "BASS_GetInfo")]
public static extern bool GetInfo(out BassInfo Info);
[DllImport("bass", EntryPoint = "BASS_FXSetParameters")]
public static extern bool FXSetParameters(int Handle, IntPtr Parameters);
public static bool FXSetParameters(int Handle, IEffectParameter Parameters)
{
using GCPin gCPin = new GCPin(Parameters);
return FXSetParameters(Handle, gCPin.Pointer);
}
[DllImport("bass", EntryPoint = "BASS_FXGetParameters")]
public static extern bool FXGetParameters(int Handle, IntPtr Parameters);
public static bool FXGetParameters(int Handle, IEffectParameter Parameters)
{
using GCPin gCPin = new GCPin(Parameters);
return FXGetParameters(Handle, gCPin.Pointer);
}
[DllImport("bass", EntryPoint = "BASS_FXReset")]
public static extern bool FXReset(int Handle);
[DllImport("bass", EntryPoint = "BASS_ChannelSetFX")]
public static extern int ChannelSetFX(int Handle, EffectType Type, int Priority);
[DllImport("bass", EntryPoint = "BASS_ChannelRemoveFX")]
public static extern bool ChannelRemoveFX(int Handle, int FX);
[DllImport("bass", EntryPoint = "BASS_FXSetPriority")]
public static extern bool FXSetPriority(int Handle, int Priority);
[DllImport("bass", EntryPoint = "BASS_MusicFree")]
public static extern bool MusicFree(int Handle);
[DllImport("bass", CharSet = CharSet.Unicode)]
private static extern int BASS_MusicLoad(bool mem, string file, long offset, int Length, BassFlags flags, int freq);
[DllImport("bass")]
private static extern int BASS_MusicLoad(bool mem, IntPtr file, long offset, int Length, BassFlags flags, int freq);
public static int MusicLoad(string File, long Offset = 0L, int Length = 0, BassFlags Flags = BassFlags.Default, int Frequency = 0)
{
return BASS_MusicLoad(mem: false, File, Offset, Length, Flags | BassFlags.Unicode, Frequency);
}
public static int MusicLoad(IntPtr Memory, long Offset, int Length, BassFlags Flags = BassFlags.Default, int Frequency = 0)
{
return BASS_MusicLoad(mem: true, new IntPtr(Memory.ToInt64() + Offset), 0L, Length, Flags, Frequency);
}
public static int MusicLoad(byte[] Memory, long Offset, int Length, BassFlags Flags = BassFlags.Default, int Frequency = 0)
{
return GCPin.CreateStreamHelper((IntPtr Pointer) => MusicLoad(Pointer, Offset, Length, Flags), Memory);
}
[DllImport("bass")]
private static extern IntPtr BASS_PluginGetInfo(int Handle);
public static PluginInfo PluginGetInfo(int Handle)
{
return Marshal.PtrToStructure<PluginInfo>(BASS_PluginGetInfo(Handle));
}
[DllImport("bass", CharSet = CharSet.Unicode)]
private static extern int BASS_PluginLoad(string FileName, BassFlags Flags = BassFlags.Unicode);
public static int PluginLoad(string FilePath)
{
if (Path.HasExtension(FilePath))
{
return BASS_PluginLoad(FilePath);
}
string directoryName = Path.GetDirectoryName(FilePath);
string fileName = Path.GetFileName(FilePath);
string[] array = new string[3]
{
Path.Combine(directoryName, fileName + ".dll"),
Path.Combine(directoryName, "lib" + fileName + ".so"),
Path.Combine(directoryName, "lib" + fileName + ".dylib")
};
foreach (string text in array)
{
if (File.Exists(text))
{
int num = BASS_PluginLoad(text);
if (num != 0 || LastError == Errors.Already)
{
return num;
}
}
}
return BASS_PluginLoad(FilePath);
}
[DllImport("bass", EntryPoint = "BASS_PluginFree")]
public static extern bool PluginFree(int Handle);
[DllImport("bass", EntryPoint = "BASS_RecordInit")]
public static extern bool RecordInit(int Device = -1);
[DllImport("bass", EntryPoint = "BASS_RecordFree")]
public static extern bool RecordFree();
[DllImport("bass")]
private static extern int BASS_RecordStart(int freq, int chans, BassFlags flags, RecordProcedure proc, IntPtr User);
public static int RecordStart(int Frequency, int Channels, BassFlags Flags, RecordProcedure Procedure, IntPtr User = default(IntPtr))
{
int num = BASS_RecordStart(Frequency, Channels, Flags, Procedure, User);
if (num != 0)
{
ChannelReferences.Add(num, 0, Procedure);
}
return num;
}
public static int RecordStart(int Frequency, int Channels, BassFlags Flags, int Period, RecordProcedure Procedure, IntPtr User = default(IntPtr))
{
return RecordStart(Frequency, Channels, (BassFlags)BitHelper.MakeLong((short)Flags, (short)Period), Procedure, User);
}
[DllImport("bass")]
private static extern int BASS_RecordGetDevice();
[DllImport("bass")]
private static extern bool BASS_RecordSetDevice(int Device);
[DllImport("bass", EntryPoint = "BASS_RecordGetDeviceInfo")]
public static extern bool RecordGetDeviceInfo(int Device, out DeviceInfo Info);
public static DeviceInfo RecordGetDeviceInfo(int Device)
{
if (!RecordGetDeviceInfo(Device, out var Info))
{
throw new BassException();
}
return Info;
}
[DllImport("bass", EntryPoint = "BASS_RecordGetInfo")]
public static extern bool RecordGetInfo(out RecordInfo info);
[DllImport("bass", EntryPoint = "BASS_RecordGetInput")]
public static extern int RecordGetInput(int Input, out float Volume);
[DllImport("bass")]
private static extern int BASS_RecordGetInput(int Input, IntPtr Volume);
public static int RecordGetInput(int Input)
{
return BASS_RecordGetInput(Input, IntPtr.Zero);
}
[DllImport("bass")]
private static extern IntPtr BASS_RecordGetInputName(int input);
public static string RecordGetInputName(int Input)
{
IntPtr intPtr = BASS_RecordGetInputName(Input);
if (intPtr == IntPtr.Zero)
{
return null;
}
return GetConfig(Configuration.UnicodeDeviceInformation) switch
{
-1 => Extensions.PtrToStringUtf8(intPtr),
0 => Marshal.PtrToStringAnsi(intPtr),
_ => Extensions.PtrToStringUtf8(intPtr),
};
}
[DllImport("bass", EntryPoint = "BASS_RecordSetInput")]
public static extern bool RecordSetInput(int Input, InputFlags Setting, float Volume);
public static int SampleGetChannel(int Sample, bool OnlyNew = false)
{
return SampleGetChannel(Sample, OnlyNew ? BassFlags.Byte : BassFlags.Default);
}
[DllImport("bass", EntryPoint = "BASS_SampleGetChannel")]
public static extern int SampleGetChannel(int Sample, BassFlags Flags);
[DllImport("bass", EntryPoint = "BASS_SampleFree")]
public static extern bool SampleFree(int Handle);
[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
public static extern bool SampleSetData(int Handle, IntPtr Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
public static extern bool SampleSetData(int Handle, byte[] Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
public static extern bool SampleSetData(int Handle, int[] Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
public static extern bool SampleSetData(int Handle, short[] Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleSetData")]
public static extern bool SampleSetData(int Handle, float[] Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleCreate")]
public static extern int CreateSample(int Length, int Frequency, int Channels, int Max, BassFlags Flags);
[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
public static extern bool SampleGetData(int Handle, IntPtr Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
public static extern bool SampleGetData(int Handle, [In][Out] byte[] Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
public static extern bool SampleGetData(int Handle, [In][Out] short[] Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
public static extern bool SampleGetData(int Handle, [In][Out] int[] Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleGetData")]
public static extern bool SampleGetData(int Handle, [In][Out] float[] Buffer);
[DllImport("bass", EntryPoint = "BASS_SampleGetInfo")]
public static extern bool SampleGetInfo(int Handle, [In][Out] SampleInfo Info);
public static SampleInfo SampleGetInfo(int Handle)
{
SampleInfo sampleInfo = new SampleInfo();
if (!SampleGetInfo(Handle, sampleInfo))
{
throw new BassException();
}
return sampleInfo;
}
[DllImport("bass", EntryPoint = "BASS_SampleSetInfo")]
public static extern bool SampleSetInfo(int Handle, SampleInfo Info);
[DllImport("bass")]
private static extern int BASS_SampleGetChannels(int handle, [In][Out] int[] channels);
public static int[] SampleGetChannels(int Handle)
{
int num = BASS_SampleGetChannels(Handle, null);
if (num < 0)
{
return null;
}
int[] array = new int[num];
num = BASS_SampleGetChannels(Handle, array);
if (num >= 0)
{
return array;
}
return null;
}
[DllImport("bass", EntryPoint = "BASS_SampleStop")]
public static extern bool SampleStop(int Handle);
[DllImport("bass", CharSet = CharSet.Unicode)]
private static extern int BASS_SampleLoad(bool mem, string file, long offset, int Length, int max, BassFlags flags);
[DllImport("bass")]
private static extern int BASS_SampleLoad(bool mem, IntPtr file, long offset, int Length, int max, BassFlags flags);
public static int SampleLoad(string File, long Offset, int Length, int MaxNoOfPlaybacks, BassFlags Flags)
{
return BASS_SampleLoad(mem: false, File, Offset, Length, MaxNoOfPlaybacks, Flags | BassFlags.Unicode);
}
public static int SampleLoad(IntPtr Memory, long Offset, int Length, int MaxNoOfPlaybacks, BassFlags Flags)
{
return BASS_SampleLoad(mem: true, new IntPtr(Memory.ToInt64() + Offset), 0L, Length, MaxNoOfPlaybacks, Flags);
}
public static int SampleLoad(byte[] Memory, long Offset, int Length, int MaxNoOfPlaybacks, BassFlags Flags)
{
return GCPin.CreateStreamHelper((IntPtr Pointer) => SampleLoad(Pointer, Offset, Length, MaxNoOfPlaybacks, Flags), Memory);
}
[DllImport("bass", EntryPoint = "BASS_StreamGetFilePosition")]
public static extern long StreamGetFilePosition(int Handle, FileStreamPosition Mode = FileStreamPosition.Current);
[DllImport("bass")]
private static extern int BASS_StreamCreate(int Frequency, int Channels, BassFlags Flags, StreamProcedure Procedure, IntPtr User);
public static int CreateStream(int Frequency, int Channels, BassFlags Flags, StreamProcedure Procedure, IntPtr User = default(IntPtr))
{
int num = BASS_StreamCreate(Frequency, Channels, Flags, Procedure, User);
if (num != 0)
{
ChannelReferences.Add(num, 0, Procedure);
}
return num;
}
[DllImport("bass")]
private static extern int BASS_StreamCreate(int Frequency, int Channels, BassFlags Flags, IntPtr ProcedureType, IntPtr User = default(IntPtr));
public static int CreateStream(int Frequency, int Channels, BassFlags Flags, StreamProcedureType ProcedureType)
{
return BASS_StreamCreate(Frequency, Channels, Flags, new IntPtr((int)ProcedureType), (IntPtr)0);
}
[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
public static extern int StreamPutData(int Handle, IntPtr Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
public static extern int StreamPutData(int Handle, byte[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
public static extern int StreamPutData(int Handle, short[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
public static extern int StreamPutData(int Handle, int[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamPutData")]
public static extern int StreamPutData(int Handle, float[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
public static extern int StreamPutFileData(int Handle, IntPtr Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
public static extern int StreamPutFileData(int Handle, byte[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
public static extern int StreamPutFileData(int Handle, short[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
public static extern int StreamPutFileData(int Handle, int[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamPutFileData")]
public static extern int StreamPutFileData(int Handle, float[] Buffer, int Length);
[DllImport("bass", EntryPoint = "BASS_StreamFree")]
public static extern bool StreamFree(int Handle);
}
public struct BassInfo
{
private BASSInfoFlags flags;
private int hwsize;
private int hwfree;
private int freesam;
private int free3d;
private int minrate;
private int maxrate;
private bool eax;
private int minbuf;
private int dsver;
private int latency;
private DeviceInitFlags initFlags;
private int speakers;
private int freq;
public int TotalHardwareMemory => hwsize;
public int FreeHardwareMemory => hwsize;
public int FreeSampleSlots => freesam;
public int Free3DSampleSlots => free3d;
public int MinSampleRate => minrate;
public int MaxSampleRate => maxrate;
public bool EAXEnabled => eax;
public int MinBufferLength => minbuf;
public int DSVersion => dsver;
public int Latency => latency;
public DeviceInitFlags InitFlags => initFlags;
public int SpeakerCount => speakers;
public int SampleRate => freq;
public bool IsCertified => flags.HasFlag(BASSInfoFlags.Certified);
public bool Supports16BitSamples => flags.HasFlag(BASSInfoFlags.Secondary16Bit);
public bool Supports8BitSamples => flags.HasFlag(BASSInfoFlags.Secondary8Bit);
public bool SupportsContinuousRate => flags.HasFlag(BASSInfoFlags.ContinuousRate);
public bool SupportsDirectSound => !flags.HasFlag(BASSInfoFlags.EmulatedDrivers);
public bool SupportsMonoSamples => flags.HasFlag(BASSInfoFlags.Mono);
public bool SupportsStereoSamples => flags.HasFlag(BASSInfoFlags.Stereo);
}
public struct ChannelInfo
{
private int freq;
private int chans;
private BassFlags flags;
private ChannelType ctype;
private int origres;
private int plugin;
private int sample;
private IntPtr filename;
public int Frequency => freq;
public int Channels => chans;
public BassFlags Flags => flags;
public ChannelType ChannelType => ctype;
public int Plugin => plugin;
public int Sample => sample;
public Resolution Resolution
{
get
{
if (flags.HasFlag(BassFlags.Byte))
{
return Resolution.Byte;
}
if (!flags.HasFlag(BassFlags.Float))
{
return Resolution.Short;
}
return Resolution.Float;
}
}
public int OriginalResolution => origres;
public string FileName
{
get
{
if (!(filename == IntPtr.Zero))
{
return Marshal.PtrToStringAnsi(filename);
}
return null;
}
}
public bool IsDecodingChannel => flags.HasFlag(BassFlags.Decode);
}
public struct DeviceInfo
{
private IntPtr name;
private IntPtr driver;
private DeviceInfoFlags flags;
public string Name => PtrToString(name);
public string Driver => PtrToString(driver);
public bool IsDefault => flags.HasFlag(DeviceInfoFlags.Default);
public bool IsEnabled => flags.HasFlag(DeviceInfoFlags.Enabled);
public bool IsInitialized => flags.HasFlag(DeviceInfoFlags.Initialized);
public bool IsLoopback => flags.HasFlag(DeviceInfoFlags.Loopback);
public DeviceType Type => (DeviceType)(flags & DeviceInfoFlags.TypeMask);
private static string PtrToString(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
{
return null;
}
return Bass.GetConfig(Configuration.UnicodeDeviceInformation) switch
{
-1 => Extensions.PtrToStringUtf8(ptr),
0 => Marshal.PtrToStringAnsi(ptr),
_ => Extensions.PtrToStringUtf8(ptr),
};
}
}
[StructLayout(LayoutKind.Sequential)]
public class FileProcedures
{
public FileCloseProcedure Close;
public FileLengthProcedure Length;
public FileReadProcedure Read;
public FileSeekProcedure Seek;
}
public struct PluginFormat
{
private ChannelType ctype;
private IntPtr name;
private IntPtr exts;
public ChannelType ChannelType => ctype;
public string Name
{
get
{
if (!(name == IntPtr.Zero))
{
return Marshal.PtrToStringAnsi(name);
}
return null;
}
}
public string FileExtensions
{
get
{
if (!(exts == IntPtr.Zero))
{
return Marshal.PtrToStringAnsi(exts);
}
return null;
}
}
}
public struct PluginInfo
{
private int version;
private int formatc;
private IntPtr formats;
public Version Version => Extensions.GetVersion(version);
public PluginFormat[] Formats
{
get
{
PluginFormat[] array = new PluginFormat[formatc];
int num = Marshal.SizeOf<PluginFormat>();
int num2 = 0;
while (num2 < formatc)
{
array[num2] = Marshal.PtrToStructure<PluginFormat>(formats);
num2++;
formats += num;
}
return array;
}
}
}
public struct RecordInfo
{
private RecordInfoFlags flags;
private int formats;
private int inputs;
private bool singlein;
private int freq;
public RecordFormatFlags SupportedFormats => (RecordFormatFlags)(formats & 0xFFFFFF);
public int Inputs => inputs;
public bool SingleInput => singlein;
public int Frequency => freq;
public int Channels => formats >> 24;
public bool IsCertified => flags.HasFlag(RecordInfoFlags.Certified);
public bool SupportsDirectSound => flags.HasFlag(RecordInfoFlags.EmulatedDrivers);
}
[StructLayout(LayoutKind.Sequential)]
public class SampleInfo
{
public int Frequency = 44100;
public float Volume = 1f;
public float Pan;
public BassFlags Flags;
public int Length;
public int Max = 1;
public int OriginalResolution;
public int Channels = 2;
public int MinGap;
public Mode3D Mode3D;
public float MinDistance;
public float MaxDistance;
public int InsideAngle;
public int OutsideAngle;
public float OutsideVolume = 1f;
public VAMMode VAM = VAMMode.Hardware;
public int Priority;
}
[StructLayout(LayoutKind.Sequential)]
public class Vector3D
{
public float X;
public float Y;
public float Z;
public Vector3D()
{
}
public Vector3D(float X, float Y, float Z)
{
this.X = X;
this.Y = Y;
this.Z = Z;
}
public override string ToString()
{
return $"({X}, {Y}, {Z})";
}
}
public static class BitHelper
{
public static long HiDword(this long DWord)
{
return DWord >>> 32;
}
public static long LoDword(this long DWord)
{
return DWord & 0xFFFFFFFFu;
}
public static int HiWord(this int DWord)
{
return DWord >>> 16;
}
public static int LoWord(this int DWord)
{
return DWord & 0xFFFF;
}
public static byte HiByte(this short Word)
{
return (byte)(Word >> 8);
}
public static byte LoByte(this short Word)
{
return (byte)((uint)Word & 0xFFu);
}
public static short MakeWord(byte Low, byte High)
{
return (short)(Low | (ushort)(High << 8));
}
public static int MakeLong(short Low, short High)
{
return (ushort)Low | (High << 16);
}
}
public enum Errors
{
Unknown = -1,
OK = 0,
Memory = 1,
FileOpen = 2,
Driver = 3,
BufferLost = 4,
Handle = 5,
SampleFormat = 6,
Position = 7,
Init = 8,
Start = 9,
[Obsolete("Use SSL instead.")]
SLL = 10,
SSL = 10,
NoCD = 12,
CDTrack = 13,
Already = 14,
NotPaused = 16,
NotAudioTrack = 17,
NoChannel = 18,
Type = 19,
Parameter = 20,
No3D = 21,
NoEAX = 22,
Device = 23,
NotPlaying = 24,
SampleRate = 25,
NotFile = 27,
NoHW = 29,
Empty = 31,
NoInternet = 32,
Create = 33,
NoFX = 34,
Playing = 35,
NotAvailable = 37,
Decode = 38,
DirectX = 39,
Timeout = 40,
FileFormat = 41,
Speaker = 42,
Version = 43,
Codec = 44,
Ended = 45,
Busy = 46,
Unstreamable = 47,
WmaLicense = 1000,
WM9 = 1001,
WmaAccesDenied = 1002,
WmaCodec = 1003,
WmaIndividual = 1004,
Wasapi = 5000,
AcmCancel = 2000,
CastDenied = 2100,
Mp4NoStream = 6000
}
public static class Extensions
{
private static bool? _floatable;
public static bool SupportsFloatingPoint
{
get
{
if (_floatable.HasValue)
{
return _floatable.Value;
}
int num = Bass.CreateStream(44100, 1, BassFlags.Float, StreamProcedureType.Dummy);
_floatable = num != 0;
if (_floatable.Value)
{
Bass.StreamFree(num);
}
return _floatable.Value;
}
}
public static StreamProcedure SilenceStreamProcedure { get; } = delegate(int Handle, IntPtr Buffer, int Length, IntPtr User)
{
for (int i = 0; i < Length; i++)
{
Marshal.WriteByte(Buffer, i, 0);
}
return Length;
};
public static T Clip<T>(this T Item, T MinValue, T MaxValue) where T : IComparable<T>
{
if (Item.CompareTo(MaxValue) > 0)
{
return MaxValue;
}
if (Item.CompareTo(MinValue) >= 0)
{
return Item;
}
return MinValue;
}
public static BassFlags ToBassFlag(this Resolution Resolution)
{
return Resolution switch
{
Resolution.Byte => BassFlags.Byte,
Resolution.Float => BassFlags.Float,
_ => BassFlags.Default,
};
}
public static BassFlags SpeakerN(int N)
{
return (BassFlags)(N << 24);
}
public static Version GetVersion(int Num)
{
return new Version((Num >> 24) & 0xFF, (Num >> 16) & 0xFF, (Num >> 8) & 0xFF, Num & 0xFF);
}
public static string ChannelCountToString(int Channels)
{
switch (Channels)
{
case 1:
return "Mono";
case 2:
return "Stereo";
case 3:
return "2.1";
case 4:
return "Quad";
case 5:
return "4.1";
case 6:
return "5.1";
case 7:
return "6.1";
default:
if (Channels < 1)
{
throw new ArgumentException("Channels must be greater than Zero.");
}
return Channels + " Channels";
}
}
public static string[] ExtractMultiStringAnsi(IntPtr Ptr)
{
List<string> list = new List<string>();
while (true)
{
string text = ((Ptr == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(Ptr));
if (string.IsNullOrEmpty(text))
{
break;
}
list.Add(text);
Ptr += text.Length + 1;
}
return list.ToArray();
}
public static string[] ExtractMultiStringUtf8(IntPtr Ptr)
{
List<string> list = new List<string>();
while (true)
{
int Size;
string text = PtrToStringUtf8(Ptr, out Size);
if (string.IsNullOrEmpty(text))
{
break;
}
list.Add(text);
Ptr += Size + 1;
}
return list.ToArray();
}
private unsafe static string PtrToStringUtf8(IntPtr Ptr, out int Size)
{
Size = 0;
byte* ptr = (byte*)Ptr.ToPointer();
if (Ptr == IntPtr.Zero || *ptr == 0)
{
return null;
}
while (ptr[Size] != 0)
{
Size++;
}
byte[] array = new byte[Size];
Marshal.Copy(Ptr, array, 0, Size);
return Encoding.UTF8.GetString(array, 0, array.Length);
}
public static string PtrToStringUtf8(IntPtr Ptr)
{
int Size;
return PtrToStringUtf8(Ptr, out Size);
}
public static FileProcedures StreamFileProcedures(Stream InputStream)
{
return new StreamFileProcedures(InputStream);
}
public static void ApplyOn<T>(this Effect<T> Effect, MediaPlayer Player, int Priority = 0) where T : class, IEffectParameter, new()
{
Effect.ApplyOn(Player.Handle, Priority);
Player.MediaLoaded += delegate(int NewHandle)
{
Effect.Dispose();
Effect.ApplyOn(NewHandle, Priority);
};
}
}
public interface IEffectParameter
{
EffectType FXType { get; }
}
public class MediaPlayer : INotifyPropertyChanged, IDisposable
{
private readonly SynchronizationContext _syncContext;
private int _handle;
private bool _restartOnNextPlayback;
private double _freq = 44100.0;
private double _pan;
private int _dev = -1;
private double _vol = 0.5;
private bool _loop;
private string _title = "";
private string _artist = "";
private string _album = "";
protected internal int Handle
{
get
{
return _handle;
}
private set
{
if (!Bass.ChannelGetInfo(value, out var _))
{
throw new ArgumentException("Invalid Channel Handle: " + value);
}
_handle = value;
Bass.ChannelSetSync(Handle, SyncFlags.Free, 0L, GetSyncProcedure(delegate
{
this.Disposed?.Invoke(this, EventArgs.Empty);
}), (IntPtr)0);
Bass.ChannelSetSync(Handle, SyncFlags.Stop, 0L, GetSyncProcedure(delegate
{
this.MediaFailed?.Invoke(this, EventArgs.Empty);
}), (IntPtr)0);
Bass.ChannelSetSync(Handle, SyncFlags.End, 0L, GetSyncProcedure(delegate
{
try
{
if (!Bass.ChannelHasFlag(Handle, BassFlags.Loop))
{
this.MediaEnded?.Invoke(this, EventArgs.Empty);
}
}
finally
{
OnStateChanged();
}
}), (IntPtr)0);
}
}
public double Frequency
{
get
{
return _freq;
}
set
{
if (Bass.ChannelSetAttribute(Handle, ChannelAttribute.Frequency, value))
{
_freq = value;
OnPropertyChanged("Frequency");
}
}
}
public double Balance
{
get
{
return _pan;
}
set
{
if (Bass.ChannelSetAttribute(Handle, ChannelAttribute.Pan, value))
{
_pan = value;
OnPropertyChanged("Balance");
}
}
}
public int Device
{
get
{
return _dev = ((_dev == -1) ? Bass.ChannelGetDevice(Handle) : _dev);
}
set
{
if ((Bass.GetDeviceInfo(value).IsInitialized || Bass.Init(value, 44100, DeviceInitFlags.Default, (IntPtr)0, (IntPtr)0)) && Bass.ChannelSetDevice(Handle, value))
{
_dev = value;
OnPropertyChanged("Device");
}
}
}
public double Volume
{
get
{
return _vol;
}
set
{
if (Bass.ChannelSetAttribute(Handle, ChannelAttribute.Volume, value))
{
_vol = value;
OnPropertyChanged("Volume");
}
}
}
public bool Loop
{
get
{
return _loop;
}
set
{
if (!(value ? (!Bass.ChannelAddFlag(Handle, BassFlags.Loop)) : (!Bass.ChannelRemoveFlag(Handle, BassFlags.Loop))))
{
_loop = value;
OnPropertyChanged("Loop");
}
}
}
public string Title
{
get
{
return _title;
}
private set
{
_title = value;
OnPropertyChanged("Title");
}
}
public string Artist
{
get
{
return _artist;
}
private set
{
_artist = value;
OnPropertyChanged("Artist");
}
}
public string Album
{
get
{
return _album;
}
private set
{
_album = value;
OnPropertyChanged("Album");
}
}
public PlaybackState State
{
get
{
if (Handle != 0)
{
return Bass.ChannelIsActive(Handle);
}
return PlaybackState.Stopped;
}
}
public TimeSpan Duration => TimeSpan.FromSeconds(Bass.ChannelBytes2Seconds(Handle, Bass.ChannelGetLength(Handle)));
public TimeSpan Position
{
get
{
return TimeSpan.FromSeconds(Bass.ChannelBytes2Seconds(Handle, Bass.ChannelGetPosition(Handle)));
}
set
{
Bass.ChannelSetPosition(Handle, Bass.ChannelSeconds2Bytes(Handle, value.TotalSeconds));
}
}
public event EventHandler Disposed;
public event EventHandler MediaEnded;
public event EventHandler MediaFailed;
public event Action<int> MediaLoaded;
public event PropertyChangedEventHandler PropertyChanged;
private SyncProcedure GetSyncProcedure(Action Handler)
{
return delegate
{
if (Handler != null)
{
if (_syncContext == null)
{
Handler();
}
else
{
_syncContext.Post(delegate
{
Handler();
}, null);
}
}
};
}
static MediaPlayer()
{
int currentDevice = Bass.CurrentDevice;
if (currentDevice == -1 || !Bass.GetDeviceInfo(Bass.CurrentDevice).IsInitialized)
{
Bass.Init(currentDevice, 44100, DeviceInitFlags.Default, (IntPtr)0, (IntPtr)0);
}
}
public MediaPlayer()
{
_syncContext = SynchronizationContext.Current;
}
protected virtual int OnLoad(string FileName)
{
return Bass.CreateStream(FileName, 0L, 0L);
}
public bool Play()
{
try
{
bool num = Bass.ChannelPlay(Handle, _restartOnNextPlayback);
if (num)
{
_restartOnNextPlayback = false;
}
return num;
}
finally
{
OnStateChanged();
}
}
public bool Pause()
{
try
{
return Bass.ChannelPause(Handle);
}
finally
{
OnStateChanged();
}
}
public bool Stop()
{
try
{
_restartOnNextPlayback = true;
return Bass.ChannelStop(Handle);
}
finally
{
OnStateChanged();
}
}
public async Task<bool> LoadAsync(string FileName)
{
try
{
if (Handle != 0)
{
Bass.StreamFree(Handle);
}
}
catch
{
}
if (_dev != -1)
{
Bass.CurrentDevice = _dev;
}
int currentDevice = Bass.CurrentDevice;
if (currentDevice == -1 || !Bass.GetDeviceInfo(Bass.CurrentDevice).IsInitialized)
{
Bass.Init(currentDevice, 44100, DeviceInitFlags.Default, (IntPtr)0, (IntPtr)0);
}
int num = await Task.Run(() => OnLoad(FileName));
if (num == 0)
{
return false;
}
Handle = num;
TagReader tagReader = TagReader.Read(Handle);
Title = ((!string.IsNullOrWhiteSpace(tagReader.Title)) ? tagReader.Title : Path.GetFileNameWithoutExtension(FileName));
Artist = tagReader.Artist;
Album = tagReader.Album;
InitProperties();
this.MediaLoaded?.Invoke(num);
OnPropertyChanged("");
return true;
}
public virtual void Dispose()
{
try
{
if (Bass.StreamFree(Handle))
{
_handle = 0;
}
}
finally
{
OnStateChanged();
}
}
protected virtual void InitProperties()
{
Frequency = _freq;
Balance = _pan;
Volume = _vol;
Loop = _loop;
}
private void OnStateChanged()
{
OnPropertyChanged("State");
}
protected virtual void OnPropertyChanged([CallerMemberName] string PropertyName = null)
{
Action f = delegate
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
};
if (_syncContext == null)
{
f();
return;
}
_syncContext.Post(delegate
{
f();
}, null);
}
}
public static class ChannelReferences
{
private static readonly ConcurrentDictionary<Tuple<int, int>, object> Procedures = new ConcurrentDictionary<Tuple<int, int>, object>();
private static readonly SyncProcedure Freeproc = Callback;
public static void Add(int Handle, int SpecificHandle, object proc)
{
if (proc != null && !proc.Equals(Freeproc))
{
Tuple<int, int> key = Tuple.Create(Handle, SpecificHandle);
bool num = Procedures.ContainsKey(key);
if (Freeproc != null && Procedures.All((KeyValuePair<Tuple<int, int>, object> pair) => pair.Key.Item1 != Handle))
{
Bass.ChannelSetSync(Handle, SyncFlags.Free, 0L, Freeproc, (IntPtr)0);
}
if (num)
{
Procedures[key] = proc;
}
else
{
Procedures.TryAdd(key, proc);
}
}
}
public static void Remove(int Handle, int SpecialHandle)
{
Tuple<int, int> key = Tuple.Create(Handle, SpecialHandle);
Procedures.TryRemove(key, out var _);
}
private static void Callback(int Handle, int Channel, int Data, IntPtr User)
{
Tuple<int, int>[] array = (from Pair in Procedures
where Pair.Key.Item1 == Channel
select Pair.Key).ToArray();
foreach (Tuple<int, int> key in array)
{
Procedures.TryRemove(key, out var _);
}
}
}
public enum Resolution
{
Short,
Byte,
Float
}
internal class StreamFileProcedures : FileProcedures
{
private readonly Stream _stream;
private byte[] b;
public StreamFileProcedures(Stream InputStream)
{
_stream = InputStream;
if (!_stream.CanRead)
{
throw new ArgumentException("Provide a readable stream", "InputStream");
}
Close = delegate
{
_stream.Dispose();
};
Length = (IntPtr M) => _stream.Length;
Read = ReadProc;
Seek = SeekProc;
}
private int ReadProc(IntPtr Buffer, int Length, IntPtr User)
{
try
{
if (b == null || b.Length < Length)
{
b = new byte[Length];
}
int num = _stream.Read(b, 0, Length);
Marshal.Copy(b, 0, Buffer, num);
return num;
}
catch
{
return 0;
}
}
private bool SeekProc(long Offset, IntPtr User)
{
if (!_stream.CanSeek)
{
return false;
}
try
{
_stream.Seek(Offset, SeekOrigin.Current);
return true;
}
catch
{
return false;
}
}
}
public class ID3v2Tag
{
private enum TextEncodings
{
Ascii,
Utf16,
Utf16Be,
Utf8
}
private IntPtr _ptr;
private readonly Version _versionInfo;
public Dictionary<string, string> TextFrames { get; } = new Dictionary<string, string>();
public List<PictureTag> PictureFrames { get; } = new List<PictureTag>();
public ID3v2Tag(IntPtr Pointer)
{
_ptr = Pointer;
if (ReadText(3, TextEncodings.Ascii) != "ID3")
{
throw new DataMisalignedException("ID3v2 info not found");
}
_versionInfo = new Version(2, ReadByte(), ReadByte());
_ptr += 1;
ReadAllFrames(ReadSize());
}
public ID3v2Tag(int Channel)
: this(Bass.ChannelGetTags(Channel, TagType.ID3v2))
{
}
private void ReadAllFrames(int Length)
{
int num = ((_versionInfo.Minor == 2) ? 3 : 4);
while (Length > 10)
{
if (ReadByte() == 0)
{
Length--;
continue;
}
_ptr -= 1;
string frameID = ReadText(num, TextEncodings.Ascii);
int val = Convert.ToInt32(ReadUInt(num));
if (num == 4)
{
ReadUInt(2);
}
val = Math.Min(val, Length - 10);
if (!AddFrame(frameID, val))
{
_ptr += val;
}
Length -= val + 10;
}
}
private bool AddFrame(string FrameID, int Length)
{
if (FrameID == null || !IsValidFrameID(FrameID))
{
return false;
}
if (FrameID[0] == 'T' || FrameID[0] == 'W')
{
TextEncodings textEncodings;
if (FrameID[0] == 'W')
{
textEncodings = TextEncodings.Ascii;
}
else
{
textEncodings = (TextEncodings)ReadByte();
Length--;
if (!Enum.IsDefined(typeof(TextEncodings), textEncodings))
{
return false;
}
}
string value = ReadText(Length, textEncodings);
AddTextFrame(FrameID, value);
return true;
}
switch (FrameID)
{
case "POPM":
{
ReadText(Length, TextEncodings.Ascii, ref Length, DetectEncoding: true);
string value2 = ReadByte().ToString();
if (--Length > 8)
{
return false;
}
_ptr += Length;
AddTextFrame("POPM", value2);
return true;
}
case "COM":
case "COMM":
{
TextEncodings textEncodings3 = (TextEncodings)ReadByte();
Length--;
if (!Enum.IsDefined(typeof(TextEncodings), textEncodings3))
{
return false;
}
_ptr += 3;
Length -= 3;
ReadText(Length, textEncodings3, ref Length, DetectEncoding: true);
AddTextFrame("COMM", ReadText(Length, textEncodings3));
return true;
}
case "APIC":
{
TextEncodings textEncodings2 = (TextEncodings)ReadByte();
Length--;
if (!Enum.IsDefined(typeof(TextEncodings), textEncodings2))
{
return false;
}
string mimeType = ReadText(Length, TextEncodings.Ascii, ref Length, DetectEncoding: true);
PictureTypes pictureType = (PictureTypes)ReadByte();
Length--;
ReadText(Length, textEncodings2, ref Length, DetectEncoding: true);
byte[] array = new byte[Length];
Read(array, 0, Length);
PictureFrames.Add(new PictureTag
{
Data = array,
MimeType = mimeType,
PictureType = pictureType
});
return true;
}
default:
return false;
}
}
private static bool IsValidFrameID(string FrameID)
{
if (FrameID == null || (FrameID.Length != 3 && FrameID.Length != 4))
{
return false;
}
return FrameID.Cast<char>().All((char ch) => char.IsUpper(ch) || char.IsDigit(ch));
}
private void AddTextFrame(string Key, string Value)
{
if (TextFrames.ContainsKey(Key))
{
Dictionary<string, string> textFrames = TextFrames;
textFrames[Key] = textFrames[Key] + ";" + Value;
}
else
{
TextFrames.Add(Key, Value);
}
}
private string ReadText(int MaxLength, TextEncodings TEncoding)
{
int ReadedLength = 0;
return ReadText(MaxLength, TEncoding, ref ReadedLength, DetectEncoding: false);
}
private string ReadText(int MaxLength, TextEncodings TEncoding, ref int ReadedLength, bool DetectEncoding)
{
if (MaxLength <= 0)
{
return "";
}
int num = 0;
using MemoryStream memoryStream = new MemoryStream();
if (DetectEncoding && MaxLength >= 3)
{
byte[] array = new byte[3];
Read(array, 0, array.Length);
if (array[0] == byte.MaxValue && array[1] == 254)
{
TEncoding = TextEncodings.Utf16;
_ptr -= 1;
num++;
MaxLength -= 2;
}
else if (array[0] == 254 && array[1] == byte.MaxValue)
{
TEncoding = TextEncodings.Utf16Be;
_ptr -= 1;
num++;
MaxLength -= 2;
}
else if (array[0] == 239 && array[1] == 187 && array[2] == 191)
{
TEncoding = TextEncodings.Utf8;
MaxLength -= 3;
}
_ptr -= 3;
num += 3;
}
bool flag = TEncoding == TextEncodings.Utf16 || TEncoding == TextEncodings.Utf16Be;
while (MaxLength > 0)
{
byte b = ReadByte();
if (b != 0)
{
memoryStream.WriteByte(b);
}
else
{
if (!flag)
{
break;
}
byte b2 = ReadByte();
if (b2 == 0)
{
break;
}
memoryStream.WriteByte(b);
memoryStream.WriteByte(b2);
MaxLength--;
}
MaxLength--;
}
if (MaxLength < 0)
{
_ptr += MaxLength;
}
ReadedLength -= num;
return GetEncoding(TEncoding).GetString(memoryStream.ToArray(), 0, (int)memoryStream.Length);
}
private byte ReadByte()
{
byte[] array = new byte[1];
Read(array, 0, 1);
return array[0];
}
private uint ReadUInt(int Length)
{
if (Length > 4 || Length < 1)
{
throw new ArgumentOutOfRangeException("Length", "ReadUInt method can read 1-4 byte(s)");
}
byte[] array = new byte[Length];
byte[] array2 = new byte[4];
Read(array, 0, Length);
array.CopyTo(array2, 4 - array.Length);
Array.Reverse((Array)array2);
return BitConverter.ToUInt32(array2, 0);
}
private int ReadSize()
{
return ReadByte() * 2097152 + ReadByte() * 16384 + ReadByte() * 128 + ReadByte();
}
private static Encoding GetEncoding(TextEncodings TEncoding)
{
return TEncoding switch
{
TextEncodings.Utf16 => Encoding.Unicode,
TextEncodings.Utf16Be => Encoding.GetEncoding("UTF-16BE"),
_ => Encoding.UTF8,
};
}
private void Read(byte[] Buffer, int Offset, int Count)
{
Marshal.Copy(_ptr, Buffer, Offset, Count);
_ptr += Count;
}
}
public class PictureTag
{
public string MimeType;
public PictureTypes PictureType;
public byte[] Data;
}
public enum PictureTypes
{
Other,
FileIcon,
OtherFileIcon,
FrontCover,
BackCover,
LeafletPage,
Media,
Soloist,
Artist,
Conductor,
Band,
Composer,
Lyricist,
RecordingLocation,
DuringRecording,
DuringPerformance,
Movie,
ABrightColouredFish,
Illustration,
BandLogo,
PublisherLogo
}
internal static class LookupTables
{
public static readonly TagProperties<IEnumerable<string>> Ape = new TagProperties<IEnumerable<string>>
{
Title = new string[1] { "title" },
Artist = new string[1] { "artist" },
Album = new string[1] { "album" },
AlbumArtist = new string[1] { "album artist" },
Track = new string[1] { "track" },
Year = new string[1] { "year" },
Genre = new string[1] { "genre" },
Copyright = new string[1] { "copyright" },
Encoder = new string[1] { "encodedby" },
Publisher = new string[1] { "label" },
Composer = new string[1] { "composer" },
Conductor = new string[1] { "conductor" },
Lyricist = new string[1] { "lyricist" },
Remixer = new string[1] { "remixer" },
Producer = new string[1] { "producer" },
Comment = new string[1] { "comment" },
Grouping = new string[1] { "grouping" },
Mood = new string[1] { "mood" },
Rating = new string[1] { "rating" },
ISRC = new string[1] { "isrc" },
BPM = new string[1] { "bpm" }
};
public static readonly TagProperties<IEnumerable<string>> Ogg = new TagProperties<IEnumerable<string>>
{
Title = new string[1] { "title" },
Artist = new string[1] { "artist" },
Album = new string[1] { "album" },
AlbumArtist = new string[1] { "albumartist" },
Track = new string[1] { "tracknumber" },
Year = new string[1] { "date" },
Genre = new string[1] { "genre" },
Copyright = new string[1] { "copyright" },
Encoder = new string[1] { "encodedby" },
Publisher = new string[1] { "label" },
Composer = new string[1] { "composer" },
Conductor = new string[1] { "conductor" },
Lyricist = new string[1] { "lyricist" },
Remixer = new string[1] { "remixer" },
Producer = new string[1] { "producer" },
Comment = new string[1] { "comment" },
Grouping = new string[1] { "grouping" },
Mood = new string[1] { "mood" },
Rating = new string[1] { "rating" },
ISRC = new string[1] { "isrc" },
BPM = new string[1] { "bpm" }
};
public static readonly TagProperties<IEnumerable<string>> RiffInfo = new TagProperties<IEnumerable<string>>
{
Title = new string[1] { "inam" },
Artist = new string[1] { "iart" },
Album = new string[1] { "iprd" },
AlbumArtist = new string[1] { "isbj" },
Track = new string[2] { "itrk", "iprt" },
Year = new string[1] { "icrd" },
Genre = new string[1] { "ignr" },
Copyright = new string[1] { "icop" },
Encoder = new string[1] { "isft" },
Publisher = new string[1] { "icms" },
Composer = new string[1] { "ieng" },
Conductor = new string[1] { "itch" },
Lyricist = new string[1] { "iwri" },
Remixer = new string[1] { "iedt" },
Producer = new string[1] { "ipro" },
Comment = new string[1] { "icmt" },
Grouping = new string[1] { "isrf" },
Mood = new string[1] { "ikey" },
Rating = new string[1] { "ishp" },
ISRC = new string[1] { "isrc" },
BPM = new string[1] { "ibpm" }
};
public static readonly TagProperties<IEnumerable<string>> Mp4 = new TagProperties<IEnumerable<string>>
{
Title = new string[1] { "©nam" },
Artist = new string[1] { "©art" },
Album = new string[1] { "©alb" },
AlbumArtist = new string[1] { "aart" },
Track = new string[1] { "trkn" },
Year = new string[1] { "©day" },
Genre = new string[1] { "©gen" },
Copyright = new string[1] { "cprt" },
Encoder = new string[1] { "©too" },
Composer = new string[1] { "©wrt" },
Comment = new string[1] { "©cmt" },
Grouping = new string[1] { "©grp" },
Rating = new string[1] { "rtng" }
};
public static readonly TagProperties<IEnumerable<string>> Id3v2 = new TagProperties<IEnumerable<string>>
{
Title = new string[2] { "TIT2", "TT2" },
Artist = new string[2] { "TPE1", "TP1" },
Album = new string[2] { "TALB", "TAL" },
AlbumArtist = new string[2] { "TPE2", "TP2" },
Subtitle = new string[2] { "TIT3", "TT3" },
Track = new string[2] { "TRK", "TRCK" },
Year = new string[2] { "TYER", "TYE" },
Genre = new string[2] { "TCON", "TCO" },
Copyright = new string[2] { "TCOP", "TCR" },
Encoder = new string[2] { "TENC", "TEN" },
Publisher = new string[2] { "TPUB", "TPB" },
Composer = new string[2] { "TCOM", "TCM" },
Conductor = new string[2] { "TPE3", "TP3" },
Lyricist = new string[2] { "TEXT", "TXT" },
Remixer = new string[2] { "TPE4", "TP4" },
Producer = new string[1] { "TIPL" },
Comment = new string[2] { "COMM", "COM" },
Grouping = new string[2] { "TIT1", "TT1" },
Mood = new string[1] { "TMOO" },
Rating = new string[1] { "POPM" },
ISRC = new string[1] { "TSCR" },
BPM = new string[2] { "TBPM", "TBP" }
};
}
public class TagProperties<T>
{
public T Title { get; set; }
public T Artist { get; set; }
public T Album { get; set; }
public T AlbumArtist { get; set; }
public T Subtitle { get; set; }
public T BPM { get; set; }
public T Composer { get; set; }
public T Copyright { get; set; }
public T Genre { get; set; }
public T Grouping { get; set; }
public T Publisher { get; set; }
public T Encoder { get; set; }
public T Lyricist { get; set; }
public T Year { get; set; }
public T Conductor { get; set; }
public T Track { get; set; }
public T Producer { get; set; }
public T Comment { get; set; }
public T Mood { get; set; }
public T Rating { get; set; }
public T ISRC { get; set; }
public T Remixer { get; set; }
}
public sealed class TagReader : TagProperties<string>
{
public Dictionary<string, string> Other { get; } = new Dictionary<string, string>();
public List<PictureTag> Pictures { get; } = new List<PictureTag>();
public string Lyrics { get; set; }
public static TagReader Read(string FileName)
{
Bass.Init(-1, 44100, DeviceInitFlags.Default, (IntPtr)0, (IntPtr)0);
int num = Bass.CreateStream(FileName, 0L, 0L, BassFlags.Prescan);
TagReader tagReader = null;
if (num != 0)
{
tagReader = Read(num);
Bass.StreamFree(num);
}
else
{
num = Bass.MusicLoad(FileName, 0L, 0, BassFlags.Prescan);
if (num != 0)
{
tagReader = Read(num);
Bass.MusicFree(num);
}
}
if (!string.IsNullOrWhiteSpace(tagReader?.Title))
{
tagReader.Title = Path.GetFileNameWithoutExtension(FileName);
}
return tagReader;
}
public static TagReader Read(int Channel)
{
TagReader tagReader = new TagReader();
switch (Bass.ChannelGetInfo(Channel).ChannelType)
{
case ChannelType.MP1:
case ChannelType.MP2:
case ChannelType.MP3:
if (!tagReader.ReadID3v2(Channel) && !tagReader.ReadID3v1(Channel) && !tagReader.ReadApe(Channel) && !tagReader.ReadBWF(Channel))
{
}
break;
case ChannelType.OGG:
if (!tagReader.ReadOgg(Channel) && !tagReader.ReadApe(Channel))
{
}
break;
case ChannelType.AAC:
case ChannelType.MP4:
if (!tagReader.ReadMp4(Channel) && !tagReader.ReadID3v2(Channel) && !tagReader.ReadApe(Channel) && !tagReader.ReadOgg(Channel))
{
}
break;
case ChannelType.Wave:
case ChannelType.WavePCM:
case ChannelType.WaveFloat:
if (!tagReader.ReadRiffInfo(Channel) && !tagReader.ReadBWF(Channel) && !tagReader.ReadID3v2(Channel))
{
}
break;
case ChannelType.DSD:
tagReader.Title = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.DSDTitle));
tagReader.Artist = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.DSDArtist));
break;
case ChannelType.MOD:
tagReader.Title = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.MusicName));
tagReader.Artist = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.MusicAuth));
tagReader.Comment = Marshal.PtrToStringAnsi(Bass.ChannelGetTags(Channel, TagType.MusicMessage));
break;
default:
if (!tagReader.ReadApe(Channel) && !tagReader.ReadOgg(Channel) && !tagReader.ReadID3v2(Channel))
{
tagReader.ReadID3v1(Channel);
}
break;
}
if (string.IsNullOrWhiteSpace(tagReader.Lyrics))
{
IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.Lyrics3v2);
if (intPtr != IntPtr.Zero)
{
tagReader.Lyrics = Marshal.PtrToStringAnsi(intPtr);
}
}
return tagReader;
}
private IEnumerable<KeyValuePair<string, string>> ReadUsingLookupTable(IEnumerable<string> Tags, TagProperties<IEnumerable<string>> LookupTable, char Separator)
{
foreach (string Tag in Tags)
{
string[] array = Tag.Split(new char[1] { Separator });
string key = array[0].ToLower();
string value = array[1];
if (!SetTagUsingLookupTable(key, value, LookupTable))
{
yield return new KeyValuePair<string, string>(array[0], value);
}
}
}
private bool SetTagUsingLookupTable(string Key, string Value, TagProperties<IEnumerable<string>> LookupTable)
{
if (LookupTable.Title != null && LookupTable.Title.Contains(Key))
{
base.Title = Value;
}
else if (LookupTable.Artist != null && LookupTable.Artist.Contains(Key))
{
base.Artist = Value;
}
else if (LookupTable.Album != null && LookupTable.Album.Contains(Key))
{
base.Album = Value;
}
else if (LookupTable.AlbumArtist != null && LookupTable.AlbumArtist.Contains(Key))
{
base.AlbumArtist = Value;
}
else if (LookupTable.Subtitle != null && LookupTable.Subtitle.Contains(Key))
{
base.Subtitle = Value;
}
else if (LookupTable.BPM != null && LookupTable.BPM.Contains(Key))
{
base.BPM = Value;
}
else if (LookupTable.Composer != null && LookupTable.Composer.Contains(Key))
{
base.Composer = Value;
}
else if (LookupTable.Copyright != null && LookupTable.Copyright.Contains(Key))
{
base.Copyright = Value;
}
else if (LookupTable.Genre != null && LookupTable.Genre.Contains(Key))
{
base.Genre = Value;
}
else if (LookupTable.Grouping != null && LookupTable.Grouping.Contains(Key))
{
base.Grouping = Value;
}
else if (LookupTable.Publisher != null && LookupTable.Publisher.Contains(Key))
{
base.Publisher = Value;
}
else if (LookupTable.Encoder != null && LookupTable.Encoder.Contains(Key))
{
base.Encoder = Value;
}
else if (LookupTable.Lyricist != null && LookupTable.Lyricist.Contains(Key))
{
base.Lyricist = Value;
}
else if (LookupTable.Year != null && LookupTable.Year.Contains(Key))
{
base.Year = Value;
}
else if (LookupTable.Conductor != null && LookupTable.Conductor.Contains(Key))
{
base.Conductor = Value;
}
else if (LookupTable.Track != null && LookupTable.Track.Contains(Key))
{
base.Track = Value;
}
else if (LookupTable.Producer != null && LookupTable.Producer.Contains(Key))
{
base.Producer = Value;
}
else if (LookupTable.Comment != null && LookupTable.Comment.Contains(Key))
{
base.Comment = Value;
}
else if (LookupTable.Mood != null && LookupTable.Mood.Contains(Key))
{
base.Mood = Value;
}
else if (LookupTable.Rating != null && LookupTable.Rating.Contains(Key))
{
base.Rating = Value;
}
else if (LookupTable.ISRC != null && LookupTable.ISRC.Contains(Key))
{
base.ISRC = Value;
}
else
{
if (LookupTable.Remixer == null || !LookupTable.Remixer.Contains(Key))
{
return false;
}
base.Remixer = Value;
}
return true;
}
public bool ReadApe(int Channel)
{
IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.APE);
if (intPtr == IntPtr.Zero)
{
return false;
}
foreach (KeyValuePair<string, string> item in ReadUsingLookupTable(Extensions.ExtractMultiStringUtf8(intPtr), LookupTables.Ape, '='))
{
Other.Add(item.Key, item.Value);
}
return true;
}
public bool ReadOgg(int Channel)
{
IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.OGG);
if (intPtr == IntPtr.Zero)
{
return false;
}
foreach (KeyValuePair<string, string> item in ReadUsingLookupTable(Extensions.ExtractMultiStringUtf8(intPtr), LookupTables.Ogg, '='))
{
Other.Add(item.Key, item.Value);
}
if (string.IsNullOrWhiteSpace(base.Encoder))
{
IntPtr intPtr2 = Bass.ChannelGetTags(Channel, TagType.OggEncoder);
if (intPtr2 != IntPtr.Zero)
{
base.Encoder = Extensions.PtrToStringUtf8(intPtr2);
}
}
return true;
}
public bool ReadRiffInfo(int Channel)
{
IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.RiffInfo);
if (intPtr == IntPtr.Zero)
{
return false;
}
foreach (KeyValuePair<string, string> item in ReadUsingLookupTable(Extensions.ExtractMultiStringAnsi(intPtr), LookupTables.RiffInfo, '='))
{
Other.Add(item.Key, item.Value);
}
return true;
}
public bool ReadMp4(int Channel)
{
IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.MP4);
if (intPtr == IntPtr.Zero)
{
return false;
}
foreach (KeyValuePair<string, string> item in ReadUsingLookupTable(Extensions.ExtractMultiStringUtf8(intPtr), LookupTables.Mp4, '='))
{
Other.Add(item.Key, item.Value);
}
return true;
}
public bool ReadID3v1(int Channel)
{
IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.ID3);
if (intPtr == IntPtr.Zero)
{
return false;
}
ID3v1Tag iD3v1Tag = Marshal.PtrToStructure<ID3v1Tag>(intPtr);
base.Title = iD3v1Tag.Title;
base.Artist = iD3v1Tag.Artist;
base.Album = iD3v1Tag.Album;
base.Year = iD3v1Tag.Year;
base.Genre = iD3v1Tag.Genre;
base.Track = iD3v1Tag.TrackNo.ToString();
base.Comment = iD3v1Tag.Comment;
return true;
}
public bool ReadID3v2(int Channel)
{
IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.ID3v2);
if (intPtr == IntPtr.Zero)
{
return false;
}
ID3v2Tag iD3v2Tag = new ID3v2Tag(intPtr);
foreach (KeyValuePair<string, string> textFrame in iD3v2Tag.TextFrames)
{
if (!SetTagUsingLookupTable(textFrame.Key, textFrame.Value, LookupTables.Id3v2))
{
Other.Add(textFrame.Key, textFrame.Value);
}
}
Pictures.AddRange(iD3v2Tag.PictureFrames);
return true;
}
public bool ReadBWF(int Channel)
{
IntPtr intPtr = Bass.ChannelGetTags(Channel, TagType.RiffBext);
if (intPtr == IntPtr.Zero)
{
return false;
}
BextTag bextTag = Marshal.PtrToStructure<BextTag>(intPtr);
base.Title = bextTag.Description;
base.Artist = bextTag.Originator;
base.Encoder = bextTag.OriginatorReference;
base.Year = bextTag.OriginationDate.Split(new char[1] { '-' })[0];
return true;
}
}
[StructLayout(LayoutKind.Sequential)]
public class BextTag
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string Description;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string Originator;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string OriginatorReference;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public string OriginationDate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string OriginationTime;
public long TimeReference;
public short Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] UMID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 190)]
private byte[] reserved;
private IntPtr codinghistory;
public DateTime OriginationDateTime
{
get
{
int year = int.Parse(OriginationDate.Substring(0, 4));
int month = int.Parse(OriginationDate.Substring(5, 2));
int day = int.Parse(OriginationDate.Substring(8, 2));
int hour = int.Parse(OriginationTime.Substring(0, 2));
int minute = int.Parse(OriginationTime.Substring(3, 2));
int second = int.Parse(OriginationTime.Substring(6, 2));
return new DateTime(year, month, day, hour, minute, second);
}
}
public string CodingHistory
{
get
{
if (!(codinghistory == IntPtr.Zero))
{
return Marshal.PtrToStringAnsi(codinghistory);
}
return null;
}
}
public static BextTag Read(int Channel)
{
return Marshal.PtrToStructure<BextTag>(Bass.ChannelGetTags(Channel, TagType.RiffBext));
}
}
[StructLayout(LayoutKind.Sequential)]
public class CACodecTag
{
public int ftype;
public int atype;
private IntPtr name;
public string Name
{
get
{
if (!(name == IntPtr.Zero))
{
return Marshal.PtrToStringAnsi(name);
}
return null;
}
}
public static CACodecTag Read(int Channel)
{
return Marshal.PtrToStructure<CACodecTag>(Bass.ChannelGetTags(Channel, TagType.WmaMeta));
}
}
[StructLayout(LayoutKind.Sequential)]
public class CartTimer
{
public int Usage;
public int Value;
}
[StructLayout(LayoutKind.Sequential)]
public class CartTag
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string Version;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string Title;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string Artist;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string CutID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string ClientID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string Category;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string Classification;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string OutCue;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
private string startDate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
private string startTime;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
private string endDate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
private string endTime;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string ProducerAppID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string ProducerAppVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string UserDef;
public int dwLevelReference;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public CartTimer[] PostTimer;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 276)]
private char[] Reserved;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
public string URL;
private IntPtr tagText;
public string TagText
{
get
{
if (!(tagText == IntPtr.Zero))
{
return Marshal.PtrToStringAnsi(tagText);
}
return null;
}
}
public DateTime StartTime
{
get
{
string[] array = startDate.Split(new char[1] { '-' });
string[] array2 = startTime.Split(new char[1] { ':' });
return new DateTime(int.Parse(array[0]), int.Parse(array[1]), int.Parse(array[2]), int.Parse(array2[0]), int.Parse(array2[1]), int.Parse(array2[2]));
}
}
public DateTime EndTime
{
get
{
string[] array = endDate.Split(new char[1] { '-' });
string[] array2 = endTime.Split(new char[1] { ':' });
return new DateTime(int.Parse(array[0]), int.Parse(array[1]), int.Parse(array[2]), int.Parse(array2[0]), int.Parse(array2[1]), int.Parse(array2[2]));
}