Skip to content

Instantly share code, notes, and snippets.

@shiftkey
Created June 18, 2011 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shiftkey/1032976 to your computer and use it in GitHub Desktop.
Save shiftkey/1032976 to your computer and use it in GitHub Desktop.
Example of a struct implemented as a class in C#
// Example of a struct implementation for passing in information about a WAVE file
// http://msdn.microsoft.com/en-us/library/aa446573.aspx
/// <summary>
/// This structure defines the header used to identify a waveform-audio buffer.
/// typedef struct
/// {
/// LPSTR lpData;
/// DWORD dwBufferLength;
/// DWORD dwBytesRecorded;
/// DWORD dwUser;
/// DWORD dwFlags;
/// DWORD dwLoops;
/// struct wavehdr_tag *lpNext;
/// DWORD reserved;}
/// WAVEHDR;
/// </summary>
public class WAVEHDR : IDisposable
{
/// <summary>
/// Used by dwFlags in WAVEHDR
/// Set by the device driver to indicate that it is finished with the buffer
/// and is returning it to the application.
/// </summary>
public const int WHDR_DONE = 0x00000001;
/// <summary>
/// Used by dwFlags in WAVEHDR
/// Set by Windows to indicate that the buffer has been prepared with the
/// waveInPrepareHeader or waveOutPrepareHeader function.
/// </summary>
public const int WHDR_PREPARED = 0x00000002;
/// <summary>
/// Used by dwFlags in WAVEHDR
/// This buffer is the first buffer in a loop. This flag is used only with
/// output buffers.
/// </summary>
public const int WHDR_BEGINLOOP = 0x00000004;
/// <summary>
/// Used by dwFlags in WAVEHDR
/// This buffer is the last buffer in a loop. This flag is used only with
/// output buffers.
/// </summary>
public const int WHDR_ENDLOOP = 0x00000008;
/// <summary>
/// Used by dwFlags in WAVEHDR
/// Set by Windows to indicate that the buffer is queued for playback.
/// </summary>
public const int WHDR_INQUEUE = 0x00000010;
/// <summary>
/// Set in WAVEFORMATEX.wFormatTag to specify PCM data.
/// </summary>
public const int WAVE_FORMAT_PCM = 1;
/// <summary>
/// Long pointer to the address of the waveform buffer. This buffer must
/// be block-aligned according to the nBlockAlign member of the
/// WAVEFORMATEX structure used to open the device.
/// </summary>
public IntPtr lpData = IntPtr.Zero;
/// <summary>
/// Specifies the length, in bytes, of the buffer.
/// </summary>
public uint dwBufferLength = 0;
/// <summary>
/// When the header is used in input, this member specifies how much data
/// is in the buffer.
/// </summary>
public uint dwBytesRecorded = 0;
/// <summary>
/// Specifies user data.
/// </summary>
public uint dwUser = 0;
/// <summary>
/// Specifies information about the buffer.
/// </summary>
public uint dwFlags = 0;
/// <summary>
/// Specifies the number of times to play the loop. This member is used
/// only with output buffers.
/// </summary>
public uint dwLoops = 0;
/// <summary>
/// Reserved.
/// </summary>
public IntPtr lpNext = IntPtr.Zero;
/// <summary>
/// Reserved.
/// </summary>
public uint reserved = 0;
/// <summary>
/// Read a data buffer from the supplied BinaryReader. This method will
/// allocate memory for the data buffer it is not already allocated.
/// </summary>
/// <param name="rdr">BinaryReader containing data</param>
/// <param name="readLength">Size, in bytes, to be read</param>
/// <returns>MMSYSERR.NOERROR if successful</returns>
public MMSYSERR Read(BinaryReader rdr, uint readLength, int align)
{
uint bufferLength = readLength;
if (bufferLength % align != 0)
bufferLength += (uint)(align - (bufferLength % align));
dwBufferLength = bufferLength;
byte[] data = new byte[readLength];
rdr.Read(data, 0, data.Length);
if (lpData == IntPtr.Zero)
lpData = Memory.LocalAlloc(Memory.LMEM_FIXED, (uint)bufferLength);
if (lpData == IntPtr.Zero)
return MMSYSERR.NOMEM;
Marshal.Copy(data, 0, lpData, data.Length);
return MMSYSERR.NOERROR;
}
/// <summary>
/// Write the contents of the recorded buffer to the supplied
/// BinaryWriter.
/// </summary>
/// <param name="wrtr">BinaryWriter used as write target</param>
/// <returns>MMSYSERR.NOERROR if successful</returns>
public Wave.MMSYSERR Write(BinaryWriter wrtr)
{
if (lpData == IntPtr.Zero)
return Wave.MMSYSERR.NOMEM;
byte[] data = new byte[dwBytesRecorded];
Marshal.Copy(lpData, data, 0, data.Length);
wrtr.Write(data);
return Wave.MMSYSERR.NOERROR;
}
/// <summary>
/// Initialize an instance of a WAVEHDR with the specified buffer
/// size.
/// </summary>
/// <param name="bufferLength">Size, in bytes, of buffer</param>
/// <param name="init">true=clear data to 0</param>
/// <returns>MMSYSERR.NOERROR if successful</returns>
public MMSYSERR Init(uint bufferLength, bool init)
{
if (lpData != IntPtr.Zero && dwBufferLength < bufferLength)
{
Memory.LocalFree(lpData);
lpData = IntPtr.Zero;
}
if (lpData == IntPtr.Zero)
lpData = Memory.LocalAlloc(Memory.LMEM_FIXED, bufferLength);
dwBufferLength = bufferLength;
if (lpData == IntPtr.Zero)
return MMSYSERR.NOMEM;
if (init)
{
for (int i = 0; i < bufferLength; i++)
{
Marshal.WriteByte(lpData, i, 0);
}
}
return MMSYSERR.NOERROR;
}
/// <summary>
/// Frees any memory allocated for the buffer.
/// </summary>
public void Dispose()
{
if (lpData != IntPtr.Zero)
Memory.LocalFree(lpData);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment