Decompiled source of CSCore v1.0.0
plugins/CSCore/CSCore.Ffmpeg.dll
Decompiled 4 months 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.Collections.ObjectModel; using System.ComponentModel; using System.Configuration; 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.Threading; using CSCore.Ffmpeg.Interops; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("5de75590-74ff-4c8c-bb0c-26164ed01e3d")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] namespace CSCore.Ffmpeg { public enum AvCodecId { None = 0, Mpeg1Video = 1, Mpeg2Video = 2, Mpeg2VideoXvmc = 3, H261 = 4, H263 = 5, Rv10 = 6, Rv20 = 7, Mjpeg = 8, Mjpegb = 9, Ljpeg = 10, Sp5X = 11, Jpegls = 12, Mpeg4 = 13, Rawvideo = 14, Msmpeg4V1 = 15, Msmpeg4V2 = 16, Msmpeg4V3 = 17, Wmv1 = 18, Wmv2 = 19, H263P = 20, H263I = 21, Flv1 = 22, Svq1 = 23, Svq3 = 24, Dvvideo = 25, Huffyuv = 26, Cyuv = 27, H264 = 28, Indeo3 = 29, Vp3 = 30, Theora = 31, Asv1 = 32, Asv2 = 33, Ffv1 = 34, _4Xm = 35, Vcr1 = 36, Cljr = 37, Mdec = 38, Roq = 39, InterplayVideo = 40, XanWc3 = 41, XanWc4 = 42, Rpza = 43, Cinepak = 44, WsVqa = 45, Msrle = 46, Msvideo1 = 47, Idcin = 48, _8Bps = 49, Smc = 50, Flic = 51, Truemotion1 = 52, Vmdvideo = 53, Mszh = 54, Zlib = 55, Qtrle = 56, Tscc = 57, Ulti = 58, Qdraw = 59, Vixl = 60, Qpeg = 61, Png = 62, Ppm = 63, Pbm = 64, Pgm = 65, Pgmyuv = 66, Pam = 67, Ffvhuff = 68, Rv30 = 69, Rv40 = 70, Vc1 = 71, Wmv3 = 72, Loco = 73, Wnv1 = 74, Aasc = 75, Indeo2 = 76, Fraps = 77, Truemotion2 = 78, Bmp = 79, Cscd = 80, Mmvideo = 81, Zmbv = 82, Avs = 83, Smackvideo = 84, Nuv = 85, Kmvc = 86, Flashsv = 87, Cavs = 88, Jpeg2000 = 89, Vmnc = 90, Vp5 = 91, Vp6 = 92, Vp6F = 93, Targa = 94, Dsicinvideo = 95, Tiertexseqvideo = 96, Tiff = 97, Gif = 98, Dxa = 99, Dnxhd = 100, Thp = 101, Sgi = 102, C93 = 103, Bethsoftvid = 104, Ptx = 105, Txd = 106, Vp6A = 107, Amv = 108, Vb = 109, Pcx = 110, Sunrast = 111, Indeo4 = 112, Indeo5 = 113, Mimic = 114, Rl2 = 115, Escape124 = 116, Dirac = 117, Bfi = 118, Cmv = 119, Motionpixels = 120, Tgv = 121, Tgq = 122, Tqi = 123, Aura = 124, Aura2 = 125, V210X = 126, Tmv = 127, V210 = 128, Dpx = 129, Mad = 130, Frwu = 131, Flashsv2 = 132, Cdgraphics = 133, R210 = 134, Anm = 135, Binkvideo = 136, IffIlbm = 137, Kgv1 = 138, Yop = 139, Vp8 = 140, Pictor = 141, Ansi = 142, A64Multi = 143, A64Multi5 = 144, R10K = 145, Mxpeg = 146, Lagarith = 147, Prores = 148, Jv = 149, Dfa = 150, Wmv3Image = 151, Vc1Image = 152, Utvideo = 153, BmvVideo = 154, Vble = 155, Dxtory = 156, V410 = 157, Xwd = 158, Cdxl = 159, Xbm = 160, Zerocodec = 161, Mss1 = 162, Msa1 = 163, Tscc2 = 164, Mts2 = 165, Cllc = 166, Mss2 = 167, Vp9 = 168, Aic = 169, Escape130 = 170, G2M = 171, Webp = 172, Hnm4Video = 173, Hevc = 174, Fic = 175, AliasPix = 176, BrenderPix = 177, PafVideo = 178, Exr = 179, Vp7 = 180, Sanm = 181, Sgirle = 182, Mvc1 = 183, Mvc2 = 184, Hqx = 185, Tdsc = 186, HqHqa = 187, Hap = 188, Dds = 189, Dxv = 190, Screenpresso = 191, Rscc = 192, Y41P = 32768, Avrp = 32769, _012V = 32770, Avui = 32771, Ayuv = 32772, TargaY216 = 32773, V308 = 32774, V408 = 32775, Yuv4 = 32776, Avrn = 32777, Cpia = 32778, Xface = 32779, Snow = 32780, Smvjpeg = 32781, Apng = 32782, Daala = 32783, Cfhd = 32784, Truemotion2Rt = 32785, M101 = 32786, Magicyuv = 32787, Sheervideo = 32788, Ylc = 32789, FirstAudio = 65536, PcmS16Le = 65536, PcmS16Be = 65537, PcmU16Le = 65538, PcmU16Be = 65539, PcmS8 = 65540, PcmU8 = 65541, PcmMulaw = 65542, PcmAlaw = 65543, PcmS32Le = 65544, PcmS32Be = 65545, PcmU32Le = 65546, PcmU32Be = 65547, PcmS24Le = 65548, PcmS24Be = 65549, PcmU24Le = 65550, PcmU24Be = 65551, PcmS24Daud = 65552, PcmZork = 65553, PcmS16LePlanar = 65554, PcmDvd = 65555, PcmF32Be = 65556, PcmF32Le = 65557, PcmF64Be = 65558, PcmF64Le = 65559, PcmBluray = 65560, PcmLxf = 65561, S302M = 65562, PcmS8Planar = 65563, PcmS24LePlanar = 65564, PcmS32LePlanar = 65565, PcmS16BePlanar = 65566, PcmS64Le = 67584, PcmS64Be = 67585, AdpcmImaQt = 69632, AdpcmImaWav = 69633, AdpcmImaDk3 = 69634, AdpcmImaDk4 = 69635, AdpcmImaWs = 69636, AdpcmImaSmjpeg = 69637, AdpcmMs = 69638, Adpcm_4Xm = 69639, AdpcmXa = 69640, AdpcmAdx = 69641, AdpcmEa = 69642, AdpcmG726 = 69643, AdpcmCt = 69644, AdpcmSwf = 69645, AdpcmYamaha = 69646, AdpcmSbpro4 = 69647, AdpcmSbpro3 = 69648, AdpcmSbpro2 = 69649, AdpcmThp = 69650, AdpcmImaAmv = 69651, AdpcmEaR1 = 69652, AdpcmEaR3 = 69653, AdpcmEaR2 = 69654, AdpcmImaEaSead = 69655, AdpcmImaEaEacs = 69656, AdpcmEaXas = 69657, AdpcmEaMaxisXa = 69658, AdpcmImaIss = 69659, AdpcmG722 = 69660, AdpcmImaApc = 69661, AdpcmVima = 69662, Vima = 69662, AdpcmAfc = 71680, AdpcmImaOki = 71681, AdpcmDtk = 71682, AdpcmImaRad = 71683, AdpcmG726Le = 71684, AdpcmThpLe = 71685, AdpcmPsx = 71686, AdpcmAica = 71687, AdpcmImaDat4 = 71688, AdpcmMtaf = 71689, AmrNb = 73728, AmrWb = 73729, Ra144 = 77824, Ra288 = 77825, RoqDpcm = 81920, InterplayDpcm = 81921, XanDpcm = 81922, SolDpcm = 81923, Sdx2Dpcm = 83968, Mp2 = 86016, Mp3 = 86017, Aac = 86018, Ac3 = 86019, Dts = 86020, Vorbis = 86021, Dvaudio = 86022, Wmav1 = 86023, Wmav2 = 86024, Mace3 = 86025, Mace6 = 86026, Vmdaudio = 86027, Flac = 86028, Mp3Adu = 86029, Mp3On4 = 86030, Shorten = 86031, Alac = 86032, WestwoodSnd1 = 86033, Gsm = 86034, Qdm2 = 86035, Cook = 86036, Truespeech = 86037, Tta = 86038, Smackaudio = 86039, Qcelp = 86040, Wavpack = 86041, Dsicinaudio = 86042, Imc = 86043, Musepack7 = 86044, Mlp = 86045, GsmMs = 86046, Atrac3 = 86047, Voxware = 86048, Ape = 86049, Nellymoser = 86050, Musepack8 = 86051, Speex = 86052, Wmavoice = 86053, Wmapro = 86054, Wmalossless = 86055, Atrac3P = 86056, Eac3 = 86057, Sipr = 86058, Mp1 = 86059, Twinvq = 86060, Truehd = 86061, Mp4Als = 86062, Atrac1 = 86063, BinkaudioRdft = 86064, BinkaudioDct = 86065, AacLatm = 86066, Qdmc = 86067, Celt = 86068, G7231 = 86069, G729 = 86070, _8SvxExp = 86071, _8SvxFib = 86072, BmvAudio = 86073, Ralf = 86074, Iac = 86075, Ilbc = 86076, Opus = 86077, ComfortNoise = 86078, Tak = 86079, Metasound = 86080, PafAudio = 86081, On2Avc = 86082, DssSp = 86083, Ffwavesynth = 88064, Sonic = 88065, SonicLs = 88066, Evrc = 88067, Smv = 88068, DsdLsbf = 88069, DsdMsbf = 88070, DsdLsbfPlanar = 88071, DsdMsbfPlanar = 88072, _4Gv = 88073, InterplayAcm = 88074, Xma1 = 88075, Xma2 = 88076, Dst = 88077, FirstSubtitle = 94208, DvdSubtitle = 94208, DvbSubtitle = 94209, Text = 94210, Xsub = 94211, Ssa = 94212, MovText = 94213, HdmvPgsSubtitle = 94214, DvbTeletext = 94215, Srt = 94216, Microdvd = 96256, Eia608 = 96257, Jacosub = 96258, Sami = 96259, Realtext = 96260, Stl = 96261, Subviewer1 = 96262, Subviewer = 96263, Subrip = 96264, Webvtt = 96265, Mpl2 = 96266, Vplayer = 96267, Pjs = 96268, Ass = 96269, HdmvTextSubtitle = 96270, FirstUnknown = 98304, Ttf = 98304, Scte35 = 98305, Bintext = 100352, Xbin = 100353, Idf = 100354, Otf = 100355, SmpteKlv = 100356, DvdNav = 100357, TimedId3 = 100358, BinData = 100359, Probe = 102400, Mpeg2Ts = 131072, Mpeg4Systems = 131073, Ffmetadata = 135168, WrappedAvframe = 135169 } internal class AvFormatContext : IDisposable { private unsafe AVFormatContext* _formatContext; private AvStream _stream; public unsafe IntPtr FormatPtr => (IntPtr)_formatContext; public int BestAudioStreamIndex { get; private set; } public AvStream SelectedStream => _stream; public unsafe bool CanSeek { get { if (_formatContext == null || _formatContext->pb == null) { return false; } return _formatContext->pb->seekable == 1; } } public double LengthInSeconds { get { if (SelectedStream == null || SelectedStream.Stream.duration < 0) { return 0.0; } AVRational time_base = SelectedStream.Stream.time_base; if (time_base.den == 0) { return 0.0; } return (double)(SelectedStream.Stream.duration * time_base.num) / (double)time_base.den; } } public unsafe AVFormatContext FormatContext { get { if (_formatContext == null) { return default(AVFormatContext); } return *_formatContext; } } public Dictionary<string, string> Metadata { get; private set; } public unsafe AvFormatContext(FfmpegStream stream) { _formatContext = FfmpegCalls.AvformatAllocContext(); fixed (AVFormatContext** formatContext = &_formatContext) { FfmpegCalls.AvformatOpenInput(formatContext, stream.AvioContext); } Initialize(); } public unsafe AvFormatContext(string url) { _formatContext = FfmpegCalls.AvformatAllocContext(); fixed (AVFormatContext** formatContext = &_formatContext) { FfmpegCalls.AvformatOpenInput(formatContext, url); } Initialize(); } private unsafe void Initialize() { FfmpegCalls.AvFormatFindStreamInfo(_formatContext); BestAudioStreamIndex = FfmpegCalls.AvFindBestStreamInfo(_formatContext); _stream = new AvStream((IntPtr)_formatContext->streams[BestAudioStreamIndex]); Metadata = new Dictionary<string, string>(); if (_formatContext->metadata != null) { AVDictionaryEntry[] elements = _formatContext->metadata->Elements; AVDictionaryEntry[] array = elements; for (int i = 0; i < array.Length; i++) { AVDictionaryEntry aVDictionaryEntry = array[i]; Metadata.Add(aVDictionaryEntry.Key, aVDictionaryEntry.Value); } } } public void SeekFile(double seconds) { AVRational time_base = SelectedStream.Stream.time_base; double time = seconds * (double)time_base.den / (double)time_base.num; FfmpegCalls.AvFormatSeekFile(this, time); } public unsafe void Dispose() { GC.SuppressFinalize(this); if (SelectedStream != null) { SelectedStream.Dispose(); _stream = null; } if (_formatContext != null) { fixed (AVFormatContext** formatContext = &_formatContext) { FfmpegCalls.AvformatCloseInput(formatContext); } _formatContext = null; BestAudioStreamIndex = 0; } } ~AvFormatContext() { Dispose(); } } internal sealed class AvFrame : IDisposable { private readonly AvFormatContext _formatContext; private unsafe AVFrame* _frame; public unsafe AvFrame(AvFormatContext formatContext) { _formatContext = formatContext; _frame = FfmpegCalls.AvFrameAlloc(); } public unsafe int ReadNextFrame(out double seconds, ref byte[] buffer) { AVStream stream = _formatContext.SelectedStream.Stream; AVPacket aVPacket = default(AVPacket); FfmpegCalls.InitPacket(&aVPacket); int num = 0; do { try { aVPacket.data = null; aVPacket.size = 0; seconds = 0.0; if (!FfmpegCalls.AvReadFrame(_formatContext, &aVPacket)) { break; } if (aVPacket.stream_index != _formatContext.SelectedStream.Stream.index) { continue; } seconds = (double)(aVPacket.pts * stream.time_base.num) / (double)stream.time_base.den; do { int bytesConsumed; try { int num2 = DecodePacket(ref buffer, num, &aVPacket, out bytesConsumed); if (num2 == 0) { break; } num += num2; goto IL_00d5; } catch (FfmpegException) { } break; IL_00d5: aVPacket.data += bytesConsumed; aVPacket.size -= bytesConsumed; } while (aVPacket.size > 0); continue; } finally { FfmpegCalls.FreePacket(&aVPacket); } } while (num <= 0); return num; } private unsafe int DecodePacket(ref byte[] buffer, int offset, AVPacket* packet, out int bytesConsumed) { AvStream selectedStream = _formatContext.SelectedStream; AVCodecContext* codec = selectedStream.Stream.codec; bool flag = FfmpegCalls.AvCodecDecodeAudio4(codec, _frame, packet, out bytesConsumed); bytesConsumed = Math.Min(bytesConsumed, packet->size); if (flag) { int num = FfmpegCalls.AvGetBytesPerSample((AVSampleFormat)_frame->format); int num2 = FfmpegCalls.AvSamplesGetBufferSize(_frame); if (buffer == null || buffer.Length < offset + num2) { byte[] array = new byte[offset + num2]; if (buffer != null) { Buffer.BlockCopy(buffer, 0, array, 0, buffer.Length); } buffer = array; } if (IsPlanar((AVSampleFormat)_frame->format)) { for (int i = 0; i < _frame->channels; i++) { for (int j = 0; j < _frame->nb_samples; j++) { switch (num) { case 1: buffer[offset + j * _frame->channels + i] = _frame->extended_data[i][j]; break; case 2: buffer[offset + j * num * _frame->channels + i * num] = _frame->extended_data[i][j * num]; buffer[offset + j * num * _frame->channels + i * num + 1] = _frame->extended_data[i][j * num + 1]; break; case 4: buffer[offset + j * num * _frame->channels + i * num] = _frame->extended_data[i][j * num]; buffer[offset + j * num * _frame->channels + i * num + 1] = _frame->extended_data[i][j * num + 1]; buffer[offset + j * num * _frame->channels + i * num + 2] = _frame->extended_data[i][j * num + 2]; buffer[offset + j * num * _frame->channels + i * num + 3] = _frame->extended_data[i][j * num + 3]; break; case 8: buffer[offset + j * num * _frame->channels + i * num] = _frame->extended_data[i][j * num]; buffer[offset + j * num * _frame->channels + i * num + 1] = _frame->extended_data[i][j * num + 1]; buffer[offset + j * num * _frame->channels + i * num + 2] = _frame->extended_data[i][j * num + 2]; buffer[offset + j * num * _frame->channels + i * num + 3] = _frame->extended_data[i][j * num + 3]; buffer[offset + j * num * _frame->channels + i * num + 4] = _frame->extended_data[i][j * num + 4]; buffer[offset + j * num * _frame->channels + i * num + 5] = _frame->extended_data[i][j * num + 5]; buffer[offset + j * num * _frame->channels + i * num + 6] = _frame->extended_data[i][j * num + 6]; buffer[offset + j * num * _frame->channels + i * num + 7] = _frame->extended_data[i][j * num + 7]; break; } } } num2 = num * _frame->channels * _frame->nb_samples; } else { for (int k = 0; k < num2; k++) { buffer[k + offset] = (*_frame->extended_data)[k]; } } if (num == 8) { num2 = ConvertDblToFloat(buffer, offset, num2); } return num2; } return 0; } private unsafe int ConvertDblToFloat(byte[] buffer, int offset, int count) { byte[] array = new byte[count / 2]; fixed (byte* ptr = &buffer[offset]) { void* ptr2 = ptr; fixed (byte* ptr3 = &array[0]) { void* ptr4 = ptr3; float* ptr5 = (float*)ptr4; double* ptr6 = (double*)ptr2; for (int i = 0; i < count / 8; i++) { ptr5[i] = (float)ptr6[i]; } } } Array.Clear(buffer, offset, count); Buffer.BlockCopy(array, 0, buffer, offset, array.Length); return array.Length; } private bool IsPlanar(AVSampleFormat sampleFormat) { return sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_U8P || sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_S16P || sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_S32P || sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_FLTP || sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_DBLP; } public unsafe void Dispose() { GC.SuppressFinalize(this); if (_frame != null) { FfmpegCalls.AvFrameFree(_frame); _frame = null; } } ~AvFrame() { Dispose(); } } internal sealed class AvioBuffer : IDisposable { public int BufferSize { get; private set; } public IntPtr Buffer { get; private set; } public bool SuppressAvFree { get; set; } public AvioBuffer() : this(4096) { } public AvioBuffer(int bufferSize) { if (bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize"); } BufferSize = bufferSize; Buffer = FfmpegCalls.AvMalloc(bufferSize); SuppressAvFree = false; } public void Dispose() { GC.SuppressFinalize(this); if (!SuppressAvFree) { FfmpegCalls.AvFree(Buffer); } } ~AvioBuffer() { Dispose(); } } internal sealed class AvioContext : IDisposable { private readonly FfmpegCalls.AvioReadData _readDataCallback; private readonly FfmpegCalls.AvioSeek _seekCallback; private readonly FfmpegCalls.AvioWriteData _writeDataCallback; private unsafe AVIOContext* _context; private AvioBuffer _buffer; public unsafe IntPtr ContextPtr => (IntPtr)_context; public unsafe AVIOContext Context { get { if (_context == null) { return default(AVIOContext); } return *_context; } } public AvioContext(FfmpegCalls.AvioReadData readDataCallback, FfmpegCalls.AvioSeek seekCallback) : this(readDataCallback, seekCallback, null) { } public unsafe AvioContext(FfmpegCalls.AvioReadData readDataCallback, FfmpegCalls.AvioSeek seekCallback, FfmpegCalls.AvioWriteData writeDataCallback) { _readDataCallback = readDataCallback; _seekCallback = seekCallback; _writeDataCallback = writeDataCallback; _buffer = new AvioBuffer { SuppressAvFree = true }; _context = FfmpegCalls.AvioAllocContext(_buffer, _writeDataCallback != null, IntPtr.Zero, _readDataCallback, _writeDataCallback, _seekCallback); } public unsafe void Dispose() { GC.SuppressFinalize(this); if (_context != null) { FfmpegCalls.AvFree((IntPtr)_context->buffer); FfmpegCalls.AvFree((IntPtr)_context); _context = null; } } ~AvioContext() { Dispose(); } } internal sealed class AvStream : IDisposable { private unsafe readonly AVStream* _stream; public unsafe AVStream Stream { get { if (_stream == null) { return default(AVStream); } return *_stream; } } public unsafe WaveFormat GetSuggestedWaveFormat() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown if (_stream == null) { throw new InvalidOperationException("No stream selected."); } int num; AudioEncoding val; switch (_stream->codec->sample_fmt) { case AVSampleFormat.AV_SAMPLE_FMT_U8: case AVSampleFormat.AV_SAMPLE_FMT_U8P: num = 8; val = (AudioEncoding)1; break; case AVSampleFormat.AV_SAMPLE_FMT_S16: case AVSampleFormat.AV_SAMPLE_FMT_S16P: num = 16; val = (AudioEncoding)1; break; case AVSampleFormat.AV_SAMPLE_FMT_S32: case AVSampleFormat.AV_SAMPLE_FMT_S32P: num = 32; val = (AudioEncoding)1; break; case AVSampleFormat.AV_SAMPLE_FMT_FLT: case AVSampleFormat.AV_SAMPLE_FMT_FLTP: num = 32; val = (AudioEncoding)3; break; case AVSampleFormat.AV_SAMPLE_FMT_DBL: case AVSampleFormat.AV_SAMPLE_FMT_DBLP: num = 32; val = (AudioEncoding)3; break; default: throw new NotSupportedException("Audio Sample Format not supported."); } return new WaveFormat(_stream->codec->sample_rate, num, _stream->codec->channels, val); } public unsafe AvStream(IntPtr stream) { if (stream == IntPtr.Zero) { throw new ArgumentNullException("stream"); } _stream = (AVStream*)(void*)stream; AVCodecContext* codec = _stream->codec; AVCodec* codec2 = FfmpegCalls.AvCodecFindDecoder(codec->codec_id); FfmpegCalls.AvCodecOpen(codec, codec2); } public unsafe void Dispose() { GC.SuppressFinalize(this); if (_stream != null) { FfmpegCalls.AvCodecClose(_stream->codec); } } ~AvStream() { Dispose(); } } internal class FfmpegCalls { [Flags] public enum SeekFlags { SeekSet = 0, SeekCur = 1, SeekEnd = 2, SeekSize = 0x10000, SeekForce = 0x20000 } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int AvioReadData(IntPtr opaque, IntPtr buffer, int bufferSize); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int AvioWriteData(IntPtr opaque, IntPtr buffer, int bufferSize); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate long AvioSeek(IntPtr opaque, long offset, SeekFlags whence); internal unsafe delegate void LogCallback(void* ptr, int level, byte* fmt, IntPtr vl); static FfmpegCalls() { string path; switch (Environment.OSVersion.Platform) { case PlatformID.Win32S: case PlatformID.Win32Windows: case PlatformID.Win32NT: path = "windows"; break; case PlatformID.Unix: case PlatformID.MacOSX: path = "unix"; break; default: throw new PlatformNotSupportedException(); } string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (directoryName != null) { string path2 = Path.Combine(directoryName, Path.Combine("FFmpeg", Path.Combine("bin", Path.Combine(path, (IntPtr.Size == 8) ? "x64" : "x86")))); InteropHelper.RegisterLibrariesSearchPath(path2); } FfmpegConfigurationSection ffmpegConfigurationSection = (FfmpegConfigurationSection)ConfigurationManager.GetSection("ffmpeg"); if (ffmpegConfigurationSection != null) { if (!string.IsNullOrEmpty(ffmpegConfigurationSection.HttpProxy)) { Environment.SetEnvironmentVariable("http_proxy", ffmpegConfigurationSection.HttpProxy); Environment.SetEnvironmentVariable("no_proxy", ffmpegConfigurationSection.ProxyWhitelist); } if (ffmpegConfigurationSection.LogLevel.HasValue) { FfmpegUtils.LogLevel = ffmpegConfigurationSection.LogLevel.Value; } } ffmpeg.av_register_all(); ffmpeg.avcodec_register_all(); ffmpeg.avformat_network_init(); } internal unsafe static AVOutputFormat[] GetOutputFormats() { List<AVOutputFormat> list = new List<AVOutputFormat>(); for (AVOutputFormat* ptr = ffmpeg.av_oformat_next(null); ptr != null; ptr = ffmpeg.av_oformat_next(ptr)) { list.Add(*ptr); } return list.ToArray(); } internal unsafe static AVInputFormat[] GetInputFormats() { List<AVInputFormat> list = new List<AVInputFormat>(); for (AVInputFormat* ptr = ffmpeg.av_iformat_next(null); ptr != null; ptr = ffmpeg.av_iformat_next(ptr)) { list.Add(*ptr); } return list.ToArray(); } internal unsafe static List<AvCodecId> GetCodecOfCodecTag(AVCodecTag** codecTag) { List<AvCodecId> list = new List<AvCodecId>(); uint num = 0u; AvCodecId item; while ((item = ffmpeg.av_codec_get_id(codecTag, num++)) != 0) { list.Add(item); } return list; } internal unsafe static IntPtr AvMalloc(int bufferSize) { void* value = ffmpeg.av_malloc((ulong)bufferSize); IntPtr intPtr = new IntPtr(value); if (intPtr == IntPtr.Zero) { throw new OutOfMemoryException("Could not allocate memory."); } return intPtr; } internal unsafe static void AvFree(IntPtr buffer) { ffmpeg.av_free((void*)buffer); } internal unsafe static AVIOContext* AvioAllocContext(AvioBuffer buffer, bool writeable, IntPtr userData, AvioReadData readData, AvioWriteData writeData, AvioSeek seek) { byte* buffer2 = (byte*)(void*)buffer.Buffer; AVIOContext* ptr = ffmpeg.avio_alloc_context(buffer2, buffer.BufferSize, writeable ? 1 : 0, (void*)userData, readData, writeData, seek); if (ptr == null) { throw new FfmpegException("Could not allocate avio-context.", "avio_alloc_context"); } return ptr; } internal unsafe static AVFormatContext* AvformatAllocContext() { AVFormatContext* ptr = ffmpeg.avformat_alloc_context(); if (ptr == null) { throw new FfmpegException("Could not allocate avformat-context.", "avformat_alloc_context"); } return ptr; } internal unsafe static void AvformatOpenInput(AVFormatContext** formatContext, AvioContext avioContext) { (*formatContext)->pb = (AVIOContext*)(void*)avioContext.ContextPtr; int errorCode = ffmpeg.avformat_open_input(formatContext, "DUMMY-FILENAME", null, null); FfmpegException.Try(errorCode, "avformat_open_input"); } internal unsafe static void AvformatOpenInput(AVFormatContext** formatContext, string url) { int errorCode = ffmpeg.avformat_open_input(formatContext, url, null, null); FfmpegException.Try(errorCode, "avformat_open_input"); } internal unsafe static void AvformatCloseInput(AVFormatContext** formatContext) { ffmpeg.avformat_close_input(formatContext); } internal unsafe static void AvFormatFindStreamInfo(AVFormatContext* formatContext) { int errorCode = ffmpeg.avformat_find_stream_info(formatContext, null); FfmpegException.Try(errorCode, "avformat_find_stream_info"); } internal unsafe static int AvFindBestStreamInfo(AVFormatContext* formatContext) { int num = ffmpeg.av_find_best_stream(formatContext, AVMediaType.AVMEDIA_TYPE_AUDIO, -1, -1, null, 0); FfmpegException.Try(num, "av_find_best_stream"); return num; } internal unsafe static AVCodec* AvCodecFindDecoder(AvCodecId codecId) { AVCodec* ptr = ffmpeg.avcodec_find_decoder(codecId); if (ptr == null) { throw new FfmpegException($"Failed to find a decoder for CodecId {codecId}.", "avcodec_find_decoder"); } return ptr; } internal unsafe static void AvCodecOpen(AVCodecContext* codecContext, AVCodec* codec) { int errorCode = ffmpeg.avcodec_open2(codecContext, codec, null); FfmpegException.Try(errorCode, "avcodec_open2"); } internal unsafe static void AvCodecClose(AVCodecContext* codecContext) { ffmpeg.avcodec_close(codecContext); } internal unsafe static AVFrame* AvFrameAlloc() { AVFrame* ptr = ffmpeg.av_frame_alloc(); if (ptr == null) { throw new FfmpegException("Could not allocate frame.", "av_frame_alloc"); } return ptr; } internal unsafe static void AvFrameFree(AVFrame* frame) { ffmpeg.av_frame_free(&frame); } internal unsafe static void InitPacket(AVPacket* packet) { ffmpeg.av_init_packet(packet); } internal unsafe static void FreePacket(AVPacket* packet) { ffmpeg.av_packet_unref(packet); } internal unsafe static bool AvReadFrame(AvFormatContext formatContext, AVPacket* packet) { int num = ffmpeg.av_read_frame((AVFormatContext*)(void*)formatContext.FormatPtr, packet); return num >= 0; } internal unsafe static bool AvCodecDecodeAudio4(AVCodecContext* codecContext, AVFrame* frame, AVPacket* packet, out int bytesConsumed) { int num = default(int); int num2 = ffmpeg.avcodec_decode_audio4(codecContext, frame, &num, packet); FfmpegException.Try(num2, "avcodec_decode_audio4"); bytesConsumed = num2; return num != 0; } internal static int AvGetBytesPerSample(AVSampleFormat sampleFormat) { int num = ffmpeg.av_get_bytes_per_sample(sampleFormat); if (num <= 0) { throw new FfmpegException("Could not calculate data size."); } return num; } internal unsafe static int AvSamplesGetBufferSize(AVFrame* frame) { int num = ffmpeg.av_samples_get_buffer_size(null, frame->channels, frame->nb_samples, (AVSampleFormat)frame->format, 1); FfmpegException.Try(num, "av_samples_get_buffer_size"); return num; } internal unsafe static void AvFormatSeekFile(AvFormatContext formatContext, double time) { int errorCode = ffmpeg.avformat_seek_file((AVFormatContext*)(void*)formatContext.FormatPtr, formatContext.BestAudioStreamIndex, long.MinValue, (long)time, (long)time, 0); FfmpegException.Try(errorCode, "avformat_seek_file"); } internal unsafe static string AvStrError(int errorCode) { byte* value = stackalloc byte[500]; int num = ffmpeg.av_strerror(errorCode, new IntPtr(value), 500uL); if (num < 0) { return "No description available."; } string text = Marshal.PtrToStringAnsi(new IntPtr(value), 500).Trim(new char[1]).Trim(); Debug.WriteLineIf(Debugger.IsAttached, text); return text; } internal static void SetLogLevel(LogLevel level) { ffmpeg.av_log_set_level((int)level); } internal static LogLevel GetLogLevel() { return (LogLevel)ffmpeg.av_log_get_level(); } internal static void SetLogCallback(LogCallback callback) { ffmpeg.av_log_set_callback(Marshal.GetFunctionPointerForDelegate(callback)); } internal unsafe static LogCallback GetDefaultLogCallback() { return delegate(void* ptr, int level, byte* fmt, IntPtr vl) { ffmpeg.av_log_default_callback(ptr, level, Marshal.PtrToStringAnsi(new IntPtr(fmt)), (sbyte*)(void*)vl); }; } internal unsafe static string FormatLine(void* avcl, int level, string fmt, IntPtr vl, ref int printPrefix) { string empty = string.Empty; byte* ptr = stackalloc byte[1024]; fixed (int* print_prefix = &printPrefix) { int num = ffmpeg.av_log_format_line2(avcl, level, fmt, (sbyte*)(void*)vl, (IntPtr)ptr, 1024, print_prefix); if (num < 0) { Debug.WriteLine("av_log_format_line2 failed with " + num.ToString("x8")); return empty; } empty = Marshal.PtrToStringAnsi((IntPtr)ptr); if (empty != null && num > 0) { empty = empty.Substring(0, num); } return empty; } } } public class FfmpegConfigurationSection : ConfigurationSection { [ConfigurationProperty("httpProxy", DefaultValue = "", IsRequired = false)] public string HttpProxy { get { return (string)((ConfigurationElement)this)["httpProxy"]; } set { ((ConfigurationElement)this)["httpProxy"] = value; } } [ConfigurationProperty("proxyWhitelist", DefaultValue = "*", IsRequired = false)] public string ProxyWhitelist { get { return (string)((ConfigurationElement)this)["proxyWhitelist"]; } set { ((ConfigurationElement)this)["proxyWhitelist"] = value; } } [ConfigurationProperty("loglevel", DefaultValue = null, IsRequired = false)] public LogLevel? LogLevel { get { object obj = ((ConfigurationElement)this)["loglevel"]; if (obj is LogLevel && Enum.IsDefined(typeof(LogLevel), obj)) { return (LogLevel?)obj; } return null; } set { ((ConfigurationElement)this)["loglevel"] = value; } } } public class FfmpegDecoder : IWaveSource, IReadableAudioSource<byte>, IAudioSource, IDisposable { private readonly object _lockObject = new object(); private readonly Uri _uri; private FfmpegStream _ffmpegStream; private AvFormatContext _formatContext; private bool _disposeStream = false; private byte[] _overflowBuffer = new byte[0]; private int _overflowCount; private int _overflowOffset; private long _position; private Stream _stream; public Dictionary<string, string> Metadata { get { if (_formatContext == null) { return new Dictionary<string, string>(); } return _formatContext.Metadata; } } public bool CanSeek { get { if (_formatContext == null) { return false; } return _formatContext.CanSeek; } } public WaveFormat WaveFormat { get; private set; } public long Position { get { return _position; } set { SeekPosition(value); } } public long Length { get { if (_formatContext == null || _formatContext.SelectedStream == null) { return 0L; } return Extensions.GetRawElements((IAudioSource)(object)this, TimeSpan.FromSeconds(_formatContext.LengthInSeconds)); } } public FfmpegDecoder(string url) { _uri = new Uri(url); try { _formatContext = new AvFormatContext(url); Initialize(); } catch (FfmpegException ex) { if (ex.ErrorCode == -22 && "avformat_open_input".Equals(ex.Function, StringComparison.OrdinalIgnoreCase)) { if (!TryInitializeWithFileAsStream(url)) { throw; } return; } throw; } } public FfmpegDecoder(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } InitializeWithStream(stream, disposeStream: false); } public int Read(byte[] buffer, int offset, int count) { int num = 0; count -= count % WaveFormat.BlockAlign; int overflows = GetOverflows(buffer, ref offset, count); num += overflows; while (num < count) { int num2; long rawElements; lock (_lockObject) { using AvFrame avFrame = new AvFrame(_formatContext); num2 = avFrame.ReadNextFrame(out var seconds, ref _overflowBuffer); rawElements = Extensions.GetRawElements((IAudioSource)(object)this, TimeSpan.FromSeconds(seconds)); } if (num2 <= 0) { if (!(_uri != null) || _uri.IsFile) { break; } Thread.Sleep(10); } int num3 = Math.Min(count - num, num2); Array.Copy(_overflowBuffer, 0, buffer, offset, num3); num += num3; offset += num3; _overflowCount = ((num2 > num3) ? (num2 - num3) : 0); _overflowOffset = ((num2 > num3) ? num3 : 0); _position = rawElements + num - overflows; } if (overflows == num) { _position += num; } return num; } public void Dispose() { Dispose(disposing: true); } protected void Dispose(bool disposing) { GC.SuppressFinalize(this); if (disposing) { if (_disposeStream && _stream != null) { _stream.Dispose(); _stream = null; } if (_formatContext != null) { _formatContext.Dispose(); _formatContext = null; } if (_ffmpegStream != null) { _ffmpegStream.Dispose(); _ffmpegStream = null; } } } private void Initialize() { WaveFormat = _formatContext.SelectedStream.GetSuggestedWaveFormat(); } private void InitializeWithStream(Stream stream, bool disposeStream) { _stream = stream; _disposeStream = disposeStream; _ffmpegStream = new FfmpegStream(stream, allowWrite: false); _formatContext = new AvFormatContext(_ffmpegStream); Initialize(); } private bool TryInitializeWithFileAsStream(string filename) { if (!File.Exists(filename)) { return false; } Stream stream = null; try { stream = File.OpenRead(filename); InitializeWithStream(stream, disposeStream: true); return true; } catch (Exception) { stream?.Dispose(); return false; } } ~FfmpegDecoder() { Dispose(disposing: false); } private void SeekPosition(long position) { double seconds = (double)Extensions.GetMilliseconds((IAudioSource)(object)this, position) / 1000.0; lock (_lockObject) { _formatContext.SeekFile(seconds); _position = position; _overflowCount = 0; _overflowOffset = 0; } } private int GetOverflows(byte[] buffer, ref int offset, int count) { if (_overflowCount != 0 && _overflowBuffer != null && count > 0) { int num = Math.Min(count, _overflowCount); Array.Copy(_overflowBuffer, _overflowOffset, buffer, offset, num); _overflowCount -= num; _overflowOffset += num; offset += num; return num; } return 0; } } public class FfmpegException : Exception { public int ErrorCode { get; private set; } public string Function { get; private set; } public static void Try(int errorCode, string function) { if (errorCode < 0) { throw new FfmpegException(errorCode, function); } } public FfmpegException(int errorCode, string function) : base($"{function} returned 0x{errorCode:x8}: {FfmpegCalls.AvStrError(errorCode)}") { ErrorCode = errorCode; Function = function; } public FfmpegException(string message, string function) : base($"{message} failed: {function}") { Function = function; } public FfmpegException(string message) : base(message) { } } public class FfmpegLogReceivedEventArgs : EventArgs { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate IntPtr ItemNameFunc(IntPtr avClass); public string Message { get; private set; } public LogLevel Level { get; private set; } public string ClassName { get; private set; } public string ItemName { get; private set; } public string ParentLogContextClassName { get; set; } public string ParentLogContextItemName { get; set; } internal unsafe FfmpegLogReceivedEventArgs(AVClass? avClass, AVClass? parentLogContext, LogLevel level, string line, void* ptr, void* ptr1) { Message = line; Level = level; if (avClass.HasValue) { AVClass value = avClass.Value; ClassName = Marshal.PtrToStringAnsi((IntPtr)value.class_name); if (value.item_name != IntPtr.Zero) { ItemNameFunc itemNameFunc = (ItemNameFunc)Marshal.GetDelegateForFunctionPointer(value.item_name, typeof(ItemNameFunc)); IntPtr intPtr = itemNameFunc((IntPtr)ptr); if (intPtr != IntPtr.Zero) { ItemName = Marshal.PtrToStringAnsi(intPtr); } } } if (!parentLogContext.HasValue) { return; } AVClass value2 = parentLogContext.Value; ParentLogContextClassName = Marshal.PtrToStringAnsi((IntPtr)value2.class_name); if (value2.item_name != IntPtr.Zero) { ItemNameFunc itemNameFunc = (ItemNameFunc)Marshal.GetDelegateForFunctionPointer(value2.item_name, typeof(ItemNameFunc)); IntPtr intPtr = itemNameFunc((IntPtr)ptr1); if (intPtr != IntPtr.Zero) { ParentLogContextItemName = Marshal.PtrToStringAnsi(intPtr); } } } } internal sealed class FfmpegStream : IDisposable { private readonly Stream _stream; public AvioContext AvioContext { get; private set; } public FfmpegStream(Stream stream) : this(stream, allowWrite: true) { } public FfmpegStream(Stream stream, bool allowWrite) { if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanRead) { throw new ArgumentException("Stream is not readable.", "stream"); } _stream = stream; AvioContext = new AvioContext(ReadDataCallback, stream.CanSeek ? new FfmpegCalls.AvioSeek(SeekCallback) : null, (stream.CanWrite && allowWrite) ? new FfmpegCalls.AvioWriteData(WriteDataCallback) : null); } private long SeekCallback(IntPtr opaque, long offset, FfmpegCalls.SeekFlags whence) { if ((whence & FfmpegCalls.SeekFlags.SeekSize) == FfmpegCalls.SeekFlags.SeekSize) { return _stream.Length; } SeekOrigin origin; if ((whence & FfmpegCalls.SeekFlags.SeekSet) == 0) { origin = SeekOrigin.Begin; } else if ((whence & FfmpegCalls.SeekFlags.SeekCur) == FfmpegCalls.SeekFlags.SeekCur) { origin = SeekOrigin.Current; } else { if ((whence & FfmpegCalls.SeekFlags.SeekEnd) != FfmpegCalls.SeekFlags.SeekEnd) { return -1L; } origin = SeekOrigin.End; } try { return _stream.Seek(offset, origin); } catch (Exception) { return -1L; } } private int WriteDataCallback(IntPtr opaque, IntPtr buffer, int bufferSize) { byte[] array = new byte[bufferSize]; Marshal.Copy(buffer, array, 0, bufferSize); _stream.Write(array, 0, bufferSize); return bufferSize; } private int ReadDataCallback(IntPtr opaque, IntPtr buffer, int bufferSize) { byte[] array = new byte[bufferSize]; int num = 0; while (num < bufferSize) { int num2 = _stream.Read(array, num, bufferSize - num); num += num2; if (num2 == 0) { break; } } num = Math.Min(num, bufferSize); Marshal.Copy(array, 0, buffer, Math.Min(num, bufferSize)); Console.WriteLine("Read: " + num); return num; } public void Dispose() { GC.SuppressFinalize(this); if (AvioContext != null) { AvioContext.Dispose(); AvioContext = null; } } ~FfmpegStream() { Dispose(); } } public static class FfmpegUtils { private static readonly FfmpegCalls.LogCallback LogCallback; private static readonly FfmpegCalls.LogCallback DefaultLogCallback; private static readonly object LockObj; public static LogLevel LogLevel { get { return FfmpegCalls.GetLogLevel(); } set { if (value < LogLevel.Quit || value > LogLevel.Debug || (int)value % 8 != 0) { throw new InvalidEnumArgumentException("value", (int)value, typeof(LogLevel)); } FfmpegCalls.SetLogLevel(value); } } public static bool LogToDefaultLogger { get; set; } public static event EventHandler<FfmpegLogReceivedEventArgs> FfmpegLogReceived; public static event EventHandler<ResolveFfmpegAssemblyLocationEventArgs> ResolveFfmpegAssemblyLocation; unsafe static FfmpegUtils() { LockObj = new object(); LogCallback = OnLogMessage; DefaultLogCallback = FfmpegCalls.GetDefaultLogCallback(); FfmpegCalls.SetLogCallback(LogCallback); } public static IEnumerable<Format> GetOutputFormats() { AVOutputFormat[] outputFormats = FfmpegCalls.GetOutputFormats(); return outputFormats.Select((AVOutputFormat format) => new Format(format)); } public static IEnumerable<Format> GetInputFormats() { AVInputFormat[] inputFormats = FfmpegCalls.GetInputFormats(); return inputFormats.Select((AVInputFormat format) => new Format(format)); } private unsafe static void OnLogMessage(void* ptr, int level, byte* fmt, IntPtr vl) { lock (LockObj) { if (level >= 0) { level &= 0xFF; } if (level > (int)LogLevel) { return; } if (LogToDefaultLogger) { DefaultLogCallback(ptr, level, fmt, vl); } EventHandler<FfmpegLogReceivedEventArgs> ffmpegLogReceived = FfmpegUtils.FfmpegLogReceived; if (ffmpegLogReceived == null) { return; } AVClass? avClass = null; AVClass? parentLogContext = null; AVClass** ptr2 = default(AVClass**); if (ptr != null) { avClass = *(*(AVClass**)ptr); if (avClass.Value.parent_log_context_offset != 0) { ptr2 = *(AVClass***)((byte*)ptr + avClass.Value.parent_log_context_offset); if (ptr2 != null && *ptr2 != null) { parentLogContext = *(*ptr2); } } } int printPrefix = 1; string line = FfmpegCalls.FormatLine(ptr, level, Marshal.PtrToStringAnsi((IntPtr)fmt), vl, ref printPrefix); ffmpegLogReceived(null, new FfmpegLogReceivedEventArgs(avClass, parentLogContext, (LogLevel)level, line, ptr, ptr2)); } } internal static DirectoryInfo FindFfmpegDirectory(PlatformID platform) { EventHandler<ResolveFfmpegAssemblyLocationEventArgs> resolveFfmpegAssemblyLocation = FfmpegUtils.ResolveFfmpegAssemblyLocation; ResolveFfmpegAssemblyLocationEventArgs resolveFfmpegAssemblyLocationEventArgs = new ResolveFfmpegAssemblyLocationEventArgs(platform); resolveFfmpegAssemblyLocation?.Invoke(null, resolveFfmpegAssemblyLocationEventArgs); return resolveFfmpegAssemblyLocationEventArgs.FfmpegDirectory; } } public class Format { public string Name { get; private set; } public string LongName { get; private set; } public ReadOnlyCollection<AvCodecId> Codecs { get; private set; } public ReadOnlyCollection<string> FileExtensions { get; private set; } internal unsafe Format(AVOutputFormat format) { LongName = Marshal.PtrToStringAnsi((IntPtr)format.long_name); Name = Marshal.PtrToStringAnsi((IntPtr)format.name); Codecs = FfmpegCalls.GetCodecOfCodecTag(format.codec_tag).AsReadOnly(); string text = Marshal.PtrToStringAnsi((IntPtr)format.extensions); FileExtensions = ((!string.IsNullOrEmpty(text)) ? text.Split(new char[1] { ',' }).ToList().AsReadOnly() : Enumerable.Empty<string>().ToList().AsReadOnly()); } internal unsafe Format(AVInputFormat format) { LongName = Marshal.PtrToStringAnsi((IntPtr)format.long_name); Name = Marshal.PtrToStringAnsi((IntPtr)format.name); Codecs = FfmpegCalls.GetCodecOfCodecTag(format.codec_tag).AsReadOnly(); string text = Marshal.PtrToStringAnsi((IntPtr)format.extensions); FileExtensions = ((!string.IsNullOrEmpty(text)) ? text.Split(new char[1] { ',' }).ToList().AsReadOnly() : Enumerable.Empty<string>().ToList().AsReadOnly()); } } public enum LogLevel { Quit = -8, LogPanic = 0, Fatal = 8, Error = 16, Warning = 24, Info = 32, Verbose = 40, Debug = 48 } public class ResolveFfmpegAssemblyLocationEventArgs : EventArgs { public PlatformID Platform { get; private set; } public DirectoryInfo FfmpegDirectory { get; set; } internal ResolveFfmpegAssemblyLocationEventArgs(PlatformID platformId) { Platform = platformId; } } } namespace CSCore.Ffmpeg.Interops { internal class ConstCharPtrMarshaler : ICustomMarshaler { private static readonly ConstCharPtrMarshaler Instance = new ConstCharPtrMarshaler(); public object MarshalNativeToManaged(IntPtr pNativeData) { return Marshal.PtrToStringAnsi(pNativeData); } public IntPtr MarshalManagedToNative(object managedObj) { return IntPtr.Zero; } public void CleanUpNativeData(IntPtr pNativeData) { } public void CleanUpManagedData(object managedObj) { } public int GetNativeDataSize() { return IntPtr.Size; } public static ICustomMarshaler GetInstance(string cookie) { return Instance; } } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct AVBuffer { } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct AVBufferPool { } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct AVBPrint { } internal struct AVDictionary { internal int count; internal unsafe AVDictionaryEntry* elems; public AVDictionaryEntry[] Elements => GetElements(); private unsafe AVDictionaryEntry[] GetElements() { AVDictionaryEntry* ptr = elems; AVDictionaryEntry[] array = new AVDictionaryEntry[count]; for (int i = 0; i < count; i++) { array[i] = ptr[i]; } return array; } } internal struct AVCodecDescriptor { internal AvCodecId id; internal AVMediaType type; internal unsafe sbyte* name; internal unsafe sbyte* long_name; internal int props; internal unsafe sbyte** mime_types; internal unsafe AVProfile* profiles; } internal struct AVProfile { internal int profile; internal unsafe sbyte* name; } internal struct RcOverride { internal int start_frame; internal int end_frame; internal int qscale; internal float quality_factor; } internal struct AVPanScan { internal int id; internal int width; internal int height; internal unsafe fixed short position0[2]; internal unsafe fixed short position1[2]; internal unsafe fixed short position2[2]; } internal struct AVCPBProperties { internal int max_bitrate; internal int min_bitrate; internal int avg_bitrate; internal int buffer_size; internal ulong vbv_delay; } internal struct AVPacketSideData { internal unsafe sbyte* data; internal int size; internal AVPacketSideDataType type; } internal struct AVPacket { internal unsafe AVBufferRef* buf; internal long pts; internal long dts; internal unsafe sbyte* data; internal int size; internal int stream_index; internal int flags; internal unsafe AVPacketSideData* side_data; internal int side_data_elems; internal long duration; internal long pos; internal long convergence_duration; } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct AVCodecInternal { } internal struct AVCodecContext { internal unsafe AVClass* av_class; internal int log_level_offset; internal AVMediaType codec_type; internal unsafe AVCodec* codec; internal unsafe fixed sbyte codec_name[32]; internal AvCodecId codec_id; internal uint codec_tag; internal uint stream_codec_tag; internal unsafe void* priv_data; internal unsafe AVCodecInternal* @internal; internal unsafe void* opaque; internal long bit_rate; internal int bit_rate_tolerance; internal int global_quality; internal int compression_level; internal int flags; internal int flags2; internal unsafe sbyte* extradata; internal int extradata_size; internal AVRational time_base; internal int ticks_per_frame; internal int delay; internal int width; internal int height; internal int coded_width; internal int coded_height; internal int gop_size; internal AVPixelFormat pix_fmt; internal int me_method; internal IntPtr draw_horiz_band; internal IntPtr get_format; internal int max_b_frames; internal float b_quant_factor; internal int rc_strategy; internal int b_frame_strategy; internal float b_quant_offset; internal int has_b_frames; internal int mpeg_quant; internal float i_quant_factor; internal float i_quant_offset; internal float lumi_masking; internal float temporal_cplx_masking; internal float spatial_cplx_masking; internal float p_masking; internal float dark_masking; internal int slice_count; internal int prediction_method; internal unsafe int* slice_offset; internal AVRational sample_aspect_ratio; internal int me_cmp; internal int me_sub_cmp; internal int mb_cmp; internal int ildct_cmp; internal int dia_size; internal int last_predictor_count; internal int pre_me; internal int me_pre_cmp; internal int pre_dia_size; internal int me_subpel_quality; internal int dtg_active_format; internal int me_range; internal int intra_quant_bias; internal int inter_quant_bias; internal int slice_flags; internal int xvmc_acceleration; internal int mb_decision; internal unsafe ushort* intra_matrix; internal unsafe ushort* inter_matrix; internal int scenechange_threshold; internal int noise_reduction; internal int me_threshold; internal int mb_threshold; internal int intra_dc_precision; internal int skip_top; internal int skip_bottom; internal float border_masking; internal int mb_lmin; internal int mb_lmax; internal int me_penalty_compensation; internal int bidir_refine; internal int brd_scale; internal int keyint_min; internal int refs; internal int chromaoffset; internal int scenechange_factor; internal int mv0_threshold; internal int b_sensitivity; internal AVColorPrimaries color_primaries; internal AVColorTransferCharacteristic color_trc; internal AVColorSpace colorspace; internal AVColorRange color_range; internal AVChromaLocation chroma_sample_location; internal int slices; internal AVFieldOrder field_order; internal int sample_rate; internal int channels; internal AVSampleFormat sample_fmt; internal int frame_size; internal int frame_number; internal int block_align; internal int cutoff; internal ulong channel_layout; internal ulong request_channel_layout; internal AVAudioServiceType audio_service_type; internal AVSampleFormat request_sample_fmt; internal IntPtr get_buffer2; internal int refcounted_frames; internal float qcompress; internal float qblur; internal int qmin; internal int qmax; internal int max_qdiff; internal float rc_qsquish; internal float rc_qmod_amp; internal int rc_qmod_freq; internal int rc_buffer_size; internal int rc_override_count; internal unsafe RcOverride* rc_override; internal unsafe sbyte* rc_eq; internal long rc_max_rate; internal long rc_min_rate; internal float rc_buffer_aggressivity; internal float rc_initial_cplx; internal float rc_max_available_vbv_use; internal float rc_min_vbv_overflow_use; internal int rc_initial_buffer_occupancy; internal int coder_type; internal int context_model; internal int lmin; internal int lmax; internal int frame_skip_threshold; internal int frame_skip_factor; internal int frame_skip_exp; internal int frame_skip_cmp; internal int trellis; internal int min_prediction_order; internal int max_prediction_order; internal long timecode_frame_start; internal IntPtr rtp_callback; internal int rtp_payload_size; internal int mv_bits; internal int header_bits; internal int i_tex_bits; internal int p_tex_bits; internal int i_count; internal int p_count; internal int skip_count; internal int misc_bits; internal int frame_bits; internal unsafe sbyte* stats_out; internal unsafe sbyte* stats_in; internal int workaround_bugs; internal int strict_std_compliance; internal int error_concealment; internal int debug; internal int debug_mv; internal int err_recognition; internal long reordered_opaque; internal unsafe AVHWAccel* hwaccel; internal unsafe void* hwaccel_context; internal unsafe fixed ulong error[8]; internal int dct_algo; internal int idct_algo; internal int bits_per_coded_sample; internal int bits_per_raw_sample; internal int lowres; internal unsafe AVFrame* coded_frame; internal int thread_count; internal int thread_type; internal int active_thread_type; internal int thread_safe_callbacks; internal IntPtr execute; internal IntPtr execute2; internal int nsse_weight; internal int profile; internal int level; internal AVDiscard skip_loop_filter; internal AVDiscard skip_idct; internal AVDiscard skip_frame; internal unsafe sbyte* subtitle_header; internal int subtitle_header_size; internal int error_rate; internal ulong vbv_delay; internal int side_data_only_packets; internal int initial_padding; internal AVRational framerate; internal AVPixelFormat sw_pix_fmt; internal AVRational pkt_timebase; internal unsafe AVCodecDescriptor* codec_descriptor; internal long pts_correction_num_faulty_pts; internal long pts_correction_num_faulty_dts; internal long pts_correction_last_pts; internal long pts_correction_last_dts; internal unsafe sbyte* sub_charenc; internal int sub_charenc_mode; internal int skip_alpha; internal int seek_preroll; internal unsafe ushort* chroma_intra_matrix; internal unsafe sbyte* dump_separator; internal unsafe sbyte* codec_whitelist; internal uint properties; internal unsafe AVPacketSideData* coded_side_data; internal int nb_coded_side_data; internal unsafe AVBufferRef* hw_frames_ctx; internal int sub_text_format; internal int trailing_padding; } internal struct AVHWAccel { internal unsafe sbyte* name; internal AVMediaType type; internal AvCodecId id; internal AVPixelFormat pix_fmt; internal int capabilities; internal unsafe AVHWAccel* next; internal IntPtr alloc_frame; internal IntPtr start_frame; internal IntPtr decode_slice; internal IntPtr end_frame; internal int frame_priv_data_size; internal IntPtr decode_mb; internal IntPtr init; internal IntPtr uninit; internal int priv_data_size; } internal struct AVCodec { internal unsafe sbyte* name; internal unsafe sbyte* long_name; internal AVMediaType type; internal AvCodecId id; internal int capabilities; internal unsafe AVRational* supported_framerates; internal unsafe AVPixelFormat* pix_fmts; internal unsafe int* supported_samplerates; internal unsafe AVSampleFormat* sample_fmts; internal unsafe ulong* channel_layouts; internal sbyte max_lowres; internal unsafe AVClass* priv_class; internal unsafe AVProfile* profiles; internal int priv_data_size; internal unsafe AVCodec* next; internal IntPtr init_thread_copy; internal IntPtr update_thread_context; internal unsafe AVCodecDefault* defaults; internal IntPtr init_static_data; internal IntPtr init; internal IntPtr encode_sub; internal IntPtr encode2; internal IntPtr decode; internal IntPtr close; internal IntPtr send_frame; internal IntPtr send_packet; internal IntPtr receive_frame; internal IntPtr receive_packet; internal IntPtr flush; internal int caps_internal; } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct AVCodecDefault { } internal struct AVSubtitle { internal ushort format; internal uint start_display_time; internal uint end_display_time; internal uint num_rects; internal unsafe AVSubtitleRect** rects; internal long pts; } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct MpegEncContext { } internal struct AVPicture { internal unsafe sbyte* data0; internal unsafe sbyte* data1; internal unsafe sbyte* data2; internal unsafe sbyte* data3; internal unsafe sbyte* data4; internal unsafe sbyte* data5; internal unsafe sbyte* data6; internal unsafe sbyte* data7; internal unsafe fixed int linesize[8]; } internal struct AVSubtitleRect { internal int x; internal int y; internal int w; internal int h; internal int nb_colors; internal AVPicture pict; internal unsafe sbyte* data0; internal unsafe sbyte* data1; internal unsafe sbyte* data2; internal unsafe sbyte* data3; internal unsafe fixed int linesize[4]; internal AVSubtitleType type; internal unsafe sbyte* text; internal unsafe sbyte* ass; internal int flags; } internal struct AVCodecParameters { internal AVMediaType codec_type; internal AvCodecId codec_id; internal uint codec_tag; internal unsafe sbyte* extradata; internal int extradata_size; internal int format; internal long bit_rate; internal int bits_per_coded_sample; internal int bits_per_raw_sample; internal int profile; internal int level; internal int width; internal int height; internal AVRational sample_aspect_ratio; internal AVFieldOrder field_order; internal AVColorRange color_range; internal AVColorPrimaries color_primaries; internal AVColorTransferCharacteristic color_trc; internal AVColorSpace color_space; internal AVChromaLocation chroma_location; internal int video_delay; internal ulong channel_layout; internal int channels; internal int sample_rate; internal int block_align; internal int frame_size; internal int initial_padding; internal int trailing_padding; internal int seek_preroll; } internal struct AVCodecParserContext { internal unsafe void* priv_data; internal unsafe AVCodecParser* parser; internal long frame_offset; internal long cur_offset; internal long next_frame_offset; internal int pict_type; internal int repeat_pict; internal long pts; internal long dts; internal long last_pts; internal long last_dts; internal int fetch_timestamp; internal int cur_frame_start_index; internal unsafe fixed long cur_frame_offset[4]; internal unsafe fixed long cur_frame_pts[4]; internal unsafe fixed long cur_frame_dts[4]; internal int flags; internal long offset; internal unsafe fixed long cur_frame_end[4]; internal int key_frame; internal long convergence_duration; internal int dts_sync_point; internal int dts_ref_dts_delta; internal int pts_dts_delta; internal unsafe fixed long cur_frame_pos[4]; internal long pos; internal long last_pos; internal int duration; internal AVFieldOrder field_order; internal AVPictureStructure picture_structure; internal int output_picture_number; internal int width; internal int height; internal int coded_width; internal int coded_height; internal int format; } internal struct AVCodecParser { internal unsafe fixed int codec_ids[5]; internal int priv_data_size; internal IntPtr parser_init; internal IntPtr parser_parse; internal IntPtr parser_close; internal IntPtr split; internal unsafe AVCodecParser* next; } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct ReSampleContext { } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct AVResampleContext { } internal struct AVBitStreamFilterContext { internal unsafe void* priv_data; internal unsafe AVBitStreamFilter* filter; internal unsafe AVCodecParserContext* parser; internal unsafe AVBitStreamFilterContext* next; internal unsafe sbyte* args; } internal struct AVBitStreamFilter { internal unsafe sbyte* name; internal unsafe AvCodecId* codec_ids; internal unsafe AVClass* priv_class; internal int priv_data_size; internal IntPtr init; internal IntPtr filter; internal IntPtr close; } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct AVBSFInternal { } internal struct AVBSFContext { internal unsafe AVClass* av_class; internal unsafe AVBitStreamFilter* filter; internal unsafe AVBSFInternal* @internal; internal unsafe void* priv_data; internal unsafe AVCodecParameters* par_in; internal unsafe AVCodecParameters* par_out; internal AVRational time_base_in; internal AVRational time_base_out; } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct AVBSFList { } internal enum Motion_Est_ID { ME_ZERO = 1, ME_FULL = 2, ME_LOG = 3, ME_PHODS = 4, ME_EPZS = 5, ME_X1 = 6, ME_HEX = 7, ME_UMH = 8, ME_TESA = 9, ME_ITER = 50 } internal enum AVDiscard { AVDISCARD_NONE = -16, AVDISCARD_DEFAULT = 0, AVDISCARD_NONREF = 8, AVDISCARD_BIDIR = 16, AVDISCARD_NONINTRA = 24, AVDISCARD_NONKEY = 32, AVDISCARD_ALL = 48 } internal enum AVAudioServiceType { AV_AUDIO_SERVICE_TYPE_MAIN, AV_AUDIO_SERVICE_TYPE_EFFECTS, AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED, AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED, AV_AUDIO_SERVICE_TYPE_DIALOGUE, AV_AUDIO_SERVICE_TYPE_COMMENTARY, AV_AUDIO_SERVICE_TYPE_EMERGENCY, AV_AUDIO_SERVICE_TYPE_VOICE_OVER, AV_AUDIO_SERVICE_TYPE_KARAOKE, AV_AUDIO_SERVICE_TYPE_NB } internal enum AVPacketSideDataType { AV_PKT_DATA_PALETTE = 0, AV_PKT_DATA_NEW_EXTRADATA = 1, AV_PKT_DATA_PARAM_CHANGE = 2, AV_PKT_DATA_H263_MB_INFO = 3, AV_PKT_DATA_REPLAYGAIN = 4, AV_PKT_DATA_DISPLAYMATRIX = 5, AV_PKT_DATA_STEREO3D = 6, AV_PKT_DATA_AUDIO_SERVICE_TYPE = 7, AV_PKT_DATA_QUALITY_STATS = 8, AV_PKT_DATA_FALLBACK_TRACK = 9, AV_PKT_DATA_CPB_PROPERTIES = 10, AV_PKT_DATA_SKIP_SAMPLES = 70, AV_PKT_DATA_JP_DUALMONO = 71, AV_PKT_DATA_STRINGS_METADATA = 72, AV_PKT_DATA_SUBTITLE_POSITION = 73, AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL = 74, AV_PKT_DATA_WEBVTT_IDENTIFIER = 75, AV_PKT_DATA_WEBVTT_SETTINGS = 76, AV_PKT_DATA_METADATA_UPDATE = 77, AV_PKT_DATA_MPEGTS_STREAM_ID = 78, AV_PKT_DATA_MASTERING_DISPLAY_METADATA = 79 } internal enum AVSideDataParamChangeFlags { AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 1, AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 2, AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 4, AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 8 } internal enum AVFieldOrder { AV_FIELD_UNKNOWN, AV_FIELD_PROGRESSIVE, AV_FIELD_TT, AV_FIELD_BB, AV_FIELD_TB, AV_FIELD_BT } internal enum AVSubtitleType { SUBTITLE_NONE, SUBTITLE_BITMAP, SUBTITLE_TEXT, SUBTITLE_ASS } internal enum AVPictureStructure { AV_PICTURE_STRUCTURE_UNKNOWN, AV_PICTURE_STRUCTURE_TOP_FIELD, AV_PICTURE_STRUCTURE_BOTTOM_FIELD, AV_PICTURE_STRUCTURE_FRAME } internal enum AVLockOp { AV_LOCK_CREATE, AV_LOCK_OBTAIN, AV_LOCK_RELEASE, AV_LOCK_DESTROY } internal static class ffmpeg { internal const int LIBAVCODEC_VERSION_MAJOR = 57; internal const int LIBAVCODEC_VERSION_MINOR = 64; internal const int LIBAVCODEC_VERSION_MICRO = 100; internal const bool FF_API_VIMA_DECODER = true; internal const bool FF_API_AUDIO_CONVERT = true; internal const bool FF_API_AVCODEC_RESAMPLE = true; internal const bool FF_API_GETCHROMA = true; internal const bool FF_API_MISSING_SAMPLE = true; internal const bool FF_API_LOWRES = true; internal const bool FF_API_CAP_VDPAU = true; internal const bool FF_API_BUFS_VDPAU = true; internal const bool FF_API_VOXWARE = true; internal const bool FF_API_SET_DIMENSIONS = true; internal const bool FF_API_DEBUG_MV = true; internal const bool FF_API_AC_VLC = true; internal const bool FF_API_OLD_MSMPEG4 = true; internal const bool FF_API_ASPECT_EXTENDED = true; internal const bool FF_API_ARCH_ALPHA = true; internal const bool FF_API_ERROR_RATE = true; internal const bool FF_API_QSCALE_TYPE = true; internal const bool FF_API_MB_TYPE = true; internal const bool FF_API_MAX_BFRAMES = true; internal const bool FF_API_NEG_LINESIZES = true; internal const bool FF_API_EMU_EDGE = true; internal const bool FF_API_ARCH_SH4 = true; internal const bool FF_API_ARCH_SPARC = true; internal const bool FF_API_UNUSED_MEMBERS = true; internal const bool FF_API_IDCT_XVIDMMX = true; internal const bool FF_API_INPUT_PRESERVED = true; internal const bool FF_API_NORMALIZE_AQP = true; internal const bool FF_API_GMC = true; internal const bool FF_API_MV0 = true; internal const bool FF_API_CODEC_NAME = true; internal const bool FF_API_AFD = true; internal const bool FF_API_VISMV = true; internal const bool FF_API_AUDIOENC_DELAY = true; internal const bool FF_API_VAAPI_CONTEXT = true; internal const bool FF_API_AVCTX_TIMEBASE = true; internal const bool FF_API_MPV_OPT = true; internal const bool FF_API_STREAM_CODEC_TAG = true; internal const bool FF_API_QUANT_BIAS = true; internal const bool FF_API_RC_STRATEGY = true; internal const bool FF_API_CODED_FRAME = true; internal const bool FF_API_MOTION_EST = true; internal const bool FF_API_WITHOUT_PREFIX = true; internal const bool FF_API_SIDEDATA_ONLY_PKT = true; internal const bool FF_API_VDPAU_PROFILE = true; internal const bool FF_API_CONVERGENCE_DURATION = true; internal const bool FF_API_AVPICTURE = true; internal const bool FF_API_AVPACKET_OLD_API = true; internal const bool FF_API_RTP_CALLBACK = true; internal const bool FF_API_VBV_DELAY = true; internal const bool FF_API_CODER_TYPE = true; internal const bool FF_API_STAT_BITS = true; internal const bool FF_API_PRIVATE_OPT = true; internal const bool FF_API_ASS_TIMING = true; internal const bool FF_API_OLD_BSF = true; internal const bool FF_API_COPY_CONTEXT = true; internal const bool FF_API_GET_CONTEXT_DEFAULTS = true; internal const bool FF_API_NVENC_OLD_NAME = true; internal const int AV_CODEC_PROP_INTRA_ONLY = 1; internal const int AV_CODEC_PROP_LOSSY = 2; internal const int AV_CODEC_PROP_LOSSLESS = 4; internal const int AV_CODEC_PROP_REORDER = 8; internal const int AV_CODEC_PROP_BITMAP_SUB = 65536; internal const int AV_CODEC_PROP_TEXT_SUB = 131072; internal const int AV_INPUT_BUFFER_PADDING_SIZE = 32; internal const int AV_INPUT_BUFFER_MIN_SIZE = 16384; internal const int FF_INPUT_BUFFER_PADDING_SIZE = 32; internal const int FF_MIN_BUFFER_SIZE = 16384; internal const int FF_MAX_B_FRAMES = 16; internal const int AV_CODEC_FLAG_UNALIGNED = 1; internal const int AV_CODEC_FLAG_QSCALE = 2; internal const int AV_CODEC_FLAG_4MV = 4; internal const int AV_CODEC_FLAG_OUTPUT_CORRUPT = 8; internal const int AV_CODEC_FLAG_QPEL = 16; internal const int AV_CODEC_FLAG_PASS1 = 512; internal const int AV_CODEC_FLAG_PASS2 = 1024; internal const int AV_CODEC_FLAG_LOOP_FILTER = 2048; internal const int AV_CODEC_FLAG_GRAY = 8192; internal const int AV_CODEC_FLAG_PSNR = 32768; internal const int AV_CODEC_FLAG_TRUNCATED = 65536; internal const int AV_CODEC_FLAG_INTERLACED_DCT = 262144; internal const int AV_CODEC_FLAG_LOW_DELAY = 524288; internal const int AV_CODEC_FLAG_GLOBAL_HEADER = 4194304; internal const int AV_CODEC_FLAG_BITEXACT = 8388608; internal const int AV_CODEC_FLAG_AC_PRED = 16777216; internal const int AV_CODEC_FLAG_INTERLACED_ME = 536870912; internal const uint AV_CODEC_FLAG_CLOSED_GOP = 2147483648u; internal const int AV_CODEC_FLAG2_FAST = 1; internal const int AV_CODEC_FLAG2_NO_OUTPUT = 4; internal const int AV_CODEC_FLAG2_LOCAL_HEADER = 8; internal const int AV_CODEC_FLAG2_DROP_FRAME_TIMECODE = 8192; internal const int AV_CODEC_FLAG2_CHUNKS = 32768; internal const int AV_CODEC_FLAG2_IGNORE_CROP = 65536; internal const int AV_CODEC_FLAG2_SHOW_ALL = 4194304; internal const int AV_CODEC_FLAG2_EXPORT_MVS = 268435456; internal const int AV_CODEC_FLAG2_SKIP_MANUAL = 536870912; internal const int AV_CODEC_FLAG2_RO_FLUSH_NOOP = 1073741824; internal const int AV_CODEC_CAP_DRAW_HORIZ_BAND = 1; internal const int AV_CODEC_CAP_DR1 = 2; internal const int AV_CODEC_CAP_TRUNCATED = 8; internal const int AV_CODEC_CAP_DELAY = 32; internal const int AV_CODEC_CAP_SMALL_LAST_FRAME = 64; internal const int AV_CODEC_CAP_HWACCEL_VDPAU = 128; internal const int AV_CODEC_CAP_SUBFRAMES = 256; internal const int AV_CODEC_CAP_EXPERIMENTAL = 512; internal const int AV_CODEC_CAP_CHANNEL_CONF = 1024; internal const int AV_CODEC_CAP_FRAME_THREADS = 4096; internal const int AV_CODEC_CAP_SLICE_THREADS = 8192; internal const int AV_CODEC_CAP_PARAM_CHANGE = 16384; internal const int AV_CODEC_CAP_AUTO_THREADS = 32768; internal const int AV_CODEC_CAP_VARIABLE_FRAME_SIZE = 65536; internal const int AV_CODEC_CAP_AVOID_PROBING = 131072; internal const int AV_CODEC_CAP_INTRA_ONLY = 1073741824; internal const uint AV_CODEC_CAP_LOSSLESS = 2147483648u; internal const int CODEC_FLAG_UNALIGNED = 1; internal const int CODEC_FLAG_QSCALE = 2; internal const int CODEC_FLAG_4MV = 4; internal const int CODEC_FLAG_OUTPUT_CORRUPT = 8; internal const int CODEC_FLAG_QPEL = 16; internal const int CODEC_FLAG_GMC = 32; internal const int CODEC_FLAG_MV0 = 64; internal const int CODEC_FLAG_INPUT_PRESERVED = 256; internal const int CODEC_FLAG_PASS1 = 512; internal const int CODEC_FLAG_PASS2 = 1024; internal const int CODEC_FLAG_GRAY = 8192; internal const int CODEC_FLAG_EMU_EDGE = 16384; internal const int CODEC_FLAG_PSNR = 32768; internal const int CODEC_FLAG_TRUNCATED = 65536; internal const int CODEC_FLAG_NORMALIZE_AQP = 131072; internal const int CODEC_FLAG_INTERLACED_DCT = 262144; internal const int CODEC_FLAG_LOW_DELAY = 524288; internal const int CODEC_FLAG_GLOBAL_HEADER = 4194304; internal const int CODEC_FLAG_BITEXACT = 8388608; internal const int CODEC_FLAG_AC_PRED = 16777216; internal const int CODEC_FLAG_LOOP_FILTER = 2048; internal const int CODEC_FLAG_INTERLACED_ME = 536870912; internal const uint CODEC_FLAG_CLOSED_GOP = 2147483648u; internal const int CODEC_FLAG2_FAST = 1; internal const int CODEC_FLAG2_NO_OUTPUT = 4; internal const int CODEC_FLAG2_LOCAL_HEADER = 8; internal const int CODEC_FLAG2_DROP_FRAME_TIMECODE = 8192; internal const int CODEC_FLAG2_IGNORE_CROP = 65536; internal const int CODEC_FLAG2_CHUNKS = 32768; internal const int CODEC_FLAG2_SHOW_ALL = 4194304; internal const int CODEC_FLAG2_EXPORT_MVS = 268435456; internal const int CODEC_FLAG2_SKIP_MANUAL = 536870912; internal const int CODEC_CAP_DRAW_HORIZ_BAND = 1; internal const int CODEC_CAP_DR1 = 2; internal const int CODEC_CAP_TRUNCATED = 8; internal const int CODEC_CAP_HWACCEL = 16; internal const int CODEC_CAP_DELAY = 32; internal const int CODEC_CAP_SMALL_LAST_FRAME = 64; internal const int CODEC_CAP_HWACCEL_VDPAU = 128; internal const int CODEC_CAP_SUBFRAMES = 256; internal const int CODEC_CAP_EXPERIMENTAL = 512; internal const int CODEC_CAP_CHANNEL_CONF = 1024; internal const int CODEC_CAP_NEG_LINESIZES = 2048; internal const int CODEC_CAP_FRAME_THREADS = 4096; internal const int CODEC_CAP_SLICE_THREADS = 8192; internal const int CODEC_CAP_PARAM_CHANGE = 16384; internal const int CODEC_CAP_AUTO_THREADS = 32768; internal const int CODEC_CAP_VARIABLE_FRAME_SIZE = 65536; internal const int CODEC_CAP_INTRA_ONLY = 1073741824; internal const uint CODEC_CAP_LOSSLESS = 2147483648u; internal const int HWACCEL_CODEC_CAP_EXPERIMENTAL = 512; internal const int MB_TYPE_INTRA4x4 = 1; internal const int MB_TYPE_INTRA16x16 = 2; internal const int MB_TYPE_INTRA_PCM = 4; internal const int MB_TYPE_16x16 = 8; internal const int MB_TYPE_16x8 = 16; internal const int MB_TYPE_8x16 = 32; internal const int MB_TYPE_8x8 = 64; internal const int MB_TYPE_INTERLACED = 128; internal const int MB_TYPE_DIRECT2 = 256; internal const int MB_TYPE_ACPRED = 512; internal const int MB_TYPE_GMC = 1024; internal const int MB_TYPE_SKIP = 2048; internal const int MB_TYPE_P0L0 = 4096; internal const int MB_TYPE_P1L0 = 8192; internal const int MB_TYPE_P0L1 = 16384; internal const int MB_TYPE_P1L1 = 32768; internal const int MB_TYPE_L0 = 12288; internal const int MB_TYPE_L1 = 49152; internal const int MB_TYPE_L0L1 = 61440; internal const int MB_TYPE_QUANT = 65536; internal const int MB_TYPE_CBP = 131072; internal const int FF_QSCALE_TYPE_MPEG1 = 0; internal const int FF_QSCALE_TYPE_MPEG2 = 1; internal const int FF_QSCALE_TYPE_H264 = 2; internal const int FF_QSCALE_TYPE_VP56 = 3; internal const int AV_GET_BUFFER_FLAG_REF = 1; internal const int AV_PKT_FLAG_KEY = 1; internal const int AV_PKT_FLAG_CORRUPT = 2; internal const int AV_PKT_FLAG_DISCARD = 4; internal const int FF_COMPRESSION_DEFAULT = -1; internal const int FF_ASPECT_EXTENDED = 15; internal const int FF_RC_STRATEGY_XVID = 1; internal const int FF_PRED_LEFT = 0; internal const int FF_PRED_PLANE = 1; internal const int FF_PRED_MEDIAN = 2; internal const int FF_CMP_SAD = 0; internal const int FF_CMP_SSE = 1; internal const int FF_CMP_SATD = 2; internal const int FF_CMP_DCT = 3; internal const int FF_CMP_PSNR = 4; internal const int FF_CMP_BIT = 5; internal const int FF_CMP_RD = 6; internal const int FF_CMP_ZERO = 7; internal const int FF_CMP_VSAD = 8; internal const int FF_CMP_VSSE = 9; internal const int FF_CMP_NSSE = 10; internal const int FF_CMP_W53 = 11; internal const int FF_CMP_W97 = 12; internal const int FF_CMP_DCTMAX = 13; internal const int FF_CMP_DCT264 = 14; internal const int FF_CMP_MEDIAN_SAD = 15; internal const int FF_CMP_CHROMA = 256; internal const int FF_DTG_AFD_SAME = 8; internal const int FF_DTG_AFD_4_3 = 9; internal const int FF_DTG_AFD_16_9 = 10; internal const int FF_DTG_AFD_14_9 = 11; internal const int FF_DTG_AFD_4_3_SP_14_9 = 13; internal const int FF_DTG_AFD_16_9_SP_14_9 = 14; internal const int FF_DTG_AFD_SP_4_3 = 15; internal const int FF_DEFAULT_QUANT_BIAS = 999999; internal const int SLICE_FLAG_CODED_ORDER = 1; internal const int SLICE_FLAG_ALLOW_FIELD = 2; internal const int SLICE_FLAG_ALLOW_PLANE = 4; internal const int FF_MB_DECISION_SIMPLE = 0; internal const int FF_MB_DECISION_BITS = 1; internal const int FF_MB_DECISION_RD = 2; internal const int FF_CODER_TYPE_VLC = 0; internal const int FF_CODER_TYPE_AC = 1; internal const int FF_CODER_TYPE_RAW = 2; internal const int FF_CODER_TYPE_RLE = 3; internal const int FF_CODER_TYPE_DEFLATE = 4; internal const int FF_BUG_AUTODETECT = 1; internal const int FF_BUG_OLD_MSMPEG4 = 2; internal const int FF_BUG_XVID_ILACE = 4; internal const int FF_BUG_UMP4 = 8; internal const int FF_BUG_NO_PADDING = 16; internal const int FF_BUG_AMV = 32; internal const int FF_BUG_AC_VLC = 0; internal const int FF_BUG_QPEL_CHROMA = 64; internal const int FF_BUG_STD_QPEL = 128; internal const int FF_BUG_QPEL_CHROMA2 = 256; internal const int FF_BUG_DIRECT_BLOCKSIZE = 512; internal const int FF_BUG_EDGE = 1024; internal const int FF_BUG_HPEL_CHROMA = 2048; internal const int FF_BUG_DC_CLIP = 4096; internal const int FF_BUG_MS = 8192; internal const int FF_BUG_TRUNCATED = 16384; internal const int FF_COMPLIANCE_VERY_STRICT = 2; internal const int FF_COMPLIANCE_STRICT = 1; internal const int FF_COMPLIANCE_NORMAL = 0; internal const int FF_COMPLIANCE_UNOFFICIAL = -1; internal const int FF_COMPLIANCE_EXPERIMENTAL = -2; internal const int FF_EC_GUESS_MVS = 1; internal const int FF_EC_DEBLOCK = 2; internal const int FF_EC_FAVOR_INTER = 256; internal const int FF_DEBUG_PICT_INFO = 1; internal const int FF_DEBUG_RC = 2; internal const int FF_DEBUG_BITSTREAM = 4; internal const int FF_DEBUG_MB_TYPE = 8; internal const int FF_DEBUG_QP = 16; internal const int FF_DEBUG_MV = 32; internal const int FF_DEBUG_DCT_COEFF = 64; internal const int FF_DEBUG_SKIP = 128; internal const int FF_DEBUG_STARTCODE = 256; internal const int FF_DEBUG_PTS = 512; internal const int FF_DEBUG_ER = 1024; internal const int FF_DEBUG_MMCO = 2048; internal const int FF_DEBUG_BUGS = 4096; internal const int FF_DEBUG_VIS_QP = 8192; internal const int FF_DEBUG_VIS_MB_TYPE = 16384; internal const int FF_DEBUG_BUFFERS = 32768; internal const int FF_DEBUG_THREADS = 65536; internal const int FF_DEBUG_GREEN_MD = 8388608; internal const int FF_DEBUG_NOMC = 16777216; internal const int FF_DEBUG_VIS_MV_P_FOR = 1; internal const int FF_DEBUG_VIS_MV_B_FOR = 2; internal const int FF_DEBUG_VIS_MV_B_BACK = 4; internal const int AV_EF_CRCCHECK = 1; internal const int AV_EF_BITSTREAM = 2; internal const int AV_EF_BUFFER = 4; internal const int AV_EF_EXPLODE = 8; internal const int AV_EF_IGNORE_ERR = 32768; internal const int AV_EF_CAREFUL = 65536; internal const int AV_EF_COMPLIANT = 131072; internal const int AV_EF_AGGRESSIVE = 262144; internal const int FF_DCT_AUTO = 0; internal const int FF_DCT_FASTINT = 1; internal const int FF_DCT_INT = 2; internal const int FF_DCT_MMX = 3; internal const int FF_DCT_ALTIVEC = 5; internal const int FF_DCT_FAAN = 6; internal const int FF_IDCT_AUTO = 0; internal const int FF_IDCT_INT = 1; internal const int FF_IDCT_SIMPLE = 2; internal const int FF_IDCT_SIMPLEMMX = 3; internal const int FF_IDCT_ARM = 7; internal const int FF_IDCT_ALTIVEC = 8; internal const int FF_IDCT_SH4 = 9; internal const int FF_IDCT_SIMPLEARM = 10; internal const int FF_IDCT_IPP = 13; internal const int FF_IDCT_XVID = 14; internal const int FF_IDCT_XVIDMMX = 14; internal const int FF_IDCT_SIMPLEARMV5TE = 16; internal const int FF_IDCT_SIMPLEARMV6 = 17; internal const int FF_IDCT_SIMPLEVIS = 18; internal const int FF_IDCT_FAAN = 20; internal const int FF_IDCT_SIMPLENEON = 22; internal const int FF_IDCT_SIMPLEALPHA = 23; internal const int FF_IDCT_SIMPLEAUTO = 128; internal const int FF_THREAD_FRAME = 1; internal const int FF_THREAD_SLICE = 2; internal const int FF_PROFILE_UNKNOWN = -99; internal const int FF_PROFILE_RESERVED = -100; internal const int FF_PROFILE_AAC_MAIN = 0; internal const int FF_PROFILE_AAC_LOW = 1; internal const int FF_PROFILE_AAC_SSR = 2; internal const int FF_PROFILE_AAC_LTP = 3; internal const int FF_PROFILE_AAC_HE = 4; internal const int FF_PROFILE_AAC_HE_V2 = 28; internal const int FF_PROFILE_AAC_LD = 22; internal const int FF_PROFILE_AAC_ELD = 38; internal const int FF_PROFILE_MPEG2_AAC_LOW = 128; internal const int FF_PROFILE_MPEG2_AAC_HE = 131; internal const int FF_PROFILE_DNXHD = 0; internal const int FF_PROFILE_DNXHR_LB = 1; internal const int FF_PROFILE_DNXHR_SQ = 2; internal const int FF_PROFILE_DNXHR_HQ = 3; internal const int FF_PROFILE_DNXHR_HQX = 4; internal const int FF_PROFILE_DNXHR_444 = 5; internal const int FF_PROFILE_DTS = 20; internal const int FF_PROFILE_DTS_ES = 30; internal const int FF_PROFILE_DTS_96_24 = 40; internal const int FF_PROFILE_DTS_HD_HRA = 50; internal const int FF_PROFILE_DTS_HD_MA = 60; internal const int FF_PROFILE_DTS_EXPRESS = 70; internal const int FF_PROFILE_MPEG2_422 = 0; internal const int FF_PROFILE_MPEG2_HIGH = 1; internal const int FF_PROFILE_MPEG2_SS = 2; internal const int FF_PROFILE_MPEG2_SNR_SCALABLE = 3; internal const int FF_PROFILE_MPEG2_MAIN = 4; internal const int FF_PROFILE_MPEG2_SIMPLE = 5; internal const int FF_PROFILE_H264_CONSTRAINED = 512; internal const int FF_PROFILE_H264_INTRA = 2048; internal const int FF_PROFILE_H264_BASELINE = 66; internal const int FF_PROFILE_H264_CONSTRAINED_BASELINE = 578; internal const int FF_PROFILE_H264_MAIN = 77; internal const int FF_PROFILE_H264_EXTENDED = 88; internal const int FF_PROFILE_H264_HIGH = 100; internal const int FF_PROFILE_H264_HIGH_10 = 110; internal const int FF_PROFILE_H264_HIGH_10_INTRA = 2158; internal const int FF_PROFILE_H264_MULTIVIEW_HIGH = 118; internal const int FF_PROFILE_H264_HIGH_422 = 122; internal const int FF_PROFILE_H264_HIGH_422_INTRA = 2170; internal const int FF_PROFILE_H264_STEREO_HIGH = 128; internal const int FF_PROFILE_H264_HIGH_444 = 144; internal const int FF_PROFILE_H264_HIGH_444_PREDICTIVE = 244; internal const int FF_PROFILE_H264_HIGH_444_INTRA = 2292; internal const int FF_PROFILE_H264_CAVLC_444 = 44; internal const int FF_PROFILE_VC1_SIMPLE = 0; internal const int FF_PROFILE_VC1_MAIN = 1; internal const int FF_PROFILE_VC1_COMPLEX = 2; internal const int FF_PROFILE_VC1_ADVANCED = 3; internal const int FF_PROFILE_MPEG4_SIMPLE = 0; internal const int FF_PROFILE_MPEG4_SIMPLE_SCALABLE = 1; internal const int FF_PROFILE_MPEG4_CORE = 2; internal const int FF_PROFILE_MPEG4_MAIN = 3; internal const int FF_PROFILE_MPEG4_N_BIT = 4; internal const int FF_PROFILE_MPEG4_SCALABLE_TEXTURE = 5; internal const int FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION = 6; internal const int FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE = 7; internal const int FF_PROFILE_MPEG4_HYBRID = 8; internal const int FF_PROFILE_MPEG4_ADVANCED_REAL_TIME = 9; internal const int FF_PROFILE_MPEG4_CORE_SCALABLE = 10; internal const int FF_PROFILE_MPEG4_ADVANCED_CODING = 11; internal const int FF_PROFILE_MPEG4_ADVANCED_CORE = 12; internal const int FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE = 13; internal const int FF_PROFILE_MPEG4_SIMPLE_STUDIO = 14; internal const int FF_PROFILE_MPEG4_ADVANCED_SIMPLE = 15; internal const int FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 = 1; internal const int FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 = 2; internal const int FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION = 32768; internal const int FF_PROFILE_JPEG2000_DCINEMA_2K = 3; internal const int FF_PROFILE_JPEG2000_DCINEMA_4K = 4; internal const int FF_PROFILE_VP9_0 = 0; internal const int FF_PROFILE_VP9_1 = 1; internal const int FF_PROFILE_VP9_2 = 2; internal const int FF_PROFILE_VP9_3 = 3; internal const int FF_PROFILE_HEVC_MAIN = 1; internal const int FF_PROFILE_HEVC_MAIN_10 = 2; internal const int FF_PROFILE_HEVC_MAIN_STILL_PICTURE = 3; internal const int FF_PROFILE_HEVC_REXT = 4; internal const int FF_LEVEL_UNKNOWN = -99; internal const int FF_SUB_CHARENC_MODE_DO_NOTHING = -1; internal const int FF_SUB_CHARENC_MODE_AUTOMATIC = 0; internal const int FF_SUB_CHARENC_MODE_PRE_DECODER = 1; internal const int FF_CODEC_PROPERTY_LOSSLESS = 1; internal const int FF_CODEC_PROPERTY_CLOSED_CAPTIONS = 2; internal const int FF_SUB_TEXT_FMT_ASS = 0; internal const int FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS = 1; internal const int AV_HWACCEL_FLAG_IGNORE_LEVEL = 1; internal const int AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH = 2; internal const int AV_SUBTITLE_FLAG_FORCED = 1; internal const int AV_PARSER_PTS_NB = 4; internal const int PARSER_FLAG_COMPLETE_FRAMES = 1; internal const int PARSER_FLAG_ONCE = 2; internal const int PARSER_FLAG_FETCHED_OFFSET = 4; internal const int PARSER_FLAG_USE_CODEC_TS = 4096; private const string libavcodec = "avcodec-57"; internal const int LIBAVFORMAT_VERSION_MAJOR = 57; internal const int LIBAVFORMAT_VERSION_MINOR = 56; internal const int LIBAVFORMAT_VERSION_MICRO = 100; internal const bool FF_API_LAVF_BITEXACT = true; internal const bool FF_API_LAVF_FRAC = true; internal const bool FF_API_LAVF_CODEC_TB = true; internal const bool FF_API_URL_FEOF = true; internal const bool FF_API_LAVF_FMT_RAWPICTURE = true; internal const bool FF_API_COMPUTE_PKT_FIELDS2 = true; internal const bool FF_API_OLD_OPEN_CALLBACKS = true; internal const bool FF_API_LAVF_AVCTX = true; internal const bool FF_API_NOCONST_GET_SIDE_DATA = true; internal const bool FF_API_HTTP_USER_AGENT = true; internal const int FF_API_R_FRAME_RATE = 1; internal const int AVIO_SEEKABLE_NORMAL = 1; internal const int AVSEEK_SIZE = 65536; internal const int AVSEEK_FORCE = 131072; internal const int AVIO_FLAG_READ = 1; internal const int AVIO_FLAG_WRITE = 2; internal const int AVIO_FLAG_READ_WRITE = 3; internal const int AVIO_FLAG_NONBLOCK = 8; internal const int AVIO_FLAG_DIRECT = 32768; internal const int AVPROBE_SCORE_RETRY = 25; internal const int AVPROBE_SCORE_STREAM_RETRY = 24; internal const int AVPROBE_SCORE_EXTENSION = 50; internal const int AVPROBE_SCORE_MIME = 75; internal const int AVPROBE_SCORE_MAX = 100; internal const int AVPROBE_PADDING_SIZE = 32; internal const int AVFMT_NOFILE = 1; internal const int AVFMT_NEEDNUMBER = 2; internal const int AVFMT_SHOW_IDS = 8; internal const int AVFMT_RAWPICTURE = 32; internal const int AVFMT_GLOBALHEADER = 64; internal const int AVFMT_NOTIMESTAMPS = 128; internal const int AVFMT_GENERIC_INDEX = 256; internal const int AVFMT_TS_DISCONT = 512; internal const int AVFMT_VARIABLE_FPS = 1024; internal const int AVFMT_NODIMENSIONS = 2048; internal const int AVFMT_NOSTREAMS = 4096; internal const int AVFMT_NOBINSEARCH = 8192; internal const int AVFMT_NOGENSEARCH = 16384; internal const int AVFMT_NO_BYTE_SEEK = 32768; internal const int AVFMT_ALLOW_FLUSH = 65536; internal const int AVFMT_TS_NONSTRICT = 131072; internal const int AVFMT_TS_NEGATIVE = 262144; internal const int AVFMT_SEEK_TO_PTS = 67108864; internal const int AVINDEX_KEYFRAME = 1; internal const int AVINDEX_DISCARD_FRAME = 2; internal const int AV_DISPOSITION_DEFAULT = 1; internal const int AV_DISPOSITION_DUB = 2; internal const int AV_DISPOSITION_ORIGINAL = 4; internal const int AV_DISPOSITION_COMMENT = 8; internal const int AV_DISPOSITION_LYRICS = 16; internal const int AV_DISPOSITION_KARAOKE = 32; internal const int AV_DISPOSITION_FORCED = 64; internal const int AV_DISPOSITION_HEARING_IMPAIRED = 128; internal const int AV_DISPOSITION_VISUAL_IMPAIRED = 256; internal const int AV_DISPOSITION_CLEAN_EFFECTS = 512; internal const int AV_DISPOSITION_ATTACHED_PIC = 1024; internal const int AV_DISPOSITION_TIMED_THUMBNAILS = 2048; internal const int AV_DISPOSITION_CAPTIONS = 65536; internal const int AV_DISPOSITION_DESCRIPTIONS = 131072; internal const int AV_DISPOSITION_METADATA = 262144; internal const int AV_PTS_WRAP_IGNORE = 0; internal const int AV_PTS_WRAP_ADD_OFFSET = 1; internal const int AV_PTS_WRAP_SUB_OFFSET = -1; internal const int AVSTREAM_EVENT_FLAG_METADATA_UPDATED = 1; internal const int MAX_STD_TIMEBASES = 399; internal const int MAX_REORDER_DELAY = 16; internal const int AV_PROGRAM_RUNNING = 1; internal const int AVFMTCTX_NOHEADER = 1; internal const int AVFMT_FLAG_GENPTS = 1; internal const int AVFMT_FLAG_IGNIDX = 2; internal const int AVFMT_FLAG_NONBLOCK = 4; internal const int AVFMT_FLAG_IGNDTS = 8; internal const int AVFMT_FLAG_NOFILLIN = 16; internal const int AVFMT_FLAG_NOPARSE = 32; internal const int AVFMT_FLAG_NOBUFFER = 64; internal const int AVFMT_FLAG_CUSTOM_IO = 128; internal const int AVFMT_FLAG_DISCARD_CORRUPT = 256; internal const int AVFMT_FLAG_FLUSH_PACKETS = 512; internal const int AVFMT_FLAG_BITEXACT = 1024; internal const int AVFMT_FLAG_MP4A_LATM = 32768; internal const int AVFMT_FLAG_SORT_DTS = 65536; internal const int AVFMT_FLAG_PRIV_OPT = 131072; internal const int AVFMT_FLAG_KEEP_SIDE_DATA = 262144; internal const int AVFMT_FLAG_FAST_SEEK = 524288; internal const int AVFMT_FLAG_SHORTEST = 1048576; internal const int AVFMT_FLAG_AUTO_BSF = 2097152; internal const int FF_FDEBUG_TS = 1; internal const int AVFMT_EVENT_FLAG_METADATA_UPDATED = 1; internal const int AVFMT_AVOID_NEG_TS_AUTO = -1; internal const int AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE = 1; internal const int AVFMT_AVOID_NEG_TS_MAKE_ZERO = 2; internal const int AVSEEK_FLAG_BACKWARD = 1; internal const int AVSEEK_FLAG_BYTE = 2; internal const int AVSEEK_FLAG_ANY = 4; internal const int AVSEEK_FLAG_FRAME = 8; internal const int AVSTREAM_INIT_IN_WRITE_HEADER = 0; internal const int AVSTREAM_INIT_IN_INIT_OUTPUT = 1; internal const int AV_FRAME_FILENAME_FLAGS_MULTIPLE = 1; private const string libavformat = "avformat-57"; internal const int __STDC_CONSTANT_MACROS = 1; internal const int AVCODEC_D3D11VA_H = 1; internal const int AVCODEC_DXVA2_H = 1; internal const int AVCODEC_QSV_H = 1; internal const int AVCODEC_VDA_H = 1; internal const int AVCODEC_VDPAU_H = 1; internal const int AVCODEC_VIDEOTOOLBOX_H = 1; internal const int AVCODEC_XVMC_H = 1; internal const int FF_LAMBDA_SHIFT = 7; internal const int FF_LAMBDA_SCALE = 128; internal const int FF_QP2LAMBDA = 118; internal const int FF_LAMBDA_MAX = 32767; internal const int FF_QUALITY_SCALE = 128; internal const ulong AV_NOPTS_VALUE = 9223372036854775808uL; internal const int AV_TIME_BASE = 1000000; internal const int LIBAVUTIL_VERSION_MAJOR = 55; internal const int LIBAVUTIL_VERSION_MINOR = 34; internal const int LIBAVUTIL_VERSION_MICRO = 100; internal const bool FF_API_VDPAU = true; internal const bool FF_API_XVMC = true; internal const bool FF_API_OPT_TYPE_METADATA = true; internal const bool FF_API_DLOG = true; internal const bool FF_API_VAAPI = true; internal const bool FF_API_FRAME_QP = true; internal const bool FF_API_PLUS1_MINUS1 = true; internal const bool FF_API_ERROR_FRAME = true; internal const bool FF_API_CRC_BIG_TABLE = true; internal const bool FF_API_PKT_PTS = true; internal const int AV_HAVE_BIGENDIAN = 0; internal const int AV_HAVE_FAST_UNALIGNED = 1; internal const int AV_ERROR_MAX_STRING_SIZE = 64; internal const double M_E = Math.E; internal const double M_LN2 = 0.6931471805599453; internal const double M_LN10 = 2.302585092994046; internal const double M_LOG2_10 = 3.321928094887362; internal const double M_PHI = 1.618033988749895; internal const double M_PI = Math.PI; internal const double M_PI_2 = Math.PI / 2.0; internal const double M_SQRT1_2 = 0.7071067811865476; internal const double M_SQRT2 = 1.4142135623730951; internal const int AV_LOG_QUIET = -8; internal const int AV_LOG_PANIC = 0; internal const int AV_LOG_FATAL = 8; internal const int AV_LOG_ERROR = 16; internal const int AV_LOG_WARNING = 24; internal const int AV_LOG_INFO = 32; internal const int AV_LOG_VERBOSE = 40; internal const int AV_LOG_DEBUG = 48; internal const int AV_LOG_TRACE = 56; internal const int AV_LOG_MAX_OFFSET = 64; internal const int AV_LOG_SKIP_REPEATED = 1; internal const int AV_LOG_PRINT_LEVEL = 2; internal const int AVPALETTE_SIZE = 1024; internal const int AVPALETTE_COUNT = 256; internal const int AV_CH_FRONT_LEFT = 1; internal const int AV_CH_FRONT_RIGHT = 2; internal const int AV_CH_FRONT_CENTER = 4; internal const int AV_CH_LOW_FREQUENCY = 8; internal const int AV_CH_BACK_LEFT = 16; internal const int AV_CH_BACK_RIGHT = 32; internal const int AV_CH_FRONT_LEFT_OF_CENTER = 64; internal const int AV_CH_FRONT_RIGHT_OF_CENTER = 128; internal const int AV_CH_BACK_CENTER = 256; internal const int AV_CH_SIDE_LEFT = 512; internal const int AV_CH_SIDE_RIGHT = 1024; internal const int AV_CH_TOP_CENTER = 2048; internal const int AV_CH_TOP_FRONT_LEFT = 4096; internal const int AV_CH_TOP_FRONT_CENTER = 8192; internal const int AV_CH_TOP_FRONT_RIGHT = 16384; internal const int AV_CH_TOP_BACK_LEFT = 32768; internal const int AV_CH_TOP_BACK_CENTER = 65536; internal const int AV_CH_TOP_BACK_RIGHT = 131072; internal const int AV_CH_STEREO_LEFT = 536870912; internal const int AV_CH_STEREO_RIGHT = 1073741824; internal const ulong AV_CH_WIDE_LEFT = 2147483648uL; internal const ulong AV_CH_WIDE_RIGHT = 4294967296uL; internal const ulong AV_CH_SURROUND_DIRECT_LEFT = 8589934592uL; internal const ulong AV_CH_SURROUND_DIRECT_RIGHT = 17179869184uL; internal const ulong AV_CH_LOW_FREQUENCY_2 = 34359738368uL; internal const ulong AV_CH_LAYOUT_NATIVE = 9223372036854775808uL; internal const int AV_CH_LAYOUT_MONO = 4; internal const int AV_CH_LAYOUT_STEREO = 3; internal const int AV_CH_LAYOUT_2POINT1 = 11; internal const int AV_CH_LAYOUT_2_1 = 259; internal const int AV_CH_LAYOUT_SURROUND = 7; internal const int AV_CH_LAYOUT_3POINT1 = 15; internal const int AV_CH_LAYOUT_4POINT0 = 263; internal const int AV_CH_LAYOUT_4POINT1 = 271; internal const int AV_CH_LAYOUT_2_2 = 1539; internal const int AV_CH_LAYOUT_QUAD = 51; internal const int AV_CH_LAYOUT_5POINT0 = 1543; internal const int AV_CH_LAYOUT_5POINT1 = 1551; internal const int AV_CH_LAYOUT_5POINT0_BACK = 55; internal const int AV_CH_LAYOUT_5POINT1_BACK = 63; internal const int AV_CH_LAYOUT_6POINT0 = 1799; internal const int AV_CH_LAYOUT_6POINT0_FRONT = 1731; internal const int AV_CH_LAYOUT_HEXAGONAL = 311; internal const int AV_CH_LAYOUT_6POINT1 = 1807; internal const int AV_CH_LAYOUT_6POINT1_BACK = 319; internal const int AV_CH_LAYOUT_6POINT1_FRONT = 1739; internal const int AV_CH_LAYOUT_7POINT0 = 1591; internal const int AV_CH_LAYOUT_7POINT0_FRONT = 1735; internal const int AV_CH_LAYOUT_7POINT1 = 1599; internal const int AV_CH_LAYOUT_7POINT1_WIDE = 1743; internal const int AV_CH_LAYOUT_7POINT1_WIDE_BACK = 255; internal const int AV_CH_LAYOUT_OCTAGONAL = 1847; internal const ulong AV_CH_LAYOUT_HEXADECAGONAL = 6442710839uL; internal const int AV_CH_LAYOUT_STEREO_DOWNMIX = 1610612736; internal const uint AV_CPU_FLAG_FORCE = 2147483648u; internal const int AV_CPU_FLAG_MMX = 1; internal const int AV_CPU_FLAG_MMXEXT = 2; internal const int AV_CPU_FLAG_MMX2 = 2; internal const int AV_CPU_FLAG_3DNOW = 4; internal const int AV_CPU_FLAG_SSE = 8; internal const int AV_CPU_FLAG_SSE2 = 16; internal const int AV_CPU_FLAG_SSE2SLOW = 1073741824; internal const int AV_CPU_FLAG_3DNOWEXT = 32; internal const int AV_CPU_FLAG_SSE3 = 64; internal const int AV_CPU_FLAG_SSE3SLOW = 536870912; internal const int AV_CPU_FLAG_SSSE3 = 128; internal const int AV_CPU_FLAG_ATOM = 268435456; internal const int AV_CPU_FLAG_SSE4 = 256; internal const int AV_CPU_FLAG_SSE42 = 512; internal const int AV_CPU_FLAG_AESNI = 524288; internal const int AV_CPU_FLAG_AVX = 16384; internal const int AV_CPU_FLAG_AVXSLOW = 134217728; internal const int AV_CPU_FLAG_XOP = 1024; internal const int AV_CPU_FLAG_FMA4 = 2048; internal const int AV_CPU_FLAG_CMOV = 4096; internal const int AV_CPU_FLAG_AVX2 = 32768; internal const int AV_CPU_FLAG_FMA3 = 65536; internal const int AV_CPU_FLAG_BMI1 = 131072; internal const int AV_CPU_FLAG_BMI2 = 262144; internal const int AV_CPU_FLAG_ALTIVEC = 1; internal const int AV_CPU_FLAG_VSX = 2; internal const int AV_CPU_FLAG_POWER8 = 4; internal const int AV_CPU_FLAG_ARMV5TE = 1; internal const int AV_CPU_FLAG_ARMV6 = 2; internal const int AV_CPU_FLAG_ARMV6T2 = 4; internal const int AV_CPU_FLAG_VFP = 8; internal const int AV_CPU_FLAG_VFPV3 = 16; internal const int AV_CPU_FLAG_NEON = 32; internal const int AV_CPU_FLAG_ARMV8 = 64; internal const int AV_CPU_FLAG_VFP_VM = 128; internal const int AV_CPU_FLAG_SETEND = 65536; internal const int AV_BUFFER_FLAG_READONLY = 1; internal const int AV_DICT_MATCH_CASE = 1; internal const int AV_DICT_IGNORE_SUFFIX = 2; internal const int AV_DICT_DONT_STRDUP_KEY = 4; internal const int AV_DICT_DONT_STRDUP_VAL = 8; internal const int AV_DICT_DONT_OVERWRITE = 16; internal const int AV_DICT_APPEND = 32; internal const int AV_DICT_MULTIKEY = 64; internal const int AV_NUM_DATA_POINTERS = 8; internal const int AV_FRAME_FLAG_CORRUPT = 1; internal const int AV_FRAME_FLAG_DISCARD = 4; internal const int FF_DECODE_ERROR_INVALID_BITSTREAM = 1; internal const int FF_DECODE_ERROR_MISSING_REFERENCE = 2; internal const int AV_OPT_FLAG_ENCODING_PARAM = 1; internal const int AV_OPT_FLAG_DECODING_PARAM = 2; internal const int AV_OPT_FLAG_METADATA = 4; internal const int AV_OPT_FLAG_AUDIO_PARAM = 8; internal const int AV_OPT_FLAG_VIDEO_PARAM = 16; internal const int AV_OPT_FLAG_SUBTITLE_PARAM = 32; internal const int AV_OPT_FLAG_EXPORT = 64; internal const int AV_OPT_FLAG_READONLY = 128; internal const int AV_OPT_FLAG_FILTERING_PARAM = 65536; internal const int AV_OPT_SEARCH_CHILDREN = 1; internal const int AV_OPT_SEARCH_FAKE_OBJ = 2; internal const int AV_OPT_ALLOW_NULL = 4; internal const int AV_OPT_MULTI_COMPONENT_RANGE = 4096; internal const int AV_OPT_SERIALIZE_SKIP_DEFAULTS = 1; internal const int AV_OPT_SERIALIZE_OPT_FLAGS_EXACT = 2; internal const int AV_PIX_FMT_FLAG_BE = 1; internal const int AV_PIX_FMT_FLAG_PAL = 2; internal const int AV_PIX_FMT_FLAG_BITSTREAM = 4; internal const int AV_PIX_FMT_FLAG_HWACCEL = 8; internal const int AV_PIX_FMT_FLAG_PLANAR = 16; internal const int AV_PIX_FMT_FLAG_RGB = 32; internal const int AV_PIX_FMT_FLAG_PSEUDOPAL = 64; internal const int AV_PIX_FMT_FLAG_ALPHA = 128; internal const int FF_LOSS_RESOLUTION = 1; internal const int FF_LOSS_DEPTH = 2; internal const int FF_LOSS_COLORSPACE = 4; internal const int FF_LOSS_ALPHA = 8; internal const int FF_LOSS_COLORQUANT = 16; internal const int FF_LOSS_CHROMA = 32; private const string libavutil = "avutil-55"; internal const int LIBSWRESAMPLE_VERSION_MAJOR = 2; internal const int LIBSWRESAMPLE_VERSION_MINOR = 3; internal const int LIBSWRESAMPLE_VERSION_MICRO = 100; internal const int SWR_FLAG_RESAMPLE = 1; private const string libswresample = "swresample-2"; [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern AVRational av_codec_get_pkt_timebase(AVCodecContext* avctx); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern void av_codec_set_pkt_timebase(AVCodecContext* avctx, AVRational val); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern AVCodecDescriptor* av_codec_get_codec_descriptor(AVCodecContext* avctx); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern void av_codec_set_codec_descriptor(AVCodecContext* avctx, AVCodecDescriptor* desc); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern uint av_codec_get_codec_properties(AVCodecContext* avctx); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern int av_codec_get_lowres(AVCodecContext* avctx); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern void av_codec_set_lowres(AVCodecContext* avctx, int val); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern int av_codec_get_seek_preroll(AVCodecContext* avctx); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern void av_codec_set_seek_preroll(AVCodecContext* avctx, int val); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern ushort* av_codec_get_chroma_intra_matrix(AVCodecContext* avctx); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern void av_codec_set_chroma_intra_matrix(AVCodecContext* avctx, ushort* val); [DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal unsafe static extern int av_codec_
plugins/CSCore/CSCore.dll
Decompiled 4 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Configuration; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Runtime.Serialization; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using CSCore.Codecs.AAC; using CSCore.Codecs.AIFF; using CSCore.Codecs.DDP; using CSCore.Codecs.FLAC; using CSCore.Codecs.FLAC.Metadata; using CSCore.Codecs.MP1; using CSCore.Codecs.MP2; using CSCore.Codecs.MP3; using CSCore.Codecs.WAV; using CSCore.Codecs.WMA; using CSCore.CoreAudioAPI; using CSCore.DMO; using CSCore.DMO.Effects; using CSCore.DSP; using CSCore.DirectSound; using CSCore.MediaFoundation; using CSCore.SoundIn; using CSCore.SoundOut; using CSCore.SoundOut.MMInterop; using CSCore.Streams; using CSCore.Streams.SampleConverter; using CSCore.Tags.ID3; using CSCore.Tags.ID3.Frames; using CSCore.Utils; using CSCore.Utils.Buffer; using CSCore.Win32; [assembly: CompilationRelaxations(8)] [assembly: AssemblyTitle("CSCore")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription(".NET Sound Library")] [assembly: Guid("7939b0f4-fed9-4dcf-bb59-a17505864c55")] [assembly: AssemblyFileVersion("1.2.1.2")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CLSCompliant(true)] [assembly: ComVisible(false)] [assembly: InternalsVisibleTo("CSCore.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100237314800493cdf9aabec35955e8928e3d5416ad1d223e8914e0e025ff9095b21bbb696235b9d3886b0edec26107ca0af49c3170fc08d117e8e9265ab371b157f2c2b27843d97c1d312850d10d1272c1d46d18f02ac56f46676cbe7946049b1b344db7154d35788fee27b3d581bd7d43e41813b10fd360a3fbfab9199d9e86a4")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CSCore")] [assembly: AssemblyCopyright("Florian R.")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.1.2")] [module: UnverifiableCode] namespace CSCore { public static class AudioSubTypes { public static readonly Guid Unknown = new Guid(0, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Pcm = new Guid(1, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Adpcm = new Guid(2, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid IeeeFloat = new Guid(3, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Vselp = new Guid(4, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid IbmCvsd = new Guid(5, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid ALaw = new Guid(6, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MuLaw = new Guid(7, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Dts = new Guid(8, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Drm = new Guid(9, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WmaVoice9 = new Guid(10, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid OkiAdpcm = new Guid(16, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid DviAdpcm = new Guid(17, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid ImaAdpcm = new Guid(17, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MediaspaceAdpcm = new Guid(18, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid SierraAdpcm = new Guid(19, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid G723Adpcm = new Guid(20, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid DigiStd = new Guid(21, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid DigiFix = new Guid(22, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid DialogicOkiAdpcm = new Guid(23, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MediaVisionAdpcm = new Guid(24, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid CUCodec = new Guid(25, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid YamahaAdpcm = new Guid(32, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid SonarC = new Guid(33, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid DspGroupTrueSpeech = new Guid(34, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid EchoSpeechCorporation1 = new Guid(35, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid AudioFileAf36 = new Guid(36, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Aptx = new Guid(37, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid AudioFileAf10 = new Guid(38, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Prosody1612 = new Guid(39, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Lrc = new Guid(40, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid DolbyAc2 = new Guid(48, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Gsm610 = new Guid(49, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MsnAudio = new Guid(50, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid AntexAdpcme = new Guid(51, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid ControlResVqlpc = new Guid(52, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid DigiReal = new Guid(53, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid DigiAdpcm = new Guid(54, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid ControlResCr10 = new Guid(55, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_NMS_VBXADPCM = new Guid(56, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_CS_IMAADPCM = new Guid(57, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_ECHOSC3 = new Guid(58, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_ROCKWELL_ADPCM = new Guid(59, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_ROCKWELL_DIGITALK = new Guid(60, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_XEBEC = new Guid(61, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_G721_ADPCM = new Guid(64, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_G728_CELP = new Guid(65, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_MSG723 = new Guid(66, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Mpeg = new Guid(80, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_RT24 = new Guid(82, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_PAC = new Guid(83, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MpegLayer3 = new Guid(85, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_LUCENT_G723 = new Guid(89, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_CIRRUS = new Guid(96, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_ESPCM = new Guid(97, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE = new Guid(98, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_CANOPUS_ATRAC = new Guid(99, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_G726_ADPCM = new Guid(100, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_G722_ADPCM = new Guid(101, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_DSAT_DISPLAY = new Guid(103, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = new Guid(105, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_AC8 = new Guid(112, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_AC10 = new Guid(113, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_AC16 = new Guid(114, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_AC20 = new Guid(115, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_RT24 = new Guid(116, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_RT29 = new Guid(117, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_RT29HW = new Guid(118, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_VR12 = new Guid(119, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_VR18 = new Guid(120, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_TQ40 = new Guid(121, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SOFTSOUND = new Guid(128, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VOXWARE_TQ60 = new Guid(129, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_MSRT24 = new Guid(130, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_G729A = new Guid(131, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_MVI_MVI2 = new Guid(132, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_DF_G726 = new Guid(133, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_DF_GSM610 = new Guid(134, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_ISIAUDIO = new Guid(136, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_ONLIVE = new Guid(137, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SBC24 = new Guid(145, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_DOLBY_AC3_SPDIF = new Guid(146, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_MEDIASONIC_G723 = new Guid(147, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_PROSODY_8KBPS = new Guid(148, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_ZYXEL_ADPCM = new Guid(151, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_PHILIPS_LPCBB = new Guid(152, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_PACKED = new Guid(153, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_MALDEN_PHONYTALK = new Guid(160, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Gsm = new Guid(161, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid G729 = new Guid(162, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid G723 = new Guid(163, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Acelp = new Guid(164, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid RawAac = new Guid(255, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_RHETOREX_ADPCM = new Guid(256, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_IRAT = new Guid(257, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VIVO_G723 = new Guid(273, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VIVO_SIREN = new Guid(274, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_DIGITAL_G723 = new Guid(291, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SANYO_LD_ADPCM = new Guid(293, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SIPROLAB_ACEPLNET = new Guid(304, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SIPROLAB_ACELP4800 = new Guid(305, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SIPROLAB_ACELP8V3 = new Guid(306, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SIPROLAB_G729 = new Guid(307, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SIPROLAB_G729A = new Guid(308, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SIPROLAB_KELVIN = new Guid(309, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_G726ADPCM = new Guid(320, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_QUALCOMM_PUREVOICE = new Guid(336, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_QUALCOMM_HALFRATE = new Guid(337, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_TUBGSM = new Guid(341, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_MSAUDIO1 = new Guid(352, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WindowsMediaAudio = new Guid(353, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WindowsMediaAudioProfessional = new Guid(354, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WindowsMediaAudioLosseless = new Guid(355, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WindowsMediaAudioSpdif = new Guid(356, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_UNISYS_NAP_ADPCM = new Guid(368, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_UNISYS_NAP_ULAW = new Guid(369, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_UNISYS_NAP_ALAW = new Guid(370, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_UNISYS_NAP_16K = new Guid(371, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_CREATIVE_ADPCM = new Guid(512, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_CREATIVE_FASTSPEECH8 = new Guid(514, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_CREATIVE_FASTSPEECH10 = new Guid(515, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_UHER_ADPCM = new Guid(528, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_QUARTERDECK = new Guid(544, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_ILINK_VC = new Guid(560, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_RAW_SPORT = new Guid(576, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_ESST_AC3 = new Guid(577, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_IPI_HSX = new Guid(592, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_IPI_RPELP = new Guid(593, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_CS2 = new Guid(608, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SONY_SCX = new Guid(624, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_FM_TOWNS_SND = new Guid(768, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_BTV_DIGITAL = new Guid(1024, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_QDESIGN_MUSIC = new Guid(1104, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_VME_VMPCM = new Guid(1664, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_TPC = new Guid(1665, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_OLIGSM = new Guid(4096, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_OLIADPCM = new Guid(4097, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_OLICELP = new Guid(4098, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_OLISBC = new Guid(4099, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_OLIOPR = new Guid(4100, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_LH_CODEC = new Guid(4352, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_NORRIS = new Guid(5120, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS = new Guid(5376, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MPEG_ADTS_AAC = new Guid(5632, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MPEG_RAW_AAC = new Guid(5633, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MPEG_LOAS = new Guid(5634, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid NOKIA_MPEG_ADTS_AAC = new Guid(5640, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid NOKIA_MPEG_RAW_AAC = new Guid(5641, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid VODAFONE_MPEG_ADTS_AAC = new Guid(5642, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid VODAFONE_MPEG_RAW_AAC = new Guid(5643, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MPEG_HEAAC = new Guid(5648, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_DVM = new Guid(8192, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Vorbis1 = new Guid(26447, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Vorbis2 = new Guid(26448, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Vorbis3 = new Guid(26449, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Vorbis1P = new Guid(26479, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Vorbis2P = new Guid(26480, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Vorbis3P = new Guid(26481, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_RAW_AAC1 = new Guid(255, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_WMAVOICE9 = new Guid(10, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid Extensible = new Guid(65534, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_DEVELOPMENT = new Guid(65535, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid WAVE_FORMAT_FLAC = new Guid(61868, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); public static readonly Guid MediaTypeAudio = new Guid("73647561-0000-0010-8000-00AA00389B71"); public static AudioEncoding EncodingFromSubType(Guid audioSubType) { byte[] value = audioSubType.ToByteArray(); int num = BitConverter.ToInt32(value, 0); if (Enum.IsDefined(typeof(AudioEncoding), (short)num)) { return (AudioEncoding)num; } throw new ArgumentException("Invalid audioSubType.", "audioSubType"); } public static Guid SubTypeFromEncoding(AudioEncoding audioEncoding) { if (Enum.IsDefined(typeof(AudioEncoding), (short)audioEncoding)) { return new Guid((int)audioEncoding, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113); } throw new ArgumentException("Invalid encoding.", "audioEncoding"); } } public enum AudioEncoding : short { 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, WAVE_FORMAT_RAW_AAC1 = 255, WAVE_FORMAT_WMAVOICE9 = 10, Extensible = -2, WAVE_FORMAT_DEVELOPMENT = -1, WAVE_FORMAT_FLAC = -3668 } [Flags] public enum ChannelMask { SpeakerFrontLeft = 1, SpeakerFrontRight = 2, SpeakerFrontCenter = 4, SpeakerLowFrequency = 8, SpeakerBackLeft = 0x10, SpeakerBackRight = 0x20, SpeakerFrontLeftOfCenter = 0x40, SpeakerFrontRightOfCenter = 0x80, SpeakerBackCenter = 0x100, SpeakerSideLeft = 0x200, SpeakerSideRight = 0x400, SpeakerTopCenter = 0x800, SpeakerTopFrontLeft = 0x1000, SpeakerTopFrontCenter = 0x2000, SpeakerTopFrontRight = 0x4000, SpeakerTopBackLeft = 0x8000, SpeakerTopBackCenter = 0x10000, SpeakerTopBackRight = 0x20000 } public static class ChannelMasks { public const ChannelMask MonoMask = ChannelMask.SpeakerFrontCenter; public const ChannelMask StereoMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight; public const ChannelMask FiveDotOneWithRearMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight; public const ChannelMask FiveDotOneWithSideMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight; public const ChannelMask SevenDotOneMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight; } public static class FluentExtensions { public static TResult AppendSource<TInput, TResult>(this TInput input, Func<TInput, TResult> func) where TInput : IAudioSource { return func(input); } public static TResult AppendSource<TInput, TResult>(this TInput input, Func<TInput, TResult> func, out TResult outputSource) where TInput : IAudioSource { outputSource = func(input); return outputSource; } public static IWaveSource ChangeSampleRate(this IWaveSource input, int destinationSampleRate) { if (input == null) { throw new ArgumentNullException("input"); } if (destinationSampleRate <= 0) { throw new ArgumentOutOfRangeException("destinationSampleRate"); } if (input.WaveFormat.SampleRate == destinationSampleRate) { return input; } return new DmoResampler(input, destinationSampleRate); } public static ISampleSource ChangeSampleRate(this ISampleSource input, int destinationSampleRate) { if (input == null) { throw new ArgumentNullException("input"); } if (destinationSampleRate <= 0) { throw new ArgumentOutOfRangeException("destinationSampleRate"); } if (input.WaveFormat.SampleRate == destinationSampleRate) { return input; } return new DmoResampler(input.ToWaveSource(), destinationSampleRate).ToSampleSource(); } public static IWaveSource ToStereo(this IWaveSource input) { if (input == null) { throw new ArgumentNullException("input"); } if (input.WaveFormat.Channels == 2) { return input; } if (input.WaveFormat.Channels == 1) { return new MonoToStereoSource(input.ToSampleSource()).ToWaveSource(input.WaveFormat.BitsPerSample); } if (input.WaveFormat is WaveFormatExtensible waveFormatExtensible) { ChannelMask channelMask = waveFormatExtensible.ChannelMask; ChannelMatrix matrix = ChannelMatrix.GetMatrix(channelMask, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight); return new DmoChannelResampler(input, matrix); } WaveFormat waveFormat = (WaveFormat)input.WaveFormat.Clone(); waveFormat.Channels = 2; return new DmoResampler(input, waveFormat); } public static ISampleSource ToStereo(this ISampleSource input) { if (input == null) { throw new ArgumentNullException("input"); } if (input.WaveFormat.Channels == 2) { return input; } if (input.WaveFormat.Channels == 1) { return new MonoToStereoSource(input); } return input.ToWaveSource().ToStereo().ToSampleSource(); } public static IWaveSource ToMono(this IWaveSource input) { if (input == null) { throw new ArgumentNullException("input"); } if (input.WaveFormat.Channels == 1) { return input; } if (input.WaveFormat.Channels == 2) { return new StereoToMonoSource(input.ToSampleSource()).ToWaveSource(input.WaveFormat.BitsPerSample); } if (input.WaveFormat is WaveFormatExtensible waveFormatExtensible) { ChannelMask channelMask = waveFormatExtensible.ChannelMask; ChannelMatrix matrix = ChannelMatrix.GetMatrix(channelMask, ChannelMask.SpeakerFrontCenter); return new DmoChannelResampler(input, matrix); } WaveFormat waveFormat = (WaveFormat)input.WaveFormat.Clone(); waveFormat.Channels = 1; return new DmoResampler(input, waveFormat); } public static ISampleSource ToMono(this ISampleSource input) { if (input == null) { throw new ArgumentNullException("input"); } if (input.WaveFormat.Channels == 1) { return input; } if (input.WaveFormat.Channels == 2) { return new StereoToMonoSource(input); } return input.ToWaveSource().ToMono().ToSampleSource(); } public static IWaveSource Loop(this IWaveSource input) { return new LoopStream(input) { EnableLoop = true }; } public static IWaveSource ToWaveSource(this ISampleSource sampleSource, int bits) { if (sampleSource == null) { throw new ArgumentNullException("sampleSource"); } return bits switch { 8 => new SampleToPcm8(sampleSource), 16 => new SampleToPcm16(sampleSource), 24 => new SampleToPcm24(sampleSource), 32 => new SampleToIeeeFloat32(sampleSource), _ => throw new ArgumentOutOfRangeException("bits", "Must be 8, 16, 24 or 32 bits."), }; } public static IWaveSource ToWaveSource(this ISampleSource sampleSource) { if (sampleSource == null) { throw new ArgumentNullException("sampleSource"); } return new SampleToIeeeFloat32(sampleSource); } public static ISampleSource ToSampleSource(this IWaveSource waveSource) { if (waveSource == null) { throw new ArgumentNullException("waveSource"); } return WaveToSampleBase.CreateConverter(waveSource); } public static SynchronizedWaveSource<TAudioSource, T> Synchronized<TAudioSource, T>(this TAudioSource audioSource) where TAudioSource : class, IReadableAudioSource<T> { if (audioSource == null) { throw new ArgumentNullException("audioSource"); } return new SynchronizedWaveSource<TAudioSource, T>(audioSource); } } public interface IAudioSource : IDisposable { bool CanSeek { get; } WaveFormat WaveFormat { get; } long Position { get; set; } long Length { get; } } public interface IWaveSource : IReadableAudioSource<byte>, IAudioSource, IDisposable { } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class WaveFormat : ICloneable, IEquatable<WaveFormat> { private AudioEncoding _encoding; private short _channels; private int _sampleRate; private int _bytesPerSecond; private short _blockAlign; private short _bitsPerSample; private short _extraSize; public virtual int Channels { get { return _channels; } protected internal set { _channels = (short)value; UpdateProperties(); } } public virtual int SampleRate { get { return _sampleRate; } protected internal set { _sampleRate = value; UpdateProperties(); } } public virtual int BytesPerSecond { get { return _bytesPerSecond; } protected internal set { _bytesPerSecond = value; } } public virtual int BlockAlign { get { return _blockAlign; } protected internal set { _blockAlign = (short)value; } } public virtual int BitsPerSample { get { return _bitsPerSample; } protected internal set { _bitsPerSample = (short)value; UpdateProperties(); } } public virtual int ExtraSize { get { return _extraSize; } protected internal set { _extraSize = (short)value; } } public virtual int BytesPerSample => BitsPerSample / 8; public virtual int BytesPerBlock => BytesPerSample * Channels; public virtual AudioEncoding WaveFormatTag { get { return _encoding; } protected internal set { _encoding = value; } } public WaveFormat() : this(44100, 16, 2) { } public WaveFormat(int sampleRate, int bits, int channels) : this(sampleRate, bits, channels, AudioEncoding.Pcm) { } public WaveFormat(int sampleRate, int bits, int channels, AudioEncoding encoding) : this(sampleRate, bits, channels, encoding, 0) { } public WaveFormat(int sampleRate, int bits, int channels, AudioEncoding encoding, int extraSize) { if (sampleRate < 1) { throw new ArgumentOutOfRangeException("sampleRate"); } if (bits < 0) { throw new ArgumentOutOfRangeException("bits"); } if (channels < 1) { throw new ArgumentOutOfRangeException("channels", "Number of channels has to be bigger than 0."); } _sampleRate = sampleRate; _bitsPerSample = (short)bits; _channels = (short)channels; _encoding = encoding; _extraSize = (short)extraSize; UpdateProperties(); } public long MillisecondsToBytes(double milliseconds) { long num = (long)((double)BytesPerSecond / 1000.0 * milliseconds); return num - num % BlockAlign; } public double BytesToMilliseconds(long bytes) { bytes -= bytes % BlockAlign; return (double)bytes / (double)BytesPerSecond * 1000.0; } public virtual bool Equals(WaveFormat other) { if (Channels == other.Channels && SampleRate == other.SampleRate && BytesPerSecond == other.BytesPerSecond && BlockAlign == other.BlockAlign && BitsPerSample == other.BitsPerSample && ExtraSize == other.ExtraSize) { return WaveFormatTag == other.WaveFormatTag; } return false; } public override string ToString() { return GetInformation().ToString(); } public virtual object Clone() { return MemberwiseClone(); } internal virtual void SetWaveFormatTagInternal(AudioEncoding waveFormatTag) { WaveFormatTag = waveFormatTag; } internal virtual void SetBitsPerSampleAndFormatProperties(int bitsPerSample) { BitsPerSample = bitsPerSample; UpdateProperties(); } protected internal virtual void UpdateProperties() { BlockAlign = BitsPerSample / 8 * Channels; BytesPerSecond = BlockAlign * SampleRate; } [DebuggerStepThrough] private StringBuilder GetInformation() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("ChannelsAvailable: " + Channels); stringBuilder.Append("|SampleRate: " + SampleRate); stringBuilder.Append("|Bps: " + BytesPerSecond); stringBuilder.Append("|BlockAlign: " + BlockAlign); stringBuilder.Append("|BitsPerSample: " + BitsPerSample); stringBuilder.Append("|Encoding: " + _encoding); return stringBuilder; } } } namespace CSCore.DSP { public class DmoResampler : WaveAggregatorBase { internal MediaBuffer InputBuffer; internal object LockObj = new object(); internal DmoOutputDataBuffer OutputBuffer; internal WaveFormat Outputformat; private readonly bool _ignoreBaseStreamPosition; internal decimal Ratio; internal WMResampler Resampler; private bool _disposed; private int _quality = 30; private byte[] _readBuffer; private long _position; public override WaveFormat WaveFormat => Outputformat; public override long Position { get { if (_ignoreBaseStreamPosition) { return _position; } return InputToOutput(base.Position); } set { base.Position = OutputToInput(value); if (_ignoreBaseStreamPosition) { _position = InputToOutput(base.Position); } } } public override long Length => InputToOutput(base.Length); public int Quality { get { return _quality; } set { if (value < 1 || value > 60) { throw new ArgumentOutOfRangeException("value"); } _quality = value; using (Resampler.MediaObject.Lock()) { Resampler.ResamplerProps.SetHalfFilterLength(value); } } } private static WaveFormat GetWaveFormatWithChangedSampleRate(IWaveSource source, int destSampleRate) { if (source == null) { throw new ArgumentNullException("source"); } WaveFormat waveFormat = (WaveFormat)source.WaveFormat.Clone(); waveFormat.SampleRate = destSampleRate; return waveFormat; } public DmoResampler(IWaveSource source, int destinationSampleRate) : this(source, GetWaveFormatWithChangedSampleRate(source, destinationSampleRate)) { } public DmoResampler(IWaveSource source, WaveFormat outputFormat) : this(source, outputFormat, ignoreBaseStreamPosition: true) { } public DmoResampler(IWaveSource source, WaveFormat outputFormat, bool ignoreBaseStreamPosition) : base(source) { if (source == null) { throw new ArgumentNullException("source"); } if (outputFormat == null) { throw new ArgumentNullException("outputFormat"); } Initialize(source.WaveFormat, outputFormat); Outputformat = outputFormat; _ignoreBaseStreamPosition = ignoreBaseStreamPosition; } internal void Initialize(WaveFormat inputformat, WaveFormat outputformat) { Ratio = (decimal)outputformat.BytesPerSecond / (decimal)inputformat.BytesPerSecond; lock (LockObj) { Resampler = new WMResampler(); MediaObject mediaObject = Resampler.MediaObject; if (!mediaObject.SupportsInputFormat(0, inputformat)) { throw new NotSupportedException("Inputformat not supported."); } mediaObject.SetInputType(0, inputformat); if (!mediaObject.SupportsOutputFormat(0, outputformat)) { throw new NotSupportedException("Outputformat not supported."); } mediaObject.SetOutputType(0, outputformat); InputBuffer = new MediaBuffer(inputformat.BytesPerSecond / 2); OutputBuffer = new DmoOutputDataBuffer(outputformat.BytesPerSecond / 2); } } public override int Read(byte[] buffer, int offset, int count) { lock (LockObj) { int num = 0; while (num < count) { MediaObject mediaObject = Resampler.MediaObject; if (mediaObject.IsReadyForInput(0)) { int num2 = (int)OutputToInput(count - num); _readBuffer = _readBuffer.CheckBuffer(num2); int num3 = base.Read(_readBuffer, 0, num2); if (num3 <= 0 || _disposed) { break; } if (InputBuffer.MaxLength < num3) { InputBuffer.Dispose(); InputBuffer = new MediaBuffer(num3); } InputBuffer.Write(_readBuffer, 0, num3); mediaObject.ProcessInput(0, InputBuffer); OutputBuffer.Reset(); MediaBuffer mediaBuffer = (MediaBuffer)OutputBuffer.Buffer; if (mediaBuffer.MaxLength < count) { mediaBuffer.Dispose(); OutputBuffer.Buffer = new MediaBuffer(count); } OutputBuffer.Buffer.SetLength(0); mediaObject.ProcessOutput(ProcessOutputFlags.None, new DmoOutputDataBuffer[1] { OutputBuffer }, 1); if (OutputBuffer.Length > 0) { OutputBuffer.Read(buffer, offset + num); num += OutputBuffer.Length; } } } if (_ignoreBaseStreamPosition) { _position += num; } return num; } } internal long InputToOutput(long position) { long num = (long)((decimal)position * Ratio); return num - num % Outputformat.BlockAlign; } internal long OutputToInput(long position) { long num = (long)((decimal)position / Ratio); return num - num % BaseSource.WaveFormat.BlockAlign; } public void DisposeResamplerOnly() { bool disposeBaseSource = base.DisposeBaseSource; base.DisposeBaseSource = false; Dispose(); base.DisposeBaseSource = disposeBaseSource; } protected override void Dispose(bool disposing) { if (!disposing) { base.DisposeBaseSource = false; } base.Dispose(disposing); DisposeAndReset(ref Resampler); OutputBuffer.Dispose(); DisposeAndReset(ref InputBuffer); _readBuffer = null; _disposed = true; } private void DisposeAndReset<T>(ref T obj) where T : class, IDisposable { if (obj != null) { try { obj.Dispose(); } catch (ObjectDisposedException) { } obj = null; } } } } namespace CSCore { public interface ISampleSource : IReadableAudioSource<float>, IAudioSource, IDisposable { } [StructLayout(LayoutKind.Sequential, Pack = 2)] public class WaveFormatExtensible : WaveFormat { internal const int WaveFormatExtensibleExtraSize = 22; private short _samplesUnion; private ChannelMask _channelMask; private Guid _subFormat; public int ValidBitsPerSample { get { return _samplesUnion; } protected internal set { _samplesUnion = (short)value; } } public int SamplesPerBlock { get { return _samplesUnion; } protected internal set { _samplesUnion = (short)value; } } public ChannelMask ChannelMask { get { return _channelMask; } protected internal set { _channelMask = value; } } public Guid SubFormat { get { return _subFormat; } protected internal set { _subFormat = value; } } public static Guid SubTypeFromWaveFormat(WaveFormat waveFormat) { if (waveFormat == null) { throw new ArgumentNullException("waveFormat"); } if (waveFormat is WaveFormatExtensible) { return ((WaveFormatExtensible)waveFormat).SubFormat; } return AudioSubTypes.SubTypeFromEncoding(waveFormat.WaveFormatTag); } internal WaveFormatExtensible() { } public WaveFormatExtensible(int sampleRate, int bits, int channels, Guid subFormat) : base(sampleRate, bits, channels, AudioEncoding.Extensible, 22) { _samplesUnion = (short)bits; _subFormat = SubTypeFromWaveFormat(this); int num = 0; for (int i = 0; i < channels; i++) { num |= 1 << i; } _channelMask = (ChannelMask)num; _subFormat = subFormat; } public WaveFormatExtensible(int sampleRate, int bits, int channels, Guid subFormat, ChannelMask channelMask) : this(sampleRate, bits, channels, subFormat) { Array values = Enum.GetValues(typeof(ChannelMask)); int num = 0; for (int i = 0; i < values.Length; i++) { if ((channelMask & (ChannelMask)values.GetValue(i)) == (ChannelMask)values.GetValue(i)) { num++; } } if (channels != num) { throw new ArgumentException("Channels has to equal the set flags in the channelmask."); } _channelMask = channelMask; } public WaveFormat ToWaveFormat() { return new WaveFormat(SampleRate, BitsPerSample, Channels, AudioSubTypes.EncodingFromSubType(SubFormat)); } public override object Clone() { return MemberwiseClone(); } internal override void SetWaveFormatTagInternal(AudioEncoding waveFormatTag) { SubFormat = AudioSubTypes.SubTypeFromEncoding(waveFormatTag); } [DebuggerStepThrough] public override string ToString() { StringBuilder stringBuilder = new StringBuilder(base.ToString()); stringBuilder.Append("|SubFormat: " + SubFormat); stringBuilder.Append("|ChannelMask: " + ChannelMask); return stringBuilder.ToString(); } } } namespace CSCore.DSP { public class ChannelMatrix { private static class Factory { private class FactoryEntry { public ChannelMask Input { get; set; } public ChannelMask Output { get; set; } public ChannelMatrix Matrix { get; set; } public FactoryEntry(ChannelMask input, ChannelMask output, ChannelMatrix matrix) { Input = input; Output = output; Matrix = matrix; } } private static readonly FactoryEntry[] FactoryEntries = new FactoryEntry[18] { new FactoryEntry(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, MonoToStereoMatrix), new FactoryEntry(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, MonoToFiveDotOneSurroundWithRear), new FactoryEntry(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, MonoToFiveDotOneSurroundWithSide), new FactoryEntry(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, MonoToSevenDotOneSurround), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontCenter, StereoToMonoMatrix), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, StereoToFiveDotOneSurroundWithRear), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, StereoToFiveDotOneSurroundWithSide), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, StereoToSevenDotOneSurround), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, ChannelMask.SpeakerFrontCenter, FiveDotOneSurroundWithRearToMono), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, FiveDotOneSurroundWithRearToStereo), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, FiveDotOneSurroundWithRearToSevenDotOne), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontCenter, FiveDotOneSurroundWithSideToMono), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, FiveDotOneSurroundWithSideToStereo), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, FiveDotOneSurroundWithSideToSevenDotOne), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontCenter, SevenDotOneSurroundToMono), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, SevenDotOneSurroundToStereo), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, SevenDotOneSurroundToFiveDotOneSurroundWithRear), new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, SevenDotOneSurroundToFiveDotOneSurroundWithSide) }; public static ChannelMatrix GetMatrix(ChannelMask from, ChannelMask to) { if (from == to) { throw new ArgumentException("from must not equal to."); } FactoryEntry factoryEntry = FactoryEntries.FirstOrDefault((FactoryEntry x) => x.Input == from && x.Output == to); if (factoryEntry == null) { throw new KeyNotFoundException("Could not find a channel matrix for specified channelmasks."); } return factoryEntry.Matrix; } } public static readonly ChannelMatrix StereoToFiveDotOneSurroundWithRear; public static readonly ChannelMatrix FiveDotOneSurroundWithRearToStereo; public static readonly ChannelMatrix StereoToFiveDotOneSurroundWithSide; public static readonly ChannelMatrix FiveDotOneSurroundWithSideToStereo; public static readonly ChannelMatrix StereoToSevenDotOneSurround; public static readonly ChannelMatrix SevenDotOneSurroundToStereo; public static readonly ChannelMatrix MonoToFiveDotOneSurroundWithRear; public static readonly ChannelMatrix FiveDotOneSurroundWithRearToMono; public static readonly ChannelMatrix MonoToFiveDotOneSurroundWithSide; public static readonly ChannelMatrix FiveDotOneSurroundWithSideToMono; public static readonly ChannelMatrix MonoToSevenDotOneSurround; public static readonly ChannelMatrix SevenDotOneSurroundToMono; public static readonly ChannelMatrix StereoToMonoMatrix; public static readonly ChannelMatrix MonoToStereoMatrix; public static readonly ChannelMatrix FiveDotOneSurroundWithRearToSevenDotOne; public static readonly ChannelMatrix SevenDotOneSurroundToFiveDotOneSurroundWithRear; public static readonly ChannelMatrix FiveDotOneSurroundWithSideToSevenDotOne; public static readonly ChannelMatrix SevenDotOneSurroundToFiveDotOneSurroundWithSide; private readonly ChannelMask _inputMask; private readonly ChannelMatrixElement[,] _matrix; private readonly ChannelMask _outputMask; public ChannelMask InputMask => _inputMask; public ChannelMask OutputMask => _outputMask; public int Height => _matrix.GetLength(0); public int Width => _matrix.GetLength(1); public int InputChannelCount => Height; public int OutputChannelCount => Width; public ChannelMatrixElement this[int input, int output] { get { return _matrix[input, output]; } set { _matrix[input, output] = value; } } public static ChannelMatrix GetMatrix(ChannelMask from, ChannelMask to) { return Factory.GetMatrix(from, to); } public static ChannelMatrix GetMatrix(WaveFormat from, WaveFormat to) { if (from == null) { throw new ArgumentNullException("from"); } if (to == null) { throw new ArgumentNullException("to"); } if (TryExtractChannelMask(from, out var channelMask) && TryExtractChannelMask(to, out var channelMask2)) { return GetMatrix(channelMask, channelMask2); } return null; } private static bool TryExtractChannelMask(WaveFormat waveFormat, out ChannelMask channelMask) { channelMask = (ChannelMask)0; if (waveFormat is WaveFormatExtensible waveFormatExtensible) { channelMask = waveFormatExtensible.ChannelMask; } else if (waveFormat.Channels == 1) { channelMask = ChannelMask.SpeakerFrontCenter; } else { if (waveFormat.Channels != 2) { return false; } channelMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight; } return true; } internal WaveFormat BuildOutputWaveFormat(IAudioSource audioSource) { if (audioSource == null) { throw new ArgumentNullException("source"); } return new WaveFormatExtensible(audioSource.WaveFormat.SampleRate, audioSource.WaveFormat.BitsPerSample, OutputChannelCount, WaveFormatExtensible.SubTypeFromWaveFormat(audioSource.WaveFormat), OutputMask); } static ChannelMatrix() { StereoToFiveDotOneSurroundWithRear = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight); StereoToFiveDotOneSurroundWithRear.SetMatrix(new float[2, 6] { { 0.314f, 0f, 0.222f, 0.031f, 0.268f, 0.164f }, { 0f, 0.314f, 0.222f, 0.031f, 0.164f, 0.268f } }); FiveDotOneSurroundWithRearToStereo = StereoToFiveDotOneSurroundWithRear.Flip(); StereoToFiveDotOneSurroundWithSide = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight); StereoToFiveDotOneSurroundWithSide.SetMatrix(new float[2, 6] { { 0.32f, 0f, 0.226f, 0.032f, 0.292f, 0.13f }, { 0f, 0.32f, 0.226f, 0.032f, 0.13f, 0.292f } }); FiveDotOneSurroundWithSideToStereo = StereoToFiveDotOneSurroundWithSide.Flip(); StereoToSevenDotOneSurround = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight); StereoToSevenDotOneSurround.SetMatrix(new float[2, 8] { { 0.222f, 0f, 0.157f, 0.022f, 0.189f, 0.116f, 0.203f, 0.09f }, { 0f, 0.222f, 0.157f, 0.022f, 0.116f, 0.189f, 0.09f, 0.203f } }); SevenDotOneSurroundToStereo = StereoToSevenDotOneSurround.Flip(); MonoToFiveDotOneSurroundWithRear = new ChannelMatrix(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight); MonoToFiveDotOneSurroundWithRear.SetMatrix(new float[1, 6] { { 0.192f, 0.192f, 0.192f, 0.038f, 0.192f, 0.192f } }); FiveDotOneSurroundWithRearToMono = MonoToFiveDotOneSurroundWithRear.Flip(); MonoToFiveDotOneSurroundWithSide = new ChannelMatrix(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight); MonoToFiveDotOneSurroundWithSide.SetMatrix(new float[1, 6] { { 0.192f, 0.192f, 0.192f, 0.038f, 0.192f, 0.192f } }); FiveDotOneSurroundWithSideToMono = MonoToFiveDotOneSurroundWithSide.Flip(); MonoToSevenDotOneSurround = new ChannelMatrix(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight); MonoToSevenDotOneSurround.SetMatrix(new float[1, 8] { { 0.139f, 0.139f, 0.139f, 0.028f, 0.139f, 0.139f, 0.139f, 0.139f } }); SevenDotOneSurroundToMono = MonoToSevenDotOneSurround.Flip(); FiveDotOneSurroundWithRearToSevenDotOne = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight); FiveDotOneSurroundWithRearToSevenDotOne.SetMatrix(new float[6, 8] { { 0.518f, 0f, 0f, 0f, 0f, 0f, 0.189f, 0f }, { 0f, 0.518f, 0f, 0f, 0f, 0f, 0f, 0.189f }, { 0f, 0f, 0.518f, 0f, 0f, 0f, 0f, 0f }, { 0f, 0f, 0f, 0.518f, 0f, 0f, 0f, 0f }, { 0f, 0f, 0f, 0f, 0.518f, 0f, 0.482f, 0f }, { 0f, 0f, 0f, 0f, 0f, 0.518f, 0f, 0.482f } }); SevenDotOneSurroundToFiveDotOneSurroundWithRear = FiveDotOneSurroundWithRearToSevenDotOne.Flip(); FiveDotOneSurroundWithSideToSevenDotOne = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight); FiveDotOneSurroundWithSideToSevenDotOne.SetMatrix(new float[6, 8] { { 0.447f, 0f, 0f, 0f, 0f, 0f, 0f, 0f }, { 0f, 0.447f, 0f, 0f, 0f, 0f, 0f, 0f }, { 0f, 0f, 0.447f, 0f, 0f, 0f, 0f, 0f }, { 0f, 0f, 0f, 0.447f, 0f, 0f, 0f, 0f }, { 0f, 0f, 0f, 0f, 0.429f, 0.124f, 0.447f, 0f }, { 0f, 0f, 0f, 0f, 0.124f, 0.429f, 0f, 0.447f } }); SevenDotOneSurroundToFiveDotOneSurroundWithSide = FiveDotOneSurroundWithSideToSevenDotOne.Flip(); StereoToMonoMatrix = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontCenter); StereoToMonoMatrix.SetMatrix(new float[2, 1] { { 0.5f }, { 0.5f } }); MonoToStereoMatrix = new ChannelMatrix(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight); MonoToStereoMatrix.SetMatrix(new float[1, 2] { { 1f, 1f } }); } public ChannelMatrix(ChannelMask inputMask, ChannelMask outputMask) { _inputMask = inputMask; _outputMask = outputMask; if (inputMask <= (ChannelMask)0) { throw new ArgumentException("Invalid inputMask"); } if (outputMask <= (ChannelMask)0) { throw new ArgumentException("Invalid outputMask"); } _matrix = new ChannelMatrixElement[GetValuesOfChannelMask(inputMask).Length, GetValuesOfChannelMask(outputMask).Length]; for (int i = 0; i < Width; i++) { for (int j = 0; j < Height; j++) { _matrix[j, i] = new ChannelMatrixElement(GetValuesOfChannelMask(inputMask)[j], GetValuesOfChannelMask(outputMask)[i]); } } } public void SetMatrix(float[,] matrix) { if (matrix == null) { throw new ArgumentException("matrix"); } if (matrix.GetLength(1) != Width) { throw new ArgumentException("Matrix has to have a width of " + Width); } if (matrix.GetLength(0) != Height) { throw new ArgumentException("Matrix has to have a height of " + Height); } for (int i = 0; i < Width; i++) { for (int j = 0; j < Height; j++) { this[j, i].Value = matrix[j, i]; } } } public float[] GetOneDimensionalMatrix() { List<float> list = new List<float>(); for (int i = 0; i < Width; i++) { for (int j = 0; j < Height; j++) { list.Add(this[j, i].Value); } } return list.ToArray(); } public ChannelMatrix Flip() { ChannelMatrix channelMatrix = new ChannelMatrix(OutputMask, InputMask); for (int i = 0; i < OutputChannelCount; i++) { for (int j = 0; j < InputChannelCount; j++) { ChannelMatrixElement channelMatrixElement = this[j, i]; channelMatrix[i, j] = new ChannelMatrixElement(channelMatrixElement.OutputChannel, channelMatrixElement.InputChannel) { Value = channelMatrixElement.Value }; } } return channelMatrix; } private static ChannelMask[] GetValuesOfChannelMask(ChannelMask channelMask) { Array values = Enum.GetValues(typeof(ChannelMask)); List<ChannelMask> list = new List<ChannelMask>(); for (int i = 0; i < values.Length; i++) { if ((channelMask & (ChannelMask)values.GetValue(i)) == (ChannelMask)values.GetValue(i)) { list.Add((ChannelMask)values.GetValue(i)); } } return list.ToArray(); } } } namespace CSCore.Streams { public sealed class MonoToStereoSource : SampleAggregatorBase { private float[] _buffer; private readonly WaveFormat _waveFormat; public override long Position { get { return base.Position * 2; } set { value -= value % WaveFormat.BlockAlign; base.Position = value / 2; } } public override long Length => base.Length * 2; public override WaveFormat WaveFormat => _waveFormat; public MonoToStereoSource(ISampleSource source) : base(source) { if (source == null) { throw new ArgumentNullException("source"); } if (source.WaveFormat.Channels != 1) { throw new ArgumentException("The WaveFormat of the source has be a mono format (one channel).", "source"); } _waveFormat = new WaveFormat(source.WaveFormat.SampleRate, 32, 2, AudioEncoding.IeeeFloat); } public override int Read(float[] buffer, int offset, int count) { int num = count / 2; _buffer = _buffer.CheckBuffer(num); int num2 = offset; int num3 = base.Read(_buffer, 0, num); for (int i = 0; i < num3; i++) { buffer[num2++] = _buffer[i]; buffer[num2++] = _buffer[i]; } return num3 * 2; } protected override void Dispose(bool disposing) { base.Dispose(disposing); _buffer = null; } } } namespace CSCore.DSP { public class DmoChannelResampler : DmoResampler { private readonly ChannelMatrix _channelMatrix; public ChannelMatrix ChannelMatrix => _channelMatrix; public DmoChannelResampler(IWaveSource source, ChannelMatrix channelMatrix) : this(source, channelMatrix, source.WaveFormat.SampleRate) { } public DmoChannelResampler(IWaveSource source, ChannelMatrix channelMatrix, WaveFormat outputFormat) : base(source, outputFormat) { if (source == null) { throw new ArgumentNullException("source"); } if (channelMatrix == null) { throw new ArgumentNullException("channelMatrix"); } if (outputFormat == null) { throw new ArgumentNullException("outputFormat"); } if (source.WaveFormat.Channels != channelMatrix.InputChannelCount) { throw new ArgumentException("The number of channels of the source has to be equal to the number of input channels specified by the channelMatrix."); } WaveFormatExtensible inputformat = new WaveFormatExtensible(source.WaveFormat.SampleRate, source.WaveFormat.BitsPerSample, source.WaveFormat.Channels, WaveFormatExtensible.SubTypeFromWaveFormat(source.WaveFormat), channelMatrix.InputMask); Outputformat = new WaveFormatExtensible(outputFormat.SampleRate, outputFormat.BitsPerSample, outputFormat.Channels, WaveFormatExtensible.SubTypeFromWaveFormat(outputFormat), channelMatrix.OutputMask); Initialize(inputformat, Outputformat); _channelMatrix = channelMatrix; CommitChannelMatrixChanges(); } public DmoChannelResampler(IWaveSource source, ChannelMatrix channelMatrix, int destinationSampleRate) : this(source, channelMatrix, GetOutputWaveFormat(source, destinationSampleRate, channelMatrix)) { } private static WaveFormat GetOutputWaveFormat(IWaveSource source, int sampleRate, ChannelMatrix channelMatrix) { if (source == null) { throw new ArgumentNullException("source"); } if (channelMatrix == null) { throw new ArgumentNullException("channelMatrix"); } WaveFormat waveFormat = channelMatrix.BuildOutputWaveFormat(source); waveFormat.SampleRate = sampleRate; return waveFormat; } public void CommitChannelMatrixChanges() { using (Resampler.MediaObject.Lock()) { Resampler.MediaObject.SetOutputType(0, Resampler.MediaObject.GetOutputCurrentType(0), SetTypeFlags.None); Resampler.ResamplerProps.SetUserChannelMtx(_channelMatrix.GetOneDimensionalMatrix()); } } } } namespace CSCore.Streams { public class StereoToMonoSource : SampleAggregatorBase { private readonly WaveFormat _waveFormat; private float[] _buffer; public override long Position { get { return BaseSource.Position / 2; } set { value -= value % WaveFormat.BlockAlign; BaseSource.Position = value * 2; } } public override long Length => BaseSource.Length / 2; public override WaveFormat WaveFormat => _waveFormat; public StereoToMonoSource(ISampleSource source) : base(source) { if (source == null) { throw new ArgumentNullException("source"); } if (source.WaveFormat.Channels != 2) { throw new ArgumentException("The WaveFormat of the source has be a stereo format (two channels).", "source"); } _waveFormat = new WaveFormat(source.WaveFormat.SampleRate, 32, 1, AudioEncoding.IeeeFloat); } public unsafe override int Read(float[] buffer, int offset, int count) { _buffer = _buffer.CheckBuffer(count * 2); int num = BaseSource.Read(_buffer, 0, count * 2); fixed (float* ptr = buffer) { float* ptr2 = ptr + offset; for (int i = 0; i < num - 1; i += 2) { *(ptr2++) = (_buffer[i] + _buffer[i + 1]) / 2f; } } return num / 2; } protected override void Dispose(bool disposing) { base.Dispose(disposing); _buffer = null; } } public class LoopStream : WaveAggregatorBase { private bool _enableLoop = true; private bool _raisedStreamFinishedEvent; public bool EnableLoop { get { return _enableLoop; } set { _enableLoop = value; } } public event EventHandler StreamFinished; public LoopStream(IWaveSource source) : base(source) { } public override int Read(byte[] buffer, int offset, int count) { int i; int num; for (i = base.Read(buffer, offset, count); i < count; i += num) { num = base.Read(buffer, offset + i, count - i); if (num == 0) { EventHandler streamFinished = this.StreamFinished; if (streamFinished != null && !_raisedStreamFinishedEvent) { streamFinished(this, EventArgs.Empty); _raisedStreamFinishedEvent = true; } if (!EnableLoop) { break; } Position = 0L; } else { _raisedStreamFinishedEvent = false; } } return i; } } } namespace CSCore.Streams.SampleConverter { public class SampleToPcm8 : SampleToWaveBase { public SampleToPcm8(ISampleSource source) : base(source, 8, AudioEncoding.Pcm) { } public override int Read(byte[] buffer, int offset, int count) { Buffer = Buffer.CheckBuffer(count); int num = Source.Read(Buffer, 0, count); for (int i = offset; i < num; i++) { byte b = (byte)((Buffer[i] + 1f) * 128f); buffer[i] = b; } return num; } } public class SampleToPcm16 : SampleToWaveBase { public SampleToPcm16(ISampleSource source) : base(source, 16, AudioEncoding.Pcm) { if (source == null) { throw new ArgumentNullException("source"); } } public override int Read(byte[] buffer, int offset, int count) { Buffer = Buffer.CheckBuffer(count / 2); int num = Source.Read(Buffer, 0, count / 2); int num2 = offset; for (int i = 0; i < num; i++) { short value = (short)(Buffer[i] * 32767f); byte[] bytes = BitConverter.GetBytes(value); buffer[num2++] = bytes[0]; buffer[num2++] = bytes[1]; } return num * 2; } } public class SampleToPcm24 : SampleToWaveBase { public SampleToPcm24(ISampleSource source) : base(source, 24, AudioEncoding.Pcm) { if (source == null) { throw new ArgumentNullException("source"); } } public unsafe override int Read(byte[] buffer, int offset, int count) { int num = count / 3; Buffer = Buffer.CheckBuffer(num); int num2 = Source.Read(Buffer, 0, num); int num3 = offset; for (int i = 0; i < num2; i++) { uint num4 = (uint)(Buffer[i] * 8388608f); byte* ptr = (byte*)(&num4); buffer[num3++] = *ptr; buffer[num3++] = ptr[1]; buffer[num3++] = ptr[2]; } return num2 * 3; } } public class SampleToIeeeFloat32 : SampleToWaveBase { public SampleToIeeeFloat32(ISampleSource source) : base(source, 32, AudioEncoding.IeeeFloat) { if (source == null) { throw new ArgumentNullException("source"); } } public override int Read(byte[] buffer, int offset, int count) { Buffer = Buffer.CheckBuffer(count / 4); int num = Source.Read(Buffer, offset / 4, count / 4); System.Buffer.BlockCopy(Buffer, 0, buffer, offset, num * 4); return num * 4; } } public abstract class WaveToSampleBase : ISampleSource, IReadableAudioSource<float>, IAudioSource, IDisposable { private readonly WaveFormat _waveFormat; protected internal IWaveSource Source; protected internal byte[] Buffer; public WaveFormat WaveFormat => _waveFormat; public long Position { get { if (!CanSeek) { return 0L; } return Source.Position / Source.WaveFormat.BytesPerSample; } set { if (CanSeek) { value -= value % WaveFormat.BlockAlign; Source.Position = value * Source.WaveFormat.BytesPerSample; return; } throw new InvalidOperationException(); } } public long Length { get { if (!CanSeek || Source.Length == 0L) { return 0L; } return Source.Length / Source.WaveFormat.BytesPerSample; } } public bool CanSeek => Source.CanSeek; protected WaveToSampleBase(IWaveSource source) { if (source == null) { throw new ArgumentNullException("source"); } Source = source; _waveFormat = (WaveFormat)source.WaveFormat.Clone(); _waveFormat.BitsPerSample = 32; _waveFormat.SetWaveFormatTagInternal(AudioEncoding.IeeeFloat); } public abstract int Read(float[] buffer, int offset, int count); public void Dispose() { Dispose(disposing: true); } protected virtual void Dispose(bool disposing) { if (Source != null) { Source.Dispose(); Source = null; } } ~WaveToSampleBase() { Dispose(disposing: false); } public static ISampleSource CreateConverter(IWaveSource source) { if (source == null) { throw new ArgumentNullException("source"); } int bitsPerSample = source.WaveFormat.BitsPerSample; if (source.WaveFormat.IsPCM()) { return bitsPerSample switch { 8 => new Pcm8BitToSample(source), 16 => new Pcm16BitToSample(source), 24 => new Pcm24BitToSample(source), 32 => new Pcm32BitToSample(source), _ => throw new NotSupportedException("Waveformat is not supported. Invalid BitsPerSample value."), }; } if (source.WaveFormat.IsIeeeFloat() && bitsPerSample == 32) { return new IeeeFloatToSample(source); } throw new NotSupportedException("Waveformat is not supported. Invalid WaveformatTag."); } } } namespace CSCore.Streams { public class SynchronizedWaveSource<TBaseSource, T> : IAggregator<T, TBaseSource>, IReadableAudioSource<T>, IAudioSource, IDisposable where TBaseSource : class, IReadableAudioSource<T> { private readonly object _lockObj = new object(); private TBaseSource _baseSource; private bool _disposed; public WaveFormat WaveFormat { get { lock (_lockObj) { return BaseSource.WaveFormat; } } } public long Position { get { lock (_lockObj) { return BaseSource.Position; } } set { lock (_lockObj) { value -= value % WaveFormat.BlockAlign; BaseSource.Position = value; } } } public long Length { get { lock (_lockObj) { return BaseSource.Length; } } } public bool CanSeek { get { lock (_lockObj) { return BaseSource.CanSeek; } } } public TBaseSource BaseSource { get { lock (_lockObj) { return _baseSource; } } set { lock (_lockObj) { if (value == null) { throw new ArgumentNullException("value"); } _baseSource = value; } } } public SynchronizedWaveSource(TBaseSource baseWaveSource) { BaseSource = baseWaveSource; } public int Read(T[] buffer, int offset, int count) { lock (_lockObj) { return BaseSource.Read(buffer, offset, count); } } public static explicit operator TBaseSource(SynchronizedWaveSource<TBaseSource, T> synchronizedWaveSource) { if (synchronizedWaveSource == null) { throw new ArgumentNullException("synchronizedWaveSource"); } return synchronizedWaveSource.BaseSource; } protected void Dispose(bool disposing) { lock (_lockObj) { if (BaseSource != null) { BaseSource.Dispose(); } _baseSource = null; } } public void Dispose() { lock (_lockObj) { if (!_disposed) { _disposed = true; Dispose(disposing: true); GC.SuppressFinalize(this); } } } ~SynchronizedWaveSource() { lock (_lockObj) { Dispose(disposing: false); } } } } namespace CSCore { public interface IReadableAudioSource<in T> : IAudioSource, IDisposable { int Read(T[] buffer, int offset, int count); } public interface IWriteable { void Write(byte[] buffer, int offset, int count); } public enum MmResult { NoError = 0, Error = 1, BadDevice = 2, NotEnabled = 3, Allocated = 4, InvalidHandle = 5, NoDriver = 6, NoMemory = 7, NotSupported = 8, BadErrorNumber = 9, InvalidFlag = 10, InvalidParameter = 11, HandleBusy = 12, InvalidAlias = 13, BadDatabase = 14, KeyNotFound = 15, ReadError = 16, WriteError = 17, DeleteError = 18, ValueNotFound = 19, NoDriverCallback = 20, MoreData = 21, BadFormat = 32, StillPlaying = 33, Unprepared = 34, Synchronous = 35 } public class StoppedEventArgs : EventArgs { private readonly Exception _exception; public virtual bool HasError => _exception != null; public virtual Exception Exception => _exception; public StoppedEventArgs() : this(null) { } public StoppedEventArgs(Exception exception) { _exception = exception; } } public abstract class TimeConverter { internal class _WaveSourceTimeConverter : TimeConverter { public override long ToRawElements(WaveFormat waveFormat, TimeSpan timeSpan) { return waveFormat.MillisecondsToBytes(timeSpan.TotalMilliseconds); } public override TimeSpan ToTimeSpan(WaveFormat waveFormat, long rawElements) { return TimeSpan.FromMilliseconds(waveFormat.BytesToMilliseconds(rawElements)); } } internal class _SampleSourceTimeConverter : TimeConverter { public override long ToRawElements(WaveFormat waveFormat, TimeSpan timeSpan) { return waveFormat.MillisecondsToBytes(timeSpan.TotalMilliseconds) / waveFormat.BytesPerSample; } public override TimeSpan ToTimeSpan(WaveFormat waveFormat, long rawElements) { return TimeSpan.FromMilliseconds(waveFormat.BytesToMilliseconds(rawElements * waveFormat.BytesPerSample)); } } public static readonly TimeConverter SampleSourceTimeConverter = new _SampleSourceTimeConverter(); public static readonly TimeConverter WaveSourceTimeConverter = new _WaveSourceTimeConverter(); public abstract long ToRawElements(WaveFormat waveFormat, TimeSpan timeSpan); public abstract TimeSpan ToTimeSpan(WaveFormat waveFormat, long rawElements); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] public sealed class TimeConverterAttribute : Attribute { public Type TimeConverterType { get; private set; } public object[] Args { get; set; } public bool ForceNewInstance { get; set; } public TimeConverterAttribute(Type timeConverterType) { if ((object)timeConverterType == null) { throw new ArgumentNullException("timeConverterType"); } if (!typeof(TimeConverter).IsAssignableFrom(timeConverterType)) { throw new ArgumentException("Specified type is no time converter.", "timeConverterType"); } TimeConverterType = timeConverterType; } } public sealed class TimeConverterFactory { private class CacheItem { public TimeConverter TimeConverter { get; set; } public TimeConverterAttribute TimeConverterAttribute { get; set; } public bool CreateNewInstance { get; set; } public TimeConverter GetTimeConverter() { if (CreateNewInstance) { return (TimeConverter)Activator.CreateInstance(TimeConverterAttribute.TimeConverterType, TimeConverterAttribute.Args); } return TimeConverter; } } private static readonly TimeConverterFactory _instance = new TimeConverterFactory(); private readonly Dictionary<Type, TimeConverter> _timeConverters; private readonly Dictionary<Type, CacheItem> _cache; public static TimeConverterFactory Instance => _instance; private TimeConverterFactory() { _timeConverters = new Dictionary<Type, TimeConverter>(); _cache = new Dictionary<Type, CacheItem>(); RegisterTimeConverterForSourceType<IWaveSource>(TimeConverter.WaveSourceTimeConverter); RegisterTimeConverterForSourceType<ISampleSource>(TimeConverter.SampleSourceTimeConverter); } public void RegisterTimeConverterForSourceType<TSource>(TimeConverter timeConverter) where TSource : IAudioSource { if (timeConverter == null) { throw new ArgumentNullException("timeConverter"); } Type typeFromHandle = typeof(TSource); if (_timeConverters.ContainsKey(typeFromHandle)) { throw new ArgumentException("A timeconverter for the same source type got already registered."); } _timeConverters.Add(typeFromHandle, timeConverter); } public void UnregisterTimeConverter<TSource>() where TSource : IAudioSource { Type typeFromHandle = typeof(TSource); if (!_timeConverters.ContainsKey(typeFromHandle)) { throw new ArgumentException("There is no timeconverter registered for the specified source type."); } _timeConverters.Remove(typeFromHandle); } public TimeConverter GetTimeConverterForSource<TSource>(TSource source) where TSource : class, IAudioSource { if (source == null) { throw new ArgumentNullException("source"); } return GetTimeConverterForSourceType(source.GetType()); } public TimeConverter GetTimeConverterForSource<TSource>() where TSource : IAudioSource { return GetTimeConverterForSourceType(typeof(TSource)); } public TimeConverter GetTimeConverterForSourceType(Type sourceType) { if ((object)sourceType == null) { throw new ArgumentNullException("sourceType"); } if (!typeof(IAudioSource).IsAssignableFrom(sourceType)) { throw new ArgumentException("Specified type is no AudioSource.", "sourceType"); } if (_cache.ContainsKey(sourceType)) { return _cache[sourceType].GetTimeConverter(); } TimeConverterAttribute timeConverterAttribute = sourceType.GetCustomAttributes(typeof(TimeConverterAttribute), inherit: false).FirstOrDefault() as TimeConverterAttribute; TimeConverter timeConverter = null; try { if (timeConverterAttribute == null) { Type[] array = (from x in GetTypes(sourceType) where _timeConverters.ContainsKey(x) select x).ToArray(); if (array.Length == 1) { timeConverter = _timeConverters[array.First()]; return timeConverter; } if (array.Length == 0) { throw new ArgumentException("No registered time converter for the specified source type was found."); } throw new ArgumentException("Multiple possible time converters, for the specified source type, were found. Specify which time converter to use, through the TimeConverterAttribute."); } Type timeConverterType = timeConverterAttribute.TimeConverterType; timeConverter = (TimeConverter)Activator.CreateInstance(timeConverterType, timeConverterAttribute.Args); return timeConverter; } finally { if (timeConverter != null) { CacheItem value = ((timeConverterAttribute != null) ? new CacheItem { CreateNewInstance = timeConverterAttribute.ForceNewInstance, TimeConverterAttribute = timeConverterAttribute, TimeConverter = (timeConverterAttribute.ForceNewInstance ? null : timeConverter) } : new CacheItem { CreateNewInstance = false, TimeConverter = timeConverter }); _cache[sourceType] = value; } } } public void ClearCache() { _cache.Clear(); } private IEnumerable<Type> GetTypes(Type type) { if ((object)type.BaseType != typeof(object)) { return Enumerable.Repeat(type.BaseType, 1).Concat<Type>(type.GetInterfaces()).Concat(GetTypes(type.BaseType)) .Distinct(); } return type.GetInterfaces(); } } public interface ISampleAggregator : ISampleSource, IReadableAudioSource<float>, IAudioSource, IDisposable, IAggregator<float, ISampleSource> { } public interface IAggregator<in T, out TAggregator> : IReadableAudioSource<T>, IAudioSource, IDisposable where TAggregator : IReadableAudioSource<T> { TAggregator BaseSource { get; } } public interface IWaveAggregator : IWaveSource, IReadableAudioSource<byte>, IAudioSource, IDisposable, IAggregator<byte, IWaveSource> { } [Serializable] public class MmException : Exception { public MmResult Result { get; private set; } [Obsolete("Use the Function property instead.")] public string Target { get; private set; } public string Function => Target; public static void Try(MmResult result, string function) { if (result != 0) { throw new MmException(result, function); } } public MmException(MmResult result, string function) { Result = result; Target = function; } public MmException(SerializationInfo info, StreamingContext context) : base(info, context) { if (info == null) { throw new ArgumentNullException("info"); } Target = info.GetString("Target"); Result = (MmResult)info.GetInt32("Result"); } public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info.AddValue("Target", Target); info.AddValue("Result", (int)Result); } } public class SampleAggregatorBase : ISampleAggregator, ISampleSource, IReadableAudioSource<float>, IAudioSource, IDisposable, IAggregator<float, ISampleSource> { private bool _disposed; private ISampleSource _baseSource; public virtual WaveFormat WaveFormat => BaseSource.WaveFormat; public virtual long Position { get { if (!CanSeek) { return 0L; } return BaseSource.Position; } set { if (CanSeek) { value -= value % WaveFormat.BlockAlign; BaseSource.Position = value; return; } throw new InvalidOperationException("Underlying BaseSource is not readable."); } } public virtual long Length { get { if (!CanSeek) { return 0L; } return BaseSource.Length; } } public bool CanSeek => BaseSource.CanSeek; public virtual ISampleSource BaseSource { get { return _baseSource; } set { if (value == null) { throw new ArgumentNullException("value"); } _baseSource = value; } } public bool DisposeBaseSource { get; set; } public SampleAggregatorBase(ISampleSource source) { if (source == null) { throw new ArgumentNullException("source"); } _baseSource = source; DisposeBaseSource = true; } public virtual int Read(float[] buffer, int offset, int count) { if (offset % WaveFormat.Channels != 0) { offset -= offset % WaveFormat.Channels; } if (count % WaveFormat.Channels != 0) { count -= count % WaveFormat.Channels; } return BaseSource.Read(buffer, offset, count); } public void Dispose() { if (!_disposed) { _disposed = true; Dispose(disposing: true); GC.SuppressFinalize(this); } } protected virtual void Dispose(bool disposing) { if (DisposeBaseSource && BaseSource != null) { BaseSource.Dispose(); _baseSource = null; } } ~SampleAggregatorBase() { Dispose(disposing: false); } } public static class Extensions { public static TimeSpan GetLength(this IAudioSource source) { return source.GetTime(source.Length); } public static TimeSpan GetPosition(this IAudioSource source) { return source.GetTime(source.Position); } public static void SetPosition(this IAudioSource source, TimeSpan position) { if (source == null) { throw new ArgumentNullException("source"); } if (position.TotalMilliseconds < 0.0) { throw new ArgumentOutOfRangeException("position"); } long rawElements = source.GetRawElements(position); source.Position = rawElements; } public static TimeSpan GetTime(this IAudioSource source, long elementCount) { if (source == null) { throw new ArgumentNullException("source"); } if (elementCount < 0) { throw new ArgumentNullException("elementCount"); } return TimeConverterFactory.Instance.GetTimeConverterForSource(source).ToTimeSpan(source.WaveFormat, elementCount); } public static long GetMilliseconds(this IAudioSource source, long elementCount) { if (source == null) { throw new ArgumentNullException("source"); } if (elementCount < 0) { throw new ArgumentOutOfRangeException("elementCount"); } return (long)source.GetTime(elementCount).TotalMilliseconds; } public static long GetRawElements(this IAudioSource source, TimeSpan timespan) { if (source == null) { throw new ArgumentNullException("source"); } return TimeConverterFactory.Instance.GetTimeConverterForSource(source).ToRawElements(source.WaveFormat, timespan); } public static long GetRawElements(this IAudioSource source, long milliseconds) { if (source == null) { throw new ArgumentNullException("source"); } if (milliseconds < 0) { throw new ArgumentOutOfRangeException("milliseconds"); } return source.GetRawElements(TimeSpan.FromMilliseconds(milliseconds)); } public static void WriteToFile(this IWaveSource source, string filename) { if (source == null) { throw new ArgumentNullException("source"); } using FileStream stream = File.OpenWrite(filename); source.WriteToWaveStream(stream); } public static void WriteToWaveStream(this IWaveSource source, Stream stream) { if (source == null) { throw new ArgumentNullException("source"); } if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanWrite) { throw new ArgumentException("Stream is not writeable.", "stream"); } using WaveWriter waveWriter = new WaveWriter(stream, source.WaveFormat); byte[] array = new byte[source.WaveFormat.BytesPerSecond]; int count; while ((count = source.Read(array, 0, array.Length)) > 0) { waveWriter.Write(array, 0, count); } } public static void WriteToStream(this IWaveSource waveSource, Stream stream) { if (waveSource == null) { throw new ArgumentNullException("waveSource"); } if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanWrite) { throw new ArgumentException("Stream is not writeable.", "stream"); } byte[] array = new byte[waveSource.WaveFormat.BytesPerSecond]; int count; while ((count = waveSource.Read(array, 0, array.Length)) > 0) { stream.Write(array, 0, count); } } public static T[] CheckBuffer<T>(this T[] inst, long size, bool exactSize = false) { if (inst == null || (!exactSize && inst.Length < size) || (exactSize && inst.Length != size)) { return new T[size]; } return inst; } internal static byte[] ReadBytes(this IWaveSource waveSource, int count) { if (waveSource == null) { throw new ArgumentNullException("waveSource"); } count -= count % waveSource.WaveFormat.BlockAlign; if (count <= 0) { throw new ArgumentOutOfRangeException("count"); } byte[] array = new byte[count]; int num = waveSource.Read(array, 0, array.Length); if (num < count) { Array.Resize(ref array, num); } return array; } internal static bool IsClosed(this Stream stream) { if (!stream.CanRead) { return !stream.CanWrite; } return false; } internal static bool IsEndOfStream(this Stream stream) { return stream.Position == stream.Length; } internal static int LowWord(this int number) { return number & 0xFFFF; } internal static int LowWord(this int number, int newValue) { return (int)((number & 0xFFFF0000u) + (newValue & 0xFFFF)); } internal static int HighWord(this int number) { return (int)(number & 0xFFFF0000u); } internal static int HighWord(this int number, int newValue) { return (number & 0xFFFF) + (newValue << 16); } internal static uint LowWord(this uint number) { return number & 0xFFFFu; } internal static uint LowWord(this uint number, int newValue) { return (uint)((uint)((int)number & -65536) + (newValue & 0xFFFF)); } internal static uint HighWord(this uint number) { return number & 0xFFFF0000u; } internal static uint HighWord(this uint number, int newValue) { return (uint)((number & 0xFFFF) + (newValue << 16)); } internal static Guid GetGuid(this object obj) { return obj.GetType().GUID; } internal static void WaitForExit(this Thread thread) { if (thread != null) { if (thread == Thread.CurrentThread) { throw new InvalidOperationException("Deadlock detected."); } thread.Join(); } } internal static bool WaitForExit(this Thread thread, int timeout) { if (thread == null) { return true; } if (thread == Thread.CurrentThread) { throw new InvalidOperationException("Deadlock detected."); } return thread.Join(timeout); } internal static bool IsPCM(this WaveFormat waveFormat) { if (waveFormat == null) { throw new ArgumentNullException("waveFormat"); } if (waveFormat is WaveFormatExtensible) { return ((WaveFormatExtensible)waveFormat).SubFormat == AudioSubTypes.Pcm; } return waveFormat.WaveFormatTag == AudioEncoding.Pcm; } internal static bool IsIeeeFloat(this WaveFormat waveFormat) { if (waveFormat == null) { throw new ArgumentNullException("waveFormat"); } if (waveFormat is WaveFormatExtensible) { return ((WaveFormatExtensible)waveFormat).SubFormat == AudioSubTypes.IeeeFloat; } return waveFormat.WaveFormatTag == AudioEncoding.IeeeFloat; } internal static AudioEncoding GetWaveFormatTag(this WaveFormat waveFormat) { if (waveFormat is WaveFormatExtensible) { return AudioSubTypes.EncodingFromSubType(((WaveFormatExtensible)waveFormat).SubFormat); } return waveFormat.WaveFormatTag; } public static bool WaitForStopped(this ISoundOut soundOut, int millisecondsTimeout) { if (soundOut == null) { throw new ArgumentNullException("soundOut"); } if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } if (soundOut.PlaybackState == PlaybackState.Stopped) { return true; } AutoResetEvent waitHandle = new AutoResetEvent(initialState: false); try { EventHandler<PlaybackStoppedEventArgs> value = delegate { waitHandle.Set(); }; soundOut.Stopped += value; bool result = waitHandle.WaitOne(millisecondsTimeout); soundOut.Stopped -= value; return result; } finally { if (waitHandle != null) { ((IDisposable)waitHandle).Dispose(); } } } public static void WaitForStopped(this ISoundOut soundOut) { soundOut.WaitForStopped(-1); } internal static void SetValueForValueType<T>(this FieldInfo field, ref T item, object value) where T : struct { field.SetValueDirect(__makeref(item), value); } } } namespace CSCore.SoundOut { public class PlaybackStoppedEventArgs : StoppedEventArgs { public PlaybackStoppedEventArgs() : this(null) { } public PlaybackStoppedEventArgs(Exception exception) : base(exception) { } } } namespace CSCore.Codecs.WAV { public class WaveWriter : IDisposable, IWriteable { private readonly WaveFormat _waveFormat; private readonly long _waveStartPosition; private int _dataLength; private bool _isDisposed; private Stream _stream; private BinaryWriter _writer; private bool _isDisposing; private readonly bool _closeStream; public bool IsDisposed => _isDisposed; public bool IsDisposing => _isDisposing; public WaveWriter(string fileName, WaveFormat waveFormat) : this(File.OpenWrite(fileName), waveFormat) { _closeStream = true; } public WaveWriter(Stream stream, WaveFormat waveFormat) { if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanWrite) { throw new ArgumentException("Stream not writeable.", "stream"); } if (!stream.CanSeek) { throw new ArgumentException("Stream not seekable.", "stream"); } _isDisposing = false; _isDisposed = false; _stream = stream; _waveStartPosition = stream.Position; _writer = new BinaryWriter(stream); for (int i = 0; i < 44; i++) { _writer.Write((byte)0); } _waveFormat = waveFormat; WriteHeader(); _closeStream = false; } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } [Obsolete("Use the Extensions.WriteToWaveStream extension instead.")] public static void WriteToFile(string filename, IWaveSource source, bool deleteFileIfAlreadyExists, int maxlength = -1) { if (deleteFileIfAlreadyExists && File.Exists(filename)) { File.Delete(filename); } int num = 0; byte[] array = new byte[source.WaveFormat.BytesPerSecond]; using WaveWriter waveWriter = new WaveWriter(filename, source.WaveFormat); int num2; while ((num2 = source.Read(array, 0, array.Length)) > 0) { waveWriter.Write(array, 0, num2); num += num2; if (maxlength != -1 && num > maxlength) { break; } } } public void WriteSample(float sample) { CheckObjectDisposed(); if (sample < -1f || sample > 1f) { sample = Math.Max(-1f, Math.Min(1f, sample)); } if (_waveFormat.IsPCM()) { switch (_waveFormat.BitsPerSample) { case 8: Write((byte)(255f * sample)); break; case 16: Write((short)(32767f * sample)); break; case 24: { byte[] bytes = BitConverter.GetBytes((int)(8388607f * sample)); Write(new byte[3] { bytes[0], bytes[1], bytes[2] }, 0, 3); break; } case 32: Write((int)(2.1474836E+09f * sample)); break; default: throw new InvalidOperationException("Invalid Waveformat", new InvalidOperationException("Invalid BitsPerSample while using PCM encoding.")); } } else if (_waveFormat.IsIeeeFloat()) { Write(sample); } else { if (_waveFormat.WaveFormatTag != AudioEncoding.Extensible || _waveFormat.BitsPerSample != 32) { throw new InvalidOperationException("Invalid Waveformat: Waveformat has to be PCM[8, 16, 24, 32] or IeeeFloat[32]"); } Write(65535 * (int)sample); } } public void WriteSamples(float[] samples, int offset, int count) { CheckObjectDisposed(); for (int i = offset; i < offset + count; i++) { WriteSample(samples[i]); } } public void Write(byte[] buffer, int offset, int count) { CheckObjectDisposed(); _stream.Write(buffer, offset, count); _dataLength += count; } public void Write(byte value) { CheckObjectDisposed(); _writer.Write(value); _dataLength++; } public void Write(short value) { CheckObjectDisposed(); _writer.Write(value); _dataLength += 2; } public void Write(int value) { CheckObjectDisposed(); _writer.Write(value); _dataLength += 4; } public void Write(float value) { CheckObjectDisposed(); _writer.Write(value); _dataLength += 4; } private void WriteHeader() { _writer.Flush(); long position = _stream.Position; _stream.Position = _waveStartPosition; WriteRiffHeader(); WriteFmtChunk(); WriteDataChunk(); _writer.Flush(); _stream.Position = position; } private void WriteRiffHeader() { _writer.Write(Encoding.UTF8.GetBytes("RIFF")); _writer.Write((int)(_stream.Length - 8)); _writer.Write(Encoding.UTF8.GetBytes("WAVE")); } private void WriteFmtChunk() { AudioEncoding audioEncoding = _waveFormat.WaveFormatTag; if (audioEncoding == AudioEncoding.Extensible && _waveFormat is WaveFormatExtensible) { audioEncoding = AudioSubTypes.EncodingFromSubType((_waveFormat as WaveFormatExtensible).SubFormat); } _writer.Write(Encoding.UTF8.GetBytes("fmt ")); _writer.Write(16); _writer.Write((short)audioEncoding); _writer.Write((short)_waveFormat.Channels); _writer.Write(_waveFormat.SampleRate); _writer.Write(_waveFormat.BytesPerSecond); _writer.Write((short)_waveFormat.BlockAlign); _writer.Write((short)_waveFormat.BitsPerSample); } private void WriteDataChunk() { _writer.Write(Encoding.UTF8.GetBytes("data")); _writer.Write(_dataLength); } private void CheckObjectDisposed() { if (_isDisposed) { throw new ObjectDisposedException("WaveWriter"); } } protected virtual void Dispose(bool disposing) { if (_isDisposed || !disposing) { return; } try { _isDisposing = true; WriteHeader(); } catch (Exception) { } finally { if (_closeStream) { if (_writer != null) { _writer.Close(); _writer = null; } if (_stream != null) { _stream.Dispose(); _stream = null; } } _isDisposing = false; } _isDisposed = true; } ~WaveWriter() { Dispose(disposing: false); } } } namespace CSCore.SoundOut { public interface ISoundOut : IDisposable { float Volume { get; set; } IWaveSource WaveSource { get; } PlaybackState PlaybackState { get; } event EventHandler<PlaybackStoppedEventArgs> Stopped; void Play(); void Pause(); void Resume(); void Stop(); void Initialize(IWaveSource source); } public enum PlaybackState { Stopped, Playing, Paused } } namespace CSCore { public abstract class WaveAggregatorBase : IWaveAggregator, IWaveSource, IReadableAudioSource<byte>, IAudioSource, IDisposable, IAggregator<byte, IWaveSource> { private IWaveSource _baseSource; private bool _disposed; public bool DisposeBaseSource { get; set; } public virtual IWaveSource BaseSource { get { return _baseSource; } set { if (value == null) { throw new ArgumentNullException("value", "BaseSource must not be null."); } _baseSource = value; } } public virtual WaveFormat WaveFormat => BaseSource.WaveFormat; public virtual long Position { get { if (!CanSeek) { return 0L; } return BaseSource.Position; } set { if (CanSeek) { value -= value % WaveFormat.BlockAlign; BaseSource.Position = value; return; } throw new InvalidOperationException(); } } public virtual long Length { get { if (!CanSeek) { return 0L; } return BaseSource.Length; } } public virtual bool CanSeek => BaseSource.CanSeek; protected WaveAggregat