//=============================================================================
// Copyright Langis Pitre 1998
// You may do whatever you want with this code, as long as you include this
// copyright notice in your implementation files.
//=============================================================================
// MixerInfo.cpp
//
// Utility function to list all available options of your mixer device interface
//
//=============================================================================
#include "stdafx.h"
#include "MixerInfo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Helper functions used by GetDevicesInfo
static void PrintLineComponentType( int nIndent, MIXERLINE &line, FILE *file );
static void PrintControl( HMIXEROBJ mixer, MIXERLINE &line, MIXERCONTROL &control, FILE *file );
//=============================================================================
// Name : GetDevicesInfo
//
// Descr. : Finds all the input and output lines, and all mixer controls
// available through the audio mixer device.
//
// Use GetDevicesInfo() to find out the capabilities of your sound card.
// Check the the file and note the type and number of destination (output)
// lines, as well as the source (input) lines associated with every
// destination line. Note also the type of the controls available.
// You will need these to create your windows controls.
//
// Return : void
// Arg : LPCSTR filename :
//=============================================================================
void GetDevicesInfo( LPCSTR filename )
{
FILE *file;
UINT nbMixers = mixerGetNumDevs();
if( nbMixers < 1 )
{
AfxMessageBox( "No mixer device present" );
return;
}
HMIXER hMixer;
if( mixerOpen( &hMixer, 0, 0, 0, 0 ) != MMSYSERR_NOERROR )
{
AfxMessageBox( "Could not open mixer device" );
return;
}
file = fopen( filename, "w" );
if( file == NULL )
{
AfxMessageBox("Could not open file.");
return;
}
MIXERCAPS caps;
if( mixerGetDevCaps( ( UINT )hMixer, &caps, sizeof( MIXERCAPS ) ) != MMSYSERR_NOERROR )
{
fclose( file );
return;
}
fprintf( file, "Name of device: %s\n", caps.szPname );
fprintf( file, "Number of destination lines: %d\n\n", caps.cDestinations );
fprintf( file, "\nPay particular attention to the \"Component type\" and \"Control type\" lines.\n"
"You will pass these to the Init() functions of the various CMixerBase-derived classes\n"
"to specify which type of control you want to use.\n");
MIXERLINE line;
MIXERLINECONTROLS mixerLineControl;
MIXERCONTROL *pMixerControl;
int nDest = caps.cDestinations;
for( int i = 0; i < nDest; i++ )
{
line.cbStruct = sizeof( MIXERLINE );
line.dwSource = 0;
line.dwDestination = i;
mixerGetLineInfo( ( HMIXEROBJ )hMixer, &line, MIXER_GETLINEINFOF_DESTINATION );
fprintf( file, "\n***************************************************************************************************\n");
fprintf( file, "** Destination line. Index = %d *******************************************************************\n", i );
fprintf( file, "***************************************************************************************************\n");
PrintLineComponentType( 0, line, file );
pMixerControl = new MIXERCONTROL[line.cControls];
ASSERT( pMixerControl != NULL );
mixerLineControl.cbStruct = sizeof( MIXERLINECONTROLS );
mixerLineControl.dwLineID = line.dwLineID;
mixerLineControl.cControls = line.cControls;
mixerLineControl.cbmxctrl = sizeof( MIXERCONTROL );
mixerLineControl.pamxctrl = pMixerControl;
mixerGetLineControls( ( HMIXEROBJ )hMixer, &mixerLineControl, MIXER_GETLINECONTROLSF_ALL );
UINT ncontrols = line.cControls;
for( UINT k = 0; k < ncontrols; k++ )
{
PrintControl( ( HMIXEROBJ )hMixer, line, pMixerControl[k], file );
}
delete[] pMixerControl;
// for each destination line, list the source lines and their controls
UINT nconn = line.cConnections;
for( UINT j = 0; j < nconn; j++ )
{
line.cbStruct = sizeof( MIXERLINE );
line.dwSource = j;
line.dwDestination = i;
mixerGetLineInfo( ( HMIXEROBJ )hMixer, &line, MIXER_GETLINEINFOF_SOURCE );
fprintf( file, "\n\t======================================================================================\n");
fprintf( file, "\t== Source line. Index = %d ===========================================================\n", j );
fprintf( file, "\t======================================================================================\n");
PrintLineComponentType( 1, line, file );
pMixerControl = new MIXERCONTROL[line.cControls];
ASSERT( pMixerControl != NULL );
mixerLineControl.cbStruct = sizeof( MIXERLINECONTROLS );
mixerLineControl.dwLineID = line.dwLineID;
mixerLineControl.cControls = line.cControls;
mixerLineControl.cbmxctrl = sizeof( MIXERCONTROL );
mixerLineControl.pamxctrl = pMixerControl;
mixerGetLineControls( ( HMIXEROBJ )hMixer, &mixerLineControl, MIXER_GETLINECONTROLSF_ALL );
UINT ncontrols = line.cControls;
for( UINT k = 0; k < ncontrols; k++ )
{
PrintControl( ( HMIXEROBJ )hMixer, line, pMixerControl[k], file );
}
delete[] pMixerControl;
}
}
fclose( file );
}
//<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
// Name : PrintLineComponentType
//
// Descr. :
//
// Return : void
// Arg : MIXERLINE &line :
// Arg : FILE *file :
//------------------------------------------------------------------------------------------
void PrintLineComponentType( int nIndent, MIXERLINE &line, FILE *file )
{
char *tabs;
if( nIndent == 0 )
tabs = "";
else
tabs = "\t";
fprintf( file, "%s -----------------------------------------------------------------------\n", tabs );
fprintf( file, "%s Component type :", tabs );
switch( line.dwComponentType )
{
case MIXERLINE_COMPONENTTYPE_DST_DIGITAL:
fprintf( file, "%s MIXERLINE_COMPONENTTYPE_DST_DIGITAL\n", tabs );
fprintf( file, "%s -----------------------------------------------------------------------\n", tabs );
fprintf( file, "%s Audio line is a digital destination (for example, digital input to a DAT or CD audio device).\n", tabs );
break;
case MIXERLINE_COMPONENTTYPE_DST_UNDEFINED:
fprintf( file, "%s MIXERLINE_COMPONENTTYPE_DST_UNDEFINED\n", tabs );
fprintf( file, "%s -----------------------------------------------------------------------\n", tabs );
fprintf( file, "%s Audio line is a destination that cannot be defined by one of the standard component types.\n", tabs );
break;
case MIXERLINE_COMPONENTTYPE_DST_LINE:
fprintf( file, "%s MIXERLINE_COMPONENTTYPE_DST_LINE\n", tabs);
fprintf( file, "%s -----------------------------------------------------------------------\n", tabs );
fprintf( file, "%s Audio line is a line level destination that will be the final recording source for the analog-to-digital converter (ADC).\n", tabs );
break;
case MIXERLINE_COMPONENTTYPE_DST_MONITOR:
fprintf( file, "%s MIXERLINE_COMPONENTTYPE_DST_MONITOR\n", tabs);
fprintf( file, "%s -----------------------------------------------------------------------\n", tabs );
fprintf( file, "%s Audio line is a destination used for a monitor.\n", tabs );
break;
case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
fprintf( file, "%s MIXERLINE_COMPONENTTYPE_DST_SPEAKERS\n", tabs);
fprintf( file, "%s -----------------------------------------------------------------------\n", tabs );
fprintf( file, "%s Audio line is an adjustable (gain and/or attenuation) destination intended to drive speakers.\n", tabs