using System; using System.Runtime.InteropServices; using NAudio.Utils; namespace NAudio.Dmo { /// /// Attempting to implement the COM IMediaBuffer interface as a .NET object /// Not sure what will happen when I pass this to an unmanaged object /// public class MediaBuffer : IMediaBuffer, IDisposable { private IntPtr buffer; private int length; private readonly int maxLength; /// /// Creates a new Media Buffer /// /// Maximum length in bytes public MediaBuffer(int maxLength) { buffer = Marshal.AllocCoTaskMem(maxLength); this.maxLength = maxLength; } /// /// Dispose and free memory for buffer /// public void Dispose() { if (buffer != IntPtr.Zero) { Marshal.FreeCoTaskMem(buffer); buffer = IntPtr.Zero; GC.SuppressFinalize(this); } } /// /// Finalizer /// ~MediaBuffer() { Dispose(); } #region IMediaBuffer Members /// /// Set length of valid data in the buffer /// /// length /// HRESULT int IMediaBuffer.SetLength(int length) { //System.Diagnostics.Debug.WriteLine(String.Format("Set Length {0}", length)); if (length > maxLength) { return HResult.E_INVALIDARG; } this.length = length; return HResult.S_OK; } /// /// Gets the maximum length of the buffer /// /// Max length (output parameter) /// HRESULT int IMediaBuffer.GetMaxLength(out int maxLength) { //System.Diagnostics.Debug.WriteLine("Get Max Length"); maxLength = this.maxLength; return HResult.S_OK; } /// /// Gets buffer and / or length /// /// Pointer to variable into which buffer pointer should be written /// Pointer to variable into which valid data length should be written /// HRESULT int IMediaBuffer.GetBufferAndLength(IntPtr bufferPointerPointer, IntPtr validDataLengthPointer) { //System.Diagnostics.Debug.WriteLine(String.Format("Get Buffer and Length {0},{1}", // bufferPointerPointer,validDataLengthPointer)); if (bufferPointerPointer != IntPtr.Zero) { Marshal.WriteIntPtr(bufferPointerPointer, this.buffer); } if (validDataLengthPointer != IntPtr.Zero) { Marshal.WriteInt32(validDataLengthPointer, this.length); } //System.Diagnostics.Debug.WriteLine("Finished Getting Buffer and Length"); return HResult.S_OK; } #endregion /// /// Length of data in the media buffer /// public int Length { get { return length; } set { if (length > maxLength) { throw new ArgumentException("Cannot be greater than maximum buffer size"); } length = value; } } /// /// Loads data into this buffer /// /// Data to load /// Number of bytes to load public void LoadData(byte[] data, int bytes) { this.Length = bytes; Marshal.Copy(data, 0, buffer, bytes); } /// /// Retrieves the data in the output buffer /// /// buffer to retrieve into /// offset within that buffer public void RetrieveData(byte[] data, int offset) { Marshal.Copy(buffer, data, offset, Length); } } }