/// <summary> /// Create the writer indicating Metadata information /// </summary> /// <param name="output"><see cref="System.IO.Stream"/> Where resulting WMA string will be written</param> /// <param name="format">PCM format of input data received in <see cref="WmaWriter.Write"/> method</param> /// <param name="profile">IWMProfile that describe the resulting compressed stream</param> /// <param name="MetadataAttributes">Array of <see cref="Yeti.WMFSdk.WM_Attr"/> structures describing the metadata information that will be in the result stream</param> public WmaWriter(Stream output, WaveFormat format, IWMProfile profile, WM_Attr[] MetadataAttributes) : base(output, format) { m_Writer = WM.CreateWriter(); IWMWriterAdvanced wa = (IWMWriterAdvanced)m_Writer; wa.AddSink((IWMWriterSink)this); m_Writer.SetProfile(profile); uint inputs; m_Writer.GetInputCount(out inputs); if (inputs == 1) { IWMInputMediaProps InpProps; Guid type; m_Writer.GetInputProps(0, out InpProps); InpProps.GetType(out type); if (type == MediaTypes.WMMEDIATYPE_Audio) { WM_MEDIA_TYPE mt; mt.majortype = MediaTypes.WMMEDIATYPE_Audio; mt.subtype = MediaTypes.WMMEDIASUBTYPE_PCM; mt.bFixedSizeSamples = true; mt.bTemporalCompression = false; mt.lSampleSize = (uint)m_InputDataFormat.nBlockAlign; mt.formattype = MediaTypes.WMFORMAT_WaveFormatEx; mt.pUnk = IntPtr.Zero; mt.cbFormat = (uint)Marshal.SizeOf(m_InputDataFormat); GCHandle h = GCHandle.Alloc(m_InputDataFormat, GCHandleType.Pinned); try { mt.pbFormat = h.AddrOfPinnedObject(); InpProps.SetMediaType(ref mt); } finally { h.Free(); } m_Writer.SetInputProps(0, InpProps); if ( MetadataAttributes != null ) { WMHeaderInfo info = new WMHeaderInfo((IWMHeaderInfo)m_Writer); foreach(WM_Attr attr in MetadataAttributes) { info.SetAttribute(attr); } info = null; } m_Writer.BeginWriting(); m_Profile = profile; } else { throw new ArgumentException("Invalid profile", "profile"); } } else { throw new ArgumentException("Invalid profile", "profile"); } }
/// <summary> /// Set an attribute specifying a stream number. Wraps IWMHeaderInfo.SetAttribute /// </summary> /// <param name="StreamNumber">Stream number. Zero for file level attributes.</param> /// <param name="attr">Attribute to set. <see cref="Yeti.WMFSdk.WM_Attr"/></param> public void SetAttribute(int StreamNumber, WM_Attr attr) { object obj; ushort size; switch (attr.DataType) { case WMT_ATTR_DATATYPE.WMT_TYPE_STRING: byte[] arr = Encoding.Unicode.GetBytes((string)attr.Value + (char)0); obj = arr; size = (ushort)arr.Length; break; case WMT_ATTR_DATATYPE.WMT_TYPE_BOOL: obj = (uint)((bool)attr?1:0); size = 4; break; case WMT_ATTR_DATATYPE.WMT_TYPE_BINARY: obj = (byte[])attr.Value; size = (ushort)((byte[])obj).Length; break; case WMT_ATTR_DATATYPE.WMT_TYPE_DWORD: obj = (uint)attr; size = 4; break; case WMT_ATTR_DATATYPE.WMT_TYPE_QWORD: obj = (ulong)attr; size = 8; break; case WMT_ATTR_DATATYPE.WMT_TYPE_WORD: obj = (ushort)attr; size = 2; break; case WMT_ATTR_DATATYPE.WMT_TYPE_GUID: obj = (Guid)attr; size = (ushort)Marshal.SizeOf(typeof(Guid)); break; default: throw new ArgumentException("Invalid data type", "attr"); } GCHandle h = GCHandle.Alloc(obj, GCHandleType.Pinned); try { m_HeaderInfo.SetAttribute((ushort)StreamNumber, attr.Name, attr.DataType, h.AddrOfPinnedObject(), size); } finally { h.Free(); } }
/// <summary> /// Set file level attributes /// </summary> /// <param name="attr">Attribute to set <see cref="Yeti.WMFSdk.WM_Attr"/></param> public void SetAttribute(WM_Attr attr) { SetAttribute(0, attr); }
/// <summary> /// Set an attribute specifying a stream number. Wraps IWMHeaderInfo.SetAttribute /// </summary> /// <param name="StreamNumber">Stream number. Zero for file level attributes.</param> /// <param name="attr">Attribute to set. <see cref="Yeti.WMFSdk.WM_Attr"/></param> public void SetAttribute(int StreamNumber, WM_Attr attr) { object obj; ushort size; switch (attr.DataType) { case WMT_ATTR_DATATYPE.WMT_TYPE_STRING: byte[] arr = Encoding.Unicode.GetBytes((string)attr.Value + (char)0); obj = arr; size = (ushort)arr.Length; break; case WMT_ATTR_DATATYPE.WMT_TYPE_BOOL: obj = (uint)((bool)attr ? 1 : 0); size = 4; break; case WMT_ATTR_DATATYPE.WMT_TYPE_BINARY: obj = (byte[])attr.Value; size = (ushort)((byte[])obj).Length; break; case WMT_ATTR_DATATYPE.WMT_TYPE_DWORD: obj = (uint)attr; size = 4; break; case WMT_ATTR_DATATYPE.WMT_TYPE_QWORD: obj = (ulong)attr; size = 8; break; case WMT_ATTR_DATATYPE.WMT_TYPE_WORD: obj = (ushort)attr; size = 2; break; case WMT_ATTR_DATATYPE.WMT_TYPE_GUID: obj = (Guid)attr; size = (ushort)Marshal.SizeOf(typeof (Guid)); break; default: throw new ArgumentException("Invalid data type", "attr"); } GCHandle h = GCHandle.Alloc(obj, GCHandleType.Pinned); try { m_HeaderInfo.SetAttribute((ushort)StreamNumber, attr.Name, attr.DataType, h.AddrOfPinnedObject(), size); } finally { h.Free(); } }