Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate-beta"
Decompiled source of RadioMod v1.0.1
NAudio.Core.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
#define DEBUG using System; using System.Collections.Generic; 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 NAudio.Dmo; using NAudio.Dsp; using NAudio.FileFormats.Wav; using NAudio.Utils; using NAudio.Wave; using NAudio.Wave.SampleProviders; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Mark Heath")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("© Mark Heath 2023")] [assembly: AssemblyFileVersion("2.2.1.0")] [assembly: AssemblyInformationalVersion("2.2.1")] [assembly: AssemblyProduct("NAudio.Core")] [assembly: AssemblyTitle("NAudio.Core")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.2.1.0")] [module: UnverifiableCode] namespace NAudio { public enum Manufacturers { Microsoft = 1, Creative = 2, Mediavision = 3, Fujitsu = 4, Artisoft = 20, TurtleBeach = 21, Ibm = 22, Vocaltec = 23, Roland = 24, DspSolutions = 25, Nec = 26, Ati = 27, Wanglabs = 28, Tandy = 29, Voyetra = 30, Antex = 31, IclPS = 32, Intel = 33, Gravis = 34, Val = 35, Interactive = 36, Yamaha = 37, Everex = 38, Echo = 39, Sierra = 40, Cat = 41, Apps = 42, DspGroup = 43, Melabs = 44, ComputerFriends = 45, Ess = 46, Audiofile = 47, Motorola = 48, Canopus = 49, Epson = 50, Truevision = 51, Aztech = 52, Videologic = 53, Scalacs = 54, Korg = 55, Apt = 56, Ics = 57, Iteratedsys = 58, Metheus = 59, Logitech = 60, Winnov = 61, Ncr = 62, Exan = 63, Ast = 64, Willowpond = 65, Sonicfoundry = 66, Vitec = 67, Moscom = 68, Siliconsoft = 69, Supermac = 73, Audiopt = 74, Speechcomp = 76, Ahead = 77, Dolby = 78, Oki = 79, Auravision = 80, Olivetti = 81, Iomagic = 82, Matsushita = 83, Controlres = 84, Xebec = 85, Newmedia = 86, Nms = 87, Lyrrus = 88, Compusic = 89, Opti = 90, Adlacc = 91, Compaq = 92, Dialogic = 93, Insoft = 94, Mptus = 95, Weitek = 96, LernoutAndHauspie = 97, Qciar = 98, Apple = 99, Digital = 100, Motu = 101, Workbit = 102, Ositech = 103, Miro = 104, Cirruslogic = 105, Isolution = 106, Horizons = 107, Concepts = 108, Vtg = 109, Radius = 110, Rockwell = 111, Xyz = 112, Opcode = 113, Voxware = 114, NorthernTelecom = 115, Apicom = 116, Grande = 117, Addx = 118, Wildcat = 119, Rhetorex = 120, Brooktree = 121, Ensoniq = 125, Fast = 126, Nvidia = 127, Oksori = 128, Diacoustics = 129, Gulbransen = 130, KayElemetrics = 131, Crystal = 132, SplashStudios = 133, Quarterdeck = 134, Tdk = 135, DigitalAudioLabs = 136, Seersys = 137, Picturetel = 138, AttMicroelectronics = 139, Osprey = 140, Mediatrix = 141, Soundesigns = 142, Aldigital = 143, SpectrumSignalProcessing = 144, Ecs = 145, Amd = 146, Coredynamics = 147, Canam = 148, Softsound = 149, Norris = 150, Ddd = 151, Euphonics = 152, Precept = 153, CrystalNet = 154, Chromatic = 155, Voiceinfo = 156, Viennasys = 157, Connectix = 158, Gadgetlabs = 159, Frontier = 160, Viona = 161, Casio = 162, Diamondmm = 163, S3 = 164, FraunhoferIis = 172 } public class MmException : Exception { public MmResult Result { get; } public string Function { get; } public MmException(MmResult result, string function) : base(ErrorMessage(result, function)) { Result = result; Function = function; } private static string ErrorMessage(MmResult result, string function) { return $"{result} calling {function}"; } public static void Try(MmResult result, string function) { if (result != 0) { throw new MmException(result, function); } } } public enum MmResult { NoError = 0, UnspecifiedError = 1, BadDeviceId = 2, NotEnabled = 3, AlreadyAllocated = 4, InvalidHandle = 5, NoDriver = 6, MemoryAllocationError = 7, NotSupported = 8, BadErrorNumber = 9, InvalidFlag = 10, InvalidParameter = 11, HandleBusy = 12, InvalidAlias = 13, BadRegistryDatabase = 14, RegistryKeyNotFound = 15, RegistryReadError = 16, RegistryWriteError = 17, RegistryDeleteError = 18, RegistryValueNotFound = 19, NoDriverCallback = 20, MoreData = 21, WaveBadFormat = 32, WaveStillPlaying = 33, WaveHeaderUnprepared = 34, WaveSync = 35, AcmNotPossible = 512, AcmBusy = 513, AcmHeaderUnprepared = 514, AcmCancelled = 515, MixerInvalidLine = 1024, MixerInvalidControl = 1025, MixerInvalidValue = 1026 } } namespace NAudio.CoreAudioApi { public enum CaptureState { Stopped, Starting, Capturing, Stopping } } namespace NAudio.Dmo { public class AudioMediaSubtypes { public static readonly Guid MEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_PCMAudioObsolete = new Guid("e436eb8a-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_MPEG1Packet = new Guid("e436eb80-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_MPEG1Payload = new Guid("e436eb81-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_MPEG2_AUDIO = new Guid("e06d802b-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MEDIASUBTYPE_DVD_LPCM_AUDIO = new Guid("e06d8032-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MEDIASUBTYPE_DRM_Audio = new Guid("00000009-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_IEEE_FLOAT = new Guid("00000003-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_DOLBY_AC3 = new Guid("e06d802c-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MEDIASUBTYPE_DOLBY_AC3_SPDIF = new Guid("00000092-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_RAW_SPORT = new Guid("00000240-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_SPDIF_TAG_241h = new Guid("00000241-0000-0010-8000-00aa00389b71"); public static readonly Guid MEDIASUBTYPE_I420 = new Guid("30323449-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_IYUV = new Guid("56555949-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_RGB1 = new Guid("e436eb78-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB24 = new Guid("e436eb7d-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB32 = new Guid("e436eb7e-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB4 = new Guid("e436eb79-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB555 = new Guid("e436eb7c-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB565 = new Guid("e436eb7b-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_RGB8 = new Guid("e436eb7a-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_UYVY = new Guid("59565955-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_VIDEOIMAGE = new Guid("1d4a45f2-e5f6-4b44-8388-f0ae5c0e0c37"); public static readonly Guid MEDIASUBTYPE_YUY2 = new Guid("32595559-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_YV12 = new Guid("31313259-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_YVU9 = new Guid("39555659-0000-0010-8000-00AA00389B71"); public static readonly Guid MEDIASUBTYPE_YVYU = new Guid("55595659-0000-0010-8000-00AA00389B71"); public static readonly Guid WMFORMAT_MPEG2Video = new Guid("e06d80e3-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid WMFORMAT_Script = new Guid("5C8510F2-DEBE-4ca7-BBA5-F07A104F8DFF"); public static readonly Guid WMFORMAT_VideoInfo = new Guid("05589f80-c356-11ce-bf01-00aa0055595a"); public static readonly Guid WMFORMAT_WaveFormatEx = new Guid("05589f81-c356-11ce-bf01-00aa0055595a"); public static readonly Guid WMFORMAT_WebStream = new Guid("da1e6b13-8359-4050-b398-388e965bf00c"); public static readonly Guid WMMEDIASUBTYPE_ACELPnet = new Guid("00000130-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_Base = new Guid("00000000-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_DRM = new Guid("00000009-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MP3 = new Guid("00000055-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MP43 = new Guid("3334504D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MP4S = new Guid("5334504D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_M4S2 = new Guid("3253344D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_P422 = new Guid("32323450-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MPEG2_VIDEO = new Guid("e06d8026-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid WMMEDIASUBTYPE_MSS1 = new Guid("3153534D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_MSS2 = new Guid("3253534D-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WebStream = new Guid("776257d4-c627-41cb-8f81-7ac7ff1c40cc"); public static readonly Guid WMMEDIASUBTYPE_WMAudio_Lossless = new Guid("00000163-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMAudioV2 = new Guid("00000161-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMAudioV7 = new Guid("00000161-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMAudioV8 = new Guid("00000161-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMAudioV9 = new Guid("00000162-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMSP1 = new Guid("0000000A-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMV1 = new Guid("31564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMV2 = new Guid("32564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMV3 = new Guid("33564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMVA = new Guid("41564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WMVP = new Guid("50564D57-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIASUBTYPE_WVP2 = new Guid("32505657-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIATYPE_Audio = new Guid("73647561-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIATYPE_FileTransfer = new Guid("D9E47579-930E-4427-ADFC-AD80F290E470"); public static readonly Guid WMMEDIATYPE_Image = new Guid("34A50FD8-8AA5-4386-81FE-A0EFE0488E31"); public static readonly Guid WMMEDIATYPE_Script = new Guid("73636d64-0000-0010-8000-00AA00389B71"); public static readonly Guid WMMEDIATYPE_Text = new Guid("9BBA1EA7-5AB2-4829-BA57-0940209BCF3E"); public static readonly Guid WMMEDIATYPE_Video = new Guid("73646976-0000-0010-8000-00AA00389B71"); public static readonly Guid WMSCRIPTTYPE_TwoStrings = new Guid("82f38a70-c29f-11d1-97ad-00a0c95ea850"); public static readonly Guid MEDIASUBTYPE_WAVE = new Guid("e436eb8b-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_AU = new Guid("e436eb8c-524f-11ce-9f53-0020af0ba770"); public static readonly Guid MEDIASUBTYPE_AIFF = new Guid("e436eb8d-524f-11ce-9f53-0020af0ba770"); public static readonly Guid[] AudioSubTypes = new Guid[13] { MEDIASUBTYPE_PCM, MEDIASUBTYPE_PCMAudioObsolete, MEDIASUBTYPE_MPEG1Packet, MEDIASUBTYPE_MPEG1Payload, MEDIASUBTYPE_MPEG2_AUDIO, MEDIASUBTYPE_DVD_LPCM_AUDIO, MEDIASUBTYPE_DRM_Audio, MEDIASUBTYPE_IEEE_FLOAT, MEDIASUBTYPE_DOLBY_AC3, MEDIASUBTYPE_DOLBY_AC3_SPDIF, MEDIASUBTYPE_RAW_SPORT, MEDIASUBTYPE_SPDIF_TAG_241h, WMMEDIASUBTYPE_MP3 }; public static readonly string[] AudioSubTypeNames = new string[13] { "PCM", "PCM Obsolete", "MPEG1Packet", "MPEG1Payload", "MPEG2_AUDIO", "DVD_LPCM_AUDIO", "DRM_Audio", "IEEE_FLOAT", "DOLBY_AC3", "DOLBY_AC3_SPDIF", "RAW_SPORT", "SPDIF_TAG_241h", "MP3" }; public static string GetAudioSubtypeName(Guid subType) { for (int i = 0; i < AudioSubTypes.Length; i++) { if (subType == AudioSubTypes[i]) { return AudioSubTypeNames[i]; } } return subType.ToString(); } } } namespace NAudio.Utils { public static class BufferHelpers { public static byte[] Ensure(byte[] buffer, int bytesRequired) { if (buffer == null || buffer.Length < bytesRequired) { buffer = new byte[bytesRequired]; } return buffer; } public static float[] Ensure(float[] buffer, int samplesRequired) { if (buffer == null || buffer.Length < samplesRequired) { buffer = new float[samplesRequired]; } return buffer; } } public static class ByteArrayExtensions { public static bool IsEntirelyNull(byte[] buffer) { for (int i = 0; i < buffer.Length; i++) { if (buffer[i] != 0) { return false; } } return true; } public static string DescribeAsHex(byte[] buffer, string separator, int bytesPerLine) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; foreach (byte b in buffer) { stringBuilder.AppendFormat("{0:X2}{1}", b, separator); if (++num % bytesPerLine == 0) { stringBuilder.Append("\r\n"); } } stringBuilder.Append("\r\n"); return stringBuilder.ToString(); } public static string DecodeAsString(byte[] buffer, int offset, int length, Encoding encoding) { for (int i = 0; i < length; i++) { if (buffer[offset + i] == 0) { length = i; } } return encoding.GetString(buffer, offset, length); } public static byte[] Concat(params byte[][] byteArrays) { int num = 0; foreach (byte[] array in byteArrays) { num += array.Length; } if (num <= 0) { return new byte[0]; } byte[] array2 = new byte[num]; int num2 = 0; foreach (byte[] array3 in byteArrays) { Array.Copy(array3, 0, array2, num2, array3.Length); num2 += array3.Length; } return array2; } } public class ByteEncoding : Encoding { public static readonly ByteEncoding Instance = new ByteEncoding(); private ByteEncoding() { } public override int GetByteCount(char[] chars, int index, int count) { return count; } public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { for (int i = 0; i < charCount; i++) { bytes[byteIndex + i] = (byte)chars[charIndex + i]; } return charCount; } public override int GetCharCount(byte[] bytes, int index, int count) { for (int i = 0; i < count; i++) { if (bytes[index + i] == 0) { return i; } } return count; } public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { for (int i = 0; i < byteCount; i++) { byte b = bytes[byteIndex + i]; if (b == 0) { return i; } chars[charIndex + i] = (char)b; } return byteCount; } public override int GetMaxCharCount(int byteCount) { return byteCount; } public override int GetMaxByteCount(int charCount) { return charCount; } } public class ChunkIdentifier { public static int ChunkIdentifierToInt32(string s) { if (s.Length != 4) { throw new ArgumentException("Must be a four character string"); } byte[] bytes = Encoding.UTF8.GetBytes(s); if (bytes.Length != 4) { throw new ArgumentException("Must encode to exactly four bytes"); } return BitConverter.ToInt32(bytes, 0); } } public class CircularBuffer { private readonly byte[] buffer; private readonly object lockObject; private int writePosition; private int readPosition; private int byteCount; public int MaxLength => buffer.Length; public int Count { get { lock (lockObject) { return byteCount; } } } public CircularBuffer(int size) { buffer = new byte[size]; lockObject = new object(); } public int Write(byte[] data, int offset, int count) { lock (lockObject) { int num = 0; if (count > buffer.Length - byteCount) { count = buffer.Length - byteCount; } int num2 = Math.Min(buffer.Length - writePosition, count); Array.Copy(data, offset, buffer, writePosition, num2); writePosition += num2; writePosition %= buffer.Length; num += num2; if (num < count) { Debug.Assert(writePosition == 0); Array.Copy(data, offset + num, buffer, writePosition, count - num); writePosition += count - num; num = count; } byteCount += num; return num; } } public int Read(byte[] data, int offset, int count) { lock (lockObject) { if (count > byteCount) { count = byteCount; } int num = 0; int num2 = Math.Min(buffer.Length - readPosition, count); Array.Copy(buffer, readPosition, data, offset, num2); num += num2; readPosition += num2; readPosition %= buffer.Length; if (num < count) { Debug.Assert(readPosition == 0); Array.Copy(buffer, readPosition, data, offset + num, count - num); readPosition += count - num; num = count; } byteCount -= num; Debug.Assert(byteCount >= 0); return num; } } public void Reset() { lock (lockObject) { ResetInner(); } } private void ResetInner() { byteCount = 0; readPosition = 0; writePosition = 0; } public void Advance(int count) { lock (lockObject) { if (count >= byteCount) { ResetInner(); return; } byteCount -= count; readPosition += count; readPosition %= MaxLength; } } } public class Decibels { private const double LOG_2_DB = 8.685889638065037; private const double DB_2_LOG = 0.11512925464970228; public static double LinearToDecibels(double lin) { return Math.Log(lin) * 8.685889638065037; } public static double DecibelsToLinear(double dB) { return Math.Exp(dB * 0.11512925464970228); } } [AttributeUsage(AttributeTargets.Field)] public class FieldDescriptionAttribute : Attribute { public string Description { get; } public FieldDescriptionAttribute(string description) { Description = description; } public override string ToString() { return Description; } } public static class FieldDescriptionHelper { public static string Describe(Type t, Guid guid) { FieldInfo[] fields = t.GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.IsPublic || !fieldInfo.IsStatic || !(fieldInfo.FieldType == typeof(Guid)) || !((Guid)fieldInfo.GetValue(null) == guid)) { continue; } object[] customAttributes = fieldInfo.GetCustomAttributes(inherit: false); foreach (object obj in customAttributes) { if (obj is FieldDescriptionAttribute fieldDescriptionAttribute) { return fieldDescriptionAttribute.Description; } } return fieldInfo.Name; } return guid.ToString(); } } public static class HResult { public const int S_OK = 0; public const int S_FALSE = 1; public const int E_INVALIDARG = -2147483645; private const int FACILITY_AAF = 18; private const int FACILITY_ACS = 20; private const int FACILITY_BACKGROUNDCOPY = 32; private const int FACILITY_CERT = 11; private const int FACILITY_COMPLUS = 17; private const int FACILITY_CONFIGURATION = 33; private const int FACILITY_CONTROL = 10; private const int FACILITY_DISPATCH = 2; private const int FACILITY_DPLAY = 21; private const int FACILITY_HTTP = 25; private const int FACILITY_INTERNET = 12; private const int FACILITY_ITF = 4; private const int FACILITY_MEDIASERVER = 13; private const int FACILITY_MSMQ = 14; private const int FACILITY_NULL = 0; private const int FACILITY_RPC = 1; private const int FACILITY_SCARD = 16; private const int FACILITY_SECURITY = 9; private const int FACILITY_SETUPAPI = 15; private const int FACILITY_SSPI = 9; private const int FACILITY_STORAGE = 3; private const int FACILITY_SXS = 23; private const int FACILITY_UMI = 22; private const int FACILITY_URT = 19; private const int FACILITY_WIN32 = 7; private const int FACILITY_WINDOWS = 8; private const int FACILITY_WINDOWS_CE = 24; public static int MAKE_HRESULT(int sev, int fac, int code) { return (sev << 31) | (fac << 16) | code; } public static int GetHResult(this COMException exception) { return exception.ErrorCode; } } public static class IEEE { private static double UnsignedToFloat(ulong u) { return (double)(long)(u - int.MaxValue - 1) + 2147483648.0; } private static double ldexp(double x, int exp) { return x * Math.Pow(2.0, exp); } private static double frexp(double x, out int exp) { exp = (int)Math.Floor(Math.Log(x) / Math.Log(2.0)) + 1; return 1.0 - (Math.Pow(2.0, exp) - x) / Math.Pow(2.0, exp); } private static ulong FloatToUnsigned(double f) { return (ulong)((long)(f - 2147483648.0) + int.MaxValue + 1); } public static byte[] ConvertToIeeeExtended(double num) { int num2; if (num < 0.0) { num2 = 32768; num *= -1.0; } else { num2 = 0; } ulong num4; ulong num5; int num3; if (num == 0.0) { num3 = 0; num4 = 0uL; num5 = 0uL; } else { double num6 = frexp(num, out num3); if (num3 > 16384 || !(num6 < 1.0)) { num3 = num2 | 0x7FFF; num4 = 0uL; num5 = 0uL; } else { num3 += 16382; if (num3 < 0) { num6 = ldexp(num6, num3); num3 = 0; } num3 |= num2; num6 = ldexp(num6, 32); double num7 = Math.Floor(num6); num4 = FloatToUnsigned(num7); num6 = ldexp(num6 - num7, 32); num7 = Math.Floor(num6); num5 = FloatToUnsigned(num7); } } return new byte[10] { (byte)(num3 >> 8), (byte)num3, (byte)(num4 >> 24), (byte)(num4 >> 16), (byte)(num4 >> 8), (byte)num4, (byte)(num5 >> 24), (byte)(num5 >> 16), (byte)(num5 >> 8), (byte)num5 }; } public static double ConvertFromIeeeExtended(byte[] bytes) { if (bytes.Length != 10) { throw new Exception("Incorrect length for IEEE extended."); } int num = ((bytes[0] & 0x7F) << 8) | bytes[1]; uint num2 = (uint)((bytes[2] << 24) | (bytes[3] << 16) | (bytes[4] << 8) | bytes[5]); uint num3 = (uint)((bytes[6] << 24) | (bytes[7] << 16) | (bytes[8] << 8) | bytes[9]); double num4; if (num == 0 && num2 == 0 && num3 == 0) { num4 = 0.0; } else if (num == 32767) { num4 = double.NaN; } else { num -= 16383; num4 = ldexp(UnsignedToFloat(num2), num -= 31); num4 += ldexp(UnsignedToFloat(num3), num -= 32); } if ((bytes[0] & 0x80) == 128) { return 0.0 - num4; } return num4; } } public class IgnoreDisposeStream : Stream { public Stream SourceStream { get; private set; } public bool IgnoreDispose { get; set; } public override bool CanRead => SourceStream.CanRead; public override bool CanSeek => SourceStream.CanSeek; public override bool CanWrite => SourceStream.CanWrite; public override long Length => SourceStream.Length; public override long Position { get { return SourceStream.Position; } set { SourceStream.Position = value; } } public IgnoreDisposeStream(Stream sourceStream) { SourceStream = sourceStream; IgnoreDispose = true; } public override void Flush() { SourceStream.Flush(); } public override int Read(byte[] buffer, int offset, int count) { return SourceStream.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return SourceStream.Seek(offset, origin); } public override void SetLength(long value) { SourceStream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { SourceStream.Write(buffer, offset, count); } protected override void Dispose(bool disposing) { if (!IgnoreDispose) { SourceStream.Dispose(); SourceStream = null; } } } public static class NativeMethods { [DllImport("kernel32.dll")] public static extern IntPtr LoadLibrary(string dllToLoad); [DllImport("kernel32.dll")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); [DllImport("kernel32.dll")] public static extern bool FreeLibrary(IntPtr hModule); } public static class WavePositionExtensions { public static TimeSpan GetPositionTimeSpan(this IWavePosition @this) { long num = @this.GetPosition() / (@this.OutputWaveFormat.Channels * @this.OutputWaveFormat.BitsPerSample / 8); return TimeSpan.FromMilliseconds((double)num * 1000.0 / (double)@this.OutputWaveFormat.SampleRate); } } } namespace NAudio.FileFormats.Wav { public class WaveFileChunkReader { private WaveFormat waveFormat; private long dataChunkPosition; private long dataChunkLength; private List<RiffChunk> riffChunks; private readonly bool strictMode; private bool isRf64; private readonly bool storeAllChunks; private long riffSize; public WaveFormat WaveFormat => waveFormat; public long DataChunkPosition => dataChunkPosition; public long DataChunkLength => dataChunkLength; public List<RiffChunk> RiffChunks => riffChunks; public WaveFileChunkReader() { storeAllChunks = true; strictMode = false; } public void ReadWaveHeader(Stream stream) { dataChunkPosition = -1L; waveFormat = null; riffChunks = new List<RiffChunk>(); dataChunkLength = 0L; BinaryReader binaryReader = new BinaryReader(stream); ReadRiffHeader(binaryReader); riffSize = binaryReader.ReadUInt32(); if (binaryReader.ReadInt32() != ChunkIdentifier.ChunkIdentifierToInt32("WAVE")) { throw new FormatException("Not a WAVE file - no WAVE header"); } if (isRf64) { ReadDs64Chunk(binaryReader); } int num = ChunkIdentifier.ChunkIdentifierToInt32("data"); int num2 = ChunkIdentifier.ChunkIdentifierToInt32("fmt "); long num3 = Math.Min(riffSize + 8, stream.Length); while (stream.Position <= num3 - 8) { int num4 = binaryReader.ReadInt32(); uint num5 = binaryReader.ReadUInt32(); if (num4 == num) { dataChunkPosition = stream.Position; if (!isRf64) { dataChunkLength = num5; } stream.Position += num5; } else if (num4 == num2) { if (num5 > int.MaxValue) { throw new InvalidDataException($"Format chunk length must be between 0 and {int.MaxValue}."); } waveFormat = WaveFormat.FromFormatChunk(binaryReader, (int)num5); } else { if (num5 > stream.Length - stream.Position) { if (strictMode) { Debug.Assert(condition: false, $"Invalid chunk length {num5}, pos: {stream.Position}. length: {stream.Length}"); } break; } if (storeAllChunks) { if (num5 > int.MaxValue) { throw new InvalidDataException($"RiffChunk chunk length must be between 0 and {int.MaxValue}."); } riffChunks.Add(GetRiffChunk(stream, num4, (int)num5)); } stream.Position += num5; } if (num5 % 2 != 0 && binaryReader.PeekChar() == 0) { stream.Position++; } } if (waveFormat == null) { throw new FormatException("Invalid WAV file - No fmt chunk found"); } if (dataChunkPosition == -1) { throw new FormatException("Invalid WAV file - No data chunk found"); } } private void ReadDs64Chunk(BinaryReader reader) { int num = ChunkIdentifier.ChunkIdentifierToInt32("ds64"); int num2 = reader.ReadInt32(); if (num2 != num) { throw new FormatException("Invalid RF64 WAV file - No ds64 chunk found"); } int num3 = reader.ReadInt32(); riffSize = reader.ReadInt64(); dataChunkLength = reader.ReadInt64(); long num4 = reader.ReadInt64(); reader.ReadBytes(num3 - 24); } private static RiffChunk GetRiffChunk(Stream stream, int chunkIdentifier, int chunkLength) { return new RiffChunk(chunkIdentifier, chunkLength, stream.Position); } private void ReadRiffHeader(BinaryReader br) { int num = br.ReadInt32(); if (num == ChunkIdentifier.ChunkIdentifierToInt32("RF64")) { isRf64 = true; } else if (num != ChunkIdentifier.ChunkIdentifierToInt32("RIFF")) { throw new FormatException("Not a WAVE file - no RIFF header"); } } } } namespace NAudio.SoundFont { public class Generator { public GeneratorEnum GeneratorType { get; set; } public ushort UInt16Amount { get; set; } public short Int16Amount { get { return (short)UInt16Amount; } set { UInt16Amount = (ushort)value; } } public byte LowByteAmount { get { return (byte)(UInt16Amount & 0xFFu); } set { UInt16Amount &= 65280; UInt16Amount += value; } } public byte HighByteAmount { get { return (byte)((UInt16Amount & 0xFF00) >> 8); } set { UInt16Amount &= 255; UInt16Amount += (ushort)(value << 8); } } public Instrument Instrument { get; set; } public SampleHeader SampleHeader { get; set; } public override string ToString() { if (GeneratorType == GeneratorEnum.Instrument) { return "Generator Instrument " + Instrument.Name; } if (GeneratorType == GeneratorEnum.SampleID) { return $"Generator SampleID {SampleHeader}"; } return $"Generator {GeneratorType} {UInt16Amount}"; } } internal class GeneratorBuilder : StructureBuilder<Generator> { public override int Length => 4; public Generator[] Generators => data.ToArray(); public override Generator Read(BinaryReader br) { Generator generator = new Generator(); generator.GeneratorType = (GeneratorEnum)br.ReadUInt16(); generator.UInt16Amount = br.ReadUInt16(); data.Add(generator); return generator; } public override void Write(BinaryWriter bw, Generator o) { } public void Load(Instrument[] instruments) { Generator[] generators = Generators; foreach (Generator generator in generators) { if (generator.GeneratorType == GeneratorEnum.Instrument) { generator.Instrument = instruments[generator.UInt16Amount]; } } } public void Load(SampleHeader[] sampleHeaders) { Generator[] generators = Generators; foreach (Generator generator in generators) { if (generator.GeneratorType == GeneratorEnum.SampleID) { generator.SampleHeader = sampleHeaders[generator.UInt16Amount]; } } } } public enum GeneratorEnum { StartAddressOffset, EndAddressOffset, StartLoopAddressOffset, EndLoopAddressOffset, StartAddressCoarseOffset, ModulationLFOToPitch, VibratoLFOToPitch, ModulationEnvelopeToPitch, InitialFilterCutoffFrequency, InitialFilterQ, ModulationLFOToFilterCutoffFrequency, ModulationEnvelopeToFilterCutoffFrequency, EndAddressCoarseOffset, ModulationLFOToVolume, Unused1, ChorusEffectsSend, ReverbEffectsSend, Pan, Unused2, Unused3, Unused4, DelayModulationLFO, FrequencyModulationLFO, DelayVibratoLFO, FrequencyVibratoLFO, DelayModulationEnvelope, AttackModulationEnvelope, HoldModulationEnvelope, DecayModulationEnvelope, SustainModulationEnvelope, ReleaseModulationEnvelope, KeyNumberToModulationEnvelopeHold, KeyNumberToModulationEnvelopeDecay, DelayVolumeEnvelope, AttackVolumeEnvelope, HoldVolumeEnvelope, DecayVolumeEnvelope, SustainVolumeEnvelope, ReleaseVolumeEnvelope, KeyNumberToVolumeEnvelopeHold, KeyNumberToVolumeEnvelopeDecay, Instrument, Reserved1, KeyRange, VelocityRange, StartLoopAddressCoarseOffset, KeyNumber, Velocity, InitialAttenuation, Reserved2, EndLoopAddressCoarseOffset, CoarseTune, FineTune, SampleID, SampleModes, Reserved3, ScaleTuning, ExclusiveClass, OverridingRootKey, Unused5, UnusedEnd } public class InfoChunk { public SFVersion SoundFontVersion { get; } public string WaveTableSoundEngine { get; set; } public string BankName { get; set; } public string DataROM { get; set; } public string CreationDate { get; set; } public string Author { get; set; } public string TargetProduct { get; set; } public string Copyright { get; set; } public string Comments { get; set; } public string Tools { get; set; } public SFVersion ROMVersion { get; set; } internal InfoChunk(RiffChunk chunk) { bool flag = false; bool flag2 = false; if (chunk.ReadChunkID() != "INFO") { throw new InvalidDataException("Not an INFO chunk"); } RiffChunk nextSubChunk; while ((nextSubChunk = chunk.GetNextSubChunk()) != null) { switch (nextSubChunk.ChunkID) { case "ifil": flag = true; SoundFontVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder()); break; case "isng": WaveTableSoundEngine = nextSubChunk.GetDataAsString(); break; case "INAM": flag2 = true; BankName = nextSubChunk.GetDataAsString(); break; case "irom": DataROM = nextSubChunk.GetDataAsString(); break; case "iver": ROMVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder()); break; case "ICRD": CreationDate = nextSubChunk.GetDataAsString(); break; case "IENG": Author = nextSubChunk.GetDataAsString(); break; case "IPRD": TargetProduct = nextSubChunk.GetDataAsString(); break; case "ICOP": Copyright = nextSubChunk.GetDataAsString(); break; case "ICMT": Comments = nextSubChunk.GetDataAsString(); break; case "ISFT": Tools = nextSubChunk.GetDataAsString(); break; default: throw new InvalidDataException("Unknown chunk type " + nextSubChunk.ChunkID); } } if (!flag) { throw new InvalidDataException("Missing SoundFont version information"); } if (!flag2) { throw new InvalidDataException("Missing SoundFont name information"); } } public override string ToString() { return string.Format("Bank Name: {0}\r\nAuthor: {1}\r\nCopyright: {2}\r\nCreation Date: {3}\r\nTools: {4}\r\nComments: {5}\r\nSound Engine: {6}\r\nSoundFont Version: {7}\r\nTarget Product: {8}\r\nData ROM: {9}\r\nROM Version: {10}", BankName, Author, Copyright, CreationDate, Tools, "TODO-fix comments", WaveTableSoundEngine, SoundFontVersion, TargetProduct, DataROM, ROMVersion); } } public class Instrument { internal ushort startInstrumentZoneIndex; internal ushort endInstrumentZoneIndex; public string Name { get; set; } public Zone[] Zones { get; set; } public override string ToString() { return Name; } } internal class InstrumentBuilder : StructureBuilder<Instrument> { private Instrument lastInstrument = null; public override int Length => 22; public Instrument[] Instruments => data.ToArray(); public override Instrument Read(BinaryReader br) { Instrument instrument = new Instrument(); string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20); if (text.IndexOf('\0') >= 0) { text = text.Substring(0, text.IndexOf('\0')); } instrument.Name = text; instrument.startInstrumentZoneIndex = br.ReadUInt16(); if (lastInstrument != null) { lastInstrument.endInstrumentZoneIndex = (ushort)(instrument.startInstrumentZoneIndex - 1); } data.Add(instrument); lastInstrument = instrument; return instrument; } public override void Write(BinaryWriter bw, Instrument instrument) { } public void LoadZones(Zone[] zones) { for (int i = 0; i < data.Count - 1; i++) { Instrument instrument = data[i]; instrument.Zones = new Zone[instrument.endInstrumentZoneIndex - instrument.startInstrumentZoneIndex + 1]; Array.Copy(zones, instrument.startInstrumentZoneIndex, instrument.Zones, 0, instrument.Zones.Length); } data.RemoveAt(data.Count - 1); } } public enum TransformEnum { Linear } public class Modulator { public ModulatorType SourceModulationData { get; set; } public GeneratorEnum DestinationGenerator { get; set; } public short Amount { get; set; } public ModulatorType SourceModulationAmount { get; set; } public TransformEnum SourceTransform { get; set; } public override string ToString() { return $"Modulator {SourceModulationData} {DestinationGenerator} {Amount} {SourceModulationAmount} {SourceTransform}"; } } internal class ModulatorBuilder : StructureBuilder<Modulator> { public override int Length => 10; public Modulator[] Modulators => data.ToArray(); public override Modulator Read(BinaryReader br) { Modulator modulator = new Modulator(); modulator.SourceModulationData = new ModulatorType(br.ReadUInt16()); modulator.DestinationGenerator = (GeneratorEnum)br.ReadUInt16(); modulator.Amount = br.ReadInt16(); modulator.SourceModulationAmount = new ModulatorType(br.ReadUInt16()); modulator.SourceTransform = (TransformEnum)br.ReadUInt16(); data.Add(modulator); return modulator; } public override void Write(BinaryWriter bw, Modulator o) { } } public enum ControllerSourceEnum { NoController = 0, NoteOnVelocity = 2, NoteOnKeyNumber = 3, PolyPressure = 10, ChannelPressure = 13, PitchWheel = 14, PitchWheelSensitivity = 16 } public enum SourceTypeEnum { Linear, Concave, Convex, Switch } public class ModulatorType { private bool polarity; private bool direction; private bool midiContinuousController; private ControllerSourceEnum controllerSource; private SourceTypeEnum sourceType; private ushort midiContinuousControllerNumber; internal ModulatorType(ushort raw) { polarity = (raw & 0x200) == 512; direction = (raw & 0x100) == 256; midiContinuousController = (raw & 0x80) == 128; sourceType = (SourceTypeEnum)((raw & 0xFC00) >> 10); controllerSource = (ControllerSourceEnum)(raw & 0x7F); midiContinuousControllerNumber = (ushort)(raw & 0x7Fu); } public override string ToString() { if (midiContinuousController) { return $"{sourceType} CC{midiContinuousControllerNumber}"; } return $"{sourceType} {controllerSource}"; } } public class Preset { internal ushort startPresetZoneIndex; internal ushort endPresetZoneIndex; internal uint library; internal uint genre; internal uint morphology; public string Name { get; set; } public ushort PatchNumber { get; set; } public ushort Bank { get; set; } public Zone[] Zones { get; set; } public override string ToString() { return $"{Bank}-{PatchNumber} {Name}"; } } internal class PresetBuilder : StructureBuilder<Preset> { private Preset lastPreset = null; public override int Length => 38; public Preset[] Presets => data.ToArray(); public override Preset Read(BinaryReader br) { Preset preset = new Preset(); string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20); if (text.IndexOf('\0') >= 0) { text = text.Substring(0, text.IndexOf('\0')); } preset.Name = text; preset.PatchNumber = br.ReadUInt16(); preset.Bank = br.ReadUInt16(); preset.startPresetZoneIndex = br.ReadUInt16(); preset.library = br.ReadUInt32(); preset.genre = br.ReadUInt32(); preset.morphology = br.ReadUInt32(); if (lastPreset != null) { lastPreset.endPresetZoneIndex = (ushort)(preset.startPresetZoneIndex - 1); } data.Add(preset); lastPreset = preset; return preset; } public override void Write(BinaryWriter bw, Preset preset) { } public void LoadZones(Zone[] presetZones) { for (int i = 0; i < data.Count - 1; i++) { Preset preset = data[i]; preset.Zones = new Zone[preset.endPresetZoneIndex - preset.startPresetZoneIndex + 1]; Array.Copy(presetZones, preset.startPresetZoneIndex, preset.Zones, 0, preset.Zones.Length); } data.RemoveAt(data.Count - 1); } } public class PresetsChunk { private PresetBuilder presetHeaders = new PresetBuilder(); private ZoneBuilder presetZones = new ZoneBuilder(); private ModulatorBuilder presetZoneModulators = new ModulatorBuilder(); private GeneratorBuilder presetZoneGenerators = new GeneratorBuilder(); private InstrumentBuilder instruments = new InstrumentBuilder(); private ZoneBuilder instrumentZones = new ZoneBuilder(); private ModulatorBuilder instrumentZoneModulators = new ModulatorBuilder(); private GeneratorBuilder instrumentZoneGenerators = new GeneratorBuilder(); private SampleHeaderBuilder sampleHeaders = new SampleHeaderBuilder(); public Preset[] Presets => presetHeaders.Presets; public Instrument[] Instruments => instruments.Instruments; public SampleHeader[] SampleHeaders => sampleHeaders.SampleHeaders; internal PresetsChunk(RiffChunk chunk) { string text = chunk.ReadChunkID(); if (text != "pdta") { throw new InvalidDataException($"Not a presets data chunk ({text})"); } RiffChunk nextSubChunk; while ((nextSubChunk = chunk.GetNextSubChunk()) != null) { switch (nextSubChunk.ChunkID) { case "PHDR": case "phdr": nextSubChunk.GetDataAsStructureArray(presetHeaders); break; case "PBAG": case "pbag": nextSubChunk.GetDataAsStructureArray(presetZones); break; case "PMOD": case "pmod": nextSubChunk.GetDataAsStructureArray(presetZoneModulators); break; case "PGEN": case "pgen": nextSubChunk.GetDataAsStructureArray(presetZoneGenerators); break; case "INST": case "inst": nextSubChunk.GetDataAsStructureArray(instruments); break; case "IBAG": case "ibag": nextSubChunk.GetDataAsStructureArray(instrumentZones); break; case "IMOD": case "imod": nextSubChunk.GetDataAsStructureArray(instrumentZoneModulators); break; case "IGEN": case "igen": nextSubChunk.GetDataAsStructureArray(instrumentZoneGenerators); break; case "SHDR": case "shdr": nextSubChunk.GetDataAsStructureArray(sampleHeaders); break; default: throw new InvalidDataException($"Unknown chunk type {nextSubChunk.ChunkID}"); } } instrumentZoneGenerators.Load(sampleHeaders.SampleHeaders); instrumentZones.Load(instrumentZoneModulators.Modulators, instrumentZoneGenerators.Generators); instruments.LoadZones(instrumentZones.Zones); presetZoneGenerators.Load(instruments.Instruments); presetZones.Load(presetZoneModulators.Modulators, presetZoneGenerators.Generators); presetHeaders.LoadZones(presetZones.Zones); sampleHeaders.RemoveEOS(); } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("Preset Headers:\r\n"); Preset[] presets = presetHeaders.Presets; foreach (Preset arg in presets) { stringBuilder.AppendFormat("{0}\r\n", arg); } stringBuilder.Append("Instruments:\r\n"); Instrument[] array = instruments.Instruments; foreach (Instrument arg2 in array) { stringBuilder.AppendFormat("{0}\r\n", arg2); } return stringBuilder.ToString(); } } internal class RiffChunk { private string chunkID; private BinaryReader riffFile; public string ChunkID { get { return chunkID; } set { if (value == null) { throw new ArgumentNullException("ChunkID may not be null"); } if (value.Length != 4) { throw new ArgumentException("ChunkID must be four characters"); } chunkID = value; } } public uint ChunkSize { get; private set; } public long DataOffset { get; private set; } public static RiffChunk GetTopLevelChunk(BinaryReader file) { RiffChunk riffChunk = new RiffChunk(file); riffChunk.ReadChunk(); return riffChunk; } private RiffChunk(BinaryReader file) { riffFile = file; chunkID = "????"; ChunkSize = 0u; DataOffset = 0L; } public string ReadChunkID() { byte[] array = riffFile.ReadBytes(4); if (array.Length != 4) { throw new InvalidDataException("Couldn't read Chunk ID"); } return ByteEncoding.Instance.GetString(array, 0, array.Length); } private void ReadChunk() { chunkID = ReadChunkID(); ChunkSize = riffFile.ReadUInt32(); DataOffset = riffFile.BaseStream.Position; } public RiffChunk GetNextSubChunk() { if (riffFile.BaseStream.Position + 8 < DataOffset + ChunkSize) { RiffChunk riffChunk = new RiffChunk(riffFile); riffChunk.ReadChunk(); return riffChunk; } return null; } public byte[] GetData() { riffFile.BaseStream.Position = DataOffset; byte[] array = riffFile.ReadBytes((int)ChunkSize); if (array.Length != ChunkSize) { throw new InvalidDataException($"Couldn't read chunk's data Chunk: {this}, read {array.Length} bytes"); } return array; } public string GetDataAsString() { byte[] data = GetData(); if (data == null) { return null; } return ByteEncoding.Instance.GetString(data, 0, data.Length); } public T GetDataAsStructure<T>(StructureBuilder<T> s) { riffFile.BaseStream.Position = DataOffset; if (s.Length != ChunkSize) { throw new InvalidDataException($"Chunk size is: {ChunkSize} so can't read structure of: {s.Length}"); } return s.Read(riffFile); } public T[] GetDataAsStructureArray<T>(StructureBuilder<T> s) { riffFile.BaseStream.Position = DataOffset; if (ChunkSize % s.Length != 0) { throw new InvalidDataException($"Chunk size is: {ChunkSize} not a multiple of structure size: {s.Length}"); } int num = (int)(ChunkSize / s.Length); T[] array = new T[num]; for (int i = 0; i < num; i++) { array[i] = s.Read(riffFile); } return array; } public override string ToString() { return $"RiffChunk ID: {ChunkID} Size: {ChunkSize} Data Offset: {DataOffset}"; } } internal class SampleDataChunk { public byte[] SampleData { get; private set; } public SampleDataChunk(RiffChunk chunk) { string text = chunk.ReadChunkID(); if (text != "sdta") { throw new InvalidDataException("Not a sample data chunk (" + text + ")"); } SampleData = chunk.GetData(); } } public class SampleHeader { public string SampleName; public uint Start; public uint End; public uint StartLoop; public uint EndLoop; public uint SampleRate; public byte OriginalPitch; public sbyte PitchCorrection; public ushort SampleLink; public SFSampleLink SFSampleLink; public override string ToString() { return SampleName; } } internal class SampleHeaderBuilder : StructureBuilder<SampleHeader> { public override int Length => 46; public SampleHeader[] SampleHeaders => data.ToArray(); public override SampleHeader Read(BinaryReader br) { SampleHeader sampleHeader = new SampleHeader(); byte[] array = br.ReadBytes(20); sampleHeader.SampleName = ByteEncoding.Instance.GetString(array, 0, array.Length); sampleHeader.Start = br.ReadUInt32(); sampleHeader.End = br.ReadUInt32(); sampleHeader.StartLoop = br.ReadUInt32(); sampleHeader.EndLoop = br.ReadUInt32(); sampleHeader.SampleRate = br.ReadUInt32(); sampleHeader.OriginalPitch = br.ReadByte(); sampleHeader.PitchCorrection = br.ReadSByte(); sampleHeader.SampleLink = br.ReadUInt16(); sampleHeader.SFSampleLink = (SFSampleLink)br.ReadUInt16(); data.Add(sampleHeader); return sampleHeader; } public override void Write(BinaryWriter bw, SampleHeader sampleHeader) { } internal void RemoveEOS() { data.RemoveAt(data.Count - 1); } } public enum SampleMode { NoLoop, LoopContinuously, ReservedNoLoop, LoopAndContinue } public enum SFSampleLink : ushort { MonoSample = 1, RightSample = 2, LeftSample = 4, LinkedSample = 8, RomMonoSample = 32769, RomRightSample = 32770, RomLeftSample = 32772, RomLinkedSample = 32776 } public class SFVersion { public short Major { get; set; } public short Minor { get; set; } } internal class SFVersionBuilder : StructureBuilder<SFVersion> { public override int Length => 4; public override SFVersion Read(BinaryReader br) { SFVersion sFVersion = new SFVersion(); sFVersion.Major = br.ReadInt16(); sFVersion.Minor = br.ReadInt16(); data.Add(sFVersion); return sFVersion; } public override void Write(BinaryWriter bw, SFVersion v) { bw.Write(v.Major); bw.Write(v.Minor); } } public class SoundFont { private InfoChunk info; private PresetsChunk presetsChunk; private SampleDataChunk sampleData; public InfoChunk FileInfo => info; public Preset[] Presets => presetsChunk.Presets; public Instrument[] Instruments => presetsChunk.Instruments; public SampleHeader[] SampleHeaders => presetsChunk.SampleHeaders; public byte[] SampleData => sampleData.SampleData; public SoundFont(string fileName) : this(new FileStream(fileName, FileMode.Open, FileAccess.Read)) { } public SoundFont(Stream sfFile) { using (sfFile) { RiffChunk topLevelChunk = RiffChunk.GetTopLevelChunk(new BinaryReader(sfFile)); if (topLevelChunk.ChunkID == "RIFF") { string text = topLevelChunk.ReadChunkID(); if (text != "sfbk") { throw new InvalidDataException($"Not a SoundFont ({text})"); } RiffChunk nextSubChunk = topLevelChunk.GetNextSubChunk(); if (nextSubChunk.ChunkID == "LIST") { info = new InfoChunk(nextSubChunk); RiffChunk nextSubChunk2 = topLevelChunk.GetNextSubChunk(); sampleData = new SampleDataChunk(nextSubChunk2); nextSubChunk2 = topLevelChunk.GetNextSubChunk(); presetsChunk = new PresetsChunk(nextSubChunk2); return; } throw new InvalidDataException($"Not info list found ({nextSubChunk.ChunkID})"); } throw new InvalidDataException("Not a RIFF file"); } } public override string ToString() { return $"Info Chunk:\r\n{info}\r\nPresets Chunk:\r\n{presetsChunk}"; } } internal abstract class StructureBuilder<T> { protected List<T> data; public abstract int Length { get; } public T[] Data => data.ToArray(); public StructureBuilder() { Reset(); } public abstract T Read(BinaryReader br); public abstract void Write(BinaryWriter bw, T o); public void Reset() { data = new List<T>(); } } public class Zone { internal ushort generatorIndex; internal ushort modulatorIndex; internal ushort generatorCount; internal ushort modulatorCount; public Modulator[] Modulators { get; set; } public Generator[] Generators { get; set; } public override string ToString() { return $"Zone {generatorCount} Gens:{generatorIndex} {modulatorCount} Mods:{modulatorIndex}"; } } internal class ZoneBuilder : StructureBuilder<Zone> { private Zone lastZone = null; public Zone[] Zones => data.ToArray(); public override int Length => 4; public override Zone Read(BinaryReader br) { Zone zone = new Zone(); zone.generatorIndex = br.ReadUInt16(); zone.modulatorIndex = br.ReadUInt16(); if (lastZone != null) { lastZone.generatorCount = (ushort)(zone.generatorIndex - lastZone.generatorIndex); lastZone.modulatorCount = (ushort)(zone.modulatorIndex - lastZone.modulatorIndex); } data.Add(zone); lastZone = zone; return zone; } public override void Write(BinaryWriter bw, Zone zone) { } public void Load(Modulator[] modulators, Generator[] generators) { for (int i = 0; i < data.Count - 1; i++) { Zone zone = data[i]; zone.Generators = new Generator[zone.generatorCount]; Array.Copy(generators, zone.generatorIndex, zone.Generators, 0, zone.generatorCount); zone.Modulators = new Modulator[zone.modulatorCount]; Array.Copy(modulators, zone.modulatorIndex, zone.Modulators, 0, zone.modulatorCount); } data.RemoveAt(data.Count - 1); } } } namespace NAudio.Wave { public enum ChannelMode { Stereo, JointStereo, DualChannel, Mono } public class Id3v2Tag { private long tagStartPosition; private long tagEndPosition; private byte[] rawData; public byte[] RawData => rawData; public static Id3v2Tag ReadTag(Stream input) { try { return new Id3v2Tag(input); } catch (FormatException) { return null; } } public static Id3v2Tag Create(IEnumerable<KeyValuePair<string, string>> tags) { return ReadTag(CreateId3v2TagStream(tags)); } private static byte[] FrameSizeToBytes(int n) { byte[] bytes = BitConverter.GetBytes(n); Array.Reverse((Array)bytes); return bytes; } private static byte[] CreateId3v2Frame(string key, string value) { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("value"); } if (key.Length != 4) { throw new ArgumentOutOfRangeException("key", "key " + key + " must be 4 characters long"); } byte[] array = new byte[2] { 255, 254 }; byte[] array2 = new byte[3]; byte[] array3 = new byte[2]; byte[] array4 = ((!(key == "COMM")) ? ByteArrayExtensions.Concat(new byte[1] { 1 }, array, Encoding.Unicode.GetBytes(value)) : ByteArrayExtensions.Concat(new byte[1] { 1 }, array2, array3, array, Encoding.Unicode.GetBytes(value))); return ByteArrayExtensions.Concat(Encoding.UTF8.GetBytes(key), FrameSizeToBytes(array4.Length), new byte[2], array4); } private static byte[] GetId3TagHeaderSize(int size) { byte[] array = new byte[4]; for (int num = array.Length - 1; num >= 0; num--) { array[num] = (byte)(size % 128); size /= 128; } return array; } private static byte[] CreateId3v2TagHeader(IEnumerable<byte[]> frames) { int num = 0; foreach (byte[] frame in frames) { num += frame.Length; } return ByteArrayExtensions.Concat(Encoding.UTF8.GetBytes("ID3"), new byte[2] { 3, 0 }, new byte[1], GetId3TagHeaderSize(num)); } private static Stream CreateId3v2TagStream(IEnumerable<KeyValuePair<string, string>> tags) { List<byte[]> list = new List<byte[]>(); foreach (KeyValuePair<string, string> tag in tags) { list.Add(CreateId3v2Frame(tag.Key, tag.Value)); } byte[] array = CreateId3v2TagHeader(list); MemoryStream memoryStream = new MemoryStream(); memoryStream.Write(array, 0, array.Length); foreach (byte[] item in list) { memoryStream.Write(item, 0, item.Length); } memoryStream.Position = 0L; return memoryStream; } private Id3v2Tag(Stream input) { tagStartPosition = input.Position; BinaryReader binaryReader = new BinaryReader(input); byte[] array = binaryReader.ReadBytes(10); if (array.Length >= 3 && array[0] == 73 && array[1] == 68 && array[2] == 51) { if ((array[5] & 0x40) == 64) { byte[] array2 = binaryReader.ReadBytes(4); int num = array2[0] * 2097152; num += array2[1] * 16384; num += array2[2] * 128; num += array2[3]; } int num2 = array[6] * 2097152; num2 += array[7] * 16384; num2 += array[8] * 128; num2 += array[9]; byte[] array3 = binaryReader.ReadBytes(num2); if ((array[5] & 0x10) == 16) { byte[] array4 = binaryReader.ReadBytes(10); } tagEndPosition = input.Position; input.Position = tagStartPosition; rawData = binaryReader.ReadBytes((int)(tagEndPosition - tagStartPosition)); return; } input.Position = tagStartPosition; throw new FormatException("Not an ID3v2 tag"); } } public interface IMp3FrameDecompressor : IDisposable { WaveFormat OutputFormat { get; } int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset); void Reset(); } public class Mp3Frame { private static readonly int[,,] bitRates = new int[2, 3, 15] { { { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 } } }; private static readonly int[,] samplesPerFrame = new int[2, 3] { { 384, 1152, 1152 }, { 384, 1152, 576 } }; private static readonly int[] sampleRatesVersion1 = new int[3] { 44100, 48000, 32000 }; private static readonly int[] sampleRatesVersion2 = new int[3] { 22050, 24000, 16000 }; private static readonly int[] sampleRatesVersion25 = new int[3] { 11025, 12000, 8000 }; private const int MaxFrameLength = 16384; public int SampleRate { get; private set; } public int FrameLength { get; private set; } public int BitRate { get; private set; } public byte[] RawData { get; private set; } public MpegVersion MpegVersion { get; private set; } public MpegLayer MpegLayer { get; private set; } public ChannelMode ChannelMode { get; private set; } public int SampleCount { get; private set; } public int ChannelExtension { get; private set; } public int BitRateIndex { get; private set; } public bool Copyright { get; private set; } public bool CrcPresent { get; private set; } public long FileOffset { get; private set; } public static Mp3Frame LoadFromStream(Stream input) { return LoadFromStream(input, readData: true); } public static Mp3Frame LoadFromStream(Stream input, bool readData) { Mp3Frame mp3Frame = new Mp3Frame(); mp3Frame.FileOffset = input.Position; byte[] array = new byte[4]; int num = input.Read(array, 0, array.Length); if (num < array.Length) { return null; } while (!IsValidHeader(array, mp3Frame)) { array[0] = array[1]; array[1] = array[2]; array[2] = array[3]; num = input.Read(array, 3, 1); if (num < 1) { return null; } mp3Frame.FileOffset++; } int num2 = mp3Frame.FrameLength - 4; if (readData) { mp3Frame.RawData = new byte[mp3Frame.FrameLength]; Array.Copy(array, mp3Frame.RawData, 4); num = input.Read(mp3Frame.RawData, 4, num2); if (num < num2) { throw new EndOfStreamException("Unexpected end of stream before frame complete"); } } else { input.Position += num2; } return mp3Frame; } private Mp3Frame() { } private static bool IsValidHeader(byte[] headerBytes, Mp3Frame frame) { if (headerBytes[0] == byte.MaxValue && (headerBytes[1] & 0xE0) == 224) { frame.MpegVersion = (MpegVersion)((headerBytes[1] & 0x18) >> 3); if (frame.MpegVersion == MpegVersion.Reserved) { return false; } frame.MpegLayer = (MpegLayer)((headerBytes[1] & 6) >> 1); if (frame.MpegLayer == MpegLayer.Reserved) { return false; } int num = ((frame.MpegLayer != MpegLayer.Layer1) ? ((frame.MpegLayer == MpegLayer.Layer2) ? 1 : 2) : 0); frame.CrcPresent = (headerBytes[1] & 1) == 0; frame.BitRateIndex = (headerBytes[2] & 0xF0) >> 4; if (frame.BitRateIndex == 15) { return false; } int num2 = ((frame.MpegVersion != MpegVersion.Version1) ? 1 : 0); frame.BitRate = bitRates[num2, num, frame.BitRateIndex] * 1000; if (frame.BitRate == 0) { return false; } int num3 = (headerBytes[2] & 0xC) >> 2; if (num3 == 3) { return false; } if (frame.MpegVersion == MpegVersion.Version1) { frame.SampleRate = sampleRatesVersion1[num3]; } else if (frame.MpegVersion == MpegVersion.Version2) { frame.SampleRate = sampleRatesVersion2[num3]; } else { frame.SampleRate = sampleRatesVersion25[num3]; } bool flag = (headerBytes[2] & 2) == 2; bool flag2 = (headerBytes[2] & 1) == 1; frame.ChannelMode = (ChannelMode)((headerBytes[3] & 0xC0) >> 6); frame.ChannelExtension = (headerBytes[3] & 0x30) >> 4; if (frame.ChannelExtension != 0 && frame.ChannelMode != ChannelMode.JointStereo) { return false; } frame.Copyright = (headerBytes[3] & 8) == 8; bool flag3 = (headerBytes[3] & 4) == 4; int num4 = headerBytes[3] & 3; int num5 = (flag ? 1 : 0); frame.SampleCount = samplesPerFrame[num2, num]; int num6 = frame.SampleCount / 8; if (frame.MpegLayer == MpegLayer.Layer1) { frame.FrameLength = (num6 * frame.BitRate / frame.SampleRate + num5) * 4; } else { frame.FrameLength = num6 * frame.BitRate / frame.SampleRate + num5; } if (frame.FrameLength > 16384) { return false; } return true; } return false; } } public enum MpegLayer { Reserved, Layer3, Layer2, Layer1 } public enum MpegVersion { Version25, Reserved, Version2, Version1 } public class XingHeader { [Flags] private enum XingHeaderOptions { Frames = 1, Bytes = 2, Toc = 4, VbrScale = 8 } private static int[] sr_table = new int[4] { 44100, 48000, 32000, 99999 }; private int vbrScale = -1; private int startOffset; private int endOffset; private int tocOffset = -1; private int framesOffset = -1; private int bytesOffset = -1; private Mp3Frame frame; public int Frames { get { if (framesOffset == -1) { return -1; } return ReadBigEndian(frame.RawData, framesOffset); } set { if (framesOffset == -1) { throw new InvalidOperationException("Frames flag is not set"); } WriteBigEndian(frame.RawData, framesOffset, value); } } public int Bytes { get { if (bytesOffset == -1) { return -1; } return ReadBigEndian(frame.RawData, bytesOffset); } set { if (framesOffset == -1) { throw new InvalidOperationException("Bytes flag is not set"); } WriteBigEndian(frame.RawData, bytesOffset, value); } } public int VbrScale => vbrScale; public Mp3Frame Mp3Frame => frame; private static int ReadBigEndian(byte[] buffer, int offset) { int num = buffer[offset]; num <<= 8; num |= buffer[offset + 1]; num <<= 8; num |= buffer[offset + 2]; num <<= 8; return num | buffer[offset + 3]; } private void WriteBigEndian(byte[] buffer, int offset, int value) { byte[] bytes = BitConverter.GetBytes(value); for (int i = 0; i < 4; i++) { buffer[offset + 3 - i] = bytes[i]; } } public static XingHeader LoadXingHeader(Mp3Frame frame) { XingHeader xingHeader = new XingHeader(); xingHeader.frame = frame; int num = 0; if (frame.MpegVersion == MpegVersion.Version1) { num = ((frame.ChannelMode == ChannelMode.Mono) ? 21 : 36); } else { if (frame.MpegVersion != MpegVersion.Version2) { return null; } num = ((frame.ChannelMode == ChannelMode.Mono) ? 13 : 21); } if (frame.RawData[num] == 88 && frame.RawData[num + 1] == 105 && frame.RawData[num + 2] == 110 && frame.RawData[num + 3] == 103) { xingHeader.startOffset = num; num += 4; } else { if (frame.RawData[num] != 73 || frame.RawData[num + 1] != 110 || frame.RawData[num + 2] != 102 || frame.RawData[num + 3] != 111) { return null; } xingHeader.startOffset = num; num += 4; } XingHeaderOptions xingHeaderOptions = (XingHeaderOptions)ReadBigEndian(frame.RawData, num); num += 4; if ((xingHeaderOptions & XingHeaderOptions.Frames) != 0) { xingHeader.framesOffset = num; num += 4; } if ((xingHeaderOptions & XingHeaderOptions.Bytes) != 0) { xingHeader.bytesOffset = num; num += 4; } if ((xingHeaderOptions & XingHeaderOptions.Toc) != 0) { xingHeader.tocOffset = num; num += 100; } if ((xingHeaderOptions & XingHeaderOptions.VbrScale) != 0) { xingHeader.vbrScale = ReadBigEndian(frame.RawData, num); num += 4; } xingHeader.endOffset = num; return xingHeader; } private XingHeader() { } } public static class WaveExtensionMethods { public static ISampleProvider ToSampleProvider(this IWaveProvider waveProvider) { return SampleProviderConverters.ConvertWaveProviderIntoSampleProvider(waveProvider); } public static void Init(this IWavePlayer wavePlayer, ISampleProvider sampleProvider, bool convertTo16Bit = false) { IWaveProvider waveProvider2; if (!convertTo16Bit) { IWaveProvider waveProvider = new SampleToWaveProvider(sampleProvider); waveProvider2 = waveProvider; } else { IWaveProvider waveProvider = new SampleToWaveProvider16(sampleProvider); waveProvider2 = waveProvider; } IWaveProvider waveProvider3 = waveProvider2; wavePlayer.Init(waveProvider3); } public static WaveFormat AsStandardWaveFormat(this WaveFormat waveFormat) { return (waveFormat is WaveFormatExtensible waveFormatExtensible) ? waveFormatExtensible.ToStandardWaveFormat() : waveFormat; } public static IWaveProvider ToWaveProvider(this ISampleProvider sampleProvider) { return new SampleToWaveProvider(sampleProvider); } public static IWaveProvider ToWaveProvider16(this ISampleProvider sampleProvider) { return new SampleToWaveProvider16(sampleProvider); } public static ISampleProvider FollowedBy(this ISampleProvider sampleProvider, ISampleProvider next) { return new ConcatenatingSampleProvider(new ISampleProvider[2] { sampleProvider, next }); } public static ISampleProvider FollowedBy(this ISampleProvider sampleProvider, TimeSpan silenceDuration, ISampleProvider next) { OffsetSampleProvider offsetSampleProvider = new OffsetSampleProvider(sampleProvider) { LeadOut = silenceDuration }; return new ConcatenatingSampleProvider(new ISampleProvider[2] { offsetSampleProvider, next }); } public static ISampleProvider Skip(this ISampleProvider sampleProvider, TimeSpan skipDuration) { return new OffsetSampleProvider(sampleProvider) { SkipOver = skipDuration }; } public static ISampleProvider Take(this ISampleProvider sampleProvider, TimeSpan takeDuration) { return new OffsetSampleProvider(sampleProvider) { Take = takeDuration }; } public static ISampleProvider ToMono(this ISampleProvider sourceProvider, float leftVol = 0.5f, float rightVol = 0.5f) { if (sourceProvider.WaveFormat.Channels == 1) { return sourceProvider; } return new StereoToMonoSampleProvider(sourceProvider) { LeftVolume = leftVol, RightVolume = rightVol }; } public static ISampleProvider ToStereo(this ISampleProvider sourceProvider, float leftVol = 1f, float rightVol = 1f) { if (sourceProvider.WaveFormat.Channels == 2) { return sourceProvider; } return new MonoToStereoSampleProvider(sourceProvider) { LeftVolume = leftVol, RightVolume = rightVol }; } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class AdpcmWaveFormat : WaveFormat { private short samplesPerBlock; private short numCoeff; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] private short[] coefficients; public int SamplesPerBlock => samplesPerBlock; public int NumCoefficients => numCoeff; public short[] Coefficients => coefficients; private AdpcmWaveFormat() : this(8000, 1) { } public AdpcmWaveFormat(int sampleRate, int channels) : base(sampleRate, 0, channels) { waveFormatTag = WaveFormatEncoding.Adpcm; extraSize = 32; switch (base.sampleRate) { case 8000: case 11025: blockAlign = 256; break; case 22050: blockAlign = 512; break; default: blockAlign = 1024; break; } bitsPerSample = 4; samplesPerBlock = (short)((blockAlign - 7 * channels) * 8 / (bitsPerSample * channels) + 2); averageBytesPerSecond = base.SampleRate * blockAlign / samplesPerBlock; numCoeff = 7; coefficients = new short[14] { 256, 0, 512, -256, 0, 0, 192, 64, 240, 0, 460, -208, 392, -232 }; } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); writer.Write(samplesPerBlock); writer.Write(numCoeff); short[] array = coefficients; foreach (short value in array) { writer.Write(value); } } public override string ToString() { return $"Microsoft ADPCM {base.SampleRate} Hz {channels} channels {bitsPerSample} bits per sample {samplesPerBlock} samples per block"; } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class Gsm610WaveFormat : WaveFormat { private readonly short samplesPerBlock; public short SamplesPerBlock => samplesPerBlock; public Gsm610WaveFormat() { waveFormatTag = WaveFormatEncoding.Gsm610; channels = 1; averageBytesPerSecond = 1625; bitsPerSample = 0; blockAlign = 65; sampleRate = 8000; extraSize = 2; samplesPerBlock = 320; } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); writer.Write(samplesPerBlock); } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class ImaAdpcmWaveFormat : WaveFormat { private short samplesPerBlock; private ImaAdpcmWaveFormat() { } public ImaAdpcmWaveFormat(int sampleRate, int channels, int bitsPerSample) { waveFormatTag = WaveFormatEncoding.DviAdpcm; base.sampleRate = sampleRate; base.channels = (short)channels; base.bitsPerSample = (short)bitsPerSample; extraSize = 2; blockAlign = 0; averageBytesPerSecond = 0; samplesPerBlock = 0; } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class Mp3WaveFormat : WaveFormat { public Mp3WaveFormatId id; public Mp3WaveFormatFlags flags; public ushort blockSize; public ushort framesPerBlock; public ushort codecDelay; private const short Mp3WaveFormatExtraBytes = 12; public Mp3WaveFormat(int sampleRate, int channels, int blockSize, int bitRate) { waveFormatTag = WaveFormatEncoding.MpegLayer3; base.channels = (short)channels; averageBytesPerSecond = bitRate / 8; bitsPerSample = 0; blockAlign = 1; base.sampleRate = sampleRate; extraSize = 12; id = Mp3WaveFormatId.Mpeg; flags = Mp3WaveFormatFlags.PaddingIso; this.blockSize = (ushort)blockSize; framesPerBlock = 1; codecDelay = 0; } } [Flags] public enum Mp3WaveFormatFlags { PaddingIso = 0, PaddingOn = 1, PaddingOff = 2 } public enum Mp3WaveFormatId : ushort { Unknown, Mpeg, ConstantFrameSize } [StructLayout(LayoutKind.Sequential, Pack = 2)] internal class OggWaveFormat : WaveFormat { public uint dwVorbisACMVersion; public uint dwLibVorbisVersion; } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class TrueSpeechWaveFormat : WaveFormat { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] private short[] unknown; public TrueSpeechWaveFormat() { waveFormatTag = WaveFormatEncoding.DspGroupTrueSpeech; channels = 1; averageBytesPerSecond = 1067; bitsPerSample = 1; blockAlign = 32; sampleRate = 8000; extraSize = 32; unknown = new short[16]; unknown[0] = 1; unknown[1] = 240; } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); short[] array = unknown; foreach (short value in array) { writer.Write(value); } } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class WaveFormat { protected WaveFormatEncoding waveFormatTag; protected short channels; protected int sampleRate; protected int averageBytesPerSecond; protected short blockAlign; protected short bitsPerSample; protected short extraSize; public WaveFormatEncoding Encoding => waveFormatTag; public int Channels => channels; public int SampleRate => sampleRate; public int AverageBytesPerSecond => averageBytesPerSecond; public virtual int BlockAlign => blockAlign; public int BitsPerSample => bitsPerSample; public int ExtraSize => extraSize; public WaveFormat() : this(44100, 16, 2) { } public WaveFormat(int sampleRate, int channels) : this(sampleRate, 16, channels) { } public int ConvertLatencyToByteSize(int milliseconds) { int num = (int)((double)AverageBytesPerSecond / 1000.0 * (double)milliseconds); if (num % BlockAlign != 0) { num = num + BlockAlign - num % BlockAlign; } return num; } public static WaveFormat CreateCustomFormat(WaveFormatEncoding tag, int sampleRate, int channels, int averageBytesPerSecond, int blockAlign, int bitsPerSample) { WaveFormat waveFormat = new WaveFormat(); waveFormat.waveFormatTag = tag; waveFormat.channels = (short)channels; waveFormat.sampleRate = sampleRate; waveFormat.averageBytesPerSecond = averageBytesPerSecond; waveFormat.blockAlign = (short)blockAlign; waveFormat.bitsPerSample = (short)bitsPerSample; waveFormat.extraSize = 0; return waveFormat; } public static WaveFormat CreateALawFormat(int sampleRate, int channels) { return CreateCustomFormat(WaveFormatEncoding.ALaw, sampleRate, channels, sampleRate * channels, channels, 8); } public static WaveFormat CreateMuLawFormat(int sampleRate, int channels) { return CreateCustomFormat(WaveFormatEncoding.MuLaw, sampleRate, channels, sampleRate * channels, channels, 8); } public WaveFormat(int rate, int bits, int channels) { if (channels < 1) { throw new ArgumentOutOfRangeException("channels", "Channels must be 1 or greater"); } waveFormatTag = WaveFormatEncoding.Pcm; this.channels = (short)channels; sampleRate = rate; bitsPerSample = (short)bits; extraSize = 0; blockAlign = (short)(channels * (bits / 8)); averageBytesPerSecond = sampleRate * blockAlign; } public static WaveFormat CreateIeeeFloatWaveFormat(int sampleRate, int channels) { WaveFormat waveFormat = new WaveFormat(); waveFormat.waveFormatTag = WaveFormatEncoding.IeeeFloat; waveFormat.channels = (short)channels; waveFormat.bitsPerSample = 32; waveFormat.sampleRate = sampleRate; waveFormat.blockAlign = (short)(4 * channels); waveFormat.averageBytesPerSecond = sampleRate * waveFormat.blockAlign; waveFormat.extraSize = 0; return waveFormat; } public static WaveFormat MarshalFromPtr(IntPtr pointer) { WaveFormat waveFormat = Marshal.PtrToStructure<WaveFormat>(pointer); switch (waveFormat.Encoding) { case WaveFormatEncoding.Pcm: waveFormat.extraSize = 0; break; case WaveFormatEncoding.Extensible: waveFormat = Marshal.PtrToStructure<WaveFormatExtensible>(pointer); break; case WaveFormatEncoding.Adpcm: waveFormat = Marshal.PtrToStructure<AdpcmWaveFormat>(pointer); break; case WaveFormatEncoding.Gsm610: waveFormat = Marshal.PtrToStructure<Gsm610WaveFormat>(pointer); break; default: if (waveFormat.ExtraSize > 0) { waveFormat = Marshal.PtrToStructure<WaveFormatExtraData>(pointer); } break; } return waveFormat; } public static IntPtr MarshalToPtr(WaveFormat format) { int cb = Marshal.SizeOf(format); IntPtr intPtr = Marshal.AllocHGlobal(cb); Marshal.StructureToPtr(format, intPtr, fDeleteOld: false); return intPtr; } public static WaveFormat FromFormatChunk(BinaryReader br, int formatChunkLength) { WaveFormatExtraData waveFormatExtraData = new WaveFormatExtraData(); waveFormatExtraData.ReadWaveFormat(br, formatChunkLength); waveFormatExtraData.ReadExtraData(br); return waveFormatExtraData; } private void ReadWaveFormat(BinaryReader br, int formatChunkLength) { if (formatChunkLength < 16) { throw new InvalidDataException("Invalid WaveFormat Structure"); } waveFormatTag = (WaveFormatEncoding)br.ReadUInt16(); channels = br.ReadInt16(); sampleRate = br.ReadInt32(); averageBytesPerSecond = br.ReadInt32(); blockAlign = br.ReadInt16(); bitsPerSample = br.ReadInt16(); if (formatChunkLength > 16) { extraSize = br.ReadInt16(); if (extraSize != formatChunkLength - 18) { Debug.WriteLine("Format chunk mismatch"); extraSize = (short)(formatChunkLength - 18); } } } public WaveFormat(BinaryReader br) { int formatChunkLength = br.ReadInt32(); ReadWaveFormat(br, formatChunkLength); } public override string ToString() { switch (waveFormatTag) { case WaveFormatEncoding.Pcm: case WaveFormatEncoding.Extensible: return $"{bitsPerSample} bit PCM: {sampleRate}Hz {channels} channels"; case WaveFormatEncoding.IeeeFloat: return $"{bitsPerSample} bit IEEFloat: {sampleRate}Hz {channels} channels"; default: return waveFormatTag.ToString(); } } public override bool Equals(object obj) { if (obj is WaveFormat waveFormat) { return waveFormatTag == waveFormat.waveFormatTag && channels == waveFormat.channels && sampleRate == waveFormat.sampleRate && averageBytesPerSecond == waveFormat.averageBytesPerSecond && blockAlign == waveFormat.blockAlign && bitsPerSample == waveFormat.bitsPerSample; } return false; } public override int GetHashCode() { return (int)waveFormatTag ^ (int)channels ^ sampleRate ^ averageBytesPerSecond ^ blockAlign ^ bitsPerSample; } public virtual void Serialize(BinaryWriter writer) { writer.Write(18 + extraSize); writer.Write((short)Encoding); writer.Write((short)Channels); writer.Write(SampleRate); writer.Write(AverageBytesPerSecond); writer.Write((short)BlockAlign); writer.Write((short)BitsPerSample); writer.Write(extraSize); } } public sealed class WaveFormatCustomMarshaler : ICustomMarshaler { private static WaveFormatCustomMarshaler marshaler; public static ICustomMarshaler GetInstance(string cookie) { if (marshaler == null) { marshaler = new WaveFormatCustomMarshaler(); } return marshaler; } public void CleanUpManagedData(object ManagedObj) { } public void CleanUpNativeData(IntPtr pNativeData) { Marshal.FreeHGlobal(pNativeData); } public int GetNativeDataSize() { throw new NotImplementedException(); } public IntPtr MarshalManagedToNative(object ManagedObj) { return WaveFormat.MarshalToPtr((WaveFormat)ManagedObj); } public object MarshalNativeToManaged(IntPtr pNativeData) { return WaveFormat.MarshalFromPtr(pNativeData); } } public enum WaveFormatEncoding : ushort { 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, WAVE_FORMAT_NMS_VBXADPCM = 56, WAVE_FORMAT_CS_IMAADPCM = 57, WAVE_FORMAT_ECHOSC3 = 58, WAVE_FORMAT_ROCKWELL_ADPCM = 59, WAVE_FORMAT_ROCKWELL_DIGITALK = 60, WAVE_FORMAT_XEBEC = 61, WAVE_FORMAT_G721_ADPCM = 64, WAVE_FORMAT_G728_CELP = 65, WAVE_FORMAT_MSG723 = 66, Mpeg = 80, WAVE_FORMAT_RT24 = 82, WAVE_FORMAT_PAC = 83, MpegLayer3 = 85, WAVE_FORMAT_LUCENT_G723 = 89, WAVE_FORMAT_CIRRUS = 96, WAVE_FORMAT_ESPCM = 97, WAVE_FORMAT_VOXWARE = 98, WAVE_FORMAT_CANOPUS_ATRAC = 99, WAVE_FORMAT_G726_ADPCM = 100, WAVE_FORMAT_G722_ADPCM = 101, WAVE_FORMAT_DSAT_DISPLAY = 103, WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = 105, WAVE_FORMAT_VOXWARE_AC8 = 112, WAVE_FORMAT_VOXWARE_AC10 = 113, WAVE_FORMAT_VOXWARE_AC16 = 114, WAVE_FORMAT_VOXWARE_AC20 = 115, WAVE_FORMAT_VOXWARE_RT24 = 116, WAVE_FORMAT_VOXWARE_RT29 = 117, WAVE_FORMAT_VOXWARE_RT29HW = 118, WAVE_FORMAT_VOXWARE_VR12 = 119, WAVE_FORMAT_VOXWARE_VR18 = 120, WAVE_FORMAT_VOXWARE_TQ40 = 121, WAVE_FORMAT_SOFTSOUND = 128, WAVE_FORMAT_VOXWARE_TQ60 = 129, WAVE_FORMAT_MSRT24 = 130, WAVE_FORMAT_G729A = 131, WAVE_FORMAT_MVI_MVI2 = 132, WAVE_FORMAT_DF_G726 = 133, WAVE_FORMAT_DF_GSM610 = 134, WAVE_FORMAT_ISIAUDIO = 136, WAVE_FORMAT_ONLIVE = 137, WAVE_FORMAT_SBC24 = 145, WAVE_FORMAT_DOLBY_AC3_SPDIF = 146, WAVE_FORMAT_MEDIASONIC_G723 = 147, WAVE_FORMAT_PROSODY_8KBPS = 148, WAVE_FORMAT_ZYXEL_ADPCM = 151, WAVE_FORMAT_PHILIPS_LPCBB = 152, WAVE_FORMAT_PACKED = 153, WAVE_FORMAT_MALDEN_PHONYTALK = 160, Gsm = 161, G729 = 162, G723 = 163, Acelp = 164, RawAac = 255, WAVE_FORMAT_RHETOREX_ADPCM = 256, WAVE_FORMAT_IRAT = 257, WAVE_FORMAT_VIVO_G723 = 273, WAVE_FORMAT_VIVO_SIREN = 274, WAVE_FORMAT_DIGITAL_G723 = 291, WAVE_FORMAT_SANYO_LD_ADPCM = 293, WAVE_FORMAT_SIPROLAB_ACEPLNET = 304, WAVE_FORMAT_SIPROLAB_ACELP4800 = 305, WAVE_FORMAT_SIPROLAB_ACELP8V3 = 306, WAVE_FORMAT_SIPROLAB_G729 = 307, WAVE_FORMAT_SIPROLAB_G729A = 308, WAVE_FORMAT_SIPROLAB_KELVIN = 309, WAVE_FORMAT_G726ADPCM = 320, WAVE_FORMAT_QUALCOMM_PUREVOICE = 336, WAVE_FORMAT_QUALCOMM_HALFRATE = 337, WAVE_FORMAT_TUBGSM = 341, WAVE_FORMAT_MSAUDIO1 = 352, WindowsMediaAudio = 353, WindowsMediaAudioProfessional = 354, WindowsMediaAudioLosseless = 355, WindowsMediaAudioSpdif = 356, WAVE_FORMAT_UNISYS_NAP_ADPCM = 368, WAVE_FORMAT_UNISYS_NAP_ULAW = 369, WAVE_FORMAT_UNISYS_NAP_ALAW = 370, WAVE_FORMAT_UNISYS_NAP_16K = 371, WAVE_FORMAT_CREATIVE_ADPCM = 512, WAVE_FORMAT_CREATIVE_FASTSPEECH8 = 514, WAVE_FORMAT_CREATIVE_FASTSPEECH10 = 515, WAVE_FORMAT_UHER_ADPCM = 528, WAVE_FORMAT_QUARTERDECK = 544, WAVE_FORMAT_ILINK_VC = 560, WAVE_FORMAT_RAW_SPORT = 576, WAVE_FORMAT_ESST_AC3 = 577, WAVE_FORMAT_IPI_HSX = 592, WAVE_FORMAT_IPI_RPELP = 593, WAVE_FORMAT_CS2 = 608, WAVE_FORMAT_SONY_SCX = 624, WAVE_FORMAT_FM_TOWNS_SND = 768, WAVE_FORMAT_BTV_DIGITAL = 1024, WAVE_FORMAT_QDESIGN_MUSIC = 1104, WAVE_FORMAT_VME_VMPCM = 1664, WAVE_FORMAT_TPC = 1665, WAVE_FORMAT_OLIGSM = 4096, WAVE_FORMAT_OLIADPCM = 4097, WAVE_FORMAT_OLICELP = 4098, WAVE_FORMAT_OLISBC = 4099, WAVE_FORMAT_OLIOPR = 4100, WAVE_FORMAT_LH_CODEC = 4352, WAVE_FORMAT_NORRIS = 5120, WAVE_FORMAT_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, WAVE_FORMAT_DVM = 8192, Vorbis1 = 26447, Vorbis2 = 26448, Vorbis3 = 26449, Vorbis1P = 26479, Vorbis2P = 26480, Vorbis3P = 26481, Extensible = 65534, WAVE_FORMAT_DEVELOPMENT = ushort.MaxValue } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class WaveFormatExtensible : WaveFormat { private short wValidBitsPerSample; private int dwChannelMask; private Guid subFormat; public Guid SubFormat => subFormat; private WaveFormatExtensible() { } public WaveFormatExtensible(int rate, int bits, int channels) : base(rate, bits, channels) { waveFormatTag = WaveFormatEncoding.Extensible; extraSize = 22; wValidBitsPerSample = (short)bits; for (int i = 0; i < channels; i++) { dwChannelMask |= 1 << i; } if (bits == 32) { subFormat = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT; } else { subFormat = AudioMediaSubtypes.MEDIASUBTYPE_PCM; } } public WaveFormat ToStandardWaveFormat() { if (subFormat == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT && bitsPerSample == 32) { return WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels); } if (subFormat == AudioMediaSubtypes.MEDIASUBTYPE_PCM) { return new WaveFormat(sampleRate, bitsPerSample, channels); } return this; } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); writer.Write(wValidBitsPerSample); writer.Write(dwChannelMask); byte[] array = subFormat.ToByteArray(); writer.Write(array, 0, array.Length); } public override string ToString() { return "WAVE_FORMAT_EXTENSIBLE " + AudioMediaSubtypes.GetAudioSubtypeName(subFormat) + " " + $"{base.SampleRate}Hz {base.Channels} channels {base.BitsPerSample} bit"; } } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class WaveFormatExtraData : WaveFormat { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)] private byte[] extraData = new byte[100]; public byte[] ExtraData => extraData; internal WaveFormatExtraData() { } public WaveFormatExtraData(BinaryReader reader) : base(reader) { ReadExtraData(reader); } internal void ReadExtraData(BinaryReader reader) { if (extraSize > 0) { reader.Read(extraData, 0, extraSize); } } public override void Serialize(BinaryWriter writer) { base.Serialize(writer); if (extraSize > 0) { writer.Write(extraData, 0, extraSize); } } } public interface IWaveIn : IDisposable { WaveFormat WaveFormat { get; set; } event EventHandler<WaveInEventArgs> DataAvailable; event EventHandler<StoppedEventArgs> RecordingStopped; void StartRecording(); void StopRecording(); } public class WaveInEventArgs : EventArgs { private byte[] buffer; private int bytes; public byte[] Buffer => buffer; public int BytesRecorded => bytes; public WaveInEventArgs(byte[] buffer, int bytes) { this.buffer = buffer; this.bytes = bytes; } } public class AiffFileWriter : Stream { private Stream outStream; private BinaryWriter writer; private long dataSizePos; private long commSampleCountPos; private long dataChunkSize = 8L; private WaveFormat format; private string filename; private byte[] value24 = new byte[3]; public string Filename => filename; public override long Length => dataChunkSize; public WaveFormat WaveFormat => format; public override bool CanRead => false; public override bool CanWrite => true; public override bool CanSeek => false; public override long Position { get { return dataChunkSize; } set { throw new InvalidOperationException("Repositioning an AiffFileWriter is not supported"); } } public static void CreateAiffFile(string filename, WaveStream sourceProvider) { using AiffFileWriter aiffFileWriter = new AiffFileWriter(filename, sourceProvider.WaveFormat); byte[] array = new byte[16384]; while (sourceProvider.Position < sourceProvider.Length) { int count = Math.Min((int)(sourceProvider.Length - sourceProvider.Position), array.Length); int num = sourceProvider.Read(array, 0, count); if (num == 0) { break; } aiffFileWriter.Write(array, 0, num); } } public AiffFileWriter(Stream outStream, WaveFormat format) { this.outStream = outStream; this.format = format; writer = new BinaryWriter(outStream, Encoding.UTF8); writer.Write(Encoding.UTF8.GetBytes("FORM")); writer.Write(0); writer.Write(Encoding.UTF8.GetBytes("AIFF")); CreateCommChunk(); WriteSsndChunkHeader(); } public AiffFileWriter(string filename, WaveFormat format) : this(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read), format) { this.filename = filename; } private void WriteSsndChunkHeader() { writer.Write(Encoding.UTF8.GetBytes("SSND")); dataSizePos = outStream.Position; writer.Write(0); writer.Write(0); writer.Write(SwapEndian(format.BlockAlign)); } private byte[] SwapEndian(short n) { return new byte[2] { (byte)(n >> 8), (byte)((uint)n & 0xFFu) }; } private byte[] SwapEndian(int n) { return new byte[4] { (byte)((uint)(n >> 24) & 0xFFu), (byte)((uint)(n >> 16) & 0xFFu), (byte)((uint)(n >> 8) & 0xFFu), (byte)((uint)n & 0xFFu) }; } private void CreateCommChunk() { writer.Write(Encoding.UTF8.GetBytes("COMM")); writer.Write(SwapEndian(18)); writer.Write(SwapEndian((short)format.Channels)); commSampleCountPos = outStream.Position; writer.Write(0); writer.Write(SwapEndian((short)format.BitsPerSample)); writer.Write(IEEE.ConvertToIeeeExtended(format.SampleRate)); } public override int Read(byte[] buffer, int offset, int count) { throw new InvalidOperationException("Cannot read from an AiffFileWriter"); } public override long Seek(long offset, SeekOrigin origin) { throw new InvalidOperationException("Cannot seek within an AiffFileWriter"); } public override void SetLength(long value) { throw new InvalidOperationException("Cannot set length of an AiffFileWriter"); } public override void Write(byte[] data, int offset, int count) { byte[] array = new byte[data.Length]; int num = format.BitsPerSample / 8; for (int i = 0; i < data.Length; i++) { int num2 = (int)Math.Floor((double)i / (double)num) * num + (num - i % num - 1); array[i] = data[num2]; } outStream.Write(array, offset, count); dataChunkSize += count; } public void WriteSample(float sample) { if (WaveFormat.BitsPerSample == 16) { writer.Write(SwapEndian((short)(32767f * sample))); dataChunkSize += 2L; } else if (WaveFormat.BitsPerSample == 24) { byte[] bytes = BitConverter.GetBytes((int)(2.1474836E+09f * sample)); value24[2] = bytes[1]; value24[1] = bytes[2]; value24[0] = bytes[3]; writer.Write(value24); dataChunkSize += 3L; } else { if (WaveFormat.BitsPerSample != 32 || WaveFormat.Encoding != WaveFormatEncoding.Extensible) { throw new InvalidOperationException("Only 16, 24 or 32 bit PCM or IEEE float audio data supported"); } writer.Write(SwapEndian(65535 * (int)sample)); dataChunkSize += 4L; } } public void WriteSamples(float[] samples, int offset, int count) { for (int i = 0; i < count; i++) { WriteSample(samples[offset + i]); } } public void WriteSamples(short[] samples, int offset, int count) { if (WaveFormat.BitsPerSample == 16) { for (int i = 0; i < count; i++) { writer.Write(SwapEndian(samples[i + offset])); } dataChunkSize += count * 2; } else if (WaveFormat.BitsPerSample == 24) { for (int j = 0; j < count; j++) { byte[] bytes = BitConverter.GetBytes(65535 * samples[j + offset]); value24[2] = bytes[1]; value24[1] = bytes[2]; value24[0] = bytes[3]; writer.Write(value24); } dataChunkSize += count * 3; } else { if (WaveFormat.BitsPerSample != 32 || WaveFormat.Encoding != WaveFormatEncoding.Extensible) { throw new InvalidOperationException("Only 16, 24 or 32 bit PCM audio data supported"); } for (int k = 0; k < count; k++) { writer.Write(SwapEndian(65535 * samples[k + offset])); } dataChunkSize += count * 4; } } public override void Flush() { writer.Flush(); } protected override void Dispose(bool disposing) { if (disposing && outStream != null) { try { UpdateHeader(writer); } finally { outStream.Dispose(); outStream = null; } } } protected virtual void UpdateHeader(BinaryWriter writer) { Flush(); writer.Seek(4, SeekOrigin.Begin); writer.Write(SwapEndian((int)(outStream.Length - 8))); UpdateCommChunk(writer); UpdateSsndChunk(writer); } private void UpdateCommChunk(BinaryWriter writer) { writer.Seek((int)commSampleCountPos, SeekOrigin.Begin); writer.Write(SwapEndian((int)(dataChunkSize * 8 / format.BitsPerSample / format.Channels))); } private void UpdateSsndChunk(BinaryWriter writer) { writer.Seek((int)dataSizePos, SeekOrigin.Begin); writer.Write(SwapEndian((int)dataChunkSize)); } ~AiffFileWriter() { Debug.Assert(condition: false, "AiffFileWriter was not disposed"); Dispose(disposing: false); } } public class BextChunkInfo { public string Description { get; set; } public string Originator { get; set; } public string OriginatorReference { get; set; } public DateTime OriginationDateTime { get; set; } public string OriginationDate => OriginationDateTime.ToString("yyyy-MM-dd"); public string OriginationTime => OriginationDateTime.ToString("HH:mm:ss"); public long TimeReference { get; set; } public ushort Version => 1; public string UniqueMaterialIdentifier { get; set; } public byte[] Reserved { get; } public string CodingHistory { get; set; } public BextChunkInfo() { Reserved = new byte[190]; } } public class BwfWriter : IDisposable { private readonly WaveFormat format; private readonly BinaryWriter writer; private readonly long dataChunkSizePosition; private long dataLength; private bool isDisposed; public BwfWriter(string filename, WaveFormat format, BextChunkInfo bextChunkInfo) { this.format = format; writer = new BinaryWriter(File.OpenWrite(filename)); writer.Write(Encoding.UTF8.GetBytes("RIFF")); writer.Write(0); writer.Write(Encoding.UTF8.GetBytes("WAVE")); writer.Write(Encoding.UTF8.GetBytes("JUNK")); writer.Write(28); writer.Write(0L); writer.Write(0L); writer.Write(0L); writer.Write(0); writer.Write(Encoding.UTF8.GetBytes("bext")); byte[] bytes = Encoding.ASCII.GetBytes(bextChunkInfo.CodingHistory ?? ""); int num = 602 + bytes.Length; if (num % 2 != 0) { num++; } writer.Write(num); long position = writer.BaseStream.Position; writer.Write(GetAsBytes(bextChunkInfo.Description, 256)); writer.Write(GetAsBytes(bextChunkInfo.Originator, 32)); writer.Write(GetAsBytes(bextChunkInfo.OriginatorReference, 32)); writer.Write(GetAsBytes(bextChunkInfo.OriginationDate, 10)); writer.Write(GetAsBytes(bextChunkInfo.OriginationTime, 8)); writer.Write(bextChunkInfo.TimeReference); writer.Write(bextChunkInfo.Version); writer.Write(GetAsBytes(bextChunkInfo.UniqueMaterialIdentifier, 64)); writer.Write(bextChunkInfo.Reserved); writer.Write(bytes); if (bytes.Length % 2 != 0) { writer.Write((byte)0); } Debug.Assert(writer.BaseStream.Position == position + num, "Invalid bext chunk size"); writer.Write(Encoding.UTF8.GetBytes("fmt ")); format.Serialize(writer); writer.Write(Encoding.UTF8.GetBytes("data")); dataChunkSizePosition = writer.BaseStream.Position; writer.Write(-1); } public void Write(byte[] buffer, int offset, int count) { if (isDisposed) { throw new ObjectDisposedException("This BWF Writer already disposed"); } writer.Write(buffer, offset, count); dataLength += count; } public void Flush() { if (isDisposed) { throw new ObjectDisposedException("This BWF Writer already disposed"); } writer.Flush(); FixUpChunkSizes(restorePosition: true); } private void FixUpChunkSizes(bool restorePosition) { long position = writer.BaseStream.Position; bool flag = dataLength > int.MaxValue; long num = writer.BaseStream.Length - 8; if (flag) { int num2 = format.BitsPerSample / 8 * format.Channels; writer.BaseStream.Position = 0L; writer.Write(Encoding.UTF8.GetBytes("RF64")); writer.Write(-1); writer.BaseStream.Position += 4L; writer.Write(Encoding.UTF8.GetBytes("ds64")); writer.BaseStream.Position += 4L; writer.Write(num); writer.Write(dataLength); writer.Write(dataLength / num2); } else { writer.BaseStream.Position = 4L; writer.Write((uint)num); writer.BaseStream.Position = dataChunkSizePosition; writer.Write((uint)dataLength); } if (restorePosition) { writer.BaseStream.Position = position; } } public void Dispose() { if (!isDisposed) { FixUpChunkSizes(restorePosition: false); writer.Dispose(); isDisposed = true; } } private static byte[] GetAsBytes(string message, int byteSize) { byte[] array = new byte[byteSize]; byte[] bytes = Encoding.ASCII.GetBytes(message ?? ""); Array.Copy(bytes, array, Math.Min(bytes.Length, byteSize)); return array; } } public class CueWaveFileWriter : WaveFileWriter { private CueList cues = null; public CueWaveFileWriter(string fileName, WaveFormat waveFormat) : base(fileName, waveFormat) { } public void AddCue(int position, string label) { if (cues == null) { cues = new CueList(); } cues.Add(new Cue(position, label)); } private void WriteCues(BinaryWriter w) { if (cues != null) { byte[] riffChunks = cues.GetRiffChunks(); int count = riffChunks.Length; w.Seek(0, SeekOrigin.End); if (w.BaseStream.Length % 2 == 1) { w.Write((byte)0); } w.Write(cues.GetRiffChunks(), 0, count); w.Seek(4, SeekOrigin.Begin); w.Write((int)(w.BaseStream.Length - 8)); } } protected override void UpdateHeader(BinaryWriter writer) { base.UpdateHeader(writer); WriteCues(writer); } } public class DirectSoundOut : IWavePlayer, IDisposable { [StructLayout(LayoutKind.Sequential, Pack = 2)] internal class BufferDescription { public int dwSize; [MarshalAs(UnmanagedType.U4)] public DirectSoundBufferCaps dwFlags; public uint dwBufferBytes; public int dwReserved; public IntPtr lpwfxFormat; public Guid guidAlgo; } [StructLayout(LayoutKind.Sequential, Pack = 2)] internal class BufferCaps { public int dwSize; public int dwFlags; public int dwBufferBytes; public int dwUnlockTransferRate; public int dwPlayCpuOverhead; } internal enum DirectSoundCooperativeLevel : uint { DSSCL_NORMAL = 1u, DSSCL_PRIORITY, DSSCL_EXCLUSIVE, DSSCL_WRITEPRIMARY } [Flags] internal enum DirectSoundPlayFlags : uint { DSBPLAY_LOOPING = 1u, DSBPLAY_LOCHARDWARE = 2u, DSBPLAY_LOCSOFTWARE = 4u, DSBPLAY_TERMINATEBY_TIME = 8u, DSBPLAY_TERMINATEBY_DISTANCE = 0x10u, DSBPLAY_TERMINATEBY_PRIORITY = 0x20u } internal enum DirectSoundBufferLockFlag : uint { None, FromWriteCursor, EntireBuffer } [Flags] internal enum DirectSoundBufferStatus : uint { DSBSTATUS_PLAYING = 1u, DSBSTATUS_BUFFERLOST = 2u, DSBSTATUS_LOOPING = 4u, DSBSTATUS_LOCHARDWARE = 8u, DSBSTATUS_LOCSOFTWARE = 0x10u, DSBSTATUS_TERMINATED = 0x20u } [Flags] internal enum DirectSoundBufferCaps : uint { DSBCAPS_PRIMARYBUFFER = 1u, DSBCAPS_STATIC = 2u, DSBCAPS_LOCHARDWARE = 4u, DSBCAPS_LOCSOFTWARE = 8u, DSBCAPS_CTRL3D = 0x10u, DSBCAPS_CTRLFREQUENCY = 0x20u, DSBCAPS_CTRLPAN = 0x40u, DSBCAPS_CTRLVOLUME = 0x80u, DSBCAPS_CTRLPOSITIONNOTIFY = 0x100u, DSBCAPS_CTRLFX = 0x200u, DSBCAPS_STICKYFOCUS = 0x4000u, DSBCAPS_GLOBALFOCUS = 0x8000u, DSBCAPS_GETCURRENTPOSITION2 = 0x10000u, DSBCAPS_MUTE3DATMAXDISTANCE = 0x20000u, DSBCAPS_LOCDEFER = 0x40000u } internal struct DirectSoundBufferPositionNotify { public uint dwOffset; public IntPtr hEventNotify; } [ComImport] [Guid("279AFA83-4981-11CE-A521-0020AF0BE560")] [SuppressUnmanagedCodeSecurity] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IDirectSound { void CreateSoundBuffer([In] BufferDescription desc, [MarshalAs(UnmanagedType.Interface)] out object dsDSoundBuffer, IntPtr pUnkOuter); void GetCaps(IntPtr caps); void DuplicateSoundBuffer([In][MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer bufferOriginal, [In][MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer bufferDuplicate); void SetCooperativeLevel(IntPtr HWND, [In][MarshalAs(UnmanagedType.U4)] DirectSoundCooperativeLevel dwLevel); void Compact(); void GetSpeakerConfig(IntPtr pdwSpeakerConfig); void SetSpeakerConfig(uint pdwSpeakerConfig); void Initialize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guid); } [ComImport] [Guid("279AFA85-4981-11CE-A521-0020AF0BE560")] [SuppressUnmanagedCodeSecurity] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IDirectSoundBuffer { void GetCaps([MarshalAs(UnmanagedType.LPStruct)] BufferCaps pBufferCaps); void GetCurrentPosition(out uint currentPlayCursor, out uint currentWriteCursor); void GetFormat(); [return: MarshalAs(UnmanagedType.I4)] int GetVolume(); void GetPan(out uint pan); [return: MarshalAs(UnmanagedType.I4)] int GetFrequency(); [return: MarshalAs(UnmanagedType.U4)] DirectSoundBufferStatus GetStatus(); void Initialize([In][MarshalAs(UnmanagedType.Interface)] IDirectSound directSound, [In] BufferDescription desc); void Lock(int dwOffset, uint dwBytes, out IntPtr audioPtr1, out int audioBytes1, out IntPtr audioPtr2, out int audioBytes2, [MarshalAs(UnmanagedType.U4)] DirectSoundBufferLockFlag dwFlags); void Play(uint dwReserved1, uint dwPriority, [In][MarshalAs(UnmanagedType.U4)] DirectSoundPlayFlags dwFlags); void SetCurrentPosition(uint dwNewPosition); void SetFormat([In] WaveFormat pcfxFormat); void SetVolume(int volume); void
NAudio.dll
Decompiled 3 days agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using NAudio.Wave.SampleProviders; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Mark Heath & Contributors")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("© Mark Heath 2023")] [assembly: AssemblyDescription("NAudio, an audio library for .NET")] [assembly: AssemblyFileVersion("2.2.1.0")] [assembly: AssemblyInformationalVersion("2.2.1")] [assembly: AssemblyProduct("NAudio")] [assembly: AssemblyTitle("NAudio")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")] [assembly: TargetPlatform("Windows7.0")] [assembly: SupportedOSPlatform("Windows7.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.2.1.0")] [module: UnverifiableCode] namespace NAudio.Wave; public class AudioFileReader : WaveStream, ISampleProvider { private WaveStream readerStream; private readonly SampleChannel sampleChannel; private readonly int destBytesPerSample; private readonly int sourceBytesPerSample; private readonly long length; private readonly object lockObject; public string FileName { get; } public override WaveFormat WaveFormat => sampleChannel.WaveFormat; public override long Length => length; public override long Position { get { return SourceToDest(((Stream)(object)readerStream).Position); } set { lock (lockObject) { ((Stream)(object)readerStream).Position = DestToSource(value); } } } public float Volume { get { return sampleChannel.Volume; } set { sampleChannel.Volume = value; } } public AudioFileReader(string fileName) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown lockObject = new object(); FileName = fileName; CreateReaderStream(fileName); sourceBytesPerSample = readerStream.WaveFormat.BitsPerSample / 8 * readerStream.WaveFormat.Channels; sampleChannel = new SampleChannel((IWaveProvider)(object)readerStream, false); destBytesPerSample = 4 * sampleChannel.WaveFormat.Channels; length = SourceToDest(((Stream)(object)readerStream).Length); } private void CreateReaderStream(string fileName) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown if (fileName.EndsWith(".wav", StringComparison.OrdinalIgnoreCase)) { readerStream = (WaveStream)new WaveFileReader(fileName); if ((int)readerStream.WaveFormat.Encoding != 1 && (int)readerStream.WaveFormat.Encoding != 3) { readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream); readerStream = (WaveStream)new BlockAlignReductionStream(readerStream); } } else if (fileName.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)) { if (Environment.OSVersion.Version.Major < 6) { readerStream = (WaveStream)(object)new Mp3FileReader(fileName); } else { readerStream = (WaveStream)new MediaFoundationReader(fileName); } } else if (fileName.EndsWith(".aiff", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".aif", StringComparison.OrdinalIgnoreCase)) { readerStream = (WaveStream)new AiffFileReader(fileName); } else { readerStream = (WaveStream)new MediaFoundationReader(fileName); } } public override int Read(byte[] buffer, int offset, int count) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown WaveBuffer val = new WaveBuffer(buffer); int count2 = count / 4; int num = Read(val.FloatBuffer, offset / 4, count2); return num * 4; } public int Read(float[] buffer, int offset, int count) { lock (lockObject) { return sampleChannel.Read(buffer, offset, count); } } private long SourceToDest(long sourceBytes) { return destBytesPerSample * (sourceBytes / sourceBytesPerSample); } private long DestToSource(long destBytes) { return sourceBytesPerSample * (destBytes / destBytesPerSample); } protected override void Dispose(bool disposing) { if (disposing && readerStream != null) { ((Stream)(object)readerStream).Dispose(); readerStream = null; } ((Stream)this).Dispose(disposing); } } public class Mp3FileReader : Mp3FileReaderBase { public Mp3FileReader(string mp3FileName) : base((Stream)File.OpenRead(mp3FileName), new FrameDecompressorBuilder(CreateAcmFrameDecompressor), true) { }//IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown public Mp3FileReader(Stream inputStream) : base(inputStream, new FrameDecompressorBuilder(CreateAcmFrameDecompressor), false) { }//IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown public static IMp3FrameDecompressor CreateAcmFrameDecompressor(WaveFormat mp3Format) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown return (IMp3FrameDecompressor)new AcmMp3FrameDecompressor(mp3Format); } }
NAudio.Wasapi.dll
Decompiled 3 days 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.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using NAudio.CoreAudioApi; using NAudio.CoreAudioApi.Interfaces; using NAudio.Dmo; using NAudio.Dmo.Effect; using NAudio.MediaFoundation; using NAudio.Utils; using NAudio.Wasapi.CoreAudioApi; using NAudio.Wasapi.CoreAudioApi.Interfaces; using NAudio.Wave; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETCore,Version=v5.0", FrameworkDisplayName = ".NET for Windows Universal")] [assembly: AssemblyCompany("Mark Heath")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("© Mark Heath 2023")] [assembly: AssemblyFileVersion("2.2.1.0")] [assembly: AssemblyInformationalVersion("2.2.1")] [assembly: AssemblyProduct("NAudio.Wasapi")] [assembly: AssemblyTitle("NAudio.Wasapi")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")] [assembly: SecurityPermission(8, SkipVerification = true)] [assembly: AssemblyVersion("2.2.1.0")] [module: UnverifiableCode] namespace NAudio.MediaFoundation { public static class AudioSubtypes { [FieldDescription("AAC")] public static readonly Guid MFAudioFormat_AAC = new Guid("00001610-0000-0010-8000-00aa00389b71"); [FieldDescription("ADTS")] public static readonly Guid MFAudioFormat_ADTS = new Guid("00001600-0000-0010-8000-00aa00389b71"); [FieldDescription("Dolby AC3 SPDIF")] public static readonly Guid MFAudioFormat_Dolby_AC3_SPDIF = new Guid("00000092-0000-0010-8000-00aa00389b71"); [FieldDescription("DRM")] public static readonly Guid MFAudioFormat_DRM = new Guid("00000009-0000-0010-8000-00aa00389b71"); [FieldDescription("DTS")] public static readonly Guid MFAudioFormat_DTS = new Guid("00000008-0000-0010-8000-00aa00389b71"); [FieldDescription("IEEE floating-point")] public static readonly Guid MFAudioFormat_Float = new Guid("00000003-0000-0010-8000-00aa00389b71"); [FieldDescription("MP3")] public static readonly Guid MFAudioFormat_MP3 = new Guid("00000055-0000-0010-8000-00aa00389b71"); [FieldDescription("MPEG")] public static readonly Guid MFAudioFormat_MPEG = new Guid("00000050-0000-0010-8000-00aa00389b71"); [FieldDescription("WMA 9 Voice codec")] public static readonly Guid MFAudioFormat_MSP1 = new Guid("0000000a-0000-0010-8000-00aa00389b71"); [FieldDescription("PCM")] public static readonly Guid MFAudioFormat_PCM = new Guid("00000001-0000-0010-8000-00aa00389b71"); [FieldDescription("WMA SPDIF")] public static readonly Guid MFAudioFormat_WMASPDIF = new Guid("00000164-0000-0010-8000-00aa00389b71"); [FieldDescription("WMAudio Lossless")] public static readonly Guid MFAudioFormat_WMAudio_Lossless = new Guid("00000163-0000-0010-8000-00aa00389b71"); [FieldDescription("Windows Media Audio")] public static readonly Guid MFAudioFormat_WMAudioV8 = new Guid("00000161-0000-0010-8000-00aa00389b71"); [FieldDescription("Windows Media Audio Professional")] public static readonly Guid MFAudioFormat_WMAudioV9 = new Guid("00000162-0000-0010-8000-00aa00389b71"); [FieldDescription("Dolby AC3")] public static readonly Guid MFAudioFormat_Dolby_AC3 = new Guid("e06d802c-db46-11cf-b4d1-00805f6cbbea"); public static readonly Guid MFAudioFormat_FLAC = new Guid("0000f1ac-0000-0010-8000-00aa00389b71"); public static readonly Guid MFAudioFormat_ALAC = new Guid("63616c61-0000-0010-8000-00aa00389b71"); [FieldDescription("MPEG-4 and AAC Audio Types")] public static readonly Guid MEDIASUBTYPE_RAW_AAC1 = new Guid("000000ff-0000-0010-8000-00aa00389b71"); [FieldDescription("Dolby Audio Types")] public static readonly Guid MEDIASUBTYPE_DVM = new Guid("00002000-0000-0010-8000-00aa00389b71"); [FieldDescription("Dolby Audio Types")] public static readonly Guid MEDIASUBTYPE_DOLBY_DDPLUS = new Guid("a7fb87af-2d02-42fb-a4d4-05cd93843bdd"); [FieldDescription("μ-law")] public static readonly Guid KSDATAFORMAT_SUBTYPE_MULAW = new Guid("00000007-0000-0010-8000-00aa00389b71"); [FieldDescription("ADPCM")] public static readonly Guid KSDATAFORMAT_SUBTYPE_ADPCM = new Guid("00000002-0000-0010-8000-00aa00389b71"); [FieldDescription("Dolby Digital Plus for HDMI")] public static readonly Guid KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS = new Guid("0000000a-0cea-0010-8000-00aa00389b71"); [FieldDescription("MSAudio1")] public static readonly Guid MEDIASUBTYPE_MSAUDIO1 = new Guid("00000160-0000-0010-8000-00aa00389b71"); [FieldDescription("IMA ADPCM")] public static readonly Guid ImaAdpcm = new Guid("00000011-0000-0010-8000-00aa00389b71"); [FieldDescription("WMSP2")] public static readonly Guid WMMEDIASUBTYPE_WMSP2 = new Guid("0000000b-0000-0010-8000-00aa00389b71"); } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("7FEE9E9A-4A89-47a6-899C-B6A53A70FB67")] public interface IMFActivate : IMFAttributes { new void GetItem([In][MarshalAs(43)] Guid guidKey, [In][Out] global::System.IntPtr pValue); new void GetItemType([In][MarshalAs(43)] Guid guidKey, out int pType); new void CompareItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr value, [MarshalAs(2)] out bool pbResult); new void Compare([MarshalAs(28)] IMFAttributes pTheirs, int matchType, [MarshalAs(2)] out bool pbResult); new void GetUINT32([In][MarshalAs(43)] Guid guidKey, out int punValue); new void GetUINT64([In][MarshalAs(43)] Guid guidKey, out long punValue); new void GetDouble([In][MarshalAs(43)] Guid guidKey, out double pfValue); new void GetGUID([In][MarshalAs(43)] Guid guidKey, out Guid pguidValue); new void GetStringLength([In][MarshalAs(43)] Guid guidKey, out int pcchLength); new void GetString([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(21)] StringBuilder pwszValue, int cchBufSize, out int pcchLength); new void GetAllocatedString([In][MarshalAs(43)] Guid guidKey, [MarshalAs(21)] out string ppwszValue, out int pcchLength); new void GetBlobSize([In][MarshalAs(43)] Guid guidKey, out int pcbBlobSize); new void GetBlob([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(42)] byte[] pBuf, int cbBufSize, out int pcbBlobSize); new void GetAllocatedBlob([In][MarshalAs(43)] Guid guidKey, out global::System.IntPtr ip, out int pcbSize); new void GetUnknown([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid riid, [MarshalAs(25)] out object ppv); new void SetItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr value); new void DeleteItem([In][MarshalAs(43)] Guid guidKey); new void DeleteAllItems(); new void SetUINT32([In][MarshalAs(43)] Guid guidKey, int unValue); new void SetUINT64([In][MarshalAs(43)] Guid guidKey, long unValue); new void SetDouble([In][MarshalAs(43)] Guid guidKey, double fValue); new void SetGUID([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid guidValue); new void SetString([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(21)] string wszValue); new void SetBlob([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(42, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize); new void SetUnknown([MarshalAs(43)] Guid guidKey, [In][MarshalAs(25)] object pUnknown); new void LockStore(); new void UnlockStore(); new void GetCount(out int pcItems); new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] global::System.IntPtr pValue); new void CopyAllItems([In][MarshalAs(28)] IMFAttributes pDest); void ActivateObject([In][MarshalAs(43)] Guid riid, [MarshalAs(28)] out object ppv); void ShutdownObject(); void DetachObject(); } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("2CD2D921-C447-44A7-A13C-4ADABFC247E3")] public interface IMFAttributes { void GetItem([In][MarshalAs(43)] Guid guidKey, [In][Out] global::System.IntPtr pValue); void GetItemType([In][MarshalAs(43)] Guid guidKey, out int pType); void CompareItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr value, [MarshalAs(2)] out bool pbResult); void Compare([MarshalAs(28)] IMFAttributes pTheirs, int matchType, [MarshalAs(2)] out bool pbResult); void GetUINT32([In][MarshalAs(43)] Guid guidKey, out int punValue); void GetUINT64([In][MarshalAs(43)] Guid guidKey, out long punValue); void GetDouble([In][MarshalAs(43)] Guid guidKey, out double pfValue); void GetGUID([In][MarshalAs(43)] Guid guidKey, out Guid pguidValue); void GetStringLength([In][MarshalAs(43)] Guid guidKey, out int pcchLength); void GetString([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(21)] StringBuilder pwszValue, int cchBufSize, out int pcchLength); void GetAllocatedString([In][MarshalAs(43)] Guid guidKey, [MarshalAs(21)] out string ppwszValue, out int pcchLength); void GetBlobSize([In][MarshalAs(43)] Guid guidKey, out int pcbBlobSize); void GetBlob([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(42)] byte[] pBuf, int cbBufSize, out int pcbBlobSize); void GetAllocatedBlob([In][MarshalAs(43)] Guid guidKey, out global::System.IntPtr ip, out int pcbSize); void GetUnknown([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid riid, [MarshalAs(25)] out object ppv); void SetItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr Value); void DeleteItem([In][MarshalAs(43)] Guid guidKey); void DeleteAllItems(); void SetUINT32([In][MarshalAs(43)] Guid guidKey, int unValue); void SetUINT64([In][MarshalAs(43)] Guid guidKey, long unValue); void SetDouble([In][MarshalAs(43)] Guid guidKey, double fValue); void SetGUID([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid guidValue); void SetString([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(21)] string wszValue); void SetBlob([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(42, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize); void SetUnknown([MarshalAs(43)] Guid guidKey, [In][MarshalAs(25)] object pUnknown); void LockStore(); void UnlockStore(); void GetCount(out int pcItems); void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] global::System.IntPtr pValue); void CopyAllItems([In][MarshalAs(28)] IMFAttributes pDest); } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("ad4c1b00-4bf7-422f-9175-756693d9130d")] public interface IMFByteStream { void GetCapabilities(ref int pdwCapabiities); void GetLength(ref long pqwLength); void SetLength(long qwLength); void GetCurrentPosition(ref long pqwPosition); void SetCurrentPosition(long qwPosition); void IsEndOfStream([MarshalAs(2)] ref bool pfEndOfStream); void Read(global::System.IntPtr pb, int cb, ref int pcbRead); void BeginRead(global::System.IntPtr pb, int cb, global::System.IntPtr pCallback, global::System.IntPtr punkState); void EndRead(global::System.IntPtr pResult, ref int pcbRead); void Write(global::System.IntPtr pb, int cb, ref int pcbWritten); void BeginWrite(global::System.IntPtr pb, int cb, global::System.IntPtr pCallback, global::System.IntPtr punkState); void EndWrite(global::System.IntPtr pResult, ref int pcbWritten); void Seek(int SeekOrigin, long llSeekOffset, int dwSeekFlags, ref long pqwCurrentPosition); void Flush(); void Close(); } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("5BC8A76B-869A-46A3-9B03-FA218A66AEBE")] public interface IMFCollection { void GetElementCount(out int pcElements); void GetElement([In] int dwElementIndex, [MarshalAs(25)] out object ppUnkElement); void AddElement([In][MarshalAs(25)] object pUnkElement); void RemoveElement([In] int dwElementIndex, [MarshalAs(25)] out object ppUnkElement); void InsertElementAt([In] int dwIndex, [In][MarshalAs(25)] object pUnknown); void RemoveAllElements(); } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("045FA593-8799-42b8-BC8D-8968C6453507")] public interface IMFMediaBuffer { void Lock(out global::System.IntPtr ppbBuffer, out int pcbMaxLength, out int pcbCurrentLength); void Unlock(); void GetCurrentLength(out int pcbCurrentLength); void SetCurrentLength(int cbCurrentLength); void GetMaxLength(out int pcbMaxLength); } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("DF598932-F10C-4E39-BBA2-C308F101DAA3")] public interface IMFMediaEvent : IMFAttributes { new void GetItem([In][MarshalAs(43)] Guid guidKey, [In][Out] global::System.IntPtr pValue); new void GetItemType([In][MarshalAs(43)] Guid guidKey, out int pType); new void CompareItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr value, [MarshalAs(2)] out bool pbResult); new void Compare([MarshalAs(28)] IMFAttributes pTheirs, int matchType, [MarshalAs(2)] out bool pbResult); new void GetUINT32([In][MarshalAs(43)] Guid guidKey, out int punValue); new void GetUINT64([In][MarshalAs(43)] Guid guidKey, out long punValue); new void GetDouble([In][MarshalAs(43)] Guid guidKey, out double pfValue); new void GetGUID([In][MarshalAs(43)] Guid guidKey, out Guid pguidValue); new void GetStringLength([In][MarshalAs(43)] Guid guidKey, out int pcchLength); new void GetString([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(21)] StringBuilder pwszValue, int cchBufSize, out int pcchLength); new void GetAllocatedString([In][MarshalAs(43)] Guid guidKey, [MarshalAs(21)] out string ppwszValue, out int pcchLength); new void GetBlobSize([In][MarshalAs(43)] Guid guidKey, out int pcbBlobSize); new void GetBlob([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(42)] byte[] pBuf, int cbBufSize, out int pcbBlobSize); new void GetAllocatedBlob([In][MarshalAs(43)] Guid guidKey, out global::System.IntPtr ip, out int pcbSize); new void GetUnknown([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid riid, [MarshalAs(25)] out object ppv); new void SetItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr value); new void DeleteItem([In][MarshalAs(43)] Guid guidKey); new void DeleteAllItems(); new void SetUINT32([In][MarshalAs(43)] Guid guidKey, int unValue); new void SetUINT64([In][MarshalAs(43)] Guid guidKey, long unValue); new void SetDouble([In][MarshalAs(43)] Guid guidKey, double fValue); new void SetGUID([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid guidValue); new void SetString([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(21)] string wszValue); new void SetBlob([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(42, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize); new void SetUnknown([MarshalAs(43)] Guid guidKey, [In][MarshalAs(25)] object pUnknown); new void LockStore(); new void UnlockStore(); new void GetCount(out int pcItems); new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] global::System.IntPtr pValue); new void CopyAllItems([In][MarshalAs(28)] IMFAttributes pDest); void GetType(out MediaEventType pmet); void GetExtendedType(out Guid pguidExtendedType); void GetStatus([MarshalAs(45)] out int phrStatus); void GetValue([Out] global::System.IntPtr pvValue); } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("44AE0FA8-EA31-4109-8D2E-4CAE4997C555")] public interface IMFMediaType : IMFAttributes { new void GetItem([In][MarshalAs(43)] Guid guidKey, [In][Out] global::System.IntPtr pValue); new void GetItemType([In][MarshalAs(43)] Guid guidKey, out int pType); new void CompareItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr value, [MarshalAs(2)] out bool pbResult); new void Compare([MarshalAs(28)] IMFAttributes pTheirs, int matchType, [MarshalAs(2)] out bool pbResult); new void GetUINT32([In][MarshalAs(43)] Guid guidKey, out int punValue); new void GetUINT64([In][MarshalAs(43)] Guid guidKey, out long punValue); new void GetDouble([In][MarshalAs(43)] Guid guidKey, out double pfValue); new void GetGUID([In][MarshalAs(43)] Guid guidKey, out Guid pguidValue); new void GetStringLength([In][MarshalAs(43)] Guid guidKey, out int pcchLength); new void GetString([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(21)] StringBuilder pwszValue, int cchBufSize, out int pcchLength); new void GetAllocatedString([In][MarshalAs(43)] Guid guidKey, [MarshalAs(21)] out string ppwszValue, out int pcchLength); new void GetBlobSize([In][MarshalAs(43)] Guid guidKey, out int pcbBlobSize); new void GetBlob([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(42)] byte[] pBuf, int cbBufSize, out int pcbBlobSize); new void GetAllocatedBlob([In][MarshalAs(43)] Guid guidKey, out global::System.IntPtr ip, out int pcbSize); new void GetUnknown([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid riid, [MarshalAs(25)] out object ppv); new void SetItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr value); new void DeleteItem([In][MarshalAs(43)] Guid guidKey); new void DeleteAllItems(); new void SetUINT32([In][MarshalAs(43)] Guid guidKey, int unValue); new void SetUINT64([In][MarshalAs(43)] Guid guidKey, long unValue); new void SetDouble([In][MarshalAs(43)] Guid guidKey, double fValue); new void SetGUID([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid guidValue); new void SetString([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(21)] string wszValue); new void SetBlob([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(42, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize); new void SetUnknown([MarshalAs(43)] Guid guidKey, [In][MarshalAs(25)] object pUnknown); new void LockStore(); new void UnlockStore(); new void GetCount(out int pcItems); new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] global::System.IntPtr pValue); new void CopyAllItems([In][MarshalAs(28)] IMFAttributes pDest); void GetMajorType(out Guid pguidMajorType); void IsCompressedFormat([MarshalAs(2)] out bool pfCompressed); [PreserveSig] int IsEqual([In][MarshalAs(28)] IMFMediaType pIMediaType, ref int pdwFlags); void GetRepresentation([In] Guid guidRepresentation, ref global::System.IntPtr ppvRepresentation); void FreeRepresentation([In] Guid guidRepresentation, [In] global::System.IntPtr pvRepresentation); } [ComImport] [Guid("E7FE2E12-661C-40DA-92F9-4F002AB67627")] [InterfaceType(/*Could not decode attribute arguments.*/)] public interface IMFReadWriteClassFactory { void CreateInstanceFromURL([In][MarshalAs(43)] Guid clsid, [In][MarshalAs(21)] string pwszURL, [In][MarshalAs(28)] IMFAttributes pAttributes, [In][MarshalAs(43)] Guid riid, [MarshalAs(28)] out object ppvObject); void CreateInstanceFromObject([In][MarshalAs(43)] Guid clsid, [In][MarshalAs(25)] object punkObject, [In][MarshalAs(28)] IMFAttributes pAttributes, [In][MarshalAs(43)] Guid riid, [MarshalAs(28)] out object ppvObject); } [ComImport] [Guid("48e2ed0f-98c2-4a37-bed5-166312ddd83f")] public class MFReadWriteClassFactory { } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("c40a00f2-b93a-4d80-ae8c-5a1c634f58e4")] public interface IMFSample : IMFAttributes { new void GetItem([In][MarshalAs(43)] Guid guidKey, [In][Out] global::System.IntPtr pValue); new void GetItemType([In][MarshalAs(43)] Guid guidKey, out int pType); new void CompareItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr value, [MarshalAs(2)] out bool pbResult); new void Compare([MarshalAs(28)] IMFAttributes pTheirs, int matchType, [MarshalAs(2)] out bool pbResult); new void GetUINT32([In][MarshalAs(43)] Guid guidKey, out int punValue); new void GetUINT64([In][MarshalAs(43)] Guid guidKey, out long punValue); new void GetDouble([In][MarshalAs(43)] Guid guidKey, out double pfValue); new void GetGUID([In][MarshalAs(43)] Guid guidKey, out Guid pguidValue); new void GetStringLength([In][MarshalAs(43)] Guid guidKey, out int pcchLength); new void GetString([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(21)] StringBuilder pwszValue, int cchBufSize, out int pcchLength); new void GetAllocatedString([In][MarshalAs(43)] Guid guidKey, [MarshalAs(21)] out string ppwszValue, out int pcchLength); new void GetBlobSize([In][MarshalAs(43)] Guid guidKey, out int pcbBlobSize); new void GetBlob([In][MarshalAs(43)] Guid guidKey, [Out][MarshalAs(42)] byte[] pBuf, int cbBufSize, out int pcbBlobSize); new void GetAllocatedBlob([In][MarshalAs(43)] Guid guidKey, out global::System.IntPtr ip, out int pcbSize); new void GetUnknown([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid riid, [MarshalAs(25)] out object ppv); new void SetItem([In][MarshalAs(43)] Guid guidKey, global::System.IntPtr value); new void DeleteItem([In][MarshalAs(43)] Guid guidKey); new void DeleteAllItems(); new void SetUINT32([In][MarshalAs(43)] Guid guidKey, int unValue); new void SetUINT64([In][MarshalAs(43)] Guid guidKey, long unValue); new void SetDouble([In][MarshalAs(43)] Guid guidKey, double fValue); new void SetGUID([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(43)] Guid guidValue); new void SetString([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(21)] string wszValue); new void SetBlob([In][MarshalAs(43)] Guid guidKey, [In][MarshalAs(42, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize); new void SetUnknown([MarshalAs(43)] Guid guidKey, [In][MarshalAs(25)] object pUnknown); new void LockStore(); new void UnlockStore(); new void GetCount(out int pcItems); new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] global::System.IntPtr pValue); new void CopyAllItems([In][MarshalAs(28)] IMFAttributes pDest); void GetSampleFlags(out int pdwSampleFlags); void SetSampleFlags(int dwSampleFlags); void GetSampleTime(out long phnsSampletime); void SetSampleTime(long hnsSampleTime); void GetSampleDuration(out long phnsSampleDuration); void SetSampleDuration(long hnsSampleDuration); void GetBufferCount(out int pdwBufferCount); void GetBufferByIndex(int dwIndex, out IMFMediaBuffer ppBuffer); void ConvertToContiguousBuffer(out IMFMediaBuffer ppBuffer); void AddBuffer(IMFMediaBuffer pBuffer); void RemoveBufferByIndex(int dwIndex); void RemoveAllBuffers(); void GetTotalLength(out int pcbTotalLength); void CopyToBuffer(IMFMediaBuffer pBuffer); } [ComImport] [Guid("3137f1cd-fe5e-4805-a5d8-fb477448cb3d")] [InterfaceType(/*Could not decode attribute arguments.*/)] public interface IMFSinkWriter { void AddStream([In][MarshalAs(28)] IMFMediaType pTargetMediaType, out int pdwStreamIndex); void SetInputMediaType([In] int dwStreamIndex, [In][MarshalAs(28)] IMFMediaType pInputMediaType, [In][MarshalAs(28)] IMFAttributes pEncodingParameters); void BeginWriting(); void WriteSample([In] int dwStreamIndex, [In][MarshalAs(28)] IMFSample pSample); void SendStreamTick([In] int dwStreamIndex, [In] long llTimestamp); void PlaceMarker([In] int dwStreamIndex, [In] global::System.IntPtr pvContext); void NotifyEndOfSegment([In] int dwStreamIndex); void Flush([In] int dwStreamIndex); void DoFinalize(); void GetServiceForStream([In] int dwStreamIndex, [In] ref Guid guidService, [In] ref Guid riid, out global::System.IntPtr ppvObject); void GetStatistics([In] int dwStreamIndex, [In][Out] MF_SINK_WRITER_STATISTICS pStats); } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("70ae66f2-c809-4e4f-8915-bdcb406b7993")] public interface IMFSourceReader { void GetStreamSelection([In] int dwStreamIndex, [MarshalAs(2)] out bool pSelected); void SetStreamSelection([In] int dwStreamIndex, [In][MarshalAs(2)] bool pSelected); void GetNativeMediaType([In] int dwStreamIndex, [In] int dwMediaTypeIndex, out IMFMediaType ppMediaType); void GetCurrentMediaType([In] int dwStreamIndex, out IMFMediaType ppMediaType); void SetCurrentMediaType([In] int dwStreamIndex, global::System.IntPtr pdwReserved, [In] IMFMediaType pMediaType); void SetCurrentPosition([In][MarshalAs(43)] Guid guidTimeFormat, [In] global::System.IntPtr varPosition); void ReadSample([In] int dwStreamIndex, [In] int dwControlFlags, out int pdwActualStreamIndex, out MF_SOURCE_READER_FLAG pdwStreamFlags, out ulong pllTimestamp, out IMFSample ppSample); void Flush([In] int dwStreamIndex); void GetServiceForStream([In] int dwStreamIndex, [In][MarshalAs(43)] Guid guidService, [In][MarshalAs(43)] Guid riid, out global::System.IntPtr ppvObject); [PreserveSig] int GetPresentationAttribute([In] int dwStreamIndex, [In][MarshalAs(43)] Guid guidAttribute, [Out] global::System.IntPtr pvarAttribute); } [Flags] public enum MF_SOURCE_READER_FLAG { None = 0, MF_SOURCE_READERF_ERROR = 1, MF_SOURCE_READERF_ENDOFSTREAM = 2, MF_SOURCE_READERF_NEWSTREAM = 4, MF_SOURCE_READERF_NATIVEMEDIATYPECHANGED = 0x10, MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED = 0x20, MF_SOURCE_READERF_STREAMTICK = 0x100, MF_SOURCE_READERF_ALLEFFECTSREMOVED = 0x200 } [ComImport] [InterfaceType(/*Could not decode attribute arguments.*/)] [Guid("bf94c121-5b05-4e6f-8000-ba598961414d")] public interface IMFTransform { void GetStreamLimits(out int pdwInputMinimum, out int pdwInputMaximum, out int pdwOutputMinimum, out int pdwOutputMaximum); void GetStreamCount(out int pcInputStreams, out int pcOutputStreams); void GetStreamIds([In] int dwInputIdArraySize, [In][Out] global::System.IntPtr pdwInputIDs, [In] int dwOutputIdArraySize, [In][Out] global::System.IntPtr pdwOutputIDs); void GetInputStreamInfo([In] int dwInputStreamId, out MFT_INPUT_STREAM_INFO pStreamInfo); void GetOutputStreamInfo([In] int dwOutputStreamId, out MFT_OUTPUT_STREAM_INFO pStreamInfo); void GetAttributes(out IMFAttributes pAttributes); void GetInputStreamAttributes([In] int dwInputStreamId, out IMFAttributes pAttributes); void GetOutputStreamAttributes([In] int dwOutputStreamId, out IMFAttributes pAttributes); void DeleteInputStream([In] int dwOutputStreamId); void AddInputStreams([In] int cStreams, [In] global::System.IntPtr adwStreamIDs); void GetInputAvailableType([In] int dwInputStreamId, [In] int dwTypeIndex, out IMFMediaType ppType); void GetOutputAvailableType([In] int dwOutputStreamId, [In] int dwTypeIndex, out IMFMediaType ppType); void SetInputType([In] int dwInputStreamId, [In] IMFMediaType pType, [In] _MFT_SET_TYPE_FLAGS dwFlags); void SetOutputType([In] int dwOutputStreamId, [In] IMFMediaType pType, [In] _MFT_SET_TYPE_FLAGS dwFlags); void GetInputCurrentType([In] int dwInputStreamId, out IMFMediaType ppType); void GetOutputCurrentType([In] int dwOutputStreamId, out IMFMediaType ppType); void GetInputStatus([In] int dwInputStreamId, out _MFT_INPUT_STATUS_FLAGS pdwFlags); void GetOutputStatus([In] int dwInputStreamId, out _MFT_OUTPUT_STATUS_FLAGS pdwFlags); void SetOutputBounds([In] long hnsLowerBound, [In] long hnsUpperBound); void ProcessEvent([In] int dwInputStreamId, [In] IMFMediaEvent pEvent); void ProcessMessage([In] MFT_MESSAGE_TYPE eMessage, [In] global::System.IntPtr ulParam); void ProcessInput([In] int dwInputStreamId, [In] IMFSample pSample, int dwFlags); [PreserveSig] int ProcessOutput([In] _MFT_PROCESS_OUTPUT_FLAGS dwFlags, [In] int cOutputBufferCount, [In][Out][MarshalAs(42, SizeParamIndex = 1)] MFT_OUTPUT_DATA_BUFFER[] pOutputSamples, out _MFT_PROCESS_OUTPUT_STATUS pdwStatus); } public enum MediaEventType { MEUnknown = 0, MEError = 1, MEExtendedType = 2, MENonFatalError = 3, MESessionUnknown = 100, MESessionTopologySet = 101, MESessionTopologiesCleared = 102, MESessionStarted = 103, MESessionPaused = 104, MESessionStopped = 105, MESessionClosed = 106, MESessionEnded = 107, MESessionRateChanged = 108, MESessionScrubSampleComplete = 109, MESessionCapabilitiesChanged = 110, MESessionTopologyStatus = 111, MESessionNotifyPresentationTime = 112, MENewPresentation = 113, MELicenseAcquisitionStart = 114, MELicenseAcquisitionCompleted = 115, MEIndividualizationStart = 116, MEIndividualizationCompleted = 117, MEEnablerProgress = 118, MEEnablerCompleted = 119, MEPolicyError = 120, MEPolicyReport = 121, MEBufferingStarted = 122, MEBufferingStopped = 123, MEConnectStart = 124, MEConnectEnd = 125, MEReconnectStart = 126, MEReconnectEnd = 127, MERendererEvent = 128, MESessionStreamSinkFormatChanged = 129, MESourceUnknown = 200, MESourceStarted = 201, MEStreamStarted = 202, MESourceSeeked = 203, MEStreamSeeked = 204, MENewStream = 205, MEUpdatedStream = 206, MESourceStopped = 207, MEStreamStopped = 208, MESourcePaused = 209, MEStreamPaused = 210, MEEndOfPresentation = 211, MEEndOfStream = 212, MEMediaSample = 213, MEStreamTick = 214, MEStreamThinMode = 215, MEStreamFormatChanged = 216, MESourceRateChanged = 217, MEEndOfPresentationSegment = 218, MESourceCharacteristicsChanged = 219, MESourceRateChangeRequested = 220, MESourceMetadataChanged = 221, MESequencerSourceTopologyUpdated = 222, MESinkUnknown = 300, MEStreamSinkStarted = 301, MEStreamSinkStopped = 302, MEStreamSinkPaused = 303, MEStreamSinkRateChanged = 304, MEStreamSinkRequestSample = 305, MEStreamSinkMarker = 306, MEStreamSinkPrerolled = 307, MEStreamSinkScrubSampleComplete = 308, MEStreamSinkFormatChanged = 309, MEStreamSinkDeviceChanged = 310, MEQualityNotify = 311, MESinkInvalidated = 312, MEAudioSessionNameChanged = 313, MEAudioSessionVolumeChanged = 314, MEAudioSessionDeviceRemoved = 315, MEAudioSessionServerShutdown = 316, MEAudioSessionGroupingParamChanged = 317, MEAudioSessionIconChanged = 318, MEAudioSessionFormatChanged = 319, MEAudioSessionDisconnected = 320, MEAudioSessionExclusiveModeOverride = 321, METrustUnknown = 400, MEPolicyChanged = 401, MEContentProtectionMessage = 402, MEPolicySet = 403, MEWMDRMLicenseBackupCompleted = 500, MEWMDRMLicenseBackupProgress = 501, MEWMDRMLicenseRestoreCompleted = 502, MEWMDRMLicenseRestoreProgress = 503, MEWMDRMLicenseAcquisitionCompleted = 506, MEWMDRMIndividualizationCompleted = 508, MEWMDRMIndividualizationProgress = 513, MEWMDRMProximityCompleted = 514, MEWMDRMLicenseStoreCleaned = 515, MEWMDRMRevocationDownloadCompleted = 516, METransformUnknown = 600, METransformNeedInput = 601, METransformHaveOutput = 602, METransformDrainComplete = 603, METransformMarker = 604 } public static class MediaFoundationAttributes { public static readonly Guid MF_TRANSFORM_ASYNC = new Guid("f81a699a-649a-497d-8c73-29f8fed6ad7a"); public static readonly Guid MF_TRANSFORM_ASYNC_UNLOCK = new Guid("e5666d6b-3422-4eb6-a421-da7db1f8e207"); [FieldDescription("Transform Flags")] public static readonly Guid MF_TRANSFORM_FLAGS_Attribute = new Guid("9359bb7e-6275-46c4-a025-1c01e45f1a86"); [FieldDescription("Transform Category")] public static readonly Guid MF_TRANSFORM_CATEGORY_Attribute = new Guid("ceabba49-506d-4757-a6ff-66c184987e4e"); [FieldDescription("Class identifier")] public static readonly Guid MFT_TRANSFORM_CLSID_Attribute = new Guid("6821c42b-65a4-4e82-99bc-9a88205ecd0c"); [FieldDescription("Container type")] public static readonly Guid MF_TRANSCODE_CONTAINERTYPE = new Guid(353366591, (short)19132, (short)18315, (byte)172, (byte)79, (byte)225, (byte)145, (byte)111, (byte)186, (byte)28, (byte)202); [FieldDescription("Input Types")] public static readonly Guid MFT_INPUT_TYPES_Attributes = new Guid("4276c9b1-759d-4bf3-9cd0-0d723d138f96"); [FieldDescription("Output Types")] public static readonly Guid MFT_OUTPUT_TYPES_Attributes = new Guid("8eae8cf3-a44f-4306-ba5c-bf5dda242818"); public static readonly Guid MFT_ENUM_HARDWARE_URL_Attribute = new Guid("2fb866ac-b078-4942-ab6c-003d05cda674"); [FieldDescription("Name")] public static readonly Guid MFT_FRIENDLY_NAME_Attribute = new Guid("314ffbae-5b41-4c95-9c19-4e7d586face3"); public static readonly Guid MFT_CONNECTED_STREAM_ATTRIBUTE = new Guid("71eeb820-a59f-4de2-bcec-38db1dd611a4"); public static readonly Guid MFT_CONNECTED_TO_HW_STREAM = new Guid("34e6e728-06d6-4491-a553-4795650db912"); [FieldDescription("Preferred Output Format")] public static readonly Guid MFT_PREFERRED_OUTPUTTYPE_Attribute = new Guid("7e700499-396a-49ee-b1b4-f628021e8c9d"); public static readonly Guid MFT_PROCESS_LOCAL_Attribute = new Guid("543186e4-4649-4e65-b588-4aa352aff379"); public static readonly Guid MFT_PREFERRED_ENCODER_PROFILE = new Guid("53004909-1ef5-46d7-a18e-5a75f8b5905f"); public static readonly Guid MFT_HW_TIMESTAMP_WITH_QPC_Attribute = new Guid("8d030fb8-cc43-4258-a22e-9210bef89be4"); public static readonly Guid MFT_FIELDOFUSE_UNLOCK_Attribute = new Guid("8ec2e9fd-9148-410d-831e-702439461a8e"); public static readonly Guid MFT_CODEC_MERIT_Attribute = new Guid("88a7cb15-7b07-4a34-9128-e64c6703c4d3"); public static readonly Guid MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE = new Guid("111ea8cd-b62a-4bdb-89f6-67ffcdc2458b"); [FieldDescription("PMP Host Context")] public static readonly Guid MF_PD_PMPHOST_CONTEXT = new Guid("6c990d31-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("App Context")] public static readonly Guid MF_PD_APP_CONTEXT = new Guid("6c990d32-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("Duration")] public static readonly Guid MF_PD_DURATION = new Guid("6c990d33-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("Total File Size")] public static readonly Guid MF_PD_TOTAL_FILE_SIZE = new Guid("6c990d34-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("Audio encoding bitrate")] public static readonly Guid MF_PD_AUDIO_ENCODING_BITRATE = new Guid("6c990d35-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("Video Encoding Bitrate")] public static readonly Guid MF_PD_VIDEO_ENCODING_BITRATE = new Guid("6c990d36-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("MIME Type")] public static readonly Guid MF_PD_MIME_TYPE = new Guid("6c990d37-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("Last Modified Time")] public static readonly Guid MF_PD_LAST_MODIFIED_TIME = new Guid("6c990d38-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("Element ID")] public static readonly Guid MF_PD_PLAYBACK_ELEMENT_ID = new Guid("6c990d39-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("Preferred Language")] public static readonly Guid MF_PD_PREFERRED_LANGUAGE = new Guid("6c990d3a-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("Playback boundary time")] public static readonly Guid MF_PD_PLAYBACK_BOUNDARY_TIME = new Guid("6c990d3b-bb8e-477a-8598-0d5d96fcd88a"); [FieldDescription("Audio is variable bitrate")] public static readonly Guid MF_PD_AUDIO_ISVARIABLEBITRATE = new Guid("33026ee0-e387-4582-ae0a-34a2ad3baa18"); [FieldDescription("Major Media Type")] public static readonly Guid MF_MT_MAJOR_TYPE = new Guid("48eba18e-f8c9-4687-bf11-0a74c9f96a8f"); [FieldDescription("Media Subtype")] public static readonly Guid MF_MT_SUBTYPE = new Guid("f7e34c9a-42e8-4714-b74b-cb29d72c35e5"); [FieldDescription("Audio block alignment")] public static readonly Guid MF_MT_AUDIO_BLOCK_ALIGNMENT = new Guid("322de230-9eeb-43bd-ab7a-ff412251541d"); [FieldDescription("Audio average bytes per second")] public static readonly Guid MF_MT_AUDIO_AVG_BYTES_PER_SECOND = new Guid("1aab75c8-cfef-451c-ab95-ac034b8e1731"); [FieldDescription("Audio number of channels")] public static readonly Guid MF_MT_AUDIO_NUM_CHANNELS = new Guid("37e48bf5-645e-4c5b-89de-ada9e29b696a"); [FieldDescription("Audio samples per second")] public static readonly Guid MF_MT_AUDIO_SAMPLES_PER_SECOND = new Guid("5faeeae7-0290-4c31-9e8a-c534f68d9dba"); [FieldDescription("Audio bits per sample")] public static readonly Guid MF_MT_AUDIO_BITS_PER_SAMPLE = new Guid("f2deb57f-40fa-4764-aa33-ed4f2d1ff669"); [FieldDescription("Enable Hardware Transforms")] public static readonly Guid MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS = new Guid("a634a91c-822b-41b9-a494-4de4643612b0"); [FieldDescription("Disable Sink Writer Throttling")] public static readonly Guid MF_SINK_WRITER_DISABLE_THROTTLING = new Guid("08b845d8-2b74-4afe-9d53-be16d2d5ae4f"); [FieldDescription("User data")] public static readonly Guid MF_MT_USER_DATA = new Guid("b6bc765f-4c3b-40a4-bd51-2535b66fe09d"); [FieldDescription("All samples independent")] public static readonly Guid MF_MT_ALL_SAMPLES_INDEPENDENT = new Guid("c9173739-5e56-461c-b713-46fb995cb95f"); [FieldDescription("Fixed size samples")] public static readonly Guid MF_MT_FIXED_SIZE_SAMPLES = new Guid("b8ebefaf-b718-4e04-b0a9-116775e3321b"); [FieldDescription("DirectShow Format Guid")] public static readonly Guid MF_MT_AM_FORMAT_TYPE = new Guid("73d1072d-1870-4174-a063-29ff4ff6c11e"); [FieldDescription("Preferred legacy format structure")] public static readonly Guid MF_MT_AUDIO_PREFER_WAVEFORMATEX = new Guid("a901aaba-e037-458a-bdf6-545be2074042"); [FieldDescription("Is Compressed")] public static readonly Guid MF_MT_COMPRESSED = new Guid("3afd0cee-18f2-4ba5-a110-8bea502e1f92"); [FieldDescription("Average bitrate")] public static readonly Guid MF_MT_AVG_BITRATE = new Guid("20332624-fb0d-4d9e-bd0d-cbf6786c102e"); [FieldDescription("AAC payload type")] public static readonly Guid MF_MT_AAC_PAYLOAD_TYPE = new Guid("bfbabe79-7434-4d1c-94f0-72a3b9e17188"); [FieldDescription("AAC Audio Profile Level Indication")] public static readonly Guid MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION = new Guid("7632f0e6-9538-4d61-acda-ea29c8c14456"); } public static class MediaFoundationErrors { public const int MF_E_PLATFORM_NOT_INITIALIZED = -1072875856; public const int MF_E_BUFFERTOOSMALL = -1072875855; public const int MF_E_INVALIDREQUEST = -1072875854; public const int MF_E_INVALIDSTREAMNUMBER = -1072875853; public const int MF_E_INVALIDMEDIATYPE = -1072875852; public const int MF_E_NOTACCEPTING = -1072875851; public const int MF_E_NOT_INITIALIZED = -1072875850; public const int MF_E_UNSUPPORTED_REPRESENTATION = -1072875849; public const int MF_E_NO_MORE_TYPES = -1072875847; public const int MF_E_UNSUPPORTED_SERVICE = -1072875846; public const int MF_E_UNEXPECTED = -1072875845; public const int MF_E_INVALIDNAME = -1072875844; public const int MF_E_INVALIDTYPE = -1072875843; public const int MF_E_INVALID_FILE_FORMAT = -1072875842; public const int MF_E_INVALIDINDEX = -1072875841; public const int MF_E_INVALID_TIMESTAMP = -1072875840; public const int MF_E_UNSUPPORTED_SCHEME = -1072875837; public const int MF_E_UNSUPPORTED_BYTESTREAM_TYPE = -1072875836; public const int MF_E_UNSUPPORTED_TIME_FORMAT = -1072875835; public const int MF_E_NO_SAMPLE_TIMESTAMP = -1072875832; public const int MF_E_NO_SAMPLE_DURATION = -1072875831; public const int MF_E_INVALID_STREAM_DATA = -1072875829; public const int MF_E_RT_UNAVAILABLE = -1072875825; public const int MF_E_UNSUPPORTED_RATE = -1072875824; public const int MF_E_THINNING_UNSUPPORTED = -1072875823; public const int MF_E_REVERSE_UNSUPPORTED = -1072875822; public const int MF_E_UNSUPPORTED_RATE_TRANSITION = -1072875821; public const int MF_E_RATE_CHANGE_PREEMPTED = -1072875820; public const int MF_E_NOT_FOUND = -1072875819; public const int MF_E_NOT_AVAILABLE = -1072875818; public const int MF_E_NO_CLOCK = -1072875817; public const int MF_S_MULTIPLE_BEGIN = 866008; public const int MF_E_MULTIPLE_BEGIN = -1072875815; public const int MF_E_MULTIPLE_SUBSCRIBERS = -1072875814; public const int MF_E_TIMER_ORPHANED = -1072875813; public const int MF_E_STATE_TRANSITION_PENDING = -1072875812; public const int MF_E_UNSUPPORTED_STATE_TRANSITION = -1072875811; public const int MF_E_UNRECOVERABLE_ERROR_OCCURRED = -1072875810; public const int MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS = -1072875809; public const int MF_E_SAMPLE_NOT_WRITABLE = -1072875808; public const int MF_E_INVALID_KEY = -1072875806; public const int MF_E_BAD_STARTUP_VERSION = -1072875805; public const int MF_E_UNSUPPORTED_CAPTION = -1072875804; public const int MF_E_INVALID_POSITION = -1072875803; public const int MF_E_ATTRIBUTENOTFOUND = -1072875802; public const int MF_E_PROPERTY_TYPE_NOT_ALLOWED = -1072875801; public const int MF_E_PROPERTY_TYPE_NOT_SUPPORTED = -1072875800; public const int MF_E_PROPERTY_EMPTY = -1072875799; public const int MF_E_PROPERTY_NOT_EMPTY = -1072875798; public const int MF_E_PROPERTY_VECTOR_NOT_ALLOWED = -1072875797; public const int MF_E_PROPERTY_VECTOR_REQUIRED = -1072875796; public const int MF_E_OPERATION_CANCELLED = -1072875795; public const int MF_E_BYTESTREAM_NOT_SEEKABLE = -1072875794; public const int MF_E_DISABLED_IN_SAFEMODE = -1072875793; public const int MF_E_CANNOT_PARSE_BYTESTREAM = -1072875792; public const int MF_E_SOURCERESOLVER_MUTUALLY_EXCLUSIVE_FLAGS = -1072875791; public const int MF_E_MEDIAPROC_WRONGSTATE = -1072875790; public const int MF_E_RT_THROUGHPUT_NOT_AVAILABLE = -1072875789; public const int MF_E_RT_TOO_MANY_CLASSES = -1072875788; public const int MF_E_RT_WOULDBLOCK = -1072875787; public const int MF_E_NO_BITPUMP = -1072875786; public const int MF_E_RT_OUTOFMEMORY = -1072875785; public const int MF_E_RT_WORKQUEUE_CLASS_NOT_SPECIFIED = -1072875784; public const int MF_E_INSUFFICIENT_BUFFER = -1072860816; public const int MF_E_CANNOT_CREATE_SINK = -1072875782; public const int MF_E_BYTESTREAM_UNKNOWN_LENGTH = -1072875781; public const int MF_E_SESSION_PAUSEWHILESTOPPED = -1072875780; public const int MF_S_ACTIVATE_REPLACED = 866045; public const int MF_E_FORMAT_CHANGE_NOT_SUPPORTED = -1072875778; public const int MF_E_INVALID_WORKQUEUE = -1072875777; public const int MF_E_DRM_UNSUPPORTED = -1072875776; public const int MF_E_UNAUTHORIZED = -1072875775; public const int MF_E_OUT_OF_RANGE = -1072875774; public const int MF_E_INVALID_CODEC_MERIT = -1072875773; public const int MF_E_HW_MFT_FAILED_START_STREAMING = -1072875772; public const int MF_S_ASF_PARSEINPROGRESS = 1074608792; public const int MF_E_ASF_PARSINGINCOMPLETE = -1072874856; public const int MF_E_ASF_MISSINGDATA = -1072874855; public const int MF_E_ASF_INVALIDDATA = -1072874854; public const int MF_E_ASF_OPAQUEPACKET = -1072874853; public const int MF_E_ASF_NOINDEX = -1072874852; public const int MF_E_ASF_OUTOFRANGE = -1072874851; public const int MF_E_ASF_INDEXNOTLOADED = -1072874850; public const int MF_E_ASF_TOO_MANY_PAYLOADS = -1072874849; public const int MF_E_ASF_UNSUPPORTED_STREAM_TYPE = -1072874848; public const int MF_E_ASF_DROPPED_PACKET = -1072874847; public const int MF_E_NO_EVENTS_AVAILABLE = -1072873856; public const int MF_E_INVALID_STATE_TRANSITION = -1072873854; public const int MF_E_END_OF_STREAM = -1072873852; public const int MF_E_SHUTDOWN = -1072873851; public const int MF_E_MP3_NOTFOUND = -1072873850; public const int MF_E_MP3_OUTOFDATA = -1072873849; public const int MF_E_MP3_NOTMP3 = -1072873848; public const int MF_E_MP3_NOTSUPPORTED = -1072873847; public const int MF_E_NO_DURATION = -1072873846; public const int MF_E_INVALID_FORMAT = -1072873844; public const int MF_E_PROPERTY_NOT_FOUND = -1072873843; public const int MF_E_PROPERTY_READ_ONLY = -1072873842; public const int MF_E_PROPERTY_NOT_ALLOWED = -1072873841; public const int MF_E_MEDIA_SOURCE_NOT_STARTED = -1072873839; public const int MF_E_UNSUPPORTED_FORMAT = -1072873832; public const int MF_E_MP3_BAD_CRC = -1072873831; public const int MF_E_NOT_PROTECTED = -1072873830; public const int MF_E_MEDIA_SOURCE_WRONGSTATE = -1072873829; public const int MF_E_MEDIA_SOURCE_NO_STREAMS_SELECTED = -1072873828; public const int MF_E_CANNOT_FIND_KEYFRAME_SAMPLE = -1072873827; public const int MF_E_NETWORK_RESOURCE_FAILURE = -1072872856; public const int MF_E_NET_WRITE = -1072872855; public const int MF_E_NET_READ = -1072872854; public const int MF_E_NET_REQUIRE_NETWORK = -1072872853; public const int MF_E_NET_REQUIRE_ASYNC = -1072872852; public const int MF_E_NET_BWLEVEL_NOT_SUPPORTED = -1072872851; public const int MF_E_NET_STREAMGROUPS_NOT_SUPPORTED = -1072872850; public const int MF_E_NET_MANUALSS_NOT_SUPPORTED = -1072872849; public const int MF_E_NET_INVALID_PRESENTATION_DESCRIPTOR = -1072872848; public const int MF_E_NET_CACHESTREAM_NOT_FOUND = -1072872847; public const int MF_I_MANUAL_PROXY = 1074610802; public const int MF_E_NET_REQUIRE_INPUT = -1072872844; public const int MF_E_NET_REDIRECT = -1072872843; public const int MF_E_NET_REDIRECT_TO_PROXY = -1072872842; public const int MF_E_NET_TOO_MANY_REDIRECTS = -1072872841; public const int MF_E_NET_TIMEOUT = -1072872840; public const int MF_E_NET_CLIENT_CLOSE = -1072872839; public const int MF_E_NET_BAD_CONTROL_DATA = -1072872838; public const int MF_E_NET_INCOMPATIBLE_SERVER = -1072872837; public const int MF_E_NET_UNSAFE_URL = -1072872836; public const int MF_E_NET_CACHE_NO_DATA = -1072872835; public const int MF_E_NET_EOL = -1072872834; public const int MF_E_NET_BAD_REQUEST = -1072872833; public const int MF_E_NET_INTERNAL_SERVER_ERROR = -1072872832; public const int MF_E_NET_SESSION_NOT_FOUND = -1072872831; public const int MF_E_NET_NOCONNECTION = -1072872830; public const int MF_E_NET_CONNECTION_FAILURE = -1072872829; public const int MF_E_NET_INCOMPATIBLE_PUSHSERVER = -1072872828; public const int MF_E_NET_SERVER_ACCESSDENIED = -1072872827; public const int MF_E_NET_PROXY_ACCESSDENIED = -1072872826; public const int MF_E_NET_CANNOTCONNECT = -1072872825; public const int MF_E_NET_INVALID_PUSH_TEMPLATE = -1072872824; public const int MF_E_NET_INVALID_PUSH_PUBLISHING_POINT = -1072872823; public const int MF_E_NET_BUSY = -1072872822; public const int MF_E_NET_RESOURCE_GONE = -1072872821; public const int MF_E_NET_ERROR_FROM_PROXY = -1072872820; public const int MF_E_NET_PROXY_TIMEOUT = -1072872819; public const int MF_E_NET_SERVER_UNAVAILABLE = -1072872818; public const int MF_E_NET_TOO_MUCH_DATA = -1072872817; public const int MF_E_NET_SESSION_INVALID = -1072872816; public const int MF_E_OFFLINE_MODE = -1072872815; public const int MF_E_NET_UDP_BLOCKED = -1072872814; public const int MF_E_NET_UNSUPPORTED_CONFIGURATION = -1072872813; public const int MF_E_NET_PROTOCOL_DISABLED = -1072872812; public const int MF_E_ALREADY_INITIALIZED = -1072871856; public const int MF_E_BANDWIDTH_OVERRUN = -1072871855; public const int MF_E_LATE_SAMPLE = -1072871854; public const int MF_E_FLUSH_NEEDED = -1072871853; public const int MF_E_INVALID_PROFILE = -1072871852; public const int MF_E_INDEX_NOT_COMMITTED = -1072871851; public const int MF_E_NO_INDEX = -1072871850; public const int MF_E_CANNOT_INDEX_IN_PLACE = -1072871849; public const int MF_E_MISSING_ASF_LEAKYBUCKET = -1072871848; public const int MF_E_INVALID_ASF_STREAMID = -1072871847; public const int MF_E_STREAMSINK_REMOVED = -1072870856; public const int MF_E_STREAMSINKS_OUT_OF_SYNC = -1072870854; public const int MF_E_STREAMSINKS_FIXED = -1072870853; public const int MF_E_STREAMSINK_EXISTS = -1072870852; public const int MF_E_SAMPLEALLOCATOR_CANCELED = -1072870851; public const int MF_E_SAMPLEALLOCATOR_EMPTY = -1072870850; public const int MF_E_SINK_ALREADYSTOPPED = -1072870849; public const int MF_E_ASF_FILESINK_BITRATE_UNKNOWN = -1072870848; public const int MF_E_SINK_NO_STREAMS = -1072870847; public const int MF_S_SINK_NOT_FINALIZED = 870978; public const int MF_E_METADATA_TOO_LONG = -1072870845; public const int MF_E_SINK_NO_SAMPLES_PROCESSED = -1072870844; public const int MF_E_VIDEO_REN_NO_PROCAMP_HW = -1072869856; public const int MF_E_VIDEO_REN_NO_DEINTERLACE_HW = -1072869855; public const int MF_E_VIDEO_REN_COPYPROT_FAILED = -1072869854; public const int MF_E_VIDEO_REN_SURFACE_NOT_SHARED = -1072869853; public const int MF_E_VIDEO_DEVICE_LOCKED = -1072869852; public const int MF_E_NEW_VIDEO_DEVICE = -1072869851; public const int MF_E_NO_VIDEO_SAMPLE_AVAILABLE = -1072869850; public const int MF_E_NO_AUDIO_PLAYBACK_DEVICE = -1072869756; public const int MF_E_AUDIO_PLAYBACK_DEVICE_IN_USE = -1072869755; public const int MF_E_AUDIO_PLAYBACK_DEVICE_INVALIDATED = -1072869754; public const int MF_E_AUDIO_SERVICE_NOT_RUNNING = -1072869753; public const int MF_E_TOPO_INVALID_OPTIONAL_NODE = -1072868850; public const int MF_E_TOPO_CANNOT_FIND_DECRYPTOR = -1072868847; public const int MF_E_TOPO_CODEC_NOT_FOUND = -1072868846; public const int MF_E_TOPO_CANNOT_CONNECT = -1072868845; public const int MF_E_TOPO_UNSUPPORTED = -1072868844; public const int MF_E_TOPO_INVALID_TIME_ATTRIBUTES = -1072868843; public const int MF_E_TOPO_LOOPS_IN_TOPOLOGY = -1072868842; public const int MF_E_TOPO_MISSING_PRESENTATION_DESCRIPTOR = -1072868841; public const int MF_E_TOPO_MISSING_STREAM_DESCRIPTOR = -1072868840; public const int MF_E_TOPO_STREAM_DESCRIPTOR_NOT_SELECTED = -1072868839; public const int MF_E_TOPO_MISSING_SOURCE = -1072868838; public const int MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED = -1072868837; public const int MF_E_SEQUENCER_UNKNOWN_SEGMENT_ID = -1072864852; public const int MF_S_SEQUENCER_CONTEXT_CANCELED = 876973; public const int MF_E_NO_SOURCE_IN_CACHE = -1072864850; public const int MF_S_SEQUENCER_SEGMENT_AT_END_OF_STREAM = 876975; public const int MF_E_TRANSFORM_TYPE_NOT_SET = -1072861856; public const int MF_E_TRANSFORM_STREAM_CHANGE = -1072861855; public const int MF_E_TRANSFORM_INPUT_REMAINING = -1072861854; public const int MF_E_TRANSFORM_PROFILE_MISSING = -1072861853; public const int MF_E_TRANSFORM_PROFILE_INVALID_OR_CORRUPT = -1072861852; public const int MF_E_TRANSFORM_PROFILE_TRUNCATED = -1072861851; public const int MF_E_TRANSFORM_PROPERTY_PID_NOT_RECOGNIZED = -1072861850; public const int MF_E_TRANSFORM_PROPERTY_VARIANT_TYPE_WRONG = -1072861849; public const int MF_E_TRANSFORM_PROPERTY_NOT_WRITEABLE = -1072861848; public const int MF_E_TRANSFORM_PROPERTY_ARRAY_VALUE_WRONG_NUM_DIM = -1072861847; public const int MF_E_TRANSFORM_PROPERTY_VALUE_SIZE_WRONG = -1072861846; public const int MF_E_TRANSFORM_PROPERTY_VALUE_OUT_OF_RANGE = -1072861845; public const int MF_E_TRANSFORM_PROPERTY_VALUE_INCOMPATIBLE = -1072861844; public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_OUTPUT_MEDIATYPE = -1072861843; public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_INPUT_MEDIATYPE = -1072861842; public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION = -1072861841; public const int MF_E_TRANSFORM_CONFLICTS_WITH_OTHER_CURRENTLY_ENABLED_FEATURES = -1072861840; public const int MF_E_TRANSFORM_NEED_MORE_INPUT = -1072861838; public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_SPKR_CONFIG = -1072861837; public const int MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING = -1072861836; public const int MF_S_TRANSFORM_DO_NOT_PROPAGATE_EVENT = 879989; public const int MF_E_UNSUPPORTED_D3D_TYPE = -1072861834; public const int MF_E_TRANSFORM_ASYNC_LOCKED = -1072861833; public const int MF_E_TRANSFORM_CANNOT_INITIALIZE_ACM_DRIVER = -1072861832; public const int MF_E_LICENSE_INCORRECT_RIGHTS = -1072860856; public const int MF_E_LICENSE_OUTOFDATE = -1072860855; public const int MF_E_LICENSE_REQUIRED = -1072860854; public const int MF_E_DRM_HARDWARE_INCONSISTENT = -1072860853; public const int MF_E_NO_CONTENT_PROTECTION_MANAGER = -1072860852; public const int MF_E_LICENSE_RESTORE_NO_RIGHTS = -1072860851; public const int MF_E_BACKUP_RESTRICTED_LICENSE = -1072860850; public const int MF_E_LICENSE_RESTORE_NEEDS_INDIVIDUALIZATION = -1072860849; public const int MF_S_PROTECTION_NOT_REQUIRED = 880976; public const int MF_E_COMPONENT_REVOKED = -1072860847; public const int MF_E_TRUST_DISABLED = -1072860846; public const int MF_E_WMDRMOTA_NO_ACTION = -1072860845; public const int MF_E_WMDRMOTA_ACTION_ALREADY_SET = -1072860844; public const int MF_E_WMDRMOTA_DRM_HEADER_NOT_AVAILABLE = -1072860843; public const int MF_E_WMDRMOTA_DRM_ENCRYPTION_SCHEME_NOT_SUPPORTED = -1072860842; public const int MF_E_WMDRMOTA_ACTION_MISMATCH = -1072860841; public const int MF_E_WMDRMOTA_INVALID_POLICY = -1072860840; public const int MF_E_POLICY_UNSUPPORTED = -1072860839; public const int MF_E_OPL_NOT_SUPPORTED = -1072860838; public const int MF_E_TOPOLOGY_VERIFICATION_FAILED = -1072860837; public const int MF_E_SIGNATURE_VERIFICATION_FAILED = -1072860836; public const int MF_E_DEBUGGING_NOT_ALLOWED = -1072860835; public const int MF_E_CODE_EXPIRED = -1072860834; public const int MF_E_GRL_VERSION_TOO_LOW = -1072860833; public const int MF_E_GRL_RENEWAL_NOT_FOUND = -1072860832; public const int MF_E_GRL_EXTENSIBLE_ENTRY_NOT_FOUND = -1072860831; public const int MF_E_KERNEL_UNTRUSTED = -1072860830; public const int MF_E_PEAUTH_UNTRUSTED = -1072860829; public const int MF_E_NON_PE_PROCESS = -1072860827; public const int MF_E_REBOOT_REQUIRED = -1072860825; public const int MF_S_WAIT_FOR_POLICY_SET = 881000; public const int MF_S_VIDEO_DISABLED_WITH_UNKNOWN_SOFTWARE_OUTPUT = 881001; public const int MF_E_GRL_INVALID_FORMAT = -1072860822; public const int MF_E_GRL_UNRECOGNIZED_FORMAT = -1072860821; public const int MF_E_ALL_PROCESS_RESTART_REQUIRED = -1072860820; public const int MF_E_PROCESS_RESTART_REQUIRED = -1072860819; public const int MF_E_USERMODE_UNTRUSTED = -1072860818; public const int MF_E_PEAUTH_SESSION_NOT_STARTED = -1072860817; public const int MF_E_PEAUTH_PUBLICKEY_REVOKED = -1072860815; public const int MF_E_GRL_ABSENT = -1072860814; public const int MF_S_PE_TRUSTED = 881011; public const int MF_E_PE_UNTRUSTED = -1072860812; public const int MF_E_PEAUTH_NOT_STARTED = -1072860811; public const int MF_E_INCOMPATIBLE_SAMPLE_PROTECTION = -1072860810; public const int MF_E_PE_SESSIONS_MAXED = -1072860809; public const int MF_E_HIGH_SECURITY_LEVEL_CONTENT_NOT_ALLOWED = -1072860808; public const int MF_E_TEST_SIGNED_COMPONENTS_NOT_ALLOWED = -1072860807; public const int MF_E_ITA_UNSUPPORTED_ACTION = -1072860806; public const int MF_E_ITA_ERROR_PARSING_SAP_PARAMETERS = -1072860805; public const int MF_E_POLICY_MGR_ACTION_OUTOFBOUNDS = -1072860804; public const int MF_E_BAD_OPL_STRUCTURE_FORMAT = -1072860803; public const int MF_E_ITA_UNRECOGNIZED_ANALOG_VIDEO_PROTECTION_GUID = -1072860802; public const int MF_E_NO_PMP_HOST = -1072860801; public const int MF_E_ITA_OPL_DATA_NOT_INITIALIZED = -1072860800; public const int MF_E_ITA_UNRECOGNIZED_ANALOG_VIDEO_OUTPUT = -1072860799; public const int MF_E_ITA_UNRECOGNIZED_DIGITAL_VIDEO_OUTPUT = -1072860798; public const int MF_E_CLOCK_INVALID_CONTINUITY_KEY = -1072849856; public const int MF_E_CLOCK_NO_TIME_SOURCE = -1072849855; public const int MF_E_CLOCK_STATE_ALREADY_SET = -1072849854; public const int MF_E_CLOCK_NOT_SIMPLE = -1072849853; public const int MF_S_CLOCK_STOPPED = 891972; public const int MF_E_NO_MORE_DROP_MODES = -1072848856; public const int MF_E_NO_MORE_QUALITY_LEVELS = -1072848855; public const int MF_E_DROPTIME_NOT_SUPPORTED = -1072848854; public const int MF_E_QUALITYKNOB_WAIT_LONGER = -1072848853; public const int MF_E_QM_INVALIDSTATE = -1072848852; public const int MF_E_TRANSCODE_NO_CONTAINERTYPE = -1072847856; public const int MF_E_TRANSCODE_PROFILE_NO_MATCHING_STREAMS = -1072847855; public const int MF_E_TRANSCODE_NO_MATCHING_ENCODER = -1072847854; public const int MF_E_ALLOCATOR_NOT_INITIALIZED = -1072846856; public const int MF_E_ALLOCATOR_NOT_COMMITED = -1072846855; public const int MF_E_ALLOCATOR_ALREADY_COMMITED = -1072846854; public const int MF_E_STREAM_ERROR = -1072846853; public const int MF_E_INVALID_STREAM_STATE = -1072846852; public const int MF_E_HW_STREAM_NOT_CONNECTED = -1072846851; } public static class MediaFoundationApi { [CompilerGenerated] private sealed class <EnumerateTransforms>d__2 : global::System.Collections.Generic.IEnumerable<IMFActivate>, global::System.Collections.IEnumerable, global::System.Collections.Generic.IEnumerator<IMFActivate>, global::System.Collections.IEnumerator, global::System.IDisposable { private int <>1__state; private IMFActivate <>2__current; private int <>l__initialThreadId; private Guid category; public Guid <>3__category; private global::System.IntPtr <interfacesPointer>5__1; private int <interfaceCount>5__2; private IMFActivate[] <interfaces>5__3; private int <n>5__4; private global::System.IntPtr <ptr>5__5; private IMFActivate[] <>s__6; private int <>s__7; private IMFActivate <i>5__8; IMFActivate global::System.Collections.Generic.IEnumerator<IMFActivate>.Current { [DebuggerHidden] get { return <>2__current; } } object global::System.Collections.IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnumerateTransforms>d__2(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void global::System.IDisposable.Dispose() { <interfaces>5__3 = null; <>s__6 = null; <i>5__8 = null; <>1__state = -2; } private bool MoveNext() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; MediaFoundationInterop.MFTEnumEx(category, _MFT_ENUM_FLAG.MFT_ENUM_FLAG_ALL, null, null, out <interfacesPointer>5__1, out <interfaceCount>5__2); <interfaces>5__3 = new IMFActivate[<interfaceCount>5__2]; <n>5__4 = 0; while (<n>5__4 < <interfaceCount>5__2) { <ptr>5__5 = Marshal.ReadIntPtr(new global::System.IntPtr(<interfacesPointer>5__1.ToInt64() + <n>5__4 * Marshal.SizeOf<global::System.IntPtr>(<interfacesPointer>5__1))); <interfaces>5__3[<n>5__4] = (IMFActivate)Marshal.GetObjectForIUnknown(<ptr>5__5); <n>5__4++; } <>s__6 = <interfaces>5__3; <>s__7 = 0; break; case 1: <>1__state = -1; <i>5__8 = null; <>s__7++; break; } if (<>s__7 < <>s__6.Length) { <i>5__8 = <>s__6[<>s__7]; <>2__current = <i>5__8; <>1__state = 1; return true; } <>s__6 = null; Marshal.FreeCoTaskMem(<interfacesPointer>5__1); return false; } bool global::System.Collections.IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void global::System.Collections.IEnumerator.Reset() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) throw new NotSupportedException(); } [DebuggerHidden] global::System.Collections.Generic.IEnumerator<IMFActivate> global::System.Collections.Generic.IEnumerable<IMFActivate>.GetEnumerator() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) <EnumerateTransforms>d__2 <EnumerateTransforms>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <EnumerateTransforms>d__ = this; } else { <EnumerateTransforms>d__ = new <EnumerateTransforms>d__2(0); } <EnumerateTransforms>d__.category = <>3__category; return <EnumerateTransforms>d__; } [DebuggerHidden] global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() { return (global::System.Collections.IEnumerator)((global::System.Collections.Generic.IEnumerable<IMFActivate>)this).GetEnumerator(); } } private static bool initialized; public static void Startup() { if (!initialized) { int num = 2; OperatingSystem oSVersion = Environment.OSVersion; if (oSVersion.Version.Major == 6 && oSVersion.Version.Minor == 0) { num = 1; } MediaFoundationInterop.MFStartup((num << 16) | 0x70); initialized = true; } } [IteratorStateMachine(typeof(<EnumerateTransforms>d__2))] public static global::System.Collections.Generic.IEnumerable<IMFActivate> EnumerateTransforms(Guid category) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnumerateTransforms>d__2(-2) { <>3__category = category }; } public static void Shutdown() { if (initialized) { MediaFoundationInterop.MFShutdown(); initialized = false; } } public static IMFMediaType CreateMediaType() { MediaFoundationInterop.MFCreateMediaType(out var ppMFType); return ppMFType; } public static IMFMediaType CreateMediaTypeFromWaveFormat(WaveFormat waveFormat) { IMFMediaType iMFMediaType = CreateMediaType(); try { MediaFoundationInterop.MFInitMediaTypeFromWaveFormatEx(iMFMediaType, waveFormat, Marshal.SizeOf<WaveFormat>(waveFormat)); } catch (global::System.Exception) { Marshal.ReleaseComObject((object)iMFMediaType); throw; } return iMFMediaType; } public static IMFMediaBuffer CreateMemoryBuffer(int bufferSize) { MediaFoundationInterop.MFCreateMemoryBuffer(bufferSize, out var ppBuffer); return ppBuffer; } public static IMFSample CreateSample() { MediaFoundationInterop.MFCreateSample(out var ppIMFSample); return ppIMFSample; } public static IMFAttributes CreateAttributes(int initialSize) { MediaFoundationInterop.MFCreateAttributes(out var ppMFAttributes, initialSize); return ppMFAttributes; } public static IMFByteStream CreateByteStream(object stream) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (stream is IStream) { MediaFoundationInterop.MFCreateMFByteStreamOnStream((IStream)((stream is IStream) ? stream : null), out var ppByteStream); return ppByteStream; } throw new ArgumentException("Stream must be IStream in desktop apps"); } public static IMFSourceReader CreateSourceReaderFromByteStream(IMFByteStream byteStream) { MediaFoundationInterop.MFCreateSourceReaderFromByteStream(byteStream, null, out var ppSourceReader); return ppSourceReader; } } public static class MediaFoundationInterop { public const int MF_SOURCE_READER_ALL_STREAMS = -2; public const int MF_SOURCE_READER_FIRST_AUDIO_STREAM = -3; public const int MF_SOURCE_READER_FIRST_VIDEO_STREAM = -4; public const int MF_SOURCE_READER_MEDIASOURCE = -1; public const int MF_SDK_VERSION = 2; public const int MF_API_VERSION = 112; public const int MF_VERSION = 131184; [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] public static extern void MFStartup(int version, int dwFlags = 0); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] public static extern void MFShutdown(); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] internal static extern void MFCreateMediaType(out IMFMediaType ppMFType); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] internal static extern void MFInitMediaTypeFromWaveFormatEx([In] IMFMediaType pMFType, [In] WaveFormat pWaveFormat, [In] int cbBufSize); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] internal static extern void MFCreateWaveFormatExFromMFMediaType(IMFMediaType pMFType, ref global::System.IntPtr ppWF, ref int pcbSize, int flags = 0); [DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)] public static extern void MFCreateSourceReaderFromURL([In][MarshalAs(21)] string pwszURL, [In] IMFAttributes pAttributes, [MarshalAs(28)] out IMFSourceReader ppSourceReader); [DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)] public static extern void MFCreateSourceReaderFromByteStream([In] IMFByteStream pByteStream, [In] IMFAttributes pAttributes, [MarshalAs(28)] out IMFSourceReader ppSourceReader); [DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)] public static extern void MFCreateSinkWriterFromURL([In][MarshalAs(21)] string pwszOutputURL, [In] IMFByteStream pByteStream, [In] IMFAttributes pAttributes, out IMFSinkWriter ppSinkWriter); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] public static extern void MFCreateMFByteStreamOnStreamEx([MarshalAs(25)] object punkStream, out IMFByteStream ppByteStream); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] public static extern void MFCreateMFByteStreamOnStream([In] IStream punkStream, out IMFByteStream ppByteStream); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] public static extern void MFTEnumEx([In] Guid guidCategory, [In] _MFT_ENUM_FLAG flags, [In] MFT_REGISTER_TYPE_INFO pInputType, [In] MFT_REGISTER_TYPE_INFO pOutputType, out global::System.IntPtr pppMFTActivate, out int pcMFTActivate); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] internal static extern void MFCreateSample(out IMFSample ppIMFSample); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] internal static extern void MFCreateMemoryBuffer(int cbMaxLength, out IMFMediaBuffer ppBuffer); [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)] internal static extern void MFCreateAttributes([MarshalAs(28)] out IMFAttributes ppMFAttributes, [In] int cInitialSize); [DllImport("mf.dll", ExactSpelling = true, PreserveSig = false)] public static extern void MFTranscodeGetAudioOutputAvailableTypes([In][MarshalAs(43)] Guid guidSubType, [In] _MFT_ENUM_FLAG dwMFTFlags, [In] IMFAttributes pCodecConfig, [MarshalAs(28)] out IMFCollection ppAvailableTypes); } public abstract class MediaFoundationTransform : IWaveProvider, global::System.IDisposable { protected readonly IWaveProvider sourceProvider; protected readonly WaveFormat outputWaveFormat; private readonly byte[] sourceBuffer; private byte[] outputBuffer; private int outputBufferOffset; private int outputBufferCount; private IMFTransform transform; private bool disposed; private long inputPosition; private long outputPosition; private bool initializedForStreaming; public WaveFormat WaveFormat => outputWaveFormat; public MediaFoundationTransform(IWaveProvider sourceProvider, WaveFormat outputFormat) { outputWaveFormat = outputFormat; this.sourceProvider = sourceProvider; sourceBuffer = new byte[sourceProvider.WaveFormat.AverageBytesPerSecond]; outputBuffer = new byte[outputWaveFormat.AverageBytesPerSecond + outputWaveFormat.BlockAlign]; } private void InitializeTransformForStreaming() { transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_COMMAND_FLUSH, global::System.IntPtr.Zero); transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, global::System.IntPtr.Zero); transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_START_OF_STREAM, global::System.IntPtr.Zero); initializedForStreaming = true; } protected abstract IMFTransform CreateTransform(); protected virtual void Dispose(bool disposing) { if (transform != null) { Marshal.ReleaseComObject((object)transform); } } public void Dispose() { if (!disposed) { disposed = true; Dispose(disposing: true); GC.SuppressFinalize((object)this); } } ~MediaFoundationTransform() { Dispose(disposing: false); } public int Read(byte[] buffer, int offset, int count) { if (transform == null) { transform = CreateTransform(); InitializeTransformForStreaming(); } int i = 0; if (outputBufferCount > 0) { i += ReadFromOutputBuffer(buffer, offset, count - i); } for (; i < count; i += ReadFromOutputBuffer(buffer, offset + i, count - i)) { IMFSample iMFSample = ReadFromSource(); if (iMFSample == null) { EndStreamAndDrain(); i += ReadFromOutputBuffer(buffer, offset + i, count - i); ClearOutputBuffer(); break; } if (!initializedForStreaming) { InitializeTransformForStreaming(); } transform.ProcessInput(0, iMFSample, 0); Marshal.ReleaseComObject((object)iMFSample); int num = ReadFromTransform(); } return i; } private void EndStreamAndDrain() { transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_END_OF_STREAM, global::System.IntPtr.Zero); transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_COMMAND_DRAIN, global::System.IntPtr.Zero); int num; do { num = ReadFromTransform(); } while (num > 0); inputPosition = 0L; outputPosition = 0L; transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_END_STREAMING, global::System.IntPtr.Zero); initializedForStreaming = false; } private void ClearOutputBuffer() { outputBufferCount = 0; outputBufferOffset = 0; } private int ReadFromTransform() { MFT_OUTPUT_DATA_BUFFER[] array = new MFT_OUTPUT_DATA_BUFFER[1]; IMFSample iMFSample = MediaFoundationApi.CreateSample(); IMFMediaBuffer iMFMediaBuffer = MediaFoundationApi.CreateMemoryBuffer(outputBuffer.Length); iMFSample.AddBuffer(iMFMediaBuffer); iMFSample.SetSampleTime(outputPosition); array[0].pSample = iMFSample; _MFT_PROCESS_OUTPUT_STATUS pdwStatus; int num = transform.ProcessOutput(_MFT_PROCESS_OUTPUT_FLAGS.None, 1, array, out pdwStatus); switch (num) { case -1072861838: Marshal.ReleaseComObject((object)iMFMediaBuffer); Marshal.ReleaseComObject((object)iMFSample); return 0; default: Marshal.ThrowExceptionForHR(num); break; case 0: break; } array[0].pSample.ConvertToContiguousBuffer(out var ppBuffer); ppBuffer.Lock(out var ppbBuffer, out var _, out var pcbCurrentLength); outputBuffer = BufferHelpers.Ensure(outputBuffer, pcbCurrentLength); Marshal.Copy(ppbBuffer, outputBuffer, 0, pcbCurrentLength); outputBufferOffset = 0; outputBufferCount = pcbCurrentLength; ppBuffer.Unlock(); outputPosition += BytesToNsPosition(outputBufferCount, WaveFormat); Marshal.ReleaseComObject((object)iMFMediaBuffer); iMFSample.RemoveAllBuffers(); Marshal.ReleaseComObject((object)iMFSample); Marshal.ReleaseComObject((object)ppBuffer); return pcbCurrentLength; } private static long BytesToNsPosition(int bytes, WaveFormat waveFormat) { return 10000000L * (long)bytes / waveFormat.AverageBytesPerSecond; } private IMFSample ReadFromSource() { int num = sourceProvider.Read(sourceBuffer, 0, sourceBuffer.Length); if (num == 0) { return null; } IMFMediaBuffer iMFMediaBuffer = MediaFoundationApi.CreateMemoryBuffer(num); iMFMediaBuffer.Lock(out var ppbBuffer, out var _, out var _); Marshal.Copy(sourceBuffer, 0, ppbBuffer, num); iMFMediaBuffer.Unlock(); iMFMediaBuffer.SetCurrentLength(num); IMFSample iMFSample = MediaFoundationApi.CreateSample(); iMFSample.AddBuffer(iMFMediaBuffer); iMFSample.SetSampleTime(inputPosition); long num2 = BytesToNsPosition(num, sourceProvider.WaveFormat); iMFSample.SetSampleDuration(num2); inputPosition += num2; Marshal.ReleaseComObject((object)iMFMediaBuffer); return iMFSample; } private int ReadFromOutputBuffer(byte[] buffer, int offset, int needed) { int num = Math.Min(needed, outputBufferCount); global::System.Array.Copy((global::System.Array)outputBuffer, outputBufferOffset, (global::System.Array)buffer, offset, num); outputBufferOffset += num; outputBufferCount -= num; if (outputBufferCount == 0) { outputBufferOffset = 0; } return num; } public void Reposition() { if (initializedForStreaming) { EndStreamAndDrain(); ClearOutputBuffer(); InitializeTransformForStreaming(); } } } public static class MediaFoundationTransformCategories { [FieldDescription("Video Decoder")] public static readonly Guid VideoDecoder = new Guid("{d6c02d4b-6833-45b4-971a-05a4b04bab91}"); [FieldDescription("Video Encoder")] public static readonly Guid VideoEncoder = new Guid("{f79eac7d-e545-4387-bdee-d647d7bde42a}"); [FieldDescription("Video Effect")] public static readonly Guid VideoEffect = new Guid("{12e17c21-532c-4a6e-8a1c-40825a736397}"); [FieldDescription("Multiplexer")] public static readonly Guid Multiplexer = new Guid("{059c561e-05ae-4b61-b69d-55b61ee54a7b}"); [FieldDescription("Demultiplexer")] public static readonly Guid Demultiplexer = new Guid("{a8700a7a-939b-44c5-99d7-76226b23b3f1}"); [FieldDescription("Audio Decoder")] public static readonly Guid AudioDecoder = new Guid("{9ea73fb4-ef7a-4559-8d5d-719d8f0426c7}"); [FieldDescription("Audio Encoder")] public static readonly Guid AudioEncoder = new Guid("{91c64bd0-f91e-4d8c-9276-db248279d975}"); [FieldDescription("Audio Effect")] public static readonly Guid AudioEffect = new Guid("{11064c48-3648-4ed0-932e-05ce8ac811b7}"); [FieldDescription("Video Processor")] public static readonly Guid VideoProcessor = new Guid("{302EA3FC-AA5F-47f9-9F7A-C2188BB16302}"); [FieldDescription("Other")] public static readonly Guid Other = new Guid("{90175d57-b7ea-4901-aeb3-933a8747756f}"); } public class MediaType { private readonly IMFMediaType mediaType; public int SampleRate { get { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_SAMPLES_PER_SECOND); } set { //IL_0007: Unknown result type (might be due to invalid IL or missing references) mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_SAMPLES_PER_SECOND, value); } } public int ChannelCount { get { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_NUM_CHANNELS); } set { //IL_0007: Unknown result type (might be due to invalid IL or missing references) mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_NUM_CHANNELS, value); } } public int BitsPerSample { get { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_BITS_PER_SAMPLE); } set { //IL_0007: Unknown result type (might be due to invalid IL or missing references) mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_BITS_PER_SAMPLE, value); } } public int AverageBytesPerSecond => GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_AVG_BYTES_PER_SECOND); public Guid SubType { get { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) return GetGuid(MediaFoundationAttributes.MF_MT_SUBTYPE); } set { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) mediaType.SetGUID(MediaFoundationAttributes.MF_MT_SUBTYPE, value); } } public Guid MajorType { get { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) return GetGuid(MediaFoundationAttributes.MF_MT_MAJOR_TYPE); } set { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) mediaType.SetGUID(MediaFoundationAttributes.MF_MT_MAJOR_TYPE, value); } } public IMFMediaType MediaFoundationObject => mediaType; public MediaType(IMFMediaType mediaType) { this.mediaType = mediaType; } public MediaType() { mediaType = MediaFoundationApi.CreateMediaType(); } public MediaType(WaveFormat waveFormat) { mediaType = MediaFoundationApi.CreateMediaTypeFromWaveFormat(waveFormat); } private int GetUInt32(Guid key) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) mediaType.GetUINT32(key, out var punValue); return punValue; } private Guid GetGuid(Guid key) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) mediaType.GetGUID(key, out var pguidValue); return pguidValue; } public int TryGetUInt32(Guid key, int defaultValue = -1) { //IL_0017: Expected O, but got Unknown //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) int punValue = defaultValue; try { mediaType.GetUINT32(key, out punValue); } catch (COMException val) { COMException val2 = val; if (HResult.GetHResult(val2) != -1072875802) { if (HResult.GetHResult(val2) == -1072875843) { throw new ArgumentException("Not a UINT32 parameter"); } throw; } } return punValue; } public void SetUInt32(Guid key, int value) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) mediaType.SetUINT32(key, value); } } public static class MediaTypes { public static readonly Guid MFMediaType_Default = new Guid("81A412E6-8103-4B06-857F-1862781024AC"); [FieldDescription("Audio")] public static readonly Guid MFMediaType_Audio = new Guid("73647561-0000-0010-8000-00aa00389b71"); [FieldDescription("Video")] public static readonly Guid MFMediaType_Video = new Guid("73646976-0000-0010-8000-00aa00389b71"); [FieldDescription("Protected Media")] public static readonly Guid MFMediaType_Protected = new Guid("7b4b6fe6-9d04-4494-be14-7e0bd076c8e4"); [FieldDescription("SAMI captions")] public static readonly Guid MFMediaType_SAMI = new Guid("e69669a0-3dcd-40cb-9e2e-3708387c0616"); [FieldDescription("Script stream")] public static readonly Guid MFMediaType_Script = new Guid("72178c22-e45b-11d5-bc2a-00b0d0f3f4ab"); [FieldDescription("Still image stream")] public static readonly Guid MFMediaType_Image = new Guid("72178c23-e45b-11d5-bc2a-00b0d0f3f4ab"); [FieldDescription("HTML stream")] public static readonly Guid MFMediaType_HTML = new Guid("72178c24-e45b-11d5-bc2a-00b0d0f3f4ab"); [FieldDescription("Binary stream")] public static readonly Guid MFMediaType_Binary = new Guid("72178c25-e45b-11d5-bc2a-00b0d0f3f4ab"); [FieldDescription("File transfer")] public static readonly Guid MFMediaType_FileTransfer = new Guid("72178c26-e45b-11d5-bc2a-00b0d0f3f4ab"); } public struct MFT_INPUT_STREAM_INFO { public long hnsMaxLatency; public _MFT_INPUT_STREAM_INFO_FLAGS dwFlags; public int cbSize; public int cbMaxLookahead; public int cbAlignment; } public enum MFT_MESSAGE_TYPE { MFT_MESSAGE_COMMAND_FLUSH = 0, MFT_MESSAGE_COMMAND_DRAIN = 1, MFT_MESSAGE_SET_D3D_MANAGER = 2, MFT_MESSAGE_DROP_SAMPLES = 3, MFT_MESSAGE_COMMAND_TICK = 4, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING = 268435456, MFT_MESSAGE_NOTIFY_END_STREAMING = 268435457, MFT_MESSAGE_NOTIFY_END_OF_STREAM = 268435458, MFT_MESSAGE_NOTIFY_START_OF_STREAM = 268435459, MFT_MESSAGE_COMMAND_MARKER = 536870912 } public struct MFT_OUTPUT_DATA_BUFFER { public int dwStreamID; public IMFSample pSample; public _MFT_OUTPUT_DATA_BUFFER_FLAGS dwStatus; public IMFCollection pEvents; } public struct MFT_OUTPUT_STREAM_INFO { public _MFT_OUTPUT_STREAM_INFO_FLAGS dwFlags; public int cbSize; public int cbAlignment; } [StructLayout(0)] public class MFT_REGISTER_TYPE_INFO { public Guid guidMajorType; public Guid guidSubtype; } [StructLayout(0)] public class MF_SINK_WRITER_STATISTICS { public int cb; public long llLastTimestampReceived; public long llLastTimestampEncoded; public long llLastTimestampProcessed; public long llLastStreamTickReceived; public long llLastSinkSampleRequest; public long qwNumSamplesReceived; public long qwNumSamplesEncoded; public long qwNumSamplesProcessed; public long qwNumStreamTicksReceived; public int dwByteCountQueued; public long qwByteCountProcessed; public int dwNumOutstandingSinkSampleRequests; public int dwAverageSampleRateReceived; public int dwAverageSampleRateEncoded; public int dwAverageSampleRateProcessed; } public static class TranscodeContainerTypes { public static readonly Guid MFTranscodeContainerType_ASF = new Guid(1125085038u, (ushort)46783, (ushort)20417, (byte)160, (byte)189, (byte)158, (byte)228, (byte)110, (byte)238, (byte)42, (byte)251); public static readonly Guid MFTranscodeContainerType_MPEG4 = new Guid(3698118749u, (ushort)47568, (ushort)16623, (byte)189, (byte)53, (byte)250, (byte)98, (byte)44, (byte)26, (byte)178, (byte)138); public static readonly Guid MFTranscodeContainerType_MP3 = new Guid(3828922642u, (ushort)33777, (ushort)19942, (byte)158, (byte)58, (byte)159, (byte)251, (byte)198, (byte)221, (byte)36, (byte)209); public static readonly Guid MFTranscodeContainerType_3GP = new Guid(885326183, (short)17522, (short)20276, (byte)158, (byte)160, (byte)196, (byte)159, (byte)186, (byte)207, (byte)3, (byte)125); public static readonly Guid MFTranscodeContainerType_AC3 = new Guid(1837994435u, (ushort)35985, (ushort)20177, (byte)135, (byte)66, (byte)140, (byte)52, (byte)125, (byte)91, (byte)68, (byte)208); public static readonly Guid MFTranscodeContainerType_ADTS = new Guid(321901181, (short)3842, (short)17374, (byte)163, (byte)1, (byte)56, (byte)251, (byte)187, (byte)179, (byte)131, (byte)78); public static readonly Guid MFTranscodeContainerType_MPEG2 = new Guid(3217218553u, (ushort)31668, (ushort)20367, (byte)175, (byte)222, (byte)225, (byte)18, (byte)196, (byte)75, (byte)168, (byte)130); public static readonly Guid MFTranscodeContainerType_FMPEG4 = new Guid(2611508977u, (ushort)16799, (ushort)19319, (byte)161, (byte)224, (byte)53, (byte)149, (byte)157, (byte)157, (byte)64, (byte)4); public static readonly Guid MFTranscodeContainerType_WAVE = new Guid(1690518844, (short)3878, (short)18241, (byte)190, (byte)99, (byte)135, (byte)189, (byte)248, (byte)187, (byte)147, (byte)91); public static readonly Guid MFTranscodeContainerType_AVI = new Guid(2128603311, (short)16431, (short)19830, (byte)163, (byte)60, (byte)97, (byte)159, (byte)209, (byte)87, (byte)208, (byte)241); public static readonly Guid MFTranscodeContainerType_AMR = new Guid(39672531, (short)25114, (short)18267, (byte)150, (byte)77, (byte)102, (byte)177, (byte)200, (byte)36, (byte)240, (byte)121); } [Flags] public enum _MFT_ENUM_FLAG { None = 0, MFT_ENUM_FLAG_SYNCMFT = 1, MFT_ENUM_FLAG_ASYNCMFT = 2, MFT_ENUM_FLAG_HARDWARE = 4, MFT_ENUM_FLAG_FIELDOFUSE = 8, MFT_ENUM_FLAG_LOCALMFT = 0x10, MFT_ENUM_FLAG_TRANSCODE_ONLY = 0x20, MFT_ENUM_FLAG_SORTANDFILTER = 0x40, MFT_ENUM_FLAG_ALL = 0x3F } [Flags] public enum _MFT_INPUT_STATUS_FLAGS { None = 0, MFT_INPUT_STATUS_ACCEPT_DATA = 1 } [Flags] public enum _MFT_INPUT_STREAM_INFO_FLAGS { None = 0, MFT_INPUT_STREAM_WHOLE_SAMPLES = 1, MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER = 2, MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE = 4, MFT_INPUT_STREAM_HOLDS_BUFFERS = 8, MFT_INPUT_STREAM_DOES_NOT_ADDREF = 0x100, MFT_INPUT_STREAM_REMOVABLE = 0x200, MFT_INPUT_STREAM_OPTIONAL = 0x400, MFT_INPUT_STREAM_PROCESSES_IN_PLACE = 0x800 } [Flags] public enum _MFT_OUTPUT_DATA_BUFFER_FLAGS { None = 0, MFT_OUTPUT_DATA_BUFFER_INCOMPLETE = 0x1000000, MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE = 0x100, MFT_OUTPUT_DATA_BUFFER_STREAM_END = 0x200, MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE = 0x300 } [Flags] public enum _MFT_OUTPUT_STATUS_FLAGS { None = 0, MFT_OUTPUT_STATUS_SAMPLE_READY = 1 } [Flags] public enum _MFT_OUTPUT_STREAM_INFO_FLAGS { None = 0, MFT_OUTPUT_STREAM_WHOLE_SAMPLES = 1, MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER = 2, MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE = 4, MFT_OUTPUT_STREAM_DISCARDABLE = 8, MFT_OUTPUT_STREAM_OPTIONAL = 0x10, MFT_OUTPUT_STREAM_PROVIDES_SAMPLES = 0x100, MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES = 0x200, MFT_OUTPUT_STREAM_LAZY_READ = 0x400, MFT_OUTPUT_STREAM_REMOVABLE = 0x800 } [Flags] public enum _MFT_PROCESS_OUTPUT_FLAGS { None = 0, MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER = 1, MFT_PROCESS_OUTPUT_REGENERATE_LAST_OUTPUT = 2 } [Flags] public enum _MFT_PROCESS_OUTPUT_STATUS { None = 0, MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS = 0x100 } [Flags] public enum _MFT_SET_TYPE_FLAGS { None = 0, MFT_SET_TYPE_TEST_ONLY = 1 } } namespace NAudio.Dmo { public class DmoDescriptor { [field: CompilerGenerated] [field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)] public string Name { [CompilerGenerated] get; [CompilerGenerated] private set; } [field: CompilerGenerated] [field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)] public Guid Clsid { [CompilerGenerated] get; [CompilerGenerated] private set; } public DmoDescriptor(string name, Guid clsid) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Name = name; Clsid = clsid; } } public class DmoEnumerator { [CompilerGenerated] private sealed class <GetDmos>d__3 : global::System.Collections.Generic.IEnumerable<DmoDescriptor>, global::System.Collections.IEnumerable, global::System.Collections.Generic.IEnumerator<DmoDescriptor>, global::System.Collections.IEnumerator, global::System.IDisposable { private int <>1__state; private DmoDescriptor <>2__current; private int <>l__initialThreadId; private Guid category; public Guid <>3__category; private IEnumDmo <enumDmo>5__1; private int <hresult>5__2; private int <itemsFetched>5__3; private Guid <guid>5__4; private global::System.IntPtr <namePointer>5__5; private string <name>5__6; DmoDescriptor global::System.Collections.Generic.IEnumerator<DmoDescriptor>.Current { [DebuggerHidden] get { return <>2__current; } } object global::System.Collections.IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetDmos>d__3(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void global::System.IDisposable.Dispose() { <enumDmo>5__1 = null; <name>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_009e: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <name>5__6 = null; goto IL_00c5; } <>1__state = -1; <hresult>5__2 = DmoInterop.DMOEnum(ref category, DmoEnumFlags.None, 0, null, 0, null, out <enumDmo>5__1); Marshal.ThrowExceptionForHR(<hresult>5__2); goto IL_004b; IL_00c5: if (<itemsFetched>5__3 <= 0) { return false; } goto IL_004b; IL_004b: <enumDmo>5__1.Next(1, out <guid>5__4, out <namePointer>5__5, out <itemsFetched>5__3); if (<itemsFetched>5__3 == 1) { <name>5__6 = Marshal.PtrToStringUni(<namePointer>5__5); Marshal.FreeCoTaskMem(<namePointer>5__5); <>2__current = new DmoDescriptor(<name>5__6, <guid>5__4); <>1__state = 1; return true; } goto IL_00c5; } bool global::System.Collections.IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void global::System.Collections.IEnumerator.Reset() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) throw new NotSupportedException(); } [DebuggerHidden] global::System.Collections.Generic.IEnumerator<DmoDescriptor> global::System.Collections.Generic.IEnumerable<DmoDescriptor>.GetEnumerator() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) <GetDmos>d__3 <GetDmos>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetDmos>d__ = this; } else { <GetDmos>d__ = new <GetDmos>d__3(0); } <GetDmos>d__.category = <>3__category; return <GetDmos>d__; } [DebuggerHidden] global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() { return (global::System.Collections.IEnumerator)((global::System.Collections.Generic.IEnumerable<DmoDescriptor>)this).GetEnumerator(); } } public static global::System.Collections.Generic.IEnumerable<DmoDescriptor> GetAudioEffectNames() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_EFFECT); } public static global::System.Collections.Generic.IEnumerable<DmoDescriptor> GetAudioEncoderNames() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_ENCODER); } public static global::System.Collections.Generic.IEnumerable<DmoDescriptor> GetAudioDecoderNames() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_DECODER); } [IteratorStateMachine(typeof(<GetDmos>d__3))] private static global::System.Collections.Generic.IEnumerable<DmoDescriptor> GetDmos(Guid category) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetDmos>d__3(-2) { <>3__category = category }; } } [Flags] internal enum DmoEnumFlags { None = 0, DMO_ENUMF_INCLUDE_KEYED = 1 } internal static class DmoGuids { public static readonly Guid DMOCATEGORY_AUDIO_DECODER = new Guid("57f2db8b-e6bb-4513-9d43-dcd2a6593125"); public static readonly Guid DMOCATEGORY_AUDIO_ENCODER = new Guid("33D9A761-90C8-11d0-BD43-00A0C911CE86"); public static readonly Guid DMOCATEGORY_VIDEO_DECODER = new Guid("4a69b442-28be-4991-969c-b500adf5d8a8"); public static readonly Guid DMOCATEGORY_VIDEO_ENCODER = new Guid("33D9A760-90C8-11d0-BD43-00A0C911CE86"); public static readonly Guid DMOCATEGORY_AUDIO_EFFECT = new Guid("f3602b3f-0592-48df-a4cd-674721e7ebeb"); public static readonly Guid DMOCATEGORY_VIDEO_EFFECT = new Guid("d990ee14-776c-4723-be46-3da2f56f10b9"); public static readonly Guid DMOCATEGORY_AUDIO_CAPTURE_EFFECT = new Guid("f665aaba-3e09-4920-aa5f-219811148f09"); } internal static class DmoMediaTypeGuids { public static readonly Guid FORMAT_None = new Guid("0F6417D6-C318-11D0-A43F-00A0C9223196"); public static readonly Guid FORMAT_VideoInfo = new Guid("05589f80-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_VideoInfo2 = new Guid("F72A76A0-EB0A-11d0-ACE4-0000C0CC16BA"); public static readonly Guid FORMAT_WaveFormatEx = new Guid("05589f81-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_MPEGVideo = new Guid("05589f82-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_MPEGStreams = new Guid("05589f83-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_DvInfo = new Guid("05589f84-c356-11ce-bf01-00aa0055595a"); public static readonly Guid FORMAT_525WSS = new Guid("C7ECF04D-4582-4869-9ABB-BFB523B62EDF"); } internal enum DmoHResults { DMO_E_INVALIDSTREAMINDEX = -2147220991, DMO_E_INVALIDTYPE, DMO_E_TYPE_NOT_SET, DMO_E_NOTACCEPTING, DMO_E_TYPE_NOT_ACCEPTED, DMO_E_NO_MORE_ITEMS } [Flags] public enum DmoInPlaceProcessFlags { Normal = 0, Zero = 1 } public enum DmoInPlaceProcessReturn { Normal, HasEffectTail } [Flags] public enum DmoInputDataBufferFlags { None = 0, SyncPoint = 1, Time = 2, TimeLength = 4 } [Flags] internal enum DmoInputStatusFlags { None = 0, DMO_INPUT_STATUSF_ACCEPT_DATA = 1 } internal static class DmoInterop { [DllImport("msdmo.dll")] public static extern int DMOEnum([In] ref Guid guidCategory, DmoEnumFlags flags, int inTypes, [In] DmoPartialMediaType[] inTypesArray, int outTypes, [In] DmoPartialMediaType[] outTypesArray, out IEnumDmo enumDmo); [DllImport("msdmo.dll")] public static extern int MoFreeMediaType([In] ref DmoMediaType mediaType); [DllImport("msdmo.dll")] public static extern int MoInitMediaType([In][Out] ref DmoMediaType mediaType, int formatBlockBytes); [DllImport("msdmo.dll")] public static extern int DMOGetName([In] ref Guid clsidDMO, [Out] StringBuilder name); } public struct DmoMediaType { private Guid majortype; private Guid subtype; private bool bFixedSizeSamples; private bool bTemporalCompression; private int lSampleSize; private Guid formattype; private global::System.IntPtr pUnk; private int cbFormat; private global::System.IntPtr pbFormat; public Guid MajorType => majortype; public string MajorTypeName => MediaTypes.GetMediaTypeName(majortype); public Guid SubType => subtype; public string SubTypeName { get { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (majortype == MediaTypes.MEDIATYPE_Audio) { return AudioMediaSubtypes.GetAudioSubtypeName(subtype); } return ((object)(Guid)(ref subtype)).ToString(); } } public bool FixedSizeSamples => bFixedSizeSamples; public int SampleSize => lSampleSize; public Guid FormatType => formattype; public string FormatTypeName { get { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (formattype == DmoMediaTypeGuids.FORMAT_None) { return "None"; } if (formattype == Guid.Empty) { return "Null"; } if (formattype == DmoMediaTypeGuids.FORMAT_WaveFormatEx) { return "WaveFormatEx"; } Guid formatType = FormatType; return ((object)(Guid)(ref formatType)).ToString(); } } public WaveFormat GetWaveFormat() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (formattype == DmoMediaTypeGuids.FORMAT_WaveFormatEx) { return WaveFormat.MarshalFromPtr(pbFormat); } throw new InvalidOperationException("Not a WaveFormat type"); } public void SetWaveFormat(WaveFormat waveFormat) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) majortype = MediaTypes.MEDIATYPE_Audio; WaveFormatExtensible val = (WaveFormatExtensible)(object)((waveFormat is WaveFormatExtensible) ? waveFormat : null); if (val != null) { subtype = val.SubFormat; } else { WaveFormatEncoding encoding = waveFormat.Encoding; WaveFormatEncoding val2 = encoding; if ((int)val2 != 1) { if ((int)val2 != 3) { if ((int)val2 != 85) { throw new ArgumentException($"Not a supported encoding {waveFormat.Encoding}"); } subtype = AudioMediaSubtypes.WMMEDIASUBTYPE_MP3; } else { subtype = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT; } } else { subtype = AudioMediaSubtypes.MEDIASUBTYPE_PCM; } } bFixedSizeSamples = SubType == AudioMediaSubtypes.MEDIASUBTYPE_PCM || SubType == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT; formattype = DmoMediaTypeGuids.FORMAT_WaveFormatEx; if (cbFormat < Marshal.SizeOf<WaveFormat>(waveFormat)) { throw new InvalidOperationException("Not enough memory assigned for a WaveFormat structure"); } Marshal.StructureToPtr<WaveFormat>(waveFormat, pbFormat, false); } } [StructLayout(0, Pack = 8)] public struct DmoOutputDataBuffer : global::System.IDisposable { [MarshalAs(28)] private IMediaBuffer pBuffer; private DmoOutputDataBufferFlags dwStatus; private long rtTimestamp; private long referenceTimeDuration; public IMediaBuffer MediaBuffer { get { return pBuffer; } internal set { pBuffer = value; } } public int Length => ((MediaBuffer)pBuffer).Length; public DmoOutputDataBufferFlags StatusFlags { get { return dwStatus; } internal set { dwStatus = value; } } public long Timestamp { get { return rtTimestamp; } internal set { rtTimestamp = value; } } public long Duration { get { return referenceTimeDuration; } internal set { referenceTimeDuration = value; } } public bool MoreDataAvailable => (StatusFlags & DmoOutputDataBufferFlags.Incomplete) == DmoOutputDataBufferFlags.Incomplete; public DmoOutputDataBuffer(int maxBufferSize) { pBuffer = new MediaBuffer(maxBufferSize); dwStatus = DmoOutputDataBufferFlags.None; rtTime
NAudio.WinMM.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
#define DEBUG using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading; using Microsoft.Win32; using NAudio.CoreAudioApi; using NAudio.Mixer; using NAudio.Utils; using NAudio.Wave.Compression; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("NAudio.WinMM")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("© Mark Heath 2023")] [assembly: AssemblyFileVersion("2.2.1.0")] [assembly: AssemblyInformationalVersion("2.2.1")] [assembly: AssemblyProduct("NAudio.WinMM")] [assembly: AssemblyTitle("NAudio.WinMM")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")] [assembly: AssemblyVersion("2.2.1.0")] namespace NAudio.Mixer { public class BooleanMixerControl : MixerControl { private MixerInterop.MIXERCONTROLDETAILS_BOOLEAN boolDetails; public bool Value { get { GetControlDetails(); return boolDetails.fValue == 1; } set { //IL_005a: Unknown result type (might be due to invalid IL or missing references) boolDetails.fValue = (value ? 1 : 0); mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf(boolDetails)); Marshal.StructureToPtr(boolDetails, mixerControlDetails.paDetails, fDeleteOld: false); MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails"); Marshal.FreeHGlobal(mixerControlDetails.paDetails); } } internal BooleanMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { boolDetails = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_BOOLEAN>(pDetails); } } public class CustomMixerControl : MixerControl { internal CustomMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { } } public class ListTextMixerControl : MixerControl { internal ListTextMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { } } public class Mixer { [CompilerGenerated] private sealed class <get_Destinations>d__16 : IEnumerable<MixerLine>, IEnumerable, IEnumerator<MixerLine>, IEnumerator, IDisposable { private int <>1__state; private MixerLine <>2__current; private int <>l__initialThreadId; public Mixer <>4__this; private int <destination>5__1; MixerLine IEnumerator<MixerLine>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <get_Destinations>d__16(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <destination>5__1 = 0; break; case 1: <>1__state = -1; <destination>5__1++; break; } if (<destination>5__1 < <>4__this.DestinationCount) { <>2__current = <>4__this.GetDestination(<destination>5__1); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<MixerLine> IEnumerable<MixerLine>.GetEnumerator() { <get_Destinations>d__16 result; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; result = this; } else { result = new <get_Destinations>d__16(0) { <>4__this = <>4__this }; } return result; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<MixerLine>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <get_Mixers>d__18 : IEnumerable<Mixer>, IEnumerable, IEnumerator<Mixer>, IEnumerator, IDisposable { private int <>1__state; private Mixer <>2__current; private int <>l__initialThreadId; private int <device>5__1; Mixer IEnumerator<Mixer>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <get_Mixers>d__18(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <device>5__1 = 0; break; case 1: <>1__state = -1; <device>5__1++; break; } if (<device>5__1 < NumberOfDevices) { <>2__current = new Mixer(<device>5__1); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<Mixer> IEnumerable<Mixer>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <get_Mixers>d__18(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<Mixer>)this).GetEnumerator(); } } private MixerInterop.MIXERCAPS caps; private IntPtr mixerHandle; private MixerFlags mixerHandleType; public static int NumberOfDevices => MixerInterop.mixerGetNumDevs(); public int DestinationCount => (int)caps.cDestinations; public string Name => caps.szPname; public Manufacturers Manufacturer => (Manufacturers)caps.wMid; public int ProductID => caps.wPid; public IEnumerable<MixerLine> Destinations { [IteratorStateMachine(typeof(<get_Destinations>d__16))] get { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() <get_Destinations>d__16 <get_Destinations>d__ = new <get_Destinations>d__16(-2); <get_Destinations>d__.<>4__this = this; return <get_Destinations>d__; } } public static IEnumerable<Mixer> Mixers { [IteratorStateMachine(typeof(<get_Mixers>d__18))] get { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <get_Mixers>d__18(-2); } } public Mixer(int mixerIndex) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (mixerIndex < 0 || mixerIndex >= NumberOfDevices) { throw new ArgumentOutOfRangeException("mixerID"); } caps = default(MixerInterop.MIXERCAPS); MmException.Try(MixerInterop.mixerGetDevCaps((IntPtr)mixerIndex, ref caps, Marshal.SizeOf(caps)), "mixerGetDevCaps"); mixerHandle = (IntPtr)mixerIndex; mixerHandleType = MixerFlags.Mixer; } public MixerLine GetDestination(int destinationIndex) { if (destinationIndex < 0 || destinationIndex >= DestinationCount) { throw new ArgumentOutOfRangeException("destinationIndex"); } return new MixerLine(mixerHandle, destinationIndex, mixerHandleType); } } public abstract class MixerControl { internal MixerInterop.MIXERCONTROL mixerControl; internal MixerInterop.MIXERCONTROLDETAILS mixerControlDetails; protected IntPtr mixerHandle; protected int nChannels; protected MixerFlags mixerHandleType; public string Name => mixerControl.szName; public MixerControlType ControlType => mixerControl.dwControlType; public bool IsBoolean => IsControlBoolean(mixerControl.dwControlType); public bool IsListText => IsControlListText(mixerControl.dwControlType); public bool IsSigned => IsControlSigned(mixerControl.dwControlType); public bool IsUnsigned => IsControlUnsigned(mixerControl.dwControlType); public bool IsCustom => IsControlCustom(mixerControl.dwControlType); public static IList<MixerControl> GetMixerControls(IntPtr mixerHandle, MixerLine mixerLine, MixerFlags mixerHandleType) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) List<MixerControl> list = new List<MixerControl>(); if (mixerLine.ControlsCount > 0) { int num = Marshal.SizeOf<MixerInterop.MIXERCONTROL>(); MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS); IntPtr intPtr = Marshal.AllocHGlobal(num * mixerLine.ControlsCount); mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls); mixerLineControls.dwLineID = mixerLine.LineId; mixerLineControls.cControls = mixerLine.ControlsCount; mixerLineControls.pamxctrl = intPtr; mixerLineControls.cbmxctrl = Marshal.SizeOf<MixerInterop.MIXERCONTROL>(); try { MmResult val = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.Mixer | mixerHandleType); if ((int)val > 0) { throw new MmException(val, "mixerGetLineControls"); } for (int i = 0; i < mixerLineControls.cControls; i++) { long num2 = intPtr.ToInt64() + num * i; MixerInterop.MIXERCONTROL mIXERCONTROL = Marshal.PtrToStructure<MixerInterop.MIXERCONTROL>((IntPtr)num2); MixerControl item = GetMixerControl(mixerHandle, mixerLine.LineId, mIXERCONTROL.dwControlID, mixerLine.Channels, mixerHandleType); list.Add(item); } } finally { Marshal.FreeHGlobal(intPtr); } } return list; } public static MixerControl GetMixerControl(IntPtr mixerHandle, int nLineId, int controlId, int nChannels, MixerFlags mixerFlags) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS); MixerInterop.MIXERCONTROL structure = default(MixerInterop.MIXERCONTROL); IntPtr intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure)); mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls); mixerLineControls.cControls = 1; mixerLineControls.dwControlID = controlId; mixerLineControls.cbmxctrl = Marshal.SizeOf(structure); mixerLineControls.pamxctrl = intPtr; mixerLineControls.dwLineID = nLineId; MmResult val = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.ListText | mixerFlags); if ((int)val > 0) { Marshal.FreeCoTaskMem(intPtr); throw new MmException(val, "mixerGetLineControls"); } structure = Marshal.PtrToStructure<MixerInterop.MIXERCONTROL>(mixerLineControls.pamxctrl); Marshal.FreeCoTaskMem(intPtr); if (IsControlBoolean(structure.dwControlType)) { return new BooleanMixerControl(structure, mixerHandle, mixerFlags, nChannels); } if (IsControlSigned(structure.dwControlType)) { return new SignedMixerControl(structure, mixerHandle, mixerFlags, nChannels); } if (IsControlUnsigned(structure.dwControlType)) { return new UnsignedMixerControl(structure, mixerHandle, mixerFlags, nChannels); } if (IsControlListText(structure.dwControlType)) { return new ListTextMixerControl(structure, mixerHandle, mixerFlags, nChannels); } if (IsControlCustom(structure.dwControlType)) { return new CustomMixerControl(structure, mixerHandle, mixerFlags, nChannels); } throw new InvalidOperationException($"Unknown mixer control type {structure.dwControlType}"); } protected void GetControlDetails() { //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Invalid comparison between Unknown and I4 //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Invalid comparison between Unknown and I4 //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) mixerControlDetails.cbStruct = Marshal.SizeOf(mixerControlDetails); mixerControlDetails.dwControlID = mixerControl.dwControlID; if (IsCustom) { mixerControlDetails.cChannels = 0; } else if ((mixerControl.fdwControl & (true ? 1u : 0u)) != 0) { mixerControlDetails.cChannels = 1; } else { mixerControlDetails.cChannels = nChannels; } if ((mixerControl.fdwControl & 2u) != 0) { mixerControlDetails.hwndOwner = (IntPtr)mixerControl.cMultipleItems; } else if (IsCustom) { mixerControlDetails.hwndOwner = IntPtr.Zero; } else { mixerControlDetails.hwndOwner = IntPtr.Zero; } if (IsBoolean) { mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_BOOLEAN>(); } else if (IsListText) { mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_LISTTEXT>(); } else if (IsSigned) { mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_SIGNED>(); } else if (IsUnsigned) { mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_UNSIGNED>(); } else { mixerControlDetails.cbDetails = mixerControl.Metrics.customData; } int num = mixerControlDetails.cbDetails * mixerControlDetails.cChannels; if ((mixerControl.fdwControl & 2u) != 0) { num *= (int)mixerControl.cMultipleItems; } IntPtr intPtr = Marshal.AllocCoTaskMem(num); mixerControlDetails.paDetails = intPtr; MmResult val = MixerInterop.mixerGetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType); if ((int)val == 0) { GetDetails(mixerControlDetails.paDetails); } Marshal.FreeCoTaskMem(intPtr); if ((int)val > 0) { throw new MmException(val, "mixerGetControlDetails"); } } protected abstract void GetDetails(IntPtr pDetails); private static bool IsControlBoolean(MixerControlType controlType) { switch (controlType) { case MixerControlType.BooleanMeter: case MixerControlType.Boolean: case MixerControlType.OnOff: case MixerControlType.Mute: case MixerControlType.Mono: case MixerControlType.Loudness: case MixerControlType.StereoEnhance: case MixerControlType.Button: case MixerControlType.SingleSelect: case MixerControlType.Mux: case MixerControlType.MultipleSelect: case MixerControlType.Mixer: return true; default: return false; } } private static bool IsControlListText(MixerControlType controlType) { if (controlType == MixerControlType.Equalizer || (uint)(controlType - 1879113728) <= 1u || (uint)(controlType - 1895890944) <= 1u) { return true; } return false; } private static bool IsControlSigned(MixerControlType controlType) { switch (controlType) { case MixerControlType.SignedMeter: case MixerControlType.PeakMeter: case MixerControlType.Signed: case MixerControlType.Decibels: case MixerControlType.Slider: case MixerControlType.Pan: case MixerControlType.QSoundPan: return true; default: return false; } } private static bool IsControlUnsigned(MixerControlType controlType) { switch (controlType) { case MixerControlType.UnsignedMeter: case MixerControlType.Unsigned: case MixerControlType.Percent: case MixerControlType.Fader: case MixerControlType.Volume: case MixerControlType.Bass: case MixerControlType.Treble: case MixerControlType.Equalizer: case MixerControlType.MicroTime: case MixerControlType.MilliTime: return true; default: return false; } } private static bool IsControlCustom(MixerControlType controlType) { return controlType == MixerControlType.Custom; } public override string ToString() { return $"{Name} {ControlType}"; } } [Flags] internal enum MixerControlClass { Custom = 0, Meter = 0x10000000, Switch = 0x20000000, Number = 0x30000000, Slider = 0x40000000, Fader = 0x50000000, Time = 0x60000000, List = 0x70000000, Mask = 0x70000000 } [Flags] internal enum MixerControlSubclass { SwitchBoolean = 0, SwitchButton = 0x1000000, MeterPolled = 0, TimeMicrosecs = 0, TimeMillisecs = 0x1000000, ListSingle = 0, ListMultiple = 0x1000000, Mask = 0xF000000 } [Flags] internal enum MixerControlUnits { Custom = 0, Boolean = 0x10000, Signed = 0x20000, Unsigned = 0x30000, Decibels = 0x40000, Percent = 0x50000, Mask = 0xFF0000 } public enum MixerControlType { Custom = 0, BooleanMeter = 268500992, SignedMeter = 268566528, PeakMeter = 268566529, UnsignedMeter = 268632064, Boolean = 536936448, OnOff = 536936449, Mute = 536936450, Mono = 536936451, Loudness = 536936452, StereoEnhance = 536936453, Button = 553713664, Decibels = 805568512, Signed = 805437440, Unsigned = 805502976, Percent = 805634048, Slider = 1073872896, Pan = 1073872897, QSoundPan = 1073872898, Fader = 1342373888, Volume = 1342373889, Bass = 1342373890, Treble = 1342373891, Equalizer = 1342373892, SingleSelect = 1879113728, Mux = 1879113729, MultipleSelect = 1895890944, Mixer = 1895890945, MicroTime = 1610809344, MilliTime = 1627586560 } [Flags] public enum MixerFlags { Handle = int.MinValue, Mixer = 0, MixerHandle = int.MinValue, WaveOut = 0x10000000, WaveOutHandle = -1879048192, WaveIn = 0x20000000, WaveInHandle = -1610612736, MidiOut = 0x30000000, MidiOutHandle = -1342177280, MidiIn = 0x40000000, MidiInHandle = -1073741824, Aux = 0x50000000, Value = 0, ListText = 1, QueryMask = 0xF, All = 0, OneById = 1, OneByType = 2, GetLineInfoOfDestination = 0, GetLineInfoOfSource = 1, GetLineInfoOfLineId = 2, GetLineInfoOfComponentType = 3, GetLineInfoOfTargetType = 4, GetLineInfoOfQueryMask = 0xF } internal class MixerInterop { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)] public struct MIXERCONTROLDETAILS { public int cbStruct; public int dwControlID; public int cChannels; public IntPtr hwndOwner; public int cbDetails; public IntPtr paDetails; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERCAPS { public ushort wMid; public ushort wPid; public uint vDriverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szPname; public uint fdwSupport; public uint cDestinations; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERLINECONTROLS { public int cbStruct; public int dwLineID; public int dwControlID; public int cControls; public int cbmxctrl; public IntPtr pamxctrl; } [Flags] public enum MIXERLINE_LINEF { MIXERLINE_LINEF_ACTIVE = 1, MIXERLINE_LINEF_DISCONNECTED = 0x8000, MIXERLINE_LINEF_SOURCE = int.MinValue } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERLINE { public int cbStruct; public int dwDestination; public int dwSource; public int dwLineID; public MIXERLINE_LINEF fdwLine; public IntPtr dwUser; public MixerLineComponentType dwComponentType; public int cChannels; public int cConnections; public int cControls; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string szShortName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szName; public uint dwType; public uint dwDeviceID; public ushort wMid; public ushort wPid; public uint vDriverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szPname; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct Bounds { public int minimum; public int maximum; public int reserved2; public int reserved3; public int reserved4; public int reserved5; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct Metrics { public int step; public int customData; public int reserved2; public int reserved3; public int reserved4; public int reserved5; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERCONTROL { public uint cbStruct; public int dwControlID; public MixerControlType dwControlType; public uint fdwControl; public uint cMultipleItems; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string szShortName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szName; public Bounds Bounds; public Metrics Metrics; } public struct MIXERCONTROLDETAILS_BOOLEAN { public int fValue; } public struct MIXERCONTROLDETAILS_SIGNED { public int lValue; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MIXERCONTROLDETAILS_LISTTEXT { public uint dwParam1; public uint dwParam2; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szName; } public struct MIXERCONTROLDETAILS_UNSIGNED { public uint dwValue; } public const uint MIXERCONTROL_CONTROLF_UNIFORM = 1u; public const uint MIXERCONTROL_CONTROLF_MULTIPLE = 2u; public const uint MIXERCONTROL_CONTROLF_DISABLED = 2147483648u; public const int MAXPNAMELEN = 32; public const int MIXER_SHORT_NAME_CHARS = 16; public const int MIXER_LONG_NAME_CHARS = 64; [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern int mixerGetNumDevs(); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerOpen(out IntPtr hMixer, int uMxId, IntPtr dwCallback, IntPtr dwInstance, MixerFlags dwOpenFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerClose(IntPtr hMixer); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetDevCaps(IntPtr nMixerID, ref MIXERCAPS mixerCaps, int mixerCapsSize); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetID(IntPtr hMixer, out int mixerID, MixerFlags dwMixerIDFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetLineControls(IntPtr hMixer, ref MIXERLINECONTROLS mixerLineControls, MixerFlags dwControlFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerGetLineInfo(IntPtr hMixer, ref MIXERLINE mixerLine, MixerFlags dwInfoFlags); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerMessage(IntPtr hMixer, uint nMessage, IntPtr dwParam1, IntPtr dwParam2); [DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern MmResult mixerSetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags); } public class MixerLine { [CompilerGenerated] private sealed class <get_Sources>d__32 : IEnumerable<MixerLine>, IEnumerable, IEnumerator<MixerLine>, IEnumerator, IDisposable { private int <>1__state; private MixerLine <>2__current; private int <>l__initialThreadId; public MixerLine <>4__this; private int <source>5__1; MixerLine IEnumerator<MixerLine>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <get_Sources>d__32(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <source>5__1 = 0; break; case 1: <>1__state = -1; <source>5__1++; break; } if (<source>5__1 < <>4__this.SourceCount) { <>2__current = <>4__this.GetSource(<source>5__1); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<MixerLine> IEnumerable<MixerLine>.GetEnumerator() { <get_Sources>d__32 result; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; result = this; } else { result = new <get_Sources>d__32(0) { <>4__this = <>4__this }; } return result; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<MixerLine>)this).GetEnumerator(); } } private MixerInterop.MIXERLINE mixerLine; private IntPtr mixerHandle; private MixerFlags mixerHandleType; public string Name => mixerLine.szName; public string ShortName => mixerLine.szShortName; public int LineId => mixerLine.dwLineID; public MixerLineComponentType ComponentType => mixerLine.dwComponentType; public string TypeDescription => mixerLine.dwComponentType switch { MixerLineComponentType.DestinationUndefined => "Undefined Destination", MixerLineComponentType.DestinationDigital => "Digital Destination", MixerLineComponentType.DestinationLine => "Line Level Destination", MixerLineComponentType.DestinationMonitor => "Monitor Destination", MixerLineComponentType.DestinationSpeakers => "Speakers Destination", MixerLineComponentType.DestinationHeadphones => "Headphones Destination", MixerLineComponentType.DestinationTelephone => "Telephone Destination", MixerLineComponentType.DestinationWaveIn => "Wave Input Destination", MixerLineComponentType.DestinationVoiceIn => "Voice Recognition Destination", MixerLineComponentType.SourceUndefined => "Undefined Source", MixerLineComponentType.SourceDigital => "Digital Source", MixerLineComponentType.SourceLine => "Line Level Source", MixerLineComponentType.SourceMicrophone => "Microphone Source", MixerLineComponentType.SourceSynthesizer => "Synthesizer Source", MixerLineComponentType.SourceCompactDisc => "Compact Disk Source", MixerLineComponentType.SourceTelephone => "Telephone Source", MixerLineComponentType.SourcePcSpeaker => "PC Speaker Source", MixerLineComponentType.SourceWaveOut => "Wave Out Source", MixerLineComponentType.SourceAuxiliary => "Auxiliary Source", MixerLineComponentType.SourceAnalog => "Analog Source", _ => "Invalid Component Type", }; public int Channels => mixerLine.cChannels; public int SourceCount => mixerLine.cConnections; public int ControlsCount => mixerLine.cControls; public bool IsActive => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_ACTIVE) != 0; public bool IsDisconnected => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_DISCONNECTED) != 0; public bool IsSource => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_SOURCE) != 0; public IEnumerable<MixerControl> Controls => MixerControl.GetMixerControls(mixerHandle, this, mixerHandleType); public IEnumerable<MixerLine> Sources { [IteratorStateMachine(typeof(<get_Sources>d__32))] get { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() <get_Sources>d__32 <get_Sources>d__ = new <get_Sources>d__32(-2); <get_Sources>d__.<>4__this = this; return <get_Sources>d__; } } public string TargetName => mixerLine.szPname; public MixerLine(IntPtr mixerHandle, int destinationIndex, MixerFlags mixerHandleType) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) this.mixerHandle = mixerHandle; this.mixerHandleType = mixerHandleType; mixerLine = default(MixerInterop.MIXERLINE); mixerLine.cbStruct = Marshal.SizeOf(mixerLine); mixerLine.dwDestination = destinationIndex; MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.Mixer), "mixerGetLineInfo"); } public MixerLine(IntPtr mixerHandle, int destinationIndex, int sourceIndex, MixerFlags mixerHandleType) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) this.mixerHandle = mixerHandle; this.mixerHandleType = mixerHandleType; mixerLine = default(MixerInterop.MIXERLINE); mixerLine.cbStruct = Marshal.SizeOf(mixerLine); mixerLine.dwDestination = destinationIndex; mixerLine.dwSource = sourceIndex; MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.ListText), "mixerGetLineInfo"); } public static int GetMixerIdForWaveIn(int waveInDevice) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) int mixerID = -1; MmException.Try(MixerInterop.mixerGetID((IntPtr)waveInDevice, out mixerID, MixerFlags.WaveIn), "mixerGetID"); return mixerID; } public MixerLine GetSource(int sourceIndex) { if (sourceIndex < 0 || sourceIndex >= SourceCount) { throw new ArgumentOutOfRangeException("sourceIndex"); } return new MixerLine(mixerHandle, mixerLine.dwDestination, sourceIndex, mixerHandleType); } public override string ToString() { return $"{Name} {TypeDescription} ({ControlsCount} controls, ID={mixerLine.dwLineID})"; } } public enum MixerLineComponentType { DestinationUndefined = 0, DestinationDigital = 1, DestinationLine = 2, DestinationMonitor = 3, DestinationSpeakers = 4, DestinationHeadphones = 5, DestinationTelephone = 6, DestinationWaveIn = 7, DestinationVoiceIn = 8, SourceUndefined = 4096, SourceDigital = 4097, SourceLine = 4098, SourceMicrophone = 4099, SourceSynthesizer = 4100, SourceCompactDisc = 4101, SourceTelephone = 4102, SourcePcSpeaker = 4103, SourceWaveOut = 4104, SourceAuxiliary = 4105, SourceAnalog = 4106 } public class SignedMixerControl : MixerControl { private MixerInterop.MIXERCONTROLDETAILS_SIGNED signedDetails; public int Value { get { GetControlDetails(); return signedDetails.lValue; } set { //IL_0054: Unknown result type (might be due to invalid IL or missing references) signedDetails.lValue = value; mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf(signedDetails)); Marshal.StructureToPtr(signedDetails, mixerControlDetails.paDetails, fDeleteOld: false); MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails"); Marshal.FreeHGlobal(mixerControlDetails.paDetails); } } public int MinValue => mixerControl.Bounds.minimum; public int MaxValue => mixerControl.Bounds.maximum; public double Percent { get { return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue); } set { Value = (int)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue)); } } internal SignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { signedDetails = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_SIGNED>(mixerControlDetails.paDetails); } public override string ToString() { return $"{base.ToString()} {Percent}%"; } } public class UnsignedMixerControl : MixerControl { private MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[] unsignedDetails; public uint Value { get { GetControlDetails(); return unsignedDetails[0].dwValue; } set { //IL_0097: Unknown result type (might be due to invalid IL or missing references) int num = Marshal.SizeOf(unsignedDetails[0]); mixerControlDetails.paDetails = Marshal.AllocHGlobal(num * nChannels); for (int i = 0; i < nChannels; i++) { unsignedDetails[i].dwValue = value; long num2 = mixerControlDetails.paDetails.ToInt64() + num * i; Marshal.StructureToPtr(unsignedDetails[i], (IntPtr)num2, fDeleteOld: false); } MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails"); Marshal.FreeHGlobal(mixerControlDetails.paDetails); } } public uint MinValue => (uint)mixerControl.Bounds.minimum; public uint MaxValue => (uint)mixerControl.Bounds.maximum; public double Percent { get { return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue); } set { Value = (uint)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue)); } } internal UnsignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels) { base.mixerControl = mixerControl; base.mixerHandle = mixerHandle; base.mixerHandleType = mixerHandleType; base.nChannels = nChannels; mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS); GetControlDetails(); } protected override void GetDetails(IntPtr pDetails) { unsignedDetails = new MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[nChannels]; for (int i = 0; i < nChannels; i++) { unsignedDetails[i] = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_UNSIGNED>(mixerControlDetails.paDetails); } } public override string ToString() { return $"{base.ToString()} {Percent}%"; } } } namespace NAudio.Wave { internal enum AcmMetrics { CountDrivers = 1, CountCodecs = 2, CountConverters = 3, CountFilters = 4, CountDisabled = 5, CountHardware = 6, CountLocalDrivers = 20, CountLocalCodecs = 21, CountLocalConverters = 22, CountLocalFilters = 23, CountLocalDisabled = 24, HardwareWaveInput = 30, HardwareWaveOutput = 31, MaxSizeFormat = 50, MaxSizeFilter = 51, DriverSupport = 100, DriverPriority = 101 } [Flags] internal enum AcmStreamConvertFlags { BlockAlign = 4, Start = 0x10, End = 0x20 } [StructLayout(LayoutKind.Explicit)] public struct MmTime { public const int TIME_MS = 1; public const int TIME_SAMPLES = 2; public const int TIME_BYTES = 4; [FieldOffset(0)] public uint wType; [FieldOffset(4)] public uint ms; [FieldOffset(4)] public uint sample; [FieldOffset(4)] public uint cb; [FieldOffset(4)] public uint ticks; [FieldOffset(4)] public byte smpteHour; [FieldOffset(5)] public byte smpteMin; [FieldOffset(6)] public byte smpteSec; [FieldOffset(7)] public byte smpteFrame; [FieldOffset(8)] public byte smpteFps; [FieldOffset(9)] public byte smpteDummy; [FieldOffset(10)] public byte smptePad0; [FieldOffset(11)] public byte smptePad1; [FieldOffset(4)] public uint midiSongPtrPos; } public enum WaveCallbackStrategy { FunctionCallback, NewWindow, ExistingWindow, Event } [StructLayout(LayoutKind.Sequential)] public sealed class WaveHeader { public IntPtr dataBuffer; public int bufferLength; public int bytesRecorded; public IntPtr userData; public WaveHeaderFlags flags; public int loops; public IntPtr next; public IntPtr reserved; } [Flags] public enum WaveHeaderFlags { BeginLoop = 4, Done = 1, EndLoop = 8, InQueue = 0x10, Prepared = 2 } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct WaveInCapabilities { private short manufacturerId; private short productId; private int driverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] private string productName; private SupportedWaveFormat supportedFormats; private short channels; private short reserved; private Guid manufacturerGuid; private Guid productGuid; private Guid nameGuid; private const int MaxProductNameLength = 32; public int Channels => channels; public string ProductName => productName; public Guid NameGuid => nameGuid; public Guid ProductGuid => productGuid; public Guid ManufacturerGuid => manufacturerGuid; public bool SupportsWaveFormat(SupportedWaveFormat waveFormat) { return (supportedFormats & waveFormat) == waveFormat; } } public static class WaveCapabilitiesHelpers { public static readonly Guid MicrosoftDefaultManufacturerId = new Guid("d5a47fa8-6d98-11d1-a21a-00a0c9223196"); public static readonly Guid DefaultWaveOutGuid = new Guid("E36DC310-6D9A-11D1-A21A-00A0C9223196"); public static readonly Guid DefaultWaveInGuid = new Guid("E36DC311-6D9A-11D1-A21A-00A0C9223196"); public static string GetNameFromGuid(Guid guid) { string result = null; using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\MediaCategories")) { using RegistryKey registryKey2 = registryKey.OpenSubKey(guid.ToString("B")); if (registryKey2 != null) { result = registryKey2.GetValue("Name") as string; } } return result; } } public class WaveInterop { [Flags] public enum WaveInOutOpenFlags { CallbackNull = 0, CallbackFunction = 0x30000, CallbackEvent = 0x50000, CallbackWindow = 0x10000, CallbackThread = 0x20000 } public enum WaveMessage { WaveInOpen = 958, WaveInClose = 959, WaveInData = 960, WaveOutClose = 956, WaveOutDone = 957, WaveOutOpen = 955 } public delegate void WaveCallback(IntPtr hWaveOut, WaveMessage message, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved); [DllImport("winmm.dll")] public static extern int mmioStringToFOURCC([MarshalAs(UnmanagedType.LPStr)] string s, int flags); [DllImport("winmm.dll")] public static extern int waveOutGetNumDevs(); [DllImport("winmm.dll")] public static extern MmResult waveOutPrepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveOutUnprepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveOutWrite(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveOutOpen(out IntPtr hWaveOut, IntPtr uDeviceID, WaveFormat lpFormat, WaveCallback dwCallback, IntPtr dwInstance, WaveInOutOpenFlags dwFlags); [DllImport("winmm.dll", EntryPoint = "waveOutOpen")] public static extern MmResult waveOutOpenWindow(out IntPtr hWaveOut, IntPtr uDeviceID, WaveFormat lpFormat, IntPtr callbackWindowHandle, IntPtr dwInstance, WaveInOutOpenFlags dwFlags); [DllImport("winmm.dll")] public static extern MmResult waveOutReset(IntPtr hWaveOut); [DllImport("winmm.dll")] public static extern MmResult waveOutClose(IntPtr hWaveOut); [DllImport("winmm.dll")] public static extern MmResult waveOutPause(IntPtr hWaveOut); [DllImport("winmm.dll")] public static extern MmResult waveOutRestart(IntPtr hWaveOut); [DllImport("winmm.dll")] public static extern MmResult waveOutGetPosition(IntPtr hWaveOut, ref MmTime mmTime, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveOutSetVolume(IntPtr hWaveOut, int dwVolume); [DllImport("winmm.dll")] public static extern MmResult waveOutGetVolume(IntPtr hWaveOut, out int dwVolume); [DllImport("winmm.dll", CharSet = CharSet.Auto)] public static extern MmResult waveOutGetDevCaps(IntPtr deviceID, out WaveOutCapabilities waveOutCaps, int waveOutCapsSize); [DllImport("winmm.dll")] public static extern int waveInGetNumDevs(); [DllImport("winmm.dll", CharSet = CharSet.Auto)] public static extern MmResult waveInGetDevCaps(IntPtr deviceID, out WaveInCapabilities waveInCaps, int waveInCapsSize); [DllImport("winmm.dll")] public static extern MmResult waveInAddBuffer(IntPtr hWaveIn, WaveHeader pwh, int cbwh); [DllImport("winmm.dll")] public static extern MmResult waveInClose(IntPtr hWaveIn); [DllImport("winmm.dll")] public static extern MmResult waveInOpen(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormat lpFormat, WaveCallback dwCallback, IntPtr dwInstance, WaveInOutOpenFlags dwFlags); [DllImport("winmm.dll", EntryPoint = "waveInOpen")] public static extern MmResult waveInOpenWindow(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormat lpFormat, IntPtr callbackWindowHandle, IntPtr dwInstance, WaveInOutOpenFlags dwFlags); [DllImport("winmm.dll")] public static extern MmResult waveInPrepareHeader(IntPtr hWaveIn, WaveHeader lpWaveInHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveInUnprepareHeader(IntPtr hWaveIn, WaveHeader lpWaveInHdr, int uSize); [DllImport("winmm.dll")] public static extern MmResult waveInReset(IntPtr hWaveIn); [DllImport("winmm.dll")] public static extern MmResult waveInStart(IntPtr hWaveIn); [DllImport("winmm.dll")] public static extern MmResult waveInStop(IntPtr hWaveIn); [DllImport("winmm.dll")] public static extern MmResult waveInGetPosition(IntPtr hWaveIn, out MmTime mmTime, int uSize); } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct WaveOutCapabilities { private short manufacturerId; private short productId; private int driverVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] private string productName; private SupportedWaveFormat supportedFormats; private short channels; private short reserved; private WaveOutSupport support; private Guid manufacturerGuid; private Guid productGuid; private Guid nameGuid; private const int MaxProductNameLength = 32; public int Channels => channels; public bool SupportsPlaybackRateControl => (support & WaveOutSupport.PlaybackRate) == WaveOutSupport.PlaybackRate; public string ProductName => productName; public Guid NameGuid => nameGuid; public Guid ProductGuid => productGuid; public Guid ManufacturerGuid => manufacturerGuid; public bool SupportsWaveFormat(SupportedWaveFormat waveFormat) { return (supportedFormats & waveFormat) == waveFormat; } } [Flags] public enum SupportedWaveFormat { WAVE_FORMAT_1M08 = 1, WAVE_FORMAT_1S08 = 2, WAVE_FORMAT_1M16 = 4, WAVE_FORMAT_1S16 = 8, WAVE_FORMAT_2M08 = 0x10, WAVE_FORMAT_2S08 = 0x20, WAVE_FORMAT_2M16 = 0x40, WAVE_FORMAT_2S16 = 0x80, WAVE_FORMAT_4M08 = 0x100, WAVE_FORMAT_4S08 = 0x200, WAVE_FORMAT_4M16 = 0x400, WAVE_FORMAT_4S16 = 0x800, WAVE_FORMAT_44M08 = 0x100, WAVE_FORMAT_44S08 = 0x200, WAVE_FORMAT_44M16 = 0x400, WAVE_FORMAT_44S16 = 0x800, WAVE_FORMAT_48M08 = 0x1000, WAVE_FORMAT_48S08 = 0x2000, WAVE_FORMAT_48M16 = 0x4000, WAVE_FORMAT_48S16 = 0x8000, WAVE_FORMAT_96M08 = 0x10000, WAVE_FORMAT_96S08 = 0x20000, WAVE_FORMAT_96M16 = 0x40000, WAVE_FORMAT_96S16 = 0x80000 } [Flags] internal enum WaveOutSupport { Pitch = 1, PlaybackRate = 2, Volume = 4, LRVolume = 8, Sync = 0x10, SampleAccurate = 0x20 } public class AcmMp3FrameDecompressor : IMp3FrameDecompressor, IDisposable { private readonly AcmStream conversionStream; private readonly WaveFormat pcmFormat; private bool disposed; public WaveFormat OutputFormat => pcmFormat; public AcmMp3FrameDecompressor(WaveFormat sourceFormat) { pcmFormat = AcmStream.SuggestPcmFormat(sourceFormat); try { conversionStream = new AcmStream(sourceFormat, pcmFormat); } catch (Exception) { disposed = true; GC.SuppressFinalize(this); throw; } } public int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset) { if (frame == null) { throw new ArgumentNullException("frame", "You must provide a non-null Mp3Frame to decompress"); } Array.Copy(frame.RawData, conversionStream.SourceBuffer, frame.FrameLength); int sourceBytesConverted; int num = conversionStream.Convert(frame.FrameLength, out sourceBytesConverted); if (sourceBytesConverted != frame.FrameLength) { throw new InvalidOperationException($"Couldn't convert the whole MP3 frame (converted {sourceBytesConverted}/{frame.FrameLength})"); } Array.Copy(conversionStream.DestBuffer, 0, dest, destOffset, num); return num; } public void Reset() { conversionStream.Reposition(); } public void Dispose() { if (!disposed) { disposed = true; if (conversionStream != null) { conversionStream.Dispose(); } GC.SuppressFinalize(this); } } ~AcmMp3FrameDecompressor() { Debug.Assert(condition: false, "AcmMp3FrameDecompressor Dispose was not called"); Dispose(); } } public class WaveFormatConversionProvider : IWaveProvider, IDisposable { private readonly AcmStream conversionStream; private readonly IWaveProvider sourceProvider; private readonly int preferredSourceReadSize; private int leftoverDestBytes; private int leftoverDestOffset; private int leftoverSourceBytes; private bool isDisposed; public WaveFormat WaveFormat { get; } public WaveFormatConversionProvider(WaveFormat targetFormat, IWaveProvider sourceProvider) { this.sourceProvider = sourceProvider; WaveFormat = targetFormat; conversionStream = new AcmStream(sourceProvider.WaveFormat, targetFormat); preferredSourceReadSize = Math.Min(sourceProvider.WaveFormat.AverageBytesPerSecond, conversionStream.SourceBuffer.Length); preferredSourceReadSize -= preferredSourceReadSize % sourceProvider.WaveFormat.BlockAlign; } public void Reposition() { leftoverDestBytes = 0; leftoverDestOffset = 0; leftoverSourceBytes = 0; conversionStream.Reposition(); } public int Read(byte[] buffer, int offset, int count) { int i = 0; if (count % WaveFormat.BlockAlign != 0) { count -= count % WaveFormat.BlockAlign; } int num6; for (; i < count; i += num6) { int num = Math.Min(count - i, leftoverDestBytes); if (num > 0) { Array.Copy(conversionStream.DestBuffer, leftoverDestOffset, buffer, offset + i, num); leftoverDestOffset += num; leftoverDestBytes -= num; i += num; } if (i >= count) { break; } int num2 = Math.Min(preferredSourceReadSize, conversionStream.SourceBuffer.Length - leftoverSourceBytes); int num3 = sourceProvider.Read(conversionStream.SourceBuffer, leftoverSourceBytes, num2); int num4 = num3 + leftoverSourceBytes; if (num4 == 0) { break; } int sourceBytesConverted; int num5 = conversionStream.Convert(num4, out sourceBytesConverted); if (sourceBytesConverted == 0) { Debug.WriteLine($"Warning: couldn't convert anything from {num4}"); break; } leftoverSourceBytes = num4 - sourceBytesConverted; if (leftoverSourceBytes > 0) { Buffer.BlockCopy(conversionStream.SourceBuffer, sourceBytesConverted, conversionStream.SourceBuffer, 0, leftoverSourceBytes); } if (num5 > 0) { int val = count - i; num6 = Math.Min(num5, val); if (num6 < num5) { leftoverDestBytes = num5 - num6; leftoverDestOffset = num6; } Array.Copy(conversionStream.DestBuffer, 0, buffer, i + offset, num6); continue; } Debug.WriteLine($"sourceBytesRead: {num3}, sourceBytesConverted {sourceBytesConverted}, destBytesConverted {num5}"); break; } return i; } protected virtual void Dispose(bool disposing) { if (!isDisposed) { isDisposed = true; conversionStream?.Dispose(); } } public void Dispose() { GC.SuppressFinalize(this); Dispose(disposing: true); } ~WaveFormatConversionProvider() { Dispose(disposing: false); } } public class WaveFormatConversionStream : WaveStream { private readonly WaveFormatConversionProvider conversionProvider; private readonly WaveFormat targetFormat; private readonly long length; private long position; private readonly WaveStream sourceStream; private bool isDisposed; public override long Position { get { return position; } set { value -= value % ((WaveStream)this).BlockAlign; long num = EstimateDestToSource(value); ((Stream)(object)sourceStream).Position = num; position = EstimateSourceToDest(((Stream)(object)sourceStream).Position); conversionProvider.Reposition(); } } public override long Length => length; public override WaveFormat WaveFormat => targetFormat; public WaveFormatConversionStream(WaveFormat targetFormat, WaveStream sourceStream) { this.sourceStream = sourceStream; this.targetFormat = targetFormat; conversionProvider = new WaveFormatConversionProvider(targetFormat, (IWaveProvider)(object)sourceStream); length = EstimateSourceToDest((int)((Stream)(object)sourceStream).Length); position = 0L; } public static WaveStream CreatePcmStream(WaveStream sourceStream) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if ((int)sourceStream.WaveFormat.Encoding == 1) { return sourceStream; } WaveFormat val = AcmStream.SuggestPcmFormat(sourceStream.WaveFormat); if (val.SampleRate < 8000) { if ((int)sourceStream.WaveFormat.Encoding != 163) { throw new InvalidOperationException("Invalid suggested output format, please explicitly provide a target format"); } val = new WaveFormat(8000, 16, 1); } return (WaveStream)(object)new WaveFormatConversionStream(val, sourceStream); } [Obsolete("can be unreliable, use of this method not encouraged")] public int SourceToDest(int source) { return (int)EstimateSourceToDest(source); } private long EstimateSourceToDest(long source) { long num = source * targetFormat.AverageBytesPerSecond / sourceStream.WaveFormat.AverageBytesPerSecond; return num - num % targetFormat.BlockAlign; } private long EstimateDestToSource(long dest) { long num = dest * sourceStream.WaveFormat.AverageBytesPerSecond / targetFormat.AverageBytesPerSecond; num -= num % sourceStream.WaveFormat.BlockAlign; return (int)num; } [Obsolete("can be unreliable, use of this method not encouraged")] public int DestToSource(int dest) { return (int)EstimateDestToSource(dest); } public override int Read(byte[] buffer, int offset, int count) { int num = conversionProvider.Read(buffer, offset, count); position += num; return num; } protected override void Dispose(bool disposing) { if (!isDisposed) { isDisposed = true; if (disposing) { ((Stream)(object)sourceStream).Dispose(); conversionProvider.Dispose(); } else { Debug.Assert(condition: false, "WaveFormatConversionStream was not disposed"); } } ((Stream)this).Dispose(disposing); } } public class WaveInBuffer : IDisposable { private readonly WaveHeader header; private readonly int bufferSize; private readonly byte[] buffer; private GCHandle hBuffer; private IntPtr waveInHandle; private GCHandle hHeader; private GCHandle hThis; public byte[] Data => buffer; public bool Done => (header.flags & WaveHeaderFlags.Done) == WaveHeaderFlags.Done; public bool InQueue => (header.flags & WaveHeaderFlags.InQueue) == WaveHeaderFlags.InQueue; public int BytesRecorded => header.bytesRecorded; public int BufferSize => bufferSize; public WaveInBuffer(IntPtr waveInHandle, int bufferSize) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) this.bufferSize = bufferSize; buffer = new byte[bufferSize]; hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); this.waveInHandle = waveInHandle; header = new WaveHeader(); hHeader = GCHandle.Alloc(header, GCHandleType.Pinned); header.dataBuffer = hBuffer.AddrOfPinnedObject(); header.bufferLength = bufferSize; header.loops = 1; hThis = GCHandle.Alloc(this); header.userData = (IntPtr)hThis; MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader"); } public void Reuse() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) MmException.Try(WaveInterop.waveInUnprepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveUnprepareHeader"); MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader"); MmException.Try(WaveInterop.waveInAddBuffer(waveInHandle, header, Marshal.SizeOf(header)), "waveInAddBuffer"); } ~WaveInBuffer() { Dispose(disposing: false); Debug.Assert(condition: true, "WaveInBuffer was not disposed"); } public void Dispose() { GC.SuppressFinalize(this); Dispose(disposing: true); } protected void Dispose(bool disposing) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (disposing) { } if (waveInHandle != IntPtr.Zero) { WaveInterop.waveInUnprepareHeader(waveInHandle, header, Marshal.SizeOf(header)); waveInHandle = IntPtr.Zero; } if (hHeader.IsAllocated) { hHeader.Free(); } if (hBuffer.IsAllocated) { hBuffer.Free(); } if (hThis.IsAllocated) { hThis.Free(); } } } public class WaveInEvent : IWaveIn, IDisposable { private readonly AutoResetEvent callbackEvent; private readonly SynchronizationContext syncContext; private IntPtr waveInHandle; private volatile CaptureState captureState; private WaveInBuffer[] buffers; public static int DeviceCount => WaveInterop.waveInGetNumDevs(); public int BufferMilliseconds { get; set; } public int NumberOfBuffers { get; set; } public int DeviceNumber { get; set; } public WaveFormat WaveFormat { get; set; } public event EventHandler<WaveInEventArgs> DataAvailable; public event EventHandler<StoppedEventArgs> RecordingStopped; public WaveInEvent() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) callbackEvent = new AutoResetEvent(initialState: false); syncContext = SynchronizationContext.Current; DeviceNumber = 0; WaveFormat = new WaveFormat(8000, 16, 1); BufferMilliseconds = 100; NumberOfBuffers = 3; captureState = (CaptureState)0; } public static WaveInCapabilities GetCapabilities(int devNumber) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) WaveInCapabilities waveInCaps = default(WaveInCapabilities); int waveInCapsSize = Marshal.SizeOf(waveInCaps); MmException.Try(WaveInterop.waveInGetDevCaps((IntPtr)devNumber, out waveInCaps, waveInCapsSize), "waveInGetDevCaps"); return waveInCaps; } private void CreateBuffers() { int num = BufferMilliseconds * WaveFormat.AverageBytesPerSecond / 1000; if (num % WaveFormat.BlockAlign != 0) { num -= num % WaveFormat.BlockAlign; } buffers = new WaveInBuffer[NumberOfBuffers]; for (int i = 0; i < buffers.Length; i++) { buffers[i] = new WaveInBuffer(waveInHandle, num); } } private void OpenWaveInDevice() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) CloseWaveInDevice(); MmResult val = WaveInterop.waveInOpenWindow(out waveInHandle, (IntPtr)DeviceNumber, WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent); MmException.Try(val, "waveInOpen"); CreateBuffers(); } public void StartRecording() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if ((int)captureState > 0) { throw new InvalidOperationException("Already recording"); } OpenWaveInDevice(); MmException.Try(WaveInterop.waveInStart(waveInHandle), "waveInStart"); captureState = (CaptureState)1; ThreadPool.QueueUserWorkItem(delegate { RecordThread(); }, null); } private void RecordThread() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) Exception e = null; try { DoRecording(); } catch (Exception ex) { e = ex; } finally { captureState = (CaptureState)0; RaiseRecordingStoppedEvent(e); } } private void DoRecording() { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Invalid comparison between Unknown and I4 //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown captureState = (CaptureState)2; WaveInBuffer[] array = buffers; foreach (WaveInBuffer waveInBuffer in array) { if (!waveInBuffer.InQueue) { waveInBuffer.Reuse(); } } while ((int)captureState == 2) { if (!callbackEvent.WaitOne()) { continue; } WaveInBuffer[] array2 = buffers; foreach (WaveInBuffer waveInBuffer2 in array2) { if (waveInBuffer2.Done) { if (waveInBuffer2.BytesRecorded > 0) { this.DataAvailable?.Invoke(this, new WaveInEventArgs(waveInBuffer2.Data, waveInBuffer2.BytesRecorded)); } if ((int)captureState == 2) { waveInBuffer2.Reuse(); } } } } } private void RaiseRecordingStoppedEvent(Exception e) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown EventHandler<StoppedEventArgs> handler = this.RecordingStopped; if (handler == null) { return; } if (syncContext == null) { handler(this, new StoppedEventArgs(e)); return; } syncContext.Post(delegate { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown handler(this, new StoppedEventArgs(e)); }, null); } public void StopRecording() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((int)captureState > 0) { captureState = (CaptureState)3; MmException.Try(WaveInterop.waveInStop(waveInHandle), "waveInStop"); MmException.Try(WaveInterop.waveInReset(waveInHandle), "waveInReset"); callbackEvent.Set(); } } public long GetPosition() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) MmTime mmTime = default(MmTime); mmTime.wType = 4u; MmException.Try(WaveInterop.waveInGetPosition(waveInHandle, out mmTime, Marshal.SizeOf(mmTime)), "waveInGetPosition"); if (mmTime.wType != 4) { throw new Exception($"waveInGetPosition: wType -> Expected {4}, Received {mmTime.wType}"); } return mmTime.cb; } protected virtual void Dispose(bool disposing) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if (disposing) { if ((int)captureState > 0) { StopRecording(); } CloseWaveInDevice(); } } private void CloseWaveInDevice() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) WaveInterop.waveInReset(waveInHandle); if (buffers != null) { for (int i = 0; i < buffers.Length; i++) { buffers[i].Dispose(); } buffers = null; } WaveInterop.waveInClose(waveInHandle); waveInHandle = IntPtr.Zero; } public MixerLine GetMixerLine() { if (waveInHandle != IntPtr.Zero) { return new MixerLine(waveInHandle, 0, MixerFlags.WaveInHandle); } return new MixerLine((IntPtr)DeviceNumber, 0, MixerFlags.WaveIn); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } } public class WaveOutBuffer : IDisposable { private readonly WaveHeader header; private readonly int bufferSize; private readonly byte[] buffer; private readonly IWaveProvider waveStream; private readonly object waveOutLock; private GCHandle hBuffer; private IntPtr hWaveOut; private GCHandle hHeader; private GCHandle hThis; public bool InQueue => (header.flags & WaveHeaderFlags.InQueue) == WaveHeaderFlags.InQueue; public int BufferSize => bufferSize; public WaveOutBuffer(IntPtr hWaveOut, int bufferSize, IWaveProvider bufferFillStream, object waveOutLock) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) this.bufferSize = bufferSize; buffer = new byte[bufferSize]; hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); this.hWaveOut = hWaveOut; waveStream = bufferFillStream; this.waveOutLock = waveOutLock; header = new WaveHeader(); hHeader = GCHandle.Alloc(header, GCHandleType.Pinned); header.dataBuffer = hBuffer.AddrOfPinnedObject(); header.bufferLength = bufferSize; header.loops = 1; hThis = GCHandle.Alloc(this); header.userData = (IntPtr)hThis; lock (waveOutLock) { MmException.Try(WaveInterop.waveOutPrepareHeader(hWaveOut, header, Marshal.SizeOf(header)), "waveOutPrepareHeader"); } } ~WaveOutBuffer() { Dispose(disposing: false); Debug.Assert(condition: true, "WaveBuffer was not disposed"); } public void Dispose() { GC.SuppressFinalize(this); Dispose(disposing: true); } protected void Dispose(bool disposing) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) if (disposing) { } if (hHeader.IsAllocated) { hHeader.Free(); } if (hBuffer.IsAllocated) { hBuffer.Free(); } if (hThis.IsAllocated) { hThis.Free(); } if (hWaveOut != IntPtr.Zero) { lock (waveOutLock) { WaveInterop.waveOutUnprepareHeader(hWaveOut, header, Marshal.SizeOf(header)); } hWaveOut = IntPtr.Zero; } } public bool OnDone() { int num; lock (waveStream) { num = waveStream.Read(buffer, 0, buffer.Length); } if (num == 0) { return false; } for (int i = num; i < buffer.Length; i++) { buffer[i] = 0; } WriteToWaveOut(); return true; } private void WriteToWaveOut() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutWrite(hWaveOut, header, Marshal.SizeOf(header)); } if ((int)val > 0) { throw new MmException(val, "waveOutWrite"); } GC.KeepAlive(this); } } public class WaveOutEvent : IWavePlayer, IDisposable, IWavePosition { private readonly object waveOutLock; private readonly SynchronizationContext syncContext; private IntPtr hWaveOut; private WaveOutBuffer[] buffers; private IWaveProvider waveStream; private volatile PlaybackState playbackState; private AutoResetEvent callbackEvent; public int DesiredLatency { get; set; } public int NumberOfBuffers { get; set; } public int DeviceNumber { get; set; } = -1; public WaveFormat OutputWaveFormat => waveStream.WaveFormat; public PlaybackState PlaybackState => playbackState; public float Volume { get { return WaveOutUtils.GetWaveOutVolume(hWaveOut, waveOutLock); } set { WaveOutUtils.SetWaveOutVolume(value, hWaveOut, waveOutLock); } } public event EventHandler<StoppedEventArgs> PlaybackStopped; public WaveOutEvent() { syncContext = SynchronizationContext.Current; if (syncContext != null && (syncContext.GetType().Name == "LegacyAspNetSynchronizationContext" || syncContext.GetType().Name == "AspNetSynchronizationContext")) { syncContext = null; } DesiredLatency = 300; NumberOfBuffers = 2; waveOutLock = new object(); } public void Init(IWaveProvider waveProvider) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if ((int)playbackState > 0) { throw new InvalidOperationException("Can't re-initialize during playback"); } if (hWaveOut != IntPtr.Zero) { DisposeBuffers(); CloseWaveOut(); } callbackEvent = new AutoResetEvent(initialState: false); waveStream = waveProvider; int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers); MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent); } MmException.Try(val, "waveOutOpen"); buffers = new WaveOutBuffer[NumberOfBuffers]; playbackState = (PlaybackState)0; for (int i = 0; i < NumberOfBuffers; i++) { buffers[i] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock); } } public void Play() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (buffers == null || waveStream == null) { throw new InvalidOperationException("Must call Init first"); } if ((int)playbackState == 0) { playbackState = (PlaybackState)1; callbackEvent.Set(); ThreadPool.QueueUserWorkItem(delegate { PlaybackThread(); }, null); } else if ((int)playbackState == 2) { Resume(); callbackEvent.Set(); } } private void PlaybackThread() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) Exception e = null; try { DoPlayback(); } catch (Exception ex) { e = ex; } finally { playbackState = (PlaybackState)0; RaisePlaybackStoppedEvent(e); } } private void DoPlayback() { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_00a0: Unknown result type (might be due to invalid IL or missing references) while ((int)playbackState > 0) { if (!callbackEvent.WaitOne(DesiredLatency) && (int)playbackState == 1) { Debug.WriteLine("WARNING: WaveOutEvent callback event timeout"); } if ((int)playbackState != 1) { continue; } int num = 0; WaveOutBuffer[] array = buffers; foreach (WaveOutBuffer waveOutBuffer in array) { if (waveOutBuffer.InQueue || waveOutBuffer.OnDone()) { num++; } } if (num == 0) { playbackState = (PlaybackState)0; callbackEvent.Set(); } } } public void Pause() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if ((int)playbackState == 1) { playbackState = (PlaybackState)2; MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutPause(hWaveOut); } if ((int)val > 0) { throw new MmException(val, "waveOutPause"); } } } private void Resume() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if ((int)playbackState == 2) { MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutRestart(hWaveOut); } if ((int)val > 0) { throw new MmException(val, "waveOutRestart"); } playbackState = (PlaybackState)1; } } public void Stop() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if ((int)playbackState > 0) { playbackState = (PlaybackState)0; MmResult val; lock (waveOutLock) { val = WaveInterop.waveOutReset(hWaveOut); } if ((int)val > 0) { throw new MmException(val, "waveOutReset"); } callbackEvent.Set(); } } public long GetPosition() { return WaveOutUtils.GetPositionBytes(hWaveOut, waveOutLock); } public void Dispose() { GC.SuppressFinalize(this); Dispose(disposing: true); } protected void Dispose(bool disposing) { Stop(); if (disposing) { DisposeBuffers(); } CloseWaveOut(); } private void CloseWaveOut() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (callbackEvent != null) { callbackEvent.Close(); callbackEvent = null; } lock (waveOutLock) { if (hWaveOut != IntPtr.Zero) { WaveInterop.waveOutClose(hWaveOut); hWaveOut = IntPtr.Zero; } } } private void DisposeBuffers() { if (buffers != null) { WaveOutBuffer[] array = buffers; foreach (WaveOutBuffer waveOutBuffer in array) { waveOutBuffer.Dispose(); } buffers = null; } } ~WaveOutEvent() { Dispose(disposing: false); Debug.Assert(condition: false, "WaveOutEvent device was not closed"); } private void RaisePlaybackStoppedEvent(Exception e) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown EventHandler<StoppedEventArgs> handler = this.PlaybackStopped; if (handler == null) { return; } if (syncContext == null) { handler(this, new StoppedEventArgs(e)); return; } syncContext.Post(delegate { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown handler(this, new StoppedEventArgs(e)); }, null); } } public static class WaveOutUtils { public static float GetWaveOutVolume(IntPtr hWaveOut, object lockObject) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) MmResult val; int dwVolume; lock (lockObject) { val = WaveInterop.waveOutGetVolume(hWaveOut, out dwVolume); } MmException.Try(val, "waveOutGetVolume"); return (float)(dwVolume & 0xFFFF) / 65535f; } public static void SetWaveOutVolume(float value, IntPtr hWaveOut, object lockObject) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (value < 0f) { throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0"); } if (value > 1f) { throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0"); } int dwVolume = (int)(value * 65535f) + ((int)(value * 65535f) << 16); MmResult val; lock (lockObject) { val = WaveInterop.waveOutSetVolume(hWaveOut, dwVolume); } MmException.Try(val, "waveOutSetVolume"); } public static long GetPositionBytes(IntPtr hWaveOut, object lockObject) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) lock (lockObject) { MmTime mmTime = default(MmTime); mmTime.wType = 4u; MmException.Try(WaveInterop.waveOutGetPosition(hWaveOut, ref mmTime, Marshal.SizeOf(mmTime)), "waveOutGetPosition"); if (mmTime.wType != 4) { throw new Exception($"waveOutGetPosition: wType -> Expected {4}, Received {mmTime.wType}"); } return mmTime.cb; } } } } namespace NAudio.Wave.Compression { public class AcmDriver : IDisposable { private static List<AcmDriver> drivers; private AcmDriverDetails details; private IntPtr driverId; private IntPtr driverHandle; private List<AcmFormatTag> formatTags; private List<AcmFormat> tempFormatsList; private IntPtr localDllHandle; public int MaxFormatSize { get { //IL_000b: Unknown result type (might be due to invalid IL or missing references) MmException.Try(AcmInterop.acmMetrics(driverHandle, AcmMetrics.MaxSizeFormat, out var output), "acmMetrics"); return output; } } public string ShortName => details.shortName; public string LongName => details.longName; public IntPtr DriverId => driverId; public IEnumerable<AcmFormatTag> FormatTags { get { //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (formatTags == null) { if (driverHandle == IntPtr.Zero) { throw new InvalidOperationException("Driver must be opened first"); } formatTags = new List<AcmFormatTag>(); AcmFormatTagDetails formatTagDetails = default(AcmFormatTagDetails); formatTagDetails.structureSize = Marshal.SizeOf(formatTagDetails); MmException.Try(AcmInterop.acmFormatTagEnum(driverHandle, ref formatTagDetails, AcmFormatTagEnumCallback, IntPtr.Zero, 0), "acmFormatTagEnum"); } return formatTags; } } public static bool IsCodecInstalled(string shortName) { foreach (AcmDriver item in EnumerateAcmDrivers()) { if (item.ShortName == shortName) { return true; } } return false; } public static AcmDriver AddLocalDriver(string driverFile) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) IntPtr intPtr = NativeMethods.LoadLibrary(driverFile); if (intPtr == IntPtr.Zero) { throw new ArgumentException("Failed to load driver file"); } IntPtr procAddress = NativeMethods.GetProcAddress(intPtr, "DriverProc"); if (procAddress == IntPtr.Zero) { NativeMethods.FreeLibrary(intPtr); throw new ArgumentException("Failed to discover DriverProc"); } IntPtr hAcmDriver; MmResult val = AcmInterop.acmDriverAdd(out hAcmDriver, intPtr, procAddress, 0, AcmDriverAddFlags.Function); if ((int)val > 0) { NativeMethods.FreeLibrary(intPtr); throw new MmException(val, "acmDriverAdd"); } AcmDriver acmDriver = new AcmDriver(hAcmDriver); if (string.IsNullOrEmpty(acmDriver.details.longName)) { acmDriver.details.longName = "Local driver: " + Path.GetFileName(driverFile); acmDriver.localDllHandle = intPtr; } return acmDriver; } public static void RemoveLocalDriver(AcmDriver localDriver) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (localDriver.localDllHandle == IntPtr.Zero) { throw new ArgumentException("Please pass in the AcmDriver returned by the AddLocalDriver method"); } MmResult val = AcmInterop.acmDriverRemove(localDriver.driverId, 0); NativeMethods.FreeLibrary(localDriver.localDllHandle); MmException.Try(val, "acmDriverRemove"); } public static bool ShowFormatChooseDialog(IntPtr ownerWindowHandle, string windowTitle, AcmFormatEnumFlags enumFlags, WaveFormat enumFormat, out WaveFormat selectedFormat, out string selectedFormatDescription, out string selectedFormatTagDescription) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Invalid comparison between Unknown and I4 //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Invalid comparison between Unknown and I4 //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Invalid comparison between Unknown and I4 //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Invalid comparison between Unknown and I4 //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) AcmFormatChoose formatChoose = default(AcmFormatChoose); formatChoose.structureSize = Marshal.SizeOf(formatChoose); formatChoose.styleFlags = AcmFormatChooseStyleFlags.None; formatChoose.ownerWindowHandle = ownerWindowHandle; int num = 200; formatChoose.selectedWaveFormatPointer = Marshal.AllocHGlobal(num); formatChoose.selectedWaveFormatByteSize = num; formatChoose.title = windowTitle; formatChoose.name = null; formatChoose.formatEnumFlags = enumFlags; formatChoose.waveFormatEnumPointer = IntPtr.Zero; if (enumFormat != null) { IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<WaveFormat>(enumFormat)); Marshal.StructureToPtr<WaveFormat>(enumFormat, intPtr, fDeleteOld: false); formatChoose.waveFormatEnumPointer = intPtr; } formatChoose.instanceHandle = IntPtr.Zero; formatChoose.templateName = null; MmResult val = AcmInterop.acmFormatChoose(ref formatChoose); selectedFormat = null; selectedFormatDescription = null; selectedFormatTagDescription = null; if ((int)val == 0) { selectedFormat = WaveFormat.MarshalFromPtr(formatChoose.selectedWaveFormatPointer); selectedFormatDescription = formatChoose.formatDescription; selectedFormatTagDescription = formatChoose.formatTagDescription; } Marshal.FreeHGlobal(formatChoose.waveFormatEnumPointer); Marshal.FreeHGlobal(formatChoose.selectedWaveFormatPointer); if ((int)val != 515 && (int)val > 0) { throw new MmException(val, "acmFormatChoose"); } return (int)val == 0; } public static AcmDriver FindByShortName(string shortName) { foreach (AcmDriver item in EnumerateAcmDrivers()) { if (item.ShortName == shortName) { return item; } } return null; } public static IEnumerable<AcmDriver> EnumerateAcmDrivers() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) drivers = new List<AcmDriver>(); MmException.Try(AcmInterop.acmDriverEnum(DriverEnumCallback, IntPtr.Zero, (AcmDriverEnumFlags)0), "acmDriverEnum"); return drivers; } private static bool DriverEnumCallback(IntPtr hAcmDriver, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags) { drivers.Add(new AcmDriver(hAcmDriver)); return true; } private AcmDriver(IntPtr hAcmDriver) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) driverId = hAcmDriver; details = default(AcmDriverDetails); details.structureSize = Marshal.SizeOf(details); MmException.Try(AcmInterop.acmDriverDetails(hAcmDriver, ref details, 0), "acmDriverDetails"); } public override string ToString() { return LongName; } public IEnumerable<AcmFormat> GetFormats(AcmFormatTag formatTag) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected I4, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (driverHandle == IntPtr.Zero) { throw new InvalidOperationException("Driver must be opened first"); } tempFormatsList = new List<AcmFormat>(); AcmFormatDetails formatDetails = default(AcmFormatDetails); formatDetails.structSize = Marshal.SizeOf(formatDetails); formatDetails.waveFormatByteSize = 1024; formatDetails.waveFormatPointer = Marshal.AllocHGlobal(formatDetails.waveFormatByteSize); formatDetails.formatTag = (int)formatTag.FormatTag; MmResult val = AcmInterop.acmFormatEnum(driverHandle, ref formatDetails, AcmFormatEnumCallback, IntPtr.Zero, AcmFormatEnumFlags.None); Marshal.FreeHGlobal(formatDetails.waveFormatPointer); MmException.Try(val, "acmFormatEnum"); return tempFormatsList; } public void Open() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (driverHandle == IntPtr.Zero) { MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, DriverId, 0), "acmDriverOpen"); } } public void Close() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (driverHandle != IntPtr.Zero) { MmException.Try(AcmInterop.acmDriverClose(driverHandle, 0), "acmDriverClose"); driverHandle = IntPtr.Zero; } } private bool AcmFormatTagEnumCallback(IntPtr hAcmDriverId, ref AcmFormatTagDetails formatTagDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags) { formatTags.Add(new AcmFormatTag(formatTagDetails)); return true; } private bool AcmFormatEnumCallback(IntPtr hAcmDriverId, ref AcmFormatDetails formatDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags) { tempFormatsList.Add(new AcmFormat(formatDetails)); return true; } public void Dispose() { if (driverHandle != IntPtr.Zero) { Close(); GC.SuppressFinalize(this); } } } internal enum AcmDriverAddFlags { Local = 0, Global = 8, Function = 3, NotifyWindowHandle = 4 } [StructLayout(LayoutKind.Sequential, Pack = 2)] internal struct AcmDriverDetails { public int structureSize; public uint fccType; public uint fccComp; public ushort manufacturerId; public ushort productId; public uint acmVersion; public uint driverVersion; public AcmDriverDetailsSupportFlags supportFlags; public int formatTagsCount; public int filterTagsCount; public IntPtr hicon; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string shortName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string longName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string copyright; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string licensing; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)] public string features; private const int ShortNameChars = 32; private const int LongNameChars = 128; private const int CopyrightChars = 80; private const int LicensingChars = 128; private const int FeaturesChars = 512; } [Flags] public enum AcmDriverDetailsSupportFlags { Codec = 1, Converter = 2, Filter = 4, Hardware = 8, Async = 0x10, Local = 0x40000000, Disabled = int.MinValue } [Flags] internal enum AcmDriverEnumFlags { NoLocal = 0x40000000, Disabled = int.MinValue } public class AcmFormat { private readonly AcmFormatDetails formatDetails; public int FormatIndex => formatDetails.formatIndex; public WaveFormatEncoding FormatTag => (WaveFormatEncoding)(ushort)formatDetails.formatTag; public AcmDriverDetailsSupportFlags SupportFlags => formatDetails.supportFlags; public WaveFormat WaveFormat { get; private set; } public int WaveFormatByteSize => formatDetails.waveFormatByteSize; public string FormatDescription => formatDetails.formatDescription; internal AcmFormat(AcmFormatDetails formatDetails) { this.formatDetails = formatDetails; WaveFormat = WaveFormat.MarshalFromPtr(formatDetails.waveFormatPointer); } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)] internal struct AcmFormatChoose { public int structureSize; public AcmFormatChooseStyleFlags styleFlags; public IntPtr ownerWindowHandle; public IntPtr selectedWaveFormatPointer; public int selectedWaveFormatByteSize; [MarshalAs(UnmanagedType.LPTStr)] public string title; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)] public string formatTagDescription; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string formatDescription; [MarshalAs(UnmanagedType.LPTStr)] public string name; public int nameByteSize; public AcmFormatEnumFlags formatEnumFlags; public IntPtr waveFormatEnumPointer; public IntPtr instanceHandle; [MarshalAs(UnmanagedType.LPTStr)] public string templateName; public IntPtr customData; public AcmInterop.AcmFormatChooseHookProc windowCallbackFunction; } [Flags] internal enum AcmFormatChooseStyleFlags { None = 0, ShowHelp = 4, EnableHook = 8, EnableTemplate = 0x10, EnableTemplateHandle = 0x20, InitToWfxStruct = 0x40, ContextHelp = 0x80 } [StructLayout(LayoutKind.Sequential, Pack = 4)] internal struct AcmFormatDetails { public int structSize; public int formatIndex; public int formatTag; public AcmDriverDetailsSupportFlags supportFlags; public IntPtr waveFormatPointer; public int waveFormatByteSize; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string formatDescription; public const int FormatDescriptionChars = 128; } [Flags] public enum AcmFormatEnumFlags { None = 0, Convert = 0x100000, Hardware = 0x400000, Input = 0x800000, Channels = 0x20000, SamplesPerSecond = 0x40000, Output = 0x1000000, Suggest = 0x200000, BitsPerSample = 0x80000, FormatTag = 0x10000 } [Flags] internal enum AcmFormatSuggestFlags { FormatTag = 0x10000, Channels = 0x20000, SamplesPerSecond = 0x40000, BitsPerSample = 0x80000, TypeMask = 0xFF0000 } public class AcmFormatTag { private AcmFormatTagDetails formatTagDetails; public int FormatTagIndex => formatTagDetails.formatTagIndex; public WaveFormatEncoding FormatTag => (WaveFormatEncoding)(ushort)formatTagDetails.formatTag; public int FormatSize => formatTagDetails.formatSize; public AcmDriverDetailsSupportFlags SupportFlags => formatTagDetails.supportFlags; public int StandardFormatsCount => formatTagDetails.standardFormatsCount; public string FormatDescription => formatTagDetails.formatDescription; internal AcmFormatTag(AcmFormatTagDetails formatTagDetails) { this.formatTagDetails = formatTagDetails; } } internal struct AcmFormatTagDetails { public int structureSize; public int formatTagIndex; public int formatTag; public int formatSize; public AcmDriverDetailsSupportFlags supportFlags; public int standardFormatsCount; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)] public string formatDescription; public const int FormatTagDescriptionChars = 48; } internal class AcmInterop { public delegate bool AcmDriverEnumCallback(IntPtr hAcmDriverId, IntPtr instance, AcmDriverDetailsSupportFlags flags); public delegate bool AcmFormatEnumCallback(IntPtr hAcmDriverId, ref AcmFormatDetails formatDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags); public delegate bool AcmFormatTagEnumCallback(IntPtr hAcmDriverId, ref AcmFormatTagDetails formatTagDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags); public delegate bool AcmFormatChooseHookProc(IntPtr windowHandle, int message, IntPtr wParam, IntPtr lParam); [DllImport("msacm32.dll")] public static extern MmResult acmDriverAdd(out IntPtr driverHandle, IntPtr driverModule, IntPtr driverFunctionAddress, int priority, AcmDriverAddFlags flags); [DllImport("msacm32.dll")] public static extern MmResult acmDriverRemove(IntPtr driverHandle, int removeFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmDriverClose(IntPtr hAcmDriver, int closeFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmDriverEnum(AcmDriverEnumCallback fnCallback, IntPtr dwInstance, AcmDriverEnumFlags flags); [DllImport("Msacm32.dll")] public static extern MmResult acmDriverDetails(IntPtr hAcmDriver, ref AcmDriverDetails driverDetails, int reserved); [DllImport("Msacm32.dll")] public static extern MmResult acmDriverOpen(out IntPtr pAcmDriver, IntPtr hAcmDriverId, int openFlags); [DllImport("Msacm32.dll", EntryPoint = "acmFormatChooseW")] public static extern MmResult acmFormatChoose(ref AcmFormatChoose formatChoose); [DllImport("Msacm32.dll")] public static extern MmResult acmFormatEnum(IntPtr hAcmDriver, ref AcmFormatDetails formatDetails, AcmFormatEnumCallback callback, IntPtr instance, AcmFormatEnumFlags flags); [DllImport("Msacm32.dll", EntryPoint = "acmFormatSuggest")] public static extern MmResult acmFormatSuggest2(IntPtr hAcmDriver, IntPtr sourceFormatPointer, IntPtr destFormatPointer, int sizeDestFormat, AcmFormatSuggestFlags suggestFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmFormatTagEnum(IntPtr hAcmDriver, ref AcmFormatTagDetails formatTagDetails, AcmFormatTagEnumCallback callback, IntPtr instance, int reserved); [DllImport("Msacm32.dll")] public static extern MmResult acmMetrics(IntPtr hAcmObject, AcmMetrics metric, out int output); [DllImport("Msacm32.dll", EntryPoint = "acmStreamOpen")] public static extern MmResult acmStreamOpen2(out IntPtr hAcmStream, IntPtr hAcmDriver, IntPtr sourceFormatPointer, IntPtr destFormatPointer, [In] WaveFilter waveFilter, IntPtr callback, IntPtr instance, AcmStreamOpenFlags openFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamClose(IntPtr hAcmStream, int closeFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamConvert(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, AcmStreamConvertFlags streamConvertFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamPrepareHeader(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, int prepareFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamReset(IntPtr hAcmStream, int resetFlags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamSize(IntPtr hAcmStream, int inputBufferSize, out int outputBufferSize, AcmStreamSizeFlags flags); [DllImport("Msacm32.dll")] public static extern MmResult acmStreamUnprepareHeader(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, int flags); } public class AcmStream : IDisposable { private IntPtr streamHandle; private IntPtr driverHandle; private AcmStreamHeader streamHeader; private readonly WaveFormat sourceFormat; public byte[] SourceBuffer => streamHeader.SourceBuffer; public byte[] DestBuffer => streamHeader.DestBuffer; public AcmStream(WaveFormat sourceFormat, WaveFormat destFormat) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) try { streamHandle = IntPtr.Zero; this.sourceFormat = sourceFormat; int num = Math.Max(65536, sourceFormat.AverageBytesPerSecond); num -= num % sourceFormat.BlockAlign; IntPtr intPtr = WaveFormat.MarshalToPtr(sourceFormat); IntPtr intPtr2 = WaveFormat.MarshalToPtr(destFormat); try { MmException.Try(AcmInterop.acmStreamOpen2(out streamHandle, IntPtr.Zero, intPtr, intPtr2, null, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen"); } finally { Marshal.FreeHGlobal(intPtr); Marshal.FreeHGlobal(intPtr2); } int destBufferLength = SourceToDest(num); streamHeader = new AcmStreamHeader(streamHandle, num, destBufferLength); driverHandle = IntPtr.Zero; } catch { Dispose(); throw; } } public AcmStream(IntPtr driverId, WaveFormat sourceFormat, WaveFilter waveFilter) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) int num = Math.Max(16384, sourceFormat.AverageBytesPerSecond); this.sourceFormat = sourceFormat; num -= num % sourceFormat.BlockAlign; MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, driverId, 0), "acmDriverOpen"); IntPtr intPtr = WaveFormat.MarshalToPtr(sourceFormat); try { MmException.Try(AcmInterop.acmStreamOpen2(out streamHandle, driverHandle, intPtr, intPtr, waveFilter, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen"); } finally { Marshal.FreeHGlobal(intPtr); } streamHeader = new AcmStreamHeader(streamHandle, num, SourceToDest(num)); } public int SourceToDest(int source) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (source == 0) { return 0; } int outputBufferSize; MmResult val = AcmInterop.acmStreamSize(streamHandle, source, out outputBufferSize, AcmStreamSizeFlags.Source); MmException.Try(val, "acmStreamSize"); return outputBufferSize; } public int DestToSource(int dest) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (dest == 0) { return 0; } MmException.Try(AcmInterop.acmStreamSize(streamHandle, dest, out var outputBufferSize, AcmStreamSizeFlags.Destination), "acmStreamSize"); return outputBufferSize; } public static WaveFormat SuggestPcmFormat(WaveFormat compressedFormat) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) WaveFormat val = new WaveFormat(compressedFormat.SampleRate, 16, compressedFormat.Channels); IntPtr intPtr = WaveFormat.MarshalToPtr(val); IntPtr intPtr2 = WaveFormat.MarshalToPtr(compressedFormat); try { MmResult val2 = AcmInterop.acmFormatSuggest2(IntPtr.Zero, intPtr2, intPtr, Marshal.SizeOf<WaveFormat>(val), AcmFormatSuggestFlags.FormatTag); val = WaveFormat.MarshalFromPtr(intPtr); MmException.Try(val2, "acmFormatSuggest"); } finally { Marshal.FreeHGlobal(intPtr); Marshal.FreeHGlobal(intPtr2); } return val; } public void Reposition() { streamHeader.Reposition(); } public int Convert(int bytesToConver
Schedule1Radio.dll
Decompiled 3 days agousing System; using System.Collections.Generic; 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 Il2CppInterop.Runtime.InteropTypes.Arrays; using MelonLoader; using NAudio.Wave; using Schedule1Radio; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(RadioMod), "RadioMod", "1.0.1", "Hyde", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: AssemblyTitle("Schedule1Radio")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Schedule1Radio")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("c7969ffa-c1dd-469e-a718-32c263ab1677")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace Schedule1Radio; public class RadioMod : MelonMod { private bool showUI = false; private string musicFolderPath; private List<string> songs = new List<string>(); private int currentSongIndex = 0; private WaveOutEvent outputDevice; private AudioFileReader audioFileReader; private Rect _windowRect = new Rect(100f, 100f, 400f, 300f); private bool _menuOpen = false; private GUIStyle _titleStyle; private GUIStyle _buttonStyle; private float volume = 0.5f; private bool loop = false; public override void OnApplicationStart() { musicFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Music"); if (!Directory.Exists(musicFolderPath)) { Directory.CreateDirectory(musicFolderPath); MelonLogger.Msg("Created Music folder! Drop .mp3 files in there."); } LoadSongs(); } private void LoadSongs() { MelonLogger.Msg("Music folder path: " + musicFolderPath); if (Directory.Exists(musicFolderPath)) { string[] files = Directory.GetFiles(musicFolderPath); MelonLogger.Msg("Files in Music folder: " + string.Join(", ", files)); songs = files.Where((string file) => file.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".ogg", StringComparison.OrdinalIgnoreCase)).ToList(); MelonLogger.Msg($"Found {songs.Count} song(s)."); } else { MelonLogger.Msg("Music folder does not exist!"); } } public override void OnUpdate() { if (Input.GetKeyDown((KeyCode)283)) { showUI = !showUI; _menuOpen = showUI; } } public override void OnGUI() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if (showUI) { GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 20, fontStyle = (FontStyle)1 }; val.normal.textColor = Color.white; _titleStyle = val; _buttonStyle = new GUIStyle(GUI.skin.button) { fontSize = 14, wordWrap = true }; GUI.Box(_windowRect, new GUIContent("Radio Mod")); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref _windowRect)).x, ((Rect)(ref _windowRect)).y, ((Rect)(ref _windowRect)).width, 30f); if ((int)Event.current.type == 3 && ((Rect)(ref val2)).Contains(Event.current.mousePosition)) { ref Rect windowRect = ref _windowRect; ((Rect)(ref windowRect)).x = ((Rect)(ref windowRect)).x + Event.current.delta.x; ref Rect windowRect2 = ref _windowRect; ((Rect)(ref windowRect2)).y = ((Rect)(ref windowRect2)).y + Event.current.delta.y; GUI.changed = true; } GUI.BeginGroup(new Rect(((Rect)(ref _windowRect)).x + 10f, ((Rect)(ref _windowRect)).y + 30f, ((Rect)(ref _windowRect)).width - 20f, ((Rect)(ref _windowRect)).height - 40f)); DrawMainContent(); GUI.EndGroup(); } } private void DrawMainContent() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Invalid comparison between Unknown and I4 GUILayout.Label("Radio Mod", _titleStyle, (Il2CppReferenceArray<GUILayoutOption>)null); if (songs.Count == 0) { GUILayout.Label("No songs available!", _titleStyle, (Il2CppReferenceArray<GUILayoutOption>)null); return; } if (GUILayout.Button((outputDevice == null || (int)outputDevice.PlaybackState != 1) ? "Play" : "Pause", _buttonStyle, Array.Empty<GUILayoutOption>())) { if (outputDevice == null || (int)outputDevice.PlaybackState != 1) { PlayCurrentSong(); } else { Pause(); } } if (GUILayout.Button("Previous", _buttonStyle, Array.Empty<GUILayoutOption>())) { PreviousSong(); } if (GUILayout.Button("Next", _buttonStyle, Array.Empty<GUILayoutOption>())) { NextSong(); } GUILayout.Space(10f); GUILayout.Label("Volume", _buttonStyle, (Il2CppReferenceArray<GUILayoutOption>)null); float num = GUILayout.HorizontalSlider(volume, 0f, 1f, (Il2CppReferenceArray<GUILayoutOption>)null); if (Math.Abs(num - volume) > 0.01f) { volume = num; if (audioFileReader != null) { audioFileReader.Volume = volume; } } GUILayout.Space(10f); if (GUILayout.Button("Loop: " + (loop ? "On" : "Off"), _buttonStyle, Array.Empty<GUILayoutOption>())) { loop = !loop; } GUILayout.Space(10f); GUILayout.Label(Path.GetFileName(songs[currentSongIndex]), _titleStyle, (Il2CppReferenceArray<GUILayoutOption>)null); } private void PlayCurrentSong() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown StopPlayback(); if (songs.Count == 0) { return; } try { audioFileReader = new AudioFileReader(songs[currentSongIndex]); audioFileReader.Volume = volume; outputDevice = new WaveOutEvent(); outputDevice.Init((IWaveProvider)(object)audioFileReader); outputDevice.PlaybackStopped += OnPlaybackStopped; outputDevice.Play(); } catch (Exception ex) { MelonLogger.Error("Error playing song: " + ex.Message); } } private void OnPlaybackStopped(object sender, StoppedEventArgs e) { if (loop) { PlayCurrentSong(); } else { NextSong(); } } private void Pause() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 if (outputDevice != null) { if ((int)outputDevice.PlaybackState == 1) { outputDevice.Pause(); } else if ((int)outputDevice.PlaybackState == 2) { outputDevice.Play(); } } } private void NextSong() { if (songs.Count != 0) { currentSongIndex = (currentSongIndex + 1) % songs.Count; PlayCurrentSong(); } } private void PreviousSong() { if (songs.Count != 0) { currentSongIndex = (currentSongIndex - 1 + songs.Count) % songs.Count; PlayCurrentSong(); } } private void StopPlayback() { if (outputDevice != null) { outputDevice.PlaybackStopped -= OnPlaybackStopped; outputDevice.Stop(); outputDevice.Dispose(); outputDevice = null; } if (audioFileReader != null) { ((Stream)(object)audioFileReader).Dispose(); audioFileReader = null; } } public override void OnApplicationQuit() { StopPlayback(); } }