waveinopen (winmm)
Last changed: Gabriel F-181.122.167.183

.
Summary

C# Signature:

[Flags]
    enum WaveInOpenFlags : uint
    {
        CALLBACK_NULL = 0,
        CALLBACK_FUNCTION = 0x30000,
        CALLBACK_EVENT = 0x50000,
        CALLBACK_WINDOW = 0x10000,
        CALLBACK_THREAD = 0x20000,
        WAVE_FORMAT_QUERY = 1,
        WAVE_MAPPED = 4,
        WAVE_FORMAT_DIRECT = 8
    }

VB Signature:

<Flags()> _
Friend Enum WaveInOpenFlags As UInteger
  CALLBACK_NULL = 0
  CALLBACK_FUNCTION = &H30000
  CALLBACK_EVENT = &H50000
  CALLBACK_WINDOW = &H10000
  CALLBACK_THREAD = &H20000
  WAVE_FORMAT_QUERY = 1
  WAVE_MAPPED = 4
  WAVE_FORMAT_DIRECT = 8
End Enum

User-Defined Types:

None.

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

Return values:

    const uint MMSYSERR_BASE = 0;
    const uint MMSYSERR_NOERROR = 0; /* no error */
    const uint MMSYSERR_ERROR = MMSYSERR_BASE + 1; /* unspecified error */
    const uint MMSYSERR_BADDEVICEID = MMSYSERR_BASE + 2; /* device ID out of range */
    const uint MMSYSERR_NOTENABLED = MMSYSERR_BASE + 3; /* driver failed enable */
    const uint MMSYSERR_ALLOCATED = MMSYSERR_BASE + 4; /* device already allocated */
    const uint MMSYSERR_INVALHANDLE = MMSYSERR_BASE + 5; /* device handle is invalid */
    const uint MMSYSERR_NODRIVER = MMSYSERR_BASE + 6; /* no device driver present */
    const uint MMSYSERR_NOMEM = MMSYSERR_BASE + 7; /* memory allocation error */
    const uint MMSYSERR_NOTSUPPORTED = MMSYSERR_BASE + 8; /* function isn't supported */
    const uint MMSYSERR_BADERRNUM = MMSYSERR_BASE + 9; /* error value out of range */
    const uint MMSYSERR_INVALFLAG = MMSYSERR_BASE + 10; /* invalid flag passed */
    const uint MMSYSERR_INVALPARAM = MMSYSERR_BASE + 11; /* invalid parameter passed */
    const uint MMSYSERR_HANDLEBUSY = MMSYSERR_BASE + 12; /* handle being used */
    const uint MMSYSERR_INVALIDALIAS = MMSYSERR_BASE + 13; /* specified alias not found */
    const uint MMSYSERR_BADDB = MMSYSERR_BASE + 14; /* bad registry database */
    const uint MMSYSERR_KEYNOTFOUND = MMSYSERR_BASE + 15; /* registry key not found */
    const uint MMSYSERR_READERROR = MMSYSERR_BASE + 16; /* registry read error */
    const uint MMSYSERR_WRITEERROR = MMSYSERR_BASE + 17; /* registry write error */
    const uint MMSYSERR_DELETEERROR = MMSYSERR_BASE + 18; /* registry delete error */
    const uint MMSYSERR_VALNOTFOUND = MMSYSERR_BASE + 19; /* registry value not found */
    const uint MMSYSERR_NODRIVERCB = MMSYSERR_BASE + 20; /* driver does not call */
    const uint MMSYSERR_MOREDATA  = MMSYSERR_BASE + 21; /* more data to be returned */
    const uint MMSYSERR_LASTERROR = MMSYSERR_BASE + 21; /* last error in range */

Tips & Tricks:

Please add some!

Sample Code:

This example open a device using waveInOpen, gets the device name and then closes it

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct WAVEINCAPS // Used by waveInGetDevCaps

    {
        public ushort wMid;
        public ushort wPid;
        public uint vDriverVersion;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
        public string szPname;
        public uint dwFormats;
        public ushort wChannels;
        public ushort wReserved1;
    }

    [DllImport("winmm.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern uint waveInGetDevCaps(IntPtr uDeviceID, ref WAVEINCAPS pwic, uint cbwic);

    const uint MMSYSERR_BASE = 0;
    const uint MMSYSERR_NOERROR = 0; /* no error */
    const uint MMSYSERR_ERROR = MMSYSERR_BASE + 1; /* unspecified error */
    const uint MMSYSERR_BADDEVICEID = MMSYSERR_BASE + 2; /* device ID out of range */
    const uint MMSYSERR_NOTENABLED = MMSYSERR_BASE + 3; /* driver failed enable */
    const uint MMSYSERR_ALLOCATED = MMSYSERR_BASE + 4; /* device already allocated */
    const uint MMSYSERR_INVALHANDLE = MMSYSERR_BASE + 5; /* device handle is invalid */
    const uint MMSYSERR_NODRIVER = MMSYSERR_BASE + 6; /* no device driver present */
    const uint MMSYSERR_NOMEM = MMSYSERR_BASE + 7; /* memory allocation error */
    const uint MMSYSERR_NOTSUPPORTED = MMSYSERR_BASE + 8; /* function isn't supported */
    const uint MMSYSERR_BADERRNUM = MMSYSERR_BASE + 9; /* error value out of range */
    const uint MMSYSERR_INVALFLAG = MMSYSERR_BASE + 10; /* invalid flag passed */
    const uint MMSYSERR_INVALPARAM = MMSYSERR_BASE + 11; /* invalid parameter passed */
    const uint MMSYSERR_HANDLEBUSY = MMSYSERR_BASE + 12; /* handle being used */
    const uint MMSYSERR_INVALIDALIAS = MMSYSERR_BASE + 13; /* specified alias not found */
    const uint MMSYSERR_BADDB = MMSYSERR_BASE + 14; /* bad registry database */
    const uint MMSYSERR_KEYNOTFOUND = MMSYSERR_BASE + 15; /* registry key not found */
    const uint MMSYSERR_READERROR = MMSYSERR_BASE + 16; /* registry read error */
    const uint MMSYSERR_WRITEERROR = MMSYSERR_BASE + 17; /* registry write error */
    const uint MMSYSERR_DELETEERROR = MMSYSERR_BASE + 18; /* registry delete error */
    const uint MMSYSERR_VALNOTFOUND = MMSYSERR_BASE + 19; /* registry value not found */
    const uint MMSYSERR_NODRIVERCB = MMSYSERR_BASE + 20; /* driver does not call */
    const uint MMSYSERR_MOREDATA = MMSYSERR_BASE + 21; /* more data to be returned */
    const uint MMSYSERR_LASTERROR = MMSYSERR_BASE + 21; /* last error in range */

    const uint WAVERR_BASE = 32; /* last error in range */
    const uint WAVERR_BADFORMAT = WAVERR_BASE + 0;    /* unsupported wave format */
    const uint WAVERR_STILLPLAYING = WAVERR_BASE + 1;    /* still something playing */
    const uint WAVERR_UNPREPARED = WAVERR_BASE + 2;    /* header not prepared */
    const uint WAVERR_SYNC = WAVERR_BASE + 3;    /* device is synchronous */
    const uint WAVERR_LASTERROR = WAVERR_BASE + 3;    /* last error in range */

    /// The waveInOpen function opens the given waveform-audio input device for recording. Then returning the devide id.
    /// </summary>
    /// <param name="hWaveIn">
    /// Pointer to a buffer that receives a handle identifying the open waveform-audio input device. Use this
    /// handle to identify the device when calling other waveform-audio input functions. This parameter can be NULL if WAVE_FORMAT_QUERY
    /// is specified for dwFlags
    /// </param>
    /// <param name="deviceId">
    /// Identifier of the waveform-audio input device to open. It can be either a device identifier or a handle of an open waveform-audio
    /// input device. You can use the following flag instead of a device identifier.
    /// </param>
    /// <param name="wfx">
    /// Pointer to a WAVEFORMATEX structure that identifies the desired format for recording waveform-audio data.
    /// You can free this structure immediately after waveInOpen returns.
    /// </param>
    /// <param name="dwCallBack">
    /// Pointer to a fixed callback function, an event handle, a handle to a window, or the identifier of a thread to be called during
    /// waveform-audio recording to process messages related to the progress of recording. If no callback function is required, this
    /// value can be zero. For more information on the callback function, see waveInProc.
    /// </param>
    /// <param name="dwInstance">
    /// User-instance data passed to the callback mechanism. This parameter is not used with the window callback mechanism.
    /// </param>
    /// <param name="dwFlags">
    /// Flags for opening the device. The following values are defined.
    /// </param>
    /// <returns></returns>
    ///
    [DllImport("winmm.dll")]
    private static extern uint waveInOpen(ref IntPtr hWaveIn, uint deviceId, ref WAVEFORMATEX wfx, IntPtr dwCallBack, uint dwInstance, uint dwFlags);

    [DllImport("winmm.dll", SetLastError = true)]
    public static extern int waveInClose(IntPtr hDev);

    /// <summary>
    /// Prefered structure to use with API call waveInOpen.
    /// Needed to encapsulate wave format data.
    /// </summary>
    public struct WAVEFORMATEX
    {
        public short wFormatTag;
        public short nChannels;
        public uint nSamplesPerSec;
        public uint nAvgBytesPerSec;
        public short nBlockAlign;
        public short wBitsPerSample;
        public short cbSize;
    }

    public enum MMSYSERR : uint
    {
        // Add MMSYSERR's here!

        MMSYSERR_BASE = 0x0000,
        MMSYSERR_NOERROR = 0x0000
    }

    private WAVEFORMATEX waveFormat;
    private const uint WAVE_MAPPER = unchecked((uint)(-1));
    private const short WAVE_FORMAT_PCM = 0x0001;
    private const uint WAVE_FORMAT_FLAG = 0x00010000;
    private IntPtr hwWaveIn = IntPtr.Zero;
    private IntPtr dwCallBack = IntPtr.Zero;

    public Form1()
    {
        InitializeComponent();
    }

    private void Test_Click(object sender, EventArgs e)
    {
        // For documentation on the correct values to use, please refer to the MSDN library.

        waveFormat = new WAVEFORMATEX();
        waveFormat.wFormatTag = WAVE_FORMAT_PCM;

        waveFormat.nChannels = 1;
        waveFormat.wBitsPerSample = 16;
        waveFormat.nSamplesPerSec = 44100;

        waveFormat.nBlockAlign = (short)(waveFormat.nChannels * waveFormat.wBitsPerSample / 8);
        waveFormat.nAvgBytesPerSec = (uint)(waveFormat.nSamplesPerSec * waveFormat.nChannels * waveFormat.wBitsPerSample / 8);
        waveFormat.cbSize = 0;

        uint retval = waveInOpen(ref hwWaveIn, WAVE_MAPPER, ref waveFormat, dwCallBack, 0, WAVE_FORMAT_FLAG); // Open device

        if (retval == MMSYSERR_NOERROR)
        {
        Debug.Print("waveInOpen OK");
        WAVEINCAPS pwoc = new WAVEINCAPS();

        if (waveInGetDevCaps(hwWaveIn, ref pwoc, (uint)Marshal.SizeOf(typeof(WAVEINCAPS))) == MMSYSERR_NOERROR) // Get device description
        {
            Debug.Print(pwoc.szPname);
        }

        if (waveInClose(hwWaveIn) != MMSYSERR_NOERROR) // Close device
        {
            Debug.Print("Error closing device");
        }
        }
    }

Documentation
waveInOpen on MSDN