






















//////////////////////////////////////////////
BOOL FNGLOBAL MMCapsEnumerateLowLevel
(
    PZYZTABBEDLISTBOX   ptlb,
    BOOL                fComplete
)
{
    TCHAR       ach[128];
    MMRESULT    mmr;
    int         n;
    int         nDevs;
    int         nIndex;
    LPARAM      lParam;
    UINT        uDevType;
    MMVERSION   uMMSysVer;
    HWND        hlb;


    //
    //
    //
    //
    //
    if (fComplete)
    {
	TlbSetTitleAndTabs(ptlb, gszDeviceFormatTitle, FALSE);
    }

    hlb = ptlb->hlb;

    uMMSysVer = (MMVERSION)GetVersion();


    //
    //
    //
    nDevs = auxGetNumDevs();
    for (n = -1; n < nDevs; n++)
    {
	AUXCAPS         ac;

	mmr = auxGetDevCaps(n, &ac, sizeof(ac));
	if (MMSYSERR_NOERROR != mmr)
	{
	    if (-1 != n)
	    {
		ac.vDriverVersion = 0;
		lstrcpy(ac.szPname, gszBogusCaps);
	    }
	    else
	    {
		if (0 == nDevs)
		    break;

		ac.vDriverVersion = uMMSysVer;
		lstrcpy(ac.szPname, gszDefaultMapper);
	    }
	}

	//
	//
	//
	uDevType = MMCAPS_DEVTYPE_AUXILIARY;
	wsprintf(ach, gszDeviceFormatList, (LPSTR)gaszDeviceType[uDevType],
		 n, (ac.vDriverVersion >> 8), (BYTE)ac.vDriverVersion,
		 (LPSTR)ac.szPname);

	nIndex = ListBox_AddString(hlb, ach);
	lParam = MAKELPARAM((WORD)n, (WORD)uDevType);
	ListBox_SetItemData(hlb, nIndex, lParam);
    }
.
.
.
.
.
    //
    //
    //
    nDevs = waveInGetNumDevs();
    for (n = -1; n < nDevs; n++)
    {
	WAVEINCAPS      wic;

	mmr = waveInGetDevCaps(n, &wic, sizeof(wic));
	if (MMSYSERR_NOERROR != mmr)
	{
	    if (-1 != n)
	    {
		wic.vDriverVersion = 0;
		lstrcpy(wic.szPname, gszBogusCaps);
	    }
	    else
	    {
		if (0 == nDevs)
		    break;

		wic.vDriverVersion = uMMSysVer;
		lstrcpy(wic.szPname, gszDefaultMapper);
	    }
	}

	//
	//
	//
	uDevType = MMCAPS_DEVTYPE_WAVEIN;
	wsprintf(ach, gszDeviceFormatList, (LPSTR)gaszDeviceType[uDevType],
		 n, (wic.vDriverVersion >> 8), (BYTE)wic.vDriverVersion,
		 (LPSTR)wic.szPname);

	nIndex = ListBox_AddString(hlb, ach);
	lParam = MAKELPARAM((WORD)n, (WORD)uDevType);
	ListBox_SetItemData(hlb, nIndex, lParam);
    }

    //
    //
    //


///////////////////////////////////////////




////////////////////////////////////////////////////////////////

BOOL FNEXPORT MMCapsDlgProc
(
    HWND            hwnd,
    UINT            uMsg,
    WPARAM          wParam,
    LPARAM          lParam
)
{
    HWND        hedit;
    UINT        u;

    switch (uMsg)
    {
	case WM_INITDIALOG:
	    hedit = GetDlgItem(hwnd, IDD_DEVCAPS_EDIT_DETAILS);
	    SetWindowFont(hedit, GetStockFont(ANSI_FIXED_FONT), FALSE);

	    //
	    //
	    //
	    switch (guDriverType)
	    {
		case MMCAPS_DRIVERTYPE_LOWLEVEL:
		    MMCapsDetailLowLevel(hedit, lParam);
		    break;

#if 0
		case MMCAPS_DRIVERTYPE_MCI:
		    MMCapsDetailMCI(hedit, lParam);
		    break;

		case MMCAPS_DRIVERTYPE_ACM:
		    MMCapsDetailACM(hedit, lParam);
		    break;

		case MMCAPS_DRIVERTYPE_VIDEO:
		    MMCapsDetailVideo(hedit, lParam);
		    break;
#endif
	    }
///////////////////////////////////////////

#include <windowsx.h>

#include <mmsystem.h>
#include "mmcaps.h"

////////////////////////////////////
BOOL FNGLOBAL MMCapsDetailLowLevel
(
    HWND            hedit,
    LPARAM          lParam
)
{
    int         nDevId;
    UINT        uDevType;

    //
    //  HIWORD(lParam): MMCAPS_DEVTYPE_*
    //  LOWORD(lParam): Device index (id)
    //
    nDevId   = (int)(short)LOWORD(lParam);
    uDevType = HIWORD(lParam);

    //
    //
    //
    //
    switch (uDevType)
    {
	case MMCAPS_DEVTYPE_AUXILIARY:
	    MMCapsDetailAuxiliary(hedit, nDevId);
	    break;

	case MMCAPS_DEVTYPE_JOYSTICK:
	    MMCapsDetailJoystick(hedit, nDevId);
	    break;

	case MMCAPS_DEVTYPE_MIDIIN:
	    MMCapsDetailMidiIn(hedit, nDevId);
	    break;

	case MMCAPS_DEVTYPE_MIDIOUT:
	    MMCapsDetailMidiOut(hedit, nDevId);
	    break;

	case MMCAPS_DEVTYPE_MIXER:
	    MMCapsDetailMixer(hedit, nDevId);
	    break;

	case MMCAPS_DEVTYPE_TIMER:
	    MMCapsDetailTimer(hedit, nDevId);
	    break;

	case MMCAPS_DEVTYPE_WAVEIN:
	    MMCapsDetailWaveIn(hedit, nDevId);
	    break;
/////////////////////////////////////////////



MMRESULT waveInPrepareHeader(
  HWAVEIN hwi,    
  LPWAVEHDR pwh,  
  UINT cbwh       
);
 
Parameters
hwi 
Handle of the waveform-audio input device. 
pwh 
Address of a WAVEHDR structure that identifies the buffer to be prepared. 
cbwh 
Size, in bytes, of the WAVEHDR structure. 
Return Values
Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:

Value Description 
MMSYSERR_INVALHANDLE Specified device handle is invalid. 
MMSYSERR_NODRIVER No device driver is present. 
MMSYSERR_NOMEM Unable to allocate or lock memory. 


Remarks
The lpData, dwBufferLength, and dwFlags members of the WAVEHDR structure must be set before calling this function (dwFlags must be zero).

////////////////////////

typedef struct { 
    LPSTR  lpData; 
    DWORD  dwBufferLength; 
    DWORD  dwBytesRecorded; 
    DWORD  dwUser; 
    DWORD  dwFlags; 
    DWORD  dwLoops; 
    struct wavehdr_tag * lpNext; 
    DWORD  reserved; 
} WAVEHDR; 
 
Members
lpData 
Address of the waveform buffer. 
dwBufferLength 
Length, in bytes, of the buffer. 
dwBytesRecorded 
When the header is used in input, this member specifies how much data is in the buffer. 
dwUser 
User data. 
dwFlags 
Flags supplying information about the buffer. The following values are defined: 
WHDR_BEGINLOOP 
This buffer is the first buffer in a loop. This flag is used only with output buffers. 
WHDR_DONE 
Set by the device driver to indicate that it is finished with the buffer and is returning it to the application. 
WHDR_ENDLOOP 
This buffer is the last buffer in a loop. This flag is used only with output buffers. 
WHDR_INQUEUE 
Set by Windows to indicate that the buffer is queued for playback. 
WHDR_PREPARED 
Set by Windows to indicate that the buffer has been prepared with the waveInPrepareHeader or waveOutPrepareHeader function. 
dwLoops 
Number of times to play the loop. This member is used only with output buffers. 
wavehdr_tag 
Reserved. 
reserved 
Reserved. 


//////

typedef struct { 
    WORD      wMid; 
    WORD      wPid; 
    MMVERSION vDriverVersion; 
    CHAR      szPname[MAXPNAMELEN]; 
    DWORD     dwFormats; 
    WORD      wChannels; 
    WORD      wReserved1; 
} WAVEINCAPS; 
 
Members
wMid 
Manufacturer identifier for the device driver for the waveform-audio input device. Manufacturer identifiers are defined in Manufacturer and Product Identifiers. 
wPid 
Product identifier for the waveform-audio input device. Product identifiers are defined in Manufacturer and Product Identifiers. 
vDriverVersion 
Version number of the device driver for the waveform-audio input device. The high-order byte is the major version number, and the low-order byte is the minor version number. 
szPname 
Product name in a null-terminated string. 
dwFormats 
Standard formats that are supported. Can be a combination of the following: Format Description 
WAVE_FORMAT_1M08 11.025 kHz, mono, 8-bit 
WAVE_FORMAT_1M16 11.025 kHz, mono, 16-bit 
WAVE_FORMAT_1S08 11.025 kHz, stereo, 8-bit 
WAVE_FORMAT_1S16 11.025 kHz, stereo, 16-bit 
WAVE_FORMAT_2M08 22.05 kHz, mono, 8-bit 
WAVE_FORMAT_2M16 22.05 kHz, mono, 16-bit 
WAVE_FORMAT_2S08 22.05 kHz, stereo, 8-bit 
WAVE_FORMAT_2S16 22.05 kHz, stereo, 16-bit 
WAVE_FORMAT_4M08 44.1 kHz, mono, 8-bit 
WAVE_FORMAT_4M16 44.1 kHz, mono, 16-bit 
WAVE_FORMAT_4S08 44.1 kHz, stereo, 8-bit 
WAVE_FORMAT_4S16 44.1 kHz, stereo, 16-bit 


wChannels 
Number specifying whether the device supports mono (1) or stereo (2) input. 
wReserved1 
Padding. 



/////////////////////

MMRESULT waveInGetDevCaps(
  UINT uDeviceID,     
  LPWAVEINCAPS pwic,  
  UINT cbwic          
);
 
Parameters
uDeviceID 
Identifier of the waveform-audio output device. It can be either a device identifier or a handle of an open waveform-audio input device. 
pwic 
Address of a WAVEINCAPS structure to be filled with information about the capabilities of the device. 
cbwic 
Size, in bytes, of the WAVEINCAPS structure. 
Return Values
Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:

Value Description 
MMSYSERR_BADDEVICEID Specified device identifier is out of range. 
MMSYSERR_NODRIVER No device driver is present. 
MMSYSERR_NOMEM Unable to allocate or lock memory. 


//////////////////


MMRESULT waveInOpen(
  LPHWAVEIN phwi,            
  UINT uDeviceID,            
  LPWAVEFORMATEX pwfx,       
  DWORD dwCallback,          
  DWORD dwCallbackInstance,  
  DWORD fdwOpen              
);
 
Parameters
phwi 
Address filled with 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 fdwOpen. 
uDeviceID 
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: 
WAVE_MAPPER 
The function selects a waveform-audio input device capable of recording in the specified format. 
pwfx 
Address of a WAVEFORMATEX structure that identifies the desired format for recording waveform-audio data. You can free this structure immediately after waveInOpen returns. 
dwCallback 
Address of 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. 
dwCallbackInstance 
User-instance data passed to the callback mechanism. This parameter is not used with the window callback mechanism. 
fdwOpen 
Flags for opening the device. The following values are defined: 
CALLBACK_EVENT 
The dwCallback parameter is an event handle. 
CALLBACK_FUNCTION 
The dwCallback parameter is a callback procedure address. 
CALLBACK_NULL 
No callback mechanism. This is the default setting. 
CALLBACK_THREAD 
The dwCallback parameter is a thread identifier. 
CALLBACK_WINDOW 
The dwCallback parameter is a window handle. 
WAVE_FORMAT_DIRECT 
If this flag is specified, the ACM driver does not perform conversions on the audio data. 
WAVE_FORMAT_QUERY 
The function queries the device to determine whether it supports the given format, but it does not open the device. 
WAVE_MAPPED 
The uDeviceID parameter specifies a waveform-audio device to be mapped to by the wave mapper. 
Return Values
Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:

Value Description 
MMSYSERR_ALLOCATED Specified resource is already allocated. 
MMSYSERR_BADDEVICEID Specified device identifier is out of range. 
MMSYSERR_NODRIVER No device driver is present. 
MMSYSERR_NOMEM Unable to allocate or lock memory. 
WAVERR_BADFORMAT Attempted to open with an unsupported waveform-audio format. 

#define MMSYSERR_NOERROR      0                    /* no error */
#define MMSYSERR_ERROR        (MMSYSERR_BASE + 1)  /* unspecified error */
#define MMSYSERR_BADDEVICEID  (MMSYSERR_BASE + 2)  /* device ID out of range */
#define MMSYSERR_NOTENABLED   (MMSYSERR_BASE + 3)  /* driver failed enable */
#define MMSYSERR_ALLOCATED    (MMSYSERR_BASE + 4)  /* device already allocated */
#define MMSYSERR_INVALHANDLE  (MMSYSERR_BASE + 5)  /* device handle is invalid */
#define MMSYSERR_NODRIVER     (MMSYSERR_BASE + 6)  /* no device driver present */
#define MMSYSERR_NOMEM        (MMSYSERR_BASE + 7)  /* memory allocation error */
#define MMSYSERR_NOTSUPPORTED (MMSYSERR_BASE + 8)  /* function isn't supported */
#define MMSYSERR_BADERRNUM    (MMSYSERR_BASE + 9)  /* error value out of range */
#define MMSYSERR_INVALFLAG    (MMSYSERR_BASE + 10) /* invalid flag passed */
#define MMSYSERR_INVALPARAM   (MMSYSERR_BASE + 11) /* invalid parameter passed */
#define MMSYSERR_HANDLEBUSY   (MMSYSERR_BASE + 12) /* handle being used */

////////////////


void CALLBACK waveInProc(
  HWAVEIN hwi,       
  UINT uMsg,         
  DWORD dwInstance,  
  DWORD dwParam1,    
  DWORD dwParam2     
);
 
Parameters
hwi 
Handle of the waveform-audio device associated with the callback function. 
uMsg 
Waveform-audio input message. It can be one of the following messages: 
WIM_CLOSE 
Sent when the device is closed using the waveInClose function. 
WIM_DATA 
Sent when the device driver is finished with a data block sent using the waveInAddBuffer function. 
WIM_OPEN 
Sent when the device is opened using the waveInOpen function. 
dwInstance 
User instance data specified with waveInOpen. 
dwParam1 
Message parameters. 
dwParam2 
Message parameters. 




////////////////////

MMRESULT waveInClose(
  HWAVEIN hwi  
);
 
Parameters
hwi 
Handle of the waveform-audio input device. If the function succeeds, the handle is no longer valid after this call. 
Return Values
Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:

Value Description 
MMSYSERR_INVALHANDLE Specified device handle is invalid. 
MMSYSERR_NODRIVER No device driver is present. 
MMSYSERR_NOMEM Unable to allocate or lock memory. 
WAVERR_STILLPLAYING There are still buffers in the queue. 



/////////////////



MMRESULT waveInStart(
  HWAVEIN hwi  
);
 
Parameters
hwi 
Handle of the waveform-audio input device. 
Return Values
Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:

Value Description 
MMSYSERR_INVALHANDLE Specified device handle is invalid. 
MMSYSERR_NODRIVER No device driver is present. 
MMSYSERR_NOMEM Unable to allocate or lock memory. 


Remarks
Buffers are returned to the application when full or when the waveInReset function is called (the dwBytesRecorded member in the header will contain the length of data). If there are no buffers in the queue, the data is thrown away without notifying the application, and input continues.

Calling this function when input is already started has no effect, and the function returns zero.



////////////////////////


The waveInReset function stops input on the given waveform-audio input device and resets the current position to zero. All pending buffers are marked as done and returned to the application.

MMRESULT waveInReset(
  HWAVEIN hwi  
);
 
Parameters
hwi 
Handle of the waveform-audio input device. 
Return Values
Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:

Value Description 
MMSYSERR_INVALHANDLE Specified device handle is invalid. 
MMSYSERR_NODRIVER No device driver is present. 
MMSYSERR_NOMEM Unable to allocate or lock memory. 


////////////////////////

MMRESULT waveInPrepareHeader(
  HWAVEIN hwi,    
  LPWAVEHDR pwh,  
  UINT cbwh       
);
 
Parameters
hwi 
Handle of the waveform-audio input device. 
pwh 
Address of a WAVEHDR structure that identifies the buffer to be prepared. 
cbwh 
Size, in bytes, of the WAVEHDR structure. 
Return Values
Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:

Value Description 
MMSYSERR_INVALHANDLE Specified device handle is invalid. 
MMSYSERR_NODRIVER No device driver is present. 
MMSYSERR_NOMEM Unable to allocate or lock memory. 


////////////////////



typedef struct { 
    WORD  wFormatTag; 
    WORD  nChannels; 
    DWORD nSamplesPerSec; 
    DWORD nAvgBytesPerSec; 
    WORD  nBlockAlign; 
    WORD  wBitsPerSample; 
    WORD  cbSize; 
} WAVEFORMATEX; 
 
Members
wFormatTag 
Waveform-audio format type. Format tags are registered with Microsoft Corporation for many compression algorithms. A complete list of format tags can be found in the MMREG.H header file. 
nChannels 
Number of channels in the waveform-audio data. Monaural data uses one channel and stereo data uses two channels. 
nSamplesPerSec 
Sample rate, in samples per second (hertz), that each channel should be played or recorded. If wFormatTag is WAVE_FORMAT_PCM, then common values for nSamplesPerSec are 8.0 kHz, 11.025 kHz, 22.05 kHz, and 44.1 kHz. For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag. 
nAvgBytesPerSec 
Required average data-transfer rate, in bytes per second, for the format tag. If wFormatTag is WAVE_FORMAT_PCM, nAvgBytesPerSec should be equal to the product of nSamplesPerSec and nBlockAlign. For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag. 
Playback and record software can estimate buffer sizes by using the nAvgBytesPerSec member. 

nBlockAlign 
Block alignment, in bytes. The block alignment is the minimum atomic unit of data for the wFormatTag format type. If wFormatTag is WAVE_FORMAT_PCM, nBlockAlign should be equal to the product of nChannels and wBitsPerSample divided by 8 (bits per byte). For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag. 
Playback and record software must process a multiple of nBlockAlign bytes of data at a time. Data written and read from a device must always start at the beginning of a block. For example, it is illegal to start playback of PCM data in the middle of a sample (that is, on a non-block-aligned boundary). 

wBitsPerSample 
Bits per sample for the wFormatTag format type. If wFormatTag is WAVE_FORMAT_PCM, then wBitsPerSample should be equal to 8 or 16. For non-PCM formats, this member must be set according to the manufacturer's specification of the format tag. Note that some compression schemes cannot define a value for wBitsPerSample, so this member can be zero. 
cbSize 
Size, in bytes, of extra format information appended to the end of the WAVEFORMATEX structure. This information can be used by non-PCM formats to store extra attributes for the wFormatTag. If no extra information is required by the wFormatTag, this member must be set to zero. Note that for WAVE_FORMAT_PCM formats (and only WAVE_FORMAT_PCM formats), this member is ignored. 
































