public AudioDecoder(string path, Stream IO) { m_path = path; isValid(path); bool pfIsProtected; WMUtils.WMIsContentProtected(path, out pfIsProtected); if (pfIsProtected) { throw new Exception("DRM present"); } WMUtils.WMCreateSyncReader(IntPtr.Zero, Rights.None, out m_syncReader); if (path == null) { m_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000); m_streamWrapper = new StreamWrapper(m_IO); m_syncReader.OpenStream(m_streamWrapper); } else { m_syncReader.Open(path); } var pProfile = (m_syncReader as IWMProfile); int dwStreamCount; pProfile.GetStreamCount(out dwStreamCount); for (int dwIndex = 0; dwIndex < dwStreamCount; dwIndex++) { IWMStreamConfig pConfig = null; pProfile.GetStream(dwIndex, out pConfig); try { Guid guid; pConfig.GetStreamType(out guid); if (MediaType.Audio != guid) { continue; } short wStreamNum; pConfig.GetStreamNumber(out wStreamNum); int dwBitrate = -1; pConfig.GetBitrate(out dwBitrate); var pIWMMediaProps = pConfig as IWMMediaProps; int cbType = 0; pIWMMediaProps.GetMediaType(null, ref cbType); var pMediaType = new AMMediaType(); pMediaType.formatSize = cbType; pIWMMediaProps.GetMediaType(pMediaType, ref cbType); if (pMediaType.formatType != FormatType.WaveEx) { continue; } if (pMediaType.subType != MediaSubType.WMAudio_Lossless) { continue; } m_wStreamNum = wStreamNum; pcm = WaveFormatExtensible.FromMediaType(pMediaType).GetConfig(); break; } finally { Marshal.ReleaseComObject(pConfig); } } if (m_wStreamNum == -1) { throw new Exception("No WMA lossless streams found"); } m_syncReader.SetReadStreamSamples(m_wStreamNum, false); bool pfCompressed; m_syncReader.GetReadStreamSamples(m_wStreamNum, out pfCompressed); if (pfCompressed) { throw new Exception("doesn't decompress"); } m_syncReader.GetOutputNumberForStream(m_wStreamNum, out m_dwAudioOutputNum); IWMOutputMediaProps pProps; m_syncReader.GetOutputProps(m_dwAudioOutputNum, out pProps); try { StringBuilder sName = null; AMMediaType pMediaType = null; int cbType = 0; cbType = 0; pMediaType = null; pProps.GetMediaType(pMediaType, ref cbType); // Get the name of the output we'll be using sName = null; short iName = 0; pProps.GetConnectionName(sName, ref iName); sName = new StringBuilder(iName); pProps.GetConnectionName(sName, ref iName); if (pcm.ChannelCount > 2) { m_syncReader.SetOutputSetting(m_dwAudioOutputNum, Constants.g_wszEnableDiscreteOutput, AttrDataType.BOOL, new byte[] { 1, 0, 0, 0 }, 4); m_syncReader.SetOutputSetting(m_dwAudioOutputNum, Constants.g_wszSpeakerConfig, AttrDataType.DWORD, new byte[] { 0, 0, 0, 0 }, 4); } pMediaType = new AMMediaType(); pMediaType.formatSize = cbType - Marshal.SizeOf(typeof(AMMediaType)); // // Get the value for MediaType // pProps.GetMediaType(pMediaType, ref cbType); try { if (MediaType.Audio != pMediaType.majorType) { throw new Exception("not Audio"); } if (FormatType.WaveEx != pMediaType.formatType) { throw new Exception("not WaveEx"); } var wfe = new WaveFormatExtensible(pcm); Marshal.FreeCoTaskMem(pMediaType.formatPtr); pMediaType.formatPtr = IntPtr.Zero; pMediaType.formatSize = 0; pMediaType.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(wfe)); pMediaType.formatSize = Marshal.SizeOf(wfe); Marshal.StructureToPtr(wfe, pMediaType.formatPtr, false); pProps.SetMediaType(pMediaType); m_syncReader.SetOutputProps(m_dwAudioOutputNum, pProps); } finally { WMUtils.FreeWMMediaType(pMediaType); } } finally { Marshal.ReleaseComObject(pProps); } //try //{ // AttrDataType wmtType; // short cbLength = 0; // short wAnyStream = 0; // var pHeaderInfo = m_syncReader as IWMHeaderInfo; // pHeaderInfo.GetAttributeByName(ref wAnyStream, Constants.g_wszWMDuration, out wmtType, null, ref cbLength); // var pbValue = new byte[cbLength]; // pHeaderInfo.GetAttributeByName(ref wAnyStream, Constants.g_wszWMDuration, out wmtType, pbValue, ref cbLength); // var m_cnsFileDuration = BitConverter.ToInt64(pbValue, 0); // _sampleCount = m_cnsFileDuration * m_pWfx.nSamplesPerSec / 10000000; // // NOT ACCURATE ENOUGH (~1ms precision observed) //} //catch (COMException) //{ //} //try //{ // var pHeaderInfo = m_syncReader as IWMHeaderInfo2; // int nCodec; // pHeaderInfo.GetCodecInfoCount(out nCodec); // for (int wIndex = 0; wIndex < nCodec; wIndex++) // { // CodecInfoType enumCodecType; // short cchName = 0; // short cchDescription = 0; // short cbCodecInfo = 0; // pHeaderInfo.GetCodecInfo(wIndex, ref cchName, null, // ref cchDescription, null, out enumCodecType, // ref cbCodecInfo, null); // var pwszName = new StringBuilder(cchName); // var pwszDescription = new StringBuilder(cchDescription); // var pbCodecInfo = new byte[cbCodecInfo]; // pHeaderInfo.GetCodecInfo(wIndex, ref cchName, pwszName, // ref cchDescription, pwszDescription, out enumCodecType, // ref cbCodecInfo, pbCodecInfo); // if (enumCodecType == CodecInfoType.Audio) // { // // pbCodecInfo = {99,1} ??/ // } // } //} //catch (COMException) //{ //} //int cbMax; //m_syncReader.GetMaxOutputSampleSize(m_dwAudioOutputNum, out cbMax); }
internal IEnumerable <WMAFormatInfo> EnumerateFormatInfo(IWMProfileManager pProfileManager2) { IWMProfileManager pProfileManager = null; try { if (pProfileManager2 == null) { WMUtils.WMCreateProfileManager(out pProfileManager); } var pCodecInfo3 = (pProfileManager2 ?? pProfileManager) as IWMCodecInfo3; int cCodecs; pCodecInfo3.GetCodecInfoCount(MediaType.Audio, out cCodecs); for (int iCodec = 0; iCodec < cCodecs; iCodec++) { int szCodecName = 0; pCodecInfo3.GetCodecName(MediaType.Audio, iCodec, null, ref szCodecName); var codecName = new StringBuilder(szCodecName); pCodecInfo3.GetCodecName(MediaType.Audio, iCodec, codecName, ref szCodecName); var attrDataType = new AttrDataType(); int dwAttrSize = 0; byte[] pAttrValue = new byte[4]; pCodecInfo3.GetCodecProp(MediaType.Audio, iCodec, Constants.g_wszIsVBRSupported, out attrDataType, pAttrValue, ref dwAttrSize); if (pAttrValue[0] != 1) { continue; } if (m_vbr) { pCodecInfo3.SetCodecEnumerationSetting(MediaType.Audio, iCodec, Constants.g_wszVBREnabled, AttrDataType.BOOL, new byte[] { 1, 0, 0, 0 }, 4); pCodecInfo3.SetCodecEnumerationSetting(MediaType.Audio, iCodec, Constants.g_wszNumPasses, AttrDataType.DWORD, new byte[] { 1, 0, 0, 0 }, 4); } else { pCodecInfo3.SetCodecEnumerationSetting(MediaType.Audio, iCodec, Constants.g_wszVBREnabled, AttrDataType.BOOL, new byte[] { 0, 0, 0, 0 }, 4); } int cFormat; pCodecInfo3.GetCodecFormatCount(MediaType.Audio, iCodec, out cFormat); for (int iFormat = 0; iFormat < cFormat; iFormat++) { IWMStreamConfig pStreamConfig; int cchDesc = 1024; StringBuilder szDesc = new StringBuilder(cchDesc); pCodecInfo3.GetCodecFormatDesc(MediaType.Audio, iCodec, iFormat, out pStreamConfig, szDesc, ref cchDesc); if (szDesc.ToString().Contains("(A/V)")) { continue; } try { var pProps = pStreamConfig as IWMMediaProps; int cbType = 0; AMMediaType pMediaType = null; pProps.GetMediaType(pMediaType, ref cbType); pMediaType = new AMMediaType(); pMediaType.formatSize = cbType - Marshal.SizeOf(typeof(AMMediaType)); pProps.GetMediaType(pMediaType, ref cbType); try { if (pMediaType.majorType == MediaType.Audio && pMediaType.formatType == FormatType.WaveEx && pMediaType.subType == m_subType) { var pcm = WaveFormatExtensible.FromMediaType(pMediaType).GetConfig(); if (PCM == null || (pcm.ChannelCount == PCM.ChannelCount && pcm.SampleRate == PCM.SampleRate && pcm.BitsPerSample >= PCM.BitsPerSample)) { yield return new WMAFormatInfo() { codec = iCodec, codecName = codecName.ToString(), format = iFormat, formatName = szDesc.ToString(), subType = pMediaType.subType, pcm = pcm } } ; } } finally { WMUtils.FreeWMMediaType(pMediaType); } } finally { Marshal.ReleaseComObject(pStreamConfig); } } } } finally { if (pProfileManager != null) { Marshal.ReleaseComObject(pProfileManager); } } }