home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
mmpm21tk.zip
/
TK
/
RECORDER
/
RECORDER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-07
|
117KB
|
3,014 lines
/******************************************************************************
* File Name : RECORDER.C
*
* Description : This file contains the C source code required for the
* Recorder sample program.
*
* Concepts : This sample program illustrates the concepts of recording
* audio data through the media control interface. It also
* illustrates how to change the characteristics of the audio
* recording and the audio device (such as bits per sample,
* samples per second, input level, input source, etc.)
*
* MMPM/2 API's : List of all MMPM/2 API's that are used in
* this module
*
* mciSendCommand MCI_OPEN
* MCI_PLAY
* MCI_RECORD
* MCI_CLOSE
* MCI_SET
* MCI_STOP
* MCI_CONNECTOR
* MCI_CONNECTION
* MCI_STATUS
* MCI_SYSINFO
* MCI_GETDEVCAPS
* mciGetErrorString
* mmioOpen
* mmioClose
*
* Required
* Files : recorder.c Source Code.
* options.c Source Code.
* recorder.h Include file.
* recorder.dlg Dialog definition.
* recorder.rc Resources.
* recorder.ipf Help text.
* makefile Make file.
* recorder.def Linker definition file.
* recorder.ico Program icon.
*
* Copyright (C) IBM 1993
******************************************************************************/
#define INCL_OS2MM /* required for MCI and MMIO headers */
#define INCL_WIN /* required to use Win APIs. */
#define INCL_PM /* required to use PM APIs. */
#define INCL_WINHELP /* required to use IPF. */
#define INCL_SECONDARYWINDOW /* required for secondary window */
#define INCL_CIRCULARSLIDER /* required for circular slider control*/
#define INCL_GRAPHICBUTTON /* required for graphic button control */
#define INCL_WINSTDSLIDER /* required for using slider control */
#define INCL_WINSTDFILE /* required for open file dlg */
#define INCL_WINSTDDLGS /* required for open file dlg */
#include <os2.h>
#include <os2me.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sw.h>
#include "recorder.h"
enum DeviceStates {ST_STOPPED, ST_PLAYING, ST_RECORDING};
/*
* Procedure/Function Prototypes
*/
MRESULT EXPENTRY MainDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
MRESULT EXPENTRY OpenFileDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
MRESULT EXPENTRY ProductInfoDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
VOID AdjustTheDlg( HWND hwnd, BOOL fShow );
VOID CloseTheDevice( VOID );
VOID DeselectTheOption( USHORT idOption );
BOOL DoesFileExist(VOID);
BOOL FileSaveAs(HWND hwnd);
VOID Finalize( VOID);
VOID FindTheDeviceCapability( VOID );
VOID EvaluateReturnCode (ULONG ulBitsPerSample, ULONG ulSampPerSec, ULONG ulChannels, ULONG ulRC);
BOOL GetFileName( PSZ szFileName, ULONG ulStringLength);
VOID Initialize( VOID);
VOID InitializeHelp( VOID );
USHORT MessageBox( USHORT usMessageID, ULONG ulStyle );
BOOL OpenTheFile( HWND hwnd, PSZ pszFileName );
BOOL PlayTheAudio( HWND hwnd );
VOID QueryTheDefaultConnection( VOID );
BOOL RecordTheAudio( HWND hwnd );
VOID SaveTheAudio( HWND hwnd );
USHORT SaveTheChanges( HWND hwnd );
BOOL SeekTheAudio( HWND hwnd, ULONG ulPosition );
VOID SetAudioVolume( HWND hwnd );
BOOL SetTheOptions( BOOL fSelectedFileType );
VOID SelectTheOption( USHORT idOption );
VOID ShowMCIErrorMessage( ULONG ulError );
BOOL ShowStandardFileDlg( USHORT usSelection );
VOID StopTheDevice( HWND hwnd );
VOID UpdateTitleText( HWND hwnd, PSZ pszFileName );
VOID UpdateTheStatusLine( HWND hwnd, USHORT usStatus );
/*************** End of Procedure/Function Prototypes *************************/
/*
* Global Variables.
*/
HAB hab;
HMQ hmq;
HWND hwndFrame; /* Handle to the frame window. */
HWND hwndHelpInstance; /* Handle to Main Help window. */
HWND hwndMainDialogBox; /* Handle to the dialog window. */
HWND hwndMenu; /* Handle to the menu */
HWND hwndPlayPB; /* Handle to the play push button */
HWND hwndRecordPB; /* Handle to the record push button */
HWND hwndProductInfo = 0; /* Handle to the product info. dialog box */
enum DeviceStates eState = ST_STOPPED; /* state of the device */
SHORT sVolumeLevel = INIT_VOLUME; /* desired volume level */
USHORT usDeviceType = MCI_MICROPHONE_CONNECTOR,/* for microphone or line in */
usStereoMono = STEREO, /* for stereo or mono */
usQualityType = MUSIC, /* for quality selection */
usInputLevel = MEDIUM_INPUT_LEVEL, /* for input level selection */
usBitType = BIT_8, /* for 8 bit or 16 bit */
usDeviceTypeOpened; /* for device type opened */
BOOL fMonoSupported = TRUE; /* Device supports mono files */
BOOL fStereoSupported = TRUE; /* Device supports stereo files */
BOOL fVoiceSupported = TRUE; /* Device supports 11 kHz files */
BOOL fMusicSupported = TRUE; /* Device supports 22 kHz files */
BOOL fHiFiSupported = TRUE; /* Device supports 44 kHz files */
BOOL fHighQualitySupported = TRUE; /* Device supports 16 bps files */
BOOL fLoQualitySupported = TRUE; /* Device supports 8 bps files */
BOOL fMonitor = TRUE; /* for Monotor - on/off */
BOOL fPassedDevice = FALSE; /* for MCI_ACQUIRE to play the file */
BOOL fFileOpen = FALSE; /* for file open or not */
BOOL fTempFileInUse = FALSE; /* for temporary file open or not */
BOOL fModified = FALSE; /* for opened file modified or not */
BOOL fFirstOpen = TRUE; /* indicate we've opened for first time*/
CHAR szFileName[FILE_NAME_SIZE]; /* buffer for fully qualified file name*/
CHAR acTempFileName[MESSAGELEN]; /* buffer for temporary file name */
CHAR achTitle[MAXNAMEL]; /* buffer for window title text */
CHAR achMsgBoxTitle[MAXNAMEL]; /* Error message box title */
MCI_OPEN_PARMS mciOpenParms; /* open parms for MCI_OPEN */
HPOINTER hptrWait, hptrArrow; /* Pointer handles for use during long waits. */
/************************** End of Global Variables ***************************/
/******************************************************************************
* Name : main
*
* Description : This function calls the Initialize procedure to prepare
* everything for the program's operation, enters the
* message loop, then call Finalize to shut everything down
* when the program is terminated.
*
* Concepts : None.
*
* MMPM/2 API's : None.
*
* Parameters : argc - Number of parameters passed into the program.
* argv - Command line parameters.
*
* Return : TRUE is returned to the operating system.
*
******************************************************************************/
INT main( VOID )
{
QMSG qmsg;
Initialize();
while ( WinGetMsg( hab, (PQMSG) &qmsg, (HWND) NULL, 0, 0) )
WinDispatchMsg( hab, (PQMSG) &qmsg );
Finalize();
return( TRUE);
} /* End of main */
/******************************************************************************
* Name : Initialize
*
* Description : This function performs the necessary initializations and
* setups that are required to show/run a dialog box as a
* main window. The message queue will be created, as will
* the dialog box.
*
* Concepts : None.
*
* MMPM/2 API's : none
*
* Parameters : None.
*
* Return : None.
*
******************************************************************************/
VOID Initialize( VOID)
{
CHAR szDefaultSize[MESSAGELEN]; /* buffer for default size menu text */
CHAR szCommandString[STRING_COMMAND_SIZE];
CHAR szReturn[STRING_COMMAND_SIZE] = "";
hab = WinInitialize( 0);
hmq = WinCreateMsgQueue( hab, 0);
hptrArrow = WinQuerySysPointer ( HWND_DESKTOP, SPTR_ARROW, FALSE );
hptrWait = WinQuerySysPointer ( HWND_DESKTOP, SPTR_WAIT, FALSE );
/*
* Initialize the dialog window. First, change pointer to a waiting
* pointer, since this might take a couple of seconds.
*/
WinSetPointer ( HWND_DESKTOP, hptrWait );
WinLoadString(
hab, /* HAB for this dialog box. */
(HMODULE) NULL, /* Get the string from the .exe. */
IDS_DEFAULTSIZE, /* Which string to get. */
sizeof(szDefaultSize), /* The size of the buffer. */
szDefaultSize); /* The buffer to place the string.*/
WinLoadString(
hab, /* HAB for this dialog box. */
(HMODULE) NULL, /* Get the string from the .exe. */
IDS_UNTITLED, /* Which string to get. */
(SHORT) sizeof( acTempFileName), /* The size of the buffer. */
acTempFileName); /* The buffer to place the string.*/
WinLoadString(
hab, /* HAB for this dialog box. */
(HMODULE) NULL, /* Get the string from the .exe. */
IDS_AUDIO_RECORDER_ERROR, /* Which string to get. */
(SHORT) sizeof( achMsgBoxTitle), /* The size of the buffer. */
achMsgBoxTitle); /* The buffer to place the string.*/
hwndFrame = /* Returns the handle to the frame. */
WinLoadSecondaryWindow(
HWND_DESKTOP, /* Parent of the dialog box. */
HWND_DESKTOP, /* Owner of the dialog box. */
(PFNWP) MainDlgProc, /* 'Window' procedure for the dialog box. */
(HMODULE) NULL, /* Where is the dialog. Null is EXE file. */
ID_DLG_MAIN, /* Dialog ID. */
(PVOID) NULL); /* Creation Parameters for the dialog. */
/*
* Retrieve the handle to the dialog box by specifying the QS_DIALOG flag.
*/
hwndMainDialogBox = WinQuerySecondaryHWND(hwndFrame, QS_DIALOG);
/*
* Add Default Size menu item to system menu of the secondary window.
*/
WinInsertDefaultSize(hwndFrame, szDefaultSize);
/*
* Get the window title string from the Resource string table
* and set it as the window text for the dialog window.
*/
WinLoadString(
hab, /* HAB for this dialog box. */
(HMODULE) NULL, /* Get the string from the .exe. */
IDS_PROGRAM_TITLE, /* Which string to get. */
(SHORT) sizeof( achTitle), /* The size of the buffer. */
achTitle); /* The buffer to place the string.*/
WinSetWindowText( hwndFrame, achTitle);
/*
* Query the device for the default connections.
*/
QueryTheDefaultConnection();
/*
* Open the audio device with a untitled file loaded.
*/
if (OpenTheFile( hwndMainDialogBox, acTempFileName ))
fTempFileInUse = TRUE;
/*
* Find the opened device capabilities like can able to play and record
* the wave audio files. Also find the device has the ability to play
* and record 16 bit audio files.
*/
FindTheDeviceCapability();
WinShowWindow( hwndFrame, TRUE );
InitializeHelp();
/*
* Now that we're done here, change the pointer back to the arrow.
*/
WinSetPointer ( HWND_DESKTOP, hptrArrow );
} /* End of Initialize */
/******************************************************************************
* Name : Finalize
*
* Description : This routine is called after the message dispatch loop
* has ended because of a WM_QUIT message. The code will
* destroy the help instance, messages queue, and window.
*
* Concepts : None.
*
* MMPM/2 API's : None.
*
* Parameters : None.
*
* Return : None.
*
******************************************************************************/
VOID Finalize( VOID )
{
/*
* Destroy the Help Instances.
*/
if ( hwndHelpInstance != (HWND) NULL)
{
WinDestroyHelpInstance( hwndHelpInstance );
}
WinDestroySecondaryWindow( hwndFrame );
WinDestroyMsgQueue( hmq );
WinTerminate( hab );
} /* End of Finalize */
/******************************************************************************
* Name : MainDlgProc
*
* Description : This function controls the main dialog box. It will handle
* received messages such as pushbutton notifications, timing
* events, etc.
*
* Concepts : - How to participate in MMPM/2 device sharing scheme.
* - How to handle notification messages.
*
* MMPM/2 API's : mciSendMessage MCI_ACQUIREDEVICE
*
* Parameters : hwnd - Handle for the Main dialog box.
* msg - Message received by the dialog box.
* mp1 - Parameter 1 for the just received message.
* mp2 - Parameter 2 for the just received message.
*
* Return :
*
******************************************************************************/
MRESULT EXPENTRY MainDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
ULONG ulError; /* rc for MCI_ACQUIRE send cmd */
HPOINTER hpProgramIcon; /* handle to program's icon */
MCI_GENERIC_PARMS mciGenericParms; /* generic parms for MCI_ACQUIRE*/
USHORT usCommandMessage; /* command message for notify */
USHORT usNotifyCode; /* notification message code */
static BOOL fShowStatus; /* for status line */
BOOL fError; /* Error return code */
switch( msg )
{
case WM_INITDLG :
hpProgramIcon =
WinLoadPointer(
HWND_DESKTOP,
(HMODULE) NULL, /* Resource is kept in .Exe file. */
ID_ICON ); /* Which icon to use. */
WinDefSecondaryWindowProc(
hwnd, /* Dialog window handle. */
WM_SETICON, /* Message to the dialog. Set it's icon.*/
(MPARAM) hpProgramIcon,
(MPARAM) 0 ); /* mp2 no value. */
/*
* get all the required handles.
*/
hwndPlayPB = WinWindowFromID( hwnd, ID_GPB_PLAY ); /* play PB */
hwndRecordPB = WinWindowFromID( hwnd, ID_GPB_RECORD ); /* record PB*/
hwndMenu = WinWindowFromID( /* menu */
WinQuerySecondaryFrame( hwnd ),
FID_MENU );
/*
* The slider control cannot be completely set from the dialog
* template so some aspects must be set here. We will set the
* volume range to 0-100, increment to 1-10, and the initial
* volume level to 75.
*/
WinSendMsg( WinWindowFromID(hwnd, ID_SL_VOLUME),
CSM_SETRANGE,
(MPARAM) 0L,
(MPARAM) 100L);
WinSendMsg( WinWindowFromID(hwnd, ID_SL_VOLUME),
CSM_SETINCREMENT,
(MPARAM) 10L,
(MPARAM) 1L);
WinSendMsg( WinWindowFromID(hwnd, ID_SL_VOLUME),
CSM_SETVALUE,
(MPARAM) sVolumeLevel,
(MPARAM) NULL);
/*
* Set up the PLAY graphic pushbutton.
*/
WinSendMsg (
hwndPlayPB, /* Play push button handle */
GBM_SETANIMATIONRATE, /* Animation rate control */
MPFROMLONG(100L), /* Update play bitmap every .1 sec */
NULL); /* Ignore return data */
/*
* Initialize all the default selections in the menu pulldowns.
*/
WinSendMsg( hwndMenu, /* select the "Microphone" as default */
MM_SETITEMATTR,
MPFROM2SHORT(IDM_MICROPHONE, TRUE),
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
WinSendMsg( hwndMenu, /* select the "Medium input level" as default*/
MM_SETITEMATTR,
MPFROM2SHORT(IDM_MEDIUM_INPUT, TRUE),
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
WinSendMsg( hwndMenu, /* select the "Monitor input" as default */
MM_SETITEMATTR,
MPFROM2SHORT(IDM_MONITOR_INPUT, TRUE),
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
WinSendMsg( hwndMenu, /* select the "Stereo" as default */
MM_SETITEMATTR,
MPFROM2SHORT(IDM_STEREO, TRUE),
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
WinSendMsg( hwndMenu, /* select "Music (22 khz)" as default */
MM_SETITEMATTR,
MPFROM2SHORT(IDM_MUSIC, TRUE),
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
WinSendMsg( hwndMenu, /* select the "Low quality" as default */
MM_SETITEMATTR,
MPFROM2SHORT(IDM_LOW_QUALITY, TRUE),
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
WinSendMsg( hwndMenu, /* select "Show status line" as default */
MM_SETITEMATTR,
MPFROM2SHORT(IDM_OPTIONS_STATUSLINE, TRUE),
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
fShowStatus = TRUE; /* set the "fShowStatus" flag to true */
return( (MRESULT) 0);
case WM_CLOSE :
/*
* Before closing the device, inform the user if there is a
* modified file open.
*/
if (!fFirstOpen)
{
if (fModified )
{
if ( SaveTheChanges( hwnd ) == MBID_CANCEL )
return( (MRESULT) 0);
else
CloseTheDevice();
}
else
CloseTheDevice();
}
return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
case WM_HELP :
/*
* The dialog window has received a request for help from the user,
* i.e., the Help pushbutton was pressed. Send the HM_DISPLAY_HELP
* message to the Help Instance with the IPF resource identifier
* for the correct HM panel. This will show the help panel for this
* sample program.
*/
WinSendMsg( hwndHelpInstance,
HM_DISPLAY_HELP,
MPFROMSHORT(1),
MPFROMSHORT(HM_RESOURCEID));
return( (MRESULT) 0);
case WM_CONTROL:
if (SHORT1FROMMP(mp1)==ID_SL_VOLUME)
{
if ((SHORT2FROMMP(mp1)==CSN_CHANGED) || /* change volume? */
(SHORT2FROMMP(mp1)==CSN_TRACKING)) /* tracking volume? */
{
sVolumeLevel = SHORT1FROMMP (mp2);
SetAudioVolume(hwnd);
}
}
return( (MRESULT) 0);
case WM_COMMAND :
/*
* To get which pushbutton was pressed the SHORT1FROMMP macro is used.
*/
switch (SHORT1FROMMP(mp1))
{
case ID_GPB_PLAY: /* user selected "Play" */
/*
* If the audio is stopped and an existing file or a tempfile is
* open, PLAY.
*/
if (eState == ST_STOPPED)
{
if (PlayTheAudio( hwnd))
{
/*
* Update the status line with appropriate message.
*/
UpdateTheStatusLine(hwnd, IDS_PLAYING);
/*
* If playing was successful, start the play button
* animation.
*/
WinSendMsg( hwndPlayPB, /* Dialog window handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(TRUE), /* Animation flag */
NULL ); /* Ignore return data */
}
else /* If playing failed, set the state to stopped */
eState = ST_STOPPED;
}
break;
case ID_GPB_RECORD: /* user selected "Record" */
/*
* If the audio is in stopped state, record
*/
if (eState == ST_STOPPED)
{
RecordTheAudio( hwnd );
}
break;
case ID_GPB_STOP: /* user selected "Stop" */
/*
* If the audio is not in stopped state, stop the device
*/
if (eState != ST_STOPPED)
StopTheDevice(hwnd);
break;
case ID_GPB_REWIND: /* user selected "Rewind" */
/*
* If an existing file open, or a temp file is modified
* seek the file.
*/
if ((fFileOpen) || (fModified))
{
/*
* Update the status line with the appropriate message and
* seek the audio to the begining.
*/
UpdateTheStatusLine(hwnd, IDS_REWINDING);
SeekTheAudio( hwnd, MCI_TO_START );
}
break;
case ID_GPB_FF: /* user selected "Fast Forward" */
/*
* If an existing file open, or a temp file is modified
* seek the file.
*/
if ((fFileOpen) || (fModified))
{
/*
* Update the status line with the appropriate message and
* seek the audio to the end.
*/
UpdateTheStatusLine(hwnd, IDS_FASTFORWARDING);
SeekTheAudio( hwnd, MCI_TO_END );
}
break;
case IDM_FILE_NEW: /* user selected "Filenew" */
if (eState != ST_STOPPED)
StopTheDevice(hwnd);
/*
* First, if any modified file is open, ask the user if he wants
* to save the changes or not.
*/
if (fModified)
{
if ( SaveTheChanges( hwnd ) == MBID_CANCEL )
return( (MRESULT) FALSE);
}
/*
* If opening is success, set the file varables.
*/
if ( OpenTheFile( hwnd, acTempFileName ))
{
/*
* Get the selected file header information and check the
* correct options and disable all the other options in the
* Type menu pulldown.
*/
SetTheOptions(NEW_FILE);
fTempFileInUse = TRUE;
fFileOpen = FALSE;
UpdateTheStatusLine(hwnd, IDS_STOPPED);
}
return( (MRESULT) TRUE);
break;
case IDM_FILE_OPEN: /* user selected "Fileopen" */
/*
* First, if any modified file is open, ask the user if he wants
* to save the changes or not.
*/
if (fModified)
{
if ( SaveTheChanges( hwnd ) == MBID_CANCEL )
return( (MRESULT) FALSE);
}
/*
* Allow the user to select a file using Open dialog.
*
*/
if (ShowStandardFileDlg(IDM_FILE_OPEN))
{
/*
* If the audio is not in stop state, stop it.
*/
if (eState != ST_STOPPED)
StopTheDevice(hwnd);
if (!fFirstOpen) /* If we've opened the device */
{
/*
* Get the selected file header information and check the
* correct options and disable all the other options in
* the Type menu pulldown.
*/
fError = SetTheOptions(EXISTING_FILE);
/* If we get an error from SetTheOptions, we want to
* exit now, before opening the file.
*/
if (!fError) {
return( (MRESULT) FALSE);
}
}
/*
* Now that the user has selected a file, open it.
*/
if (OpenTheFile( hwnd, szFileName ))
{
fFileOpen = TRUE;
fTempFileInUse = FALSE;
UpdateTheStatusLine(hwnd, IDS_STOPPED);
}
}
return( (MRESULT) TRUE);
break;
case IDM_FILE_SAVE: /* user selected "Save" */
if ((!fTempFileInUse) && (!fFileOpen) || (fTempFileInUse))
{
if ( FileSaveAs( hwnd ) )
{
/*
* If the audio is not in stop state, stop it.
*/
if (eState != ST_STOPPED)
StopTheDevice(hwnd);
fFileOpen = TRUE;
UpdateTitleText( hwndFrame, szFileName );
}
}
else
SaveTheAudio(hwnd);
return( (MRESULT) TRUE);
break;
case IDM_FILE_SAVE_AS: /* user selected "Saveas" */
if ( FileSaveAs( hwnd ) )
{
/*
* If the audio is not in stop state, stop it.
*/
if (eState != ST_STOPPED)
StopTheDevice(hwnd);
fFileOpen = TRUE;
UpdateTitleText( hwndFrame, szFileName );
}
return( (MRESULT) TRUE);
break;
case IDM_MICROPHONE: /* user selected "Microphone" */
/*
* First, select the "Microphone" then, deselect the "Line in"
* and set the usDeviceType.
*/
SelectTheOption(IDM_MICROPHONE);
DeselectTheOption(IDM_LINEIN);
usDeviceType = MCI_MICROPHONE_CONNECTOR;
return( 0 );
case IDM_LINEIN: /* user selected "Line in" */
/*
* First, select the "Line in" then, deselect the "Microphone"
* and set the usDeviceType.
*/
SelectTheOption(IDM_LINEIN);
DeselectTheOption(IDM_MICROPHONE);
usDeviceType = MCI_LINE_IN_CONNECTOR;
return( 0 );
case IDM_LOW_INPUT: /* user selected "Low input level"*/
/*
* First, select the "Low input level" then, deselect the
* "Medium input level" and "High input level" and set the
* usInputLevel.
*/
SelectTheOption(IDM_LOW_INPUT);
DeselectTheOption( IDM_MEDIUM_INPUT );
DeselectTheOption( IDM_HIGH_INPUT );
usInputLevel = LOW_INPUT_LEVEL;
return( 0 );
case IDM_MEDIUM_INPUT: /* user selected "Medium input level"*/
/*
* First, select the "Medium input level" then, deselect the
* "Low input level" and "High input level" and set the
* usInputLevel.
*/
SelectTheOption(IDM_MEDIUM_INPUT);
DeselectTheOption( IDM_LOW_INPUT );
DeselectTheOption( IDM_HIGH_INPUT );
usInputLevel = MEDIUM_INPUT_LEVEL;
return( 0 );
case IDM_HIGH_INPUT: /* user selected "High input level" */
/*
* First, select the "High input level" then, deselect the
* "Low input level" and "Medium input level" and set the
* usInputLevel.
*/
SelectTheOption(IDM_HIGH_INPUT);
DeselectTheOption( IDM_LOW_INPUT );
DeselectTheOption( IDM_MEDIUM_INPUT );
usInputLevel = HIGH_INPUT_LEVEL;
return( 0 );
case IDM_MONITOR_INPUT: /* user selected "Monitor input" */
/*
* Check to see the status of the "Monitor input" option.
*/
if (fMonitor)
{
/*
* Previously this item was checked, so now uncheck the
* "Monitor input" item and set fMonitor to false.
*/
WinSendMsg( hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(IDM_MONITOR_INPUT, TRUE),
MPFROM2SHORT(MIA_CHECKED, FALSE));
fMonitor = FALSE;
}
else
{
/*
* Previously this item was unchecked, so now check the
* "Monitor input" item and set fMonitor to true.
*/
WinSendMsg( hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(IDM_MONITOR_INPUT, TRUE),
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
fMonitor = TRUE;
}
return( 0 );
case IDM_STEREO: /* user selected "Stereo" */
/*
* First, select the "Stereo" then, deselect the "Mono" and
* set the usStereoMono.
*/
SelectTheOption(IDM_STEREO);
DeselectTheOption( IDM_MONO );
usStereoMono = STEREO;
return( 0 );
case IDM_MONO: /* user selected "Mono" */
/*
* First, select the "Mono" then, deselect the "Stereo" and
* and set the usStereoMono
*/
SelectTheOption(IDM_MONO);
DeselectTheOption( IDM_STEREO );
usStereoMono = MONO;
return( 0 );
case IDM_VOICE: /* user selected "Voice (11 khz)" */
/*
* First, select the "Voice (11 khz)" then, deselect the
* "Music (22 khz)" and "High fidelity (44 khz)" and set the
* usQualityType
*/
SelectTheOption(IDM_VOICE);
DeselectTheOption( IDM_MUSIC );
DeselectTheOption( IDM_HIGH_FIDELITY );
usQualityType = VOICE;
return( 0 );
case IDM_MUSIC: /* user selected "Music (22 khz)" */
/*
* First, select the "Music (22 khz)" then, deselect the
* "Voice (11 khz)" and "High fidelity (44 khz)" and set the
* usQualityType
*/
SelectTheOption(IDM_MUSIC);
DeselectTheOption( IDM_VOICE );
DeselectTheOption( IDM_HIGH_FIDELITY );
usQualityType = MUSIC;
return( 0 );
case IDM_HIGH_FIDELITY: /* user selected "High fidelity (44 khz)"*/
/*
* First, select the "High fidelity (44 khz)" then, deselect
* the "Voice (11 khz)" and "Music (22 khz)" and set the
* usQualityType
*/
SelectTheOption(IDM_HIGH_FIDELITY);
DeselectTheOption( IDM_VOICE );
DeselectTheOption( IDM_MUSIC );
usQualityType = HIGH_FIDELITY;
return( 0 );
case IDM_LOW_QUALITY: /* user selected "Low quality" */
/*
* First, select the "Low quality" then, deselect the
* "High quality" and set the usBitType.
*/
SelectTheOption(IDM_LOW_QUALITY);
DeselectTheOption( IDM_HIGH_QUALITY );
usBitType = BIT_8;
return( 0 );
case IDM_HIGH_QUALITY: /* user selected "High quality"*/
/*
* First, select the "High quality" then, deselect the
* "Low quality" and set the usBitType.
*/
SelectTheOption(IDM_HIGH_QUALITY);
DeselectTheOption( IDM_LOW_QUALITY );
usBitType = BIT_16;
return( 0 );
case IDM_OPTIONS_STATUSLINE :
/*
* Check to see the status of the "Show status line" option.
*/
if (fShowStatus)
{
/*
* Previously this item was checked, so now uncheck the
* "Show status line" item and set fShowStatus to false.
*/
WinSendMsg( hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(IDM_OPTIONS_STATUSLINE, TRUE),
MPFROM2SHORT(MIA_CHECKED, FALSE));
fShowStatus = FALSE;
/*
* Adjust the Dialog window.
*/
AdjustTheDlg(hwnd, fShowStatus);
}
else
{
/*
* Previously this item was unchecked, so now check the
* "Show status line" item and set fShowStatus to true.
*/
WinSendMsg( hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(IDM_OPTIONS_STATUSLINE, TRUE),
MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
fShowStatus = TRUE;
/*
* Adjust the Dialog window.
*/
AdjustTheDlg(hwnd, fShowStatus);
}
return( 0 );
case IDM_HELP_PRODUCTINFO :
/*
* See if the product information dialog box was created.
*/
if (!hwndProductInfo)
{
/*
* Product Window was not created, create and display the
* window.
*/
hwndProductInfo =
WinLoadSecondaryWindow(
HWND_DESKTOP, /* Parent of the dialog box*/
hwndFrame, /* Owner of the dialog box.*/
(PFNWP)ProductInfoDlgProc,/* Dialog box procedure. */
(HMODULE) NULL, /* Dialog is where,EXE file*/
ID_DLG_PRODUCTINFO, /* Dialog ID. */
(PVOID) NULL); /* Dialog Creation Params */
}
else
{
/*
* Product window was created earlier, reposition the window
* and give the focus.
*/
WinSetWindowPos(
hwndProductInfo,
HWND_TOP,
(SHORT) NULL,
(SHORT) NULL,
(SHORT) NULL,
(SHORT) NULL,
SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE );
WinSetFocus( HWND_DESKTOP, hwndProductInfo );
}
return( 0 );
case IDM_HELP_INDEX : /* user selected "Help Index" */
/*
* Call system default help index panel.
*/
WinSendMsg( hwndHelpInstance,
HM_HELP_INDEX,
NULL,
NULL);
break;
case IDM_HELP_GENERAL : /* user selected "General Help" */
/*
* Call general help panel.
*/
WinSendMsg( hwndHelpInstance,
HM_DISPLAY_HELP,
MPFROMSHORT(1),
MPFROMSHORT(HM_RESOURCEID));
break;
case IDM_HELP_USING : /* user selected "Using Help" */
/*
* Call system default using help panel.
*/
WinSendMsg( hwndHelpInstance,
HM_DISPLAY_HELP,
NULL,
NULL);
break;
case IDM_HELP_KEYS : /* user selected "Keys Help" */
/*
* Call keys help panel.
*/
WinSendMsg( hwndHelpInstance,
HM_DISPLAY_HELP,
MPFROMSHORT(2),
MPFROMSHORT(HM_RESOURCEID));
break;
default:
break;
} /* End of Command Switch */
return( (MRESULT) 0);
/*
* The next two messages are handled so that the audio recorder
* application can participate in device sharing. Since it opens
* the device as shareable device, other applications can gain
* control of the device. When this happens, we will receive a
* MM_MCIPASSDEVICE message. We keep track of this device passing in
* the fPassedDevice boolean variable.
*
* If we do not have access to the device when we receive an WM_ACTIVATE
* message, then we will issue an acquire device command to gain
* access to the device.
*
*
* This is one possible method that can be used to implement
* device sharing. For applications that are more complex
* than this sample program, developers may wish to take
* advantage of a more robust method of device sharing.
* This can be done by using the MCI_ACQUIRE_QUEUE flag on
* the MCI_ACQUIREDEVICE command. Please refer to the MMPM/2
* documentation for more information on this flag.
*/
case MM_MCIPASSDEVICE:
if (SHORT1FROMMP(mp2) == MCI_GAINING_USE) /* GAINING USE */
{
fPassedDevice = FALSE; /* Gaining control of device.*/
if (eState == ST_PLAYING) /* If the file was playing */
{
/*
* Start play button animation and update the status line
* with appropriate text.
*/
WinSendMsg( hwndPlayPB, /* Play button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(TRUE), /* Animation flag */
NULL ); /* Ignore return data */
UpdateTheStatusLine(hwnd, IDS_PLAYING);
}
else if (eState == ST_RECORDING)
{
/*
* Start record button animation and update the status line
* with appropriate text.
*/
WinSendMsg( hwndRecordPB, /* Record button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(TRUE), /* Animation flag */
NULL ); /* Ignore return data */
UpdateTheStatusLine(hwnd, IDS_RECORDING);
}
else
/*
* Update the status line with appropriate text.
*/
UpdateTheStatusLine(hwnd, IDS_STOPPED);
}
else /* LOSING USE */
{
fPassedDevice = TRUE; /* Losing control of device.*/
if (eState == ST_PLAYING) /* If the file was playing */
{
/*
* Stop play button animation and update the status line
* with appropriate text.
*/
WinSendMsg( hwndPlayPB, /* Play button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(FALSE), /* Animation flag */
NULL ); /* Ignore return data */
UpdateTheStatusLine(hwnd, IDS_PLAYING);
}
else if (eState == ST_RECORDING)
{
/*
* Stop record button animation and update the status line
* with appropriate text.
*/
WinSendMsg( hwndRecordPB, /* Record button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(FALSE), /* Animation flag */
NULL ); /* Ignore return data */
UpdateTheStatusLine(hwnd, IDS_RECORDING);
}
else
/*
* Update the status line with appropriate text.
*/
UpdateTheStatusLine(hwnd, IDS_STOPPED);
}
return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
case WM_ACTIVATE:
/* We use the WM_ACTIVATE message to participate in device
* sharing. We first check to see if this is an activate
* or a deactivate message (indicated by mp1). Then,
* we check to see if we've passed control of the audio'
* devices. If these conditions are true, then
* we issue an acquire device command to regain control of
* the device, since we're now the active window on the screen.
*/
if ((BOOL)mp1 && fPassedDevice == TRUE)
{
mciGenericParms.hwndCallback = hwnd;
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_ACQUIREDEVICE,
(ULONG)MCI_NOTIFY,
(PVOID) &mciGenericParms,
(USHORT)NULL);
if (ulError)
ShowMCIErrorMessage( ulError);
}
return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
case MM_MCINOTIFY:
/*
* This message is returned to an application when a device
* successfully completes a command that was issued with a NOTIFY
* flag, or when an error occurs with the command.
*
* This message returns two values. A user parameter (mp1) and
* the command message (mp2) that was issued. The low word of mp1
* is the Notification Message Code which indicates the status of the
* command like success or failure. The high word of mp2 is the
* Command Message which indicates the source of the command.
*/
usNotifyCode = (USHORT) SHORT1FROMMP( mp1); /* low-word */
usCommandMessage = (USHORT) SHORT2FROMMP( mp2); /* high-word */
switch (usCommandMessage)
{
case MCI_PLAY:
switch (usNotifyCode)
{
case MCI_NOTIFY_SUCCESSFUL:
if (eState != ST_STOPPED)
{
/*
* Update the status line with appropriate message.
*/
UpdateTheStatusLine(hwnd, IDS_STOPPED);
eState = ST_STOPPED;
/*
* Stop the play button animation
*/
WinSendMsg( hwndPlayPB, /* Play button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(FALSE),/* Animation flag */
NULL ); /* Ignore return data */
}
break;
case MCI_NOTIFY_SUPERSEDED:
case MCI_NOTIFY_ABORTED:
/* we don't need to handle these messages. */
break;
default:
/*
* If the message is none of the above, then it must be
* a notification error message.
*/
ShowMCIErrorMessage( usNotifyCode);
eState = ST_STOPPED;
/*
* Stop the play button animation and update the status
* line with appropriate text.
*/
WinSendMsg( hwndPlayPB, /* Play button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(FALSE), /* Animation flag */
NULL ); /* Ignore return data */
UpdateTheStatusLine(hwnd, IDS_STOPPED);
break;
}
break;
}
return( (MRESULT) 0);
default:
return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2));
} /* End of msg Switch */
return( (MRESULT) FALSE);
} /* End of MainDlgProc */
/******************************************************************************
* Name : InitializeHelp
*
* Description : This procedure will set up the initial values in the
* global help structure. This help structure will then
* be passed on to the Help Manager when the Help Instance
* is created. The handle to the Help Instance will be
* kept for later use.
*
* Concepts : None.
*
* MMPM/2 API's : None.
*
* Parameters : None.
*
* Return : None.
*
******************************************************************************/
VOID InitializeHelp( VOID )
{
HELPINIT helpInit; /* Help initialization structure. */
CHAR achHelpLibraryName[LEN_HELP_LIBRARY_NAME];
CHAR achHelpWindowTitle[LEN_HELP_WINDOW_TITLE];
/*
* Load the strings for the Help window title and library name.
* Initialize the help structure and associate the help instance.
*/
WinLoadString( hab,
(HMODULE) NULL,
IDS_HELP_WINDOW_TITLE,
(SHORT) sizeof( achHelpWindowTitle),
achHelpWindowTitle);
WinLoadString( hab,
(HMODULE) NULL,
IDS_HELP_LIBRARY_NAME,
(SHORT) sizeof( achHelpLibraryName),
achHelpLibraryName);
memset ( &helpInit, 0, sizeof(helpInit) );
/*
* Initialize the help structure.
*/
helpInit.cb = sizeof( helpInit); /* size of the help struc*/
helpInit.ulReturnCode = (ULONG) 0; /* RC from HM init */
helpInit.pszTutorialName = (PSZ) NULL; /* No tutorial program */
helpInit.pszHelpWindowTitle = achHelpWindowTitle; /* The Help window title.*/
helpInit.fShowPanelId = (ULONG) 0; /* help panel ID. */
helpInit.pszHelpLibraryName = achHelpLibraryName; /* library name */
helpInit.phtHelpTable = (PVOID)(0xffff0000 | ID_AUDIO_HELPTABLE);
/*
* Create the Help Instance for IPF.
* Give IPF the Anchor Block handle and address of the IPF initialization
* structure, and check that creation of Help was a success.
*/
hwndHelpInstance = WinCreateHelpInstance(
hab, /* Anchor Block Handle. */
&helpInit ); /* Help Structure. */
if ( hwndHelpInstance == (HWND) NULL)
{
MessageBox( IDS_HELP_CREATION_FAILED, /* ID of the message */
MB_OK | MB_INFORMATION | MB_MOVEABLE); /* style */
}
else
{
if ( helpInit.ulReturnCode)
{
WinDestroyHelpInstance( hwndHelpInstance);
MessageBox( IDS_HELP_CREATION_FAILED, /* ID of the message */
MB_OK | MB_INFORMATION | MB_MOVEABLE); /* style */
}
else /* help creation worked */
WinAssociateHelpInstance(
hwndHelpInstance, /* The handle of the Help Instance. */
hwndFrame); /* Associate to this dialog window. */
} /* End of IF checking the creation of the Help Instance. */
} /* End of InitializeHelp */
/******************************************************************************
* Name : ProcuctInfoDlgProc
*
* Description : This function controls the product information dialog box.
*
* Concepts : None.
*
* MMPM/2 API's: None.
*
* Parameters : hwnd - Handle for the Include dialog box.
* msg - Message received by the dialog box.
* mp1 - Parameter 1 for the just received message.
* mp2 - Parameter 2 for the just received message.
*
* Return : 0 or the result of default processing.
*
******************************************************************************/
MRESULT EXPENTRY ProductInfoDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
{
switch( msg )
{
case WM_INITDLG :
/*
* Add Default Size menu item to system menu of the secondary window.
*/
WinInsertDefaultSize(hwnd, "~DefaultSize");
break;
case WM_CLOSE :
WinDestroySecondaryWindow( hwnd ); /* Close the Dialog box. */
return( 0 );
break;
case WM_DESTROY:
hwndProductInfo = 0;
break;
case WM_COMMAND :
switch( SHORT1FROMMP( mp1 ) )
{
case DID_OK :
case DID_CANCEL:
WinDestroySecondaryWindow( hwnd ); /* Close the Dialog box. */
return( (MRESULT)TRUE);
break;
} /* End of Command Switch */
} /* End of Switch */
return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
} /* End of FileDlgProc */
/******************************************************************************
* Name : OpenTheFile
*
* Description : This procedure will Open the audio device with a specific
* file loaded, if the audio device is not already opened.
* If the audio device is open, an audio file will be loaded
* onto it.
*
* Concepts : - Open a device using the MCI interface.
* - Loading a file into an already open device.
*
* MMPM/2 API's : mciSendCommand MCI_OPEN
* MCI_LOAD
*
* Parameters : hwnd - Handle for the Main dialog box.
* pszFileName - selected file name to open
*
* Return : TRUE - if the operation was initiated without error.
* FALSE - if an error occurred.
*
******************************************************************************/
BOOL OpenTheFile( HWND hwnd, PSZ pszFileName )
{
ULONG ulError; /* return value for mci command */
MCI_LOAD_PARMS mciLoadParms; /* load parms for MCI_LOAD */
BOOL bReturn = TRUE; /* function return value */
if (fFirstOpen)
/* If this is the first time thru this routine, then we need to open
* the device.
*
* On subsequent calls to this routine, the devices are already open,
* so we only need to load the appropriate file onto the device.
*
*/
{
/*
* Update the status line with appropriate message.
*/
UpdateTheStatusLine(hwnd, IDS_OPENINGDEVICE);
/*
* To Open the device, we will issue an MCI_OPEN command via
* mciSendCommand using an MCI_OPEN_PARMS structure. The device ID
* will be returned in the device ID field of the open data structure.
*/
memset( &mciOpenParms, /* Object to fill with zeros. */
0, /* Value to place into the object. */
sizeof( mciOpenParms ) ); /* How many zero's to use. */
mciOpenParms.hwndCallback = hwnd; /* For MM_MCIPASSDEVICE */
mciOpenParms.usDeviceID = (USHORT) NULL; /* this is returned */
/*
* Specify the device type. The pszDeviceType is to be interpreted as
* the low-order word is a standard device type, and the high-order
* word is the ordinal index for the device. In other words we are
* explecitely trying to open the default device on the system. This
* gives the ability to load a non existing (untitled) audio file.
*/
mciOpenParms.pszDeviceType = (PSZ) MAKEULONG(
MCI_DEVTYPE_WAVEFORM_AUDIO,
usDeviceTypeOpened);
/*
* Specify the name of the file to be opened.
*/
mciOpenParms.pszElementName = (PSZ)NULL;
ulError = mciSendCommand( (USHORT) 0,
MCI_OPEN,
MCI_WAIT | MCI_OPEN_TYPE_ID |
MCI_OPEN_SHAREABLE | MCI_OPEN_ELEMENT,
(PVOID) &mciOpenParms,
UP_OPEN);
if (ulError)
{
ShowMCIErrorMessage( ulError);
UpdateTheStatusLine(hwnd, IDS_STOPPED);
bReturn = FALSE;
}
else
/*
* Open success, set the flag to indicate that next time thru this
* routine we do not need to open the device.
*/
fFirstOpen = FALSE;
}
else
{
/*
* Change pointer to a waiting pointer first, since this might take a
* couple of seconds.
*/
WinSetPointer( HWND_DESKTOP, hptrWait );
/*
* The device is already open. We just need to load the appropriate
* audio file.
*
* Update the status line with appropriate message.
*/
UpdateTheStatusLine(hwnd, IDS_LOADINGFILE);
mciLoadParms.hwndCallback = (HWND) NULL; /* We're waiting */
/*
* If we're not using a temporary file, load the filename.
* Otherwise, just pass NULL as the filename and let the audio
* device handle the temporary file for us.
*/
if ( strcmp ( pszFileName, acTempFileName) )
mciLoadParms.pszElementName = (PSZ)pszFileName;
else
mciLoadParms.pszElementName = (PSZ)NULL;
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_LOAD,
MCI_WAIT,
(PVOID) &mciLoadParms,
(ULONG) NULL);
if (ulError)
{
ShowMCIErrorMessage( ulError ); /* Display the error message */
UpdateTheStatusLine(hwnd, IDS_STOPPED);
bReturn = FALSE;
}
/*
* Now that we're done here, change the pointer back to the arrow.
*/
WinSetPointer ( HWND_DESKTOP, hptrArrow );
}
if (bReturn)
/*
* Update the main window title bar with the selected file name.
*/
UpdateTitleText(hwndFrame, pszFileName);
return( bReturn);
} /* end of OpenTheFile */
/******************************************************************************
* Name : QueryTheDefaultConnection
*
* Description : This procedure will query the default connection and find
* the device play/record capabilities. Also find the device
* ability to play/record 16 bit audio files.
*
* Concepts : - Query the default device of waveaudio type.
* - Get the ordinal value of the first device of the waveaudio.
*
* MMPM/2 API's : mciSendCommand MCI_SYSINFO
*
* Parameters : none
*
* Return : none
*
******************************************************************************/
VOID QueryTheDefaultConnection( VOID )
{
MCI_SYSINFO_PARMS mciSysinfoParms;
MCI_SYSINFO_DEFAULTDEVICE mciSysinfoDefaultdevice;
MCI_SYSINFO_QUERY_NAME mciSysinfoQueryName;
ULONG ulError;
memset( &mciSysinfoParms, 0, sizeof( mciSysinfoParms ) );
memset( &mciSysinfoDefaultdevice, 0, sizeof(mciSysinfoDefaultdevice));
/*
* Set up parameters to query the default device for
* MCI_DEVTYPE_WAVEFORM_AUDIO device type. If no explicit default exists,
* then the first device of the indicated type is implicitely the default.
*
* First, initialize MCI_SYSINFO_PARMS and MCI_SYSINFO_DEFAULTDEVICE
* structures with the pertinent information then issue MCI_SYSINFO
* command via mciSendCommand. The pSysInfoParm field points to the
* MCI_SYSINFO_DEFAULTDEVICE structure. The default device name will be
* returned in the szInstallName field.
*/
mciSysinfoParms.ulItem = MCI_SYSINFO_QUERY_DEFAULT;
mciSysinfoParms.pSysInfoParm = &mciSysinfoDefaultdevice;
mciSysinfoDefaultdevice.usDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
ulError = mciSendCommand( (USHORT) 0,
MCI_SYSINFO,
MCI_WAIT | MCI_SYSINFO_ITEM,
(PVOID) &mciSysinfoParms,
0);
if (ulError == 0L)
{
memset( &mciSysinfoParms , 0, sizeof(MCI_SYSINFO_PARMS));
memset( &mciSysinfoQueryName , 0, sizeof(MCI_SYSINFO_QUERY_NAME));
/*
* Set up parameters to query the device ordinal value. This message
* query the given device name which is in the szInstallName field of the
* MCI_SYSINFO_DEFAULTDEVICE structure and returns the ordinal value of
* the first device of that type. The pSysInfoParm field points to the
* MCI_SYSINFO_QUERY_NAME structure which has the default device name.
*/
mciSysinfoParms.ulItem = MCI_SYSINFO_QUERY_NAMES;
mciSysinfoParms.pSysInfoParm = &mciSysinfoQueryName;
memmove( &mciSysinfoQueryName.szInstallName,
&mciSysinfoDefaultdevice.szInstallName,
sizeof(mciSysinfoQueryName.szInstallName ) );
ulError = mciSendCommand( (USHORT) 0,
MCI_SYSINFO,
MCI_WAIT | MCI_SYSINFO_ITEM,
(PVOID) &mciSysinfoParms,
0);
if (ulError == 0L)
/*
* Get the device type ordinal value for further use.
*/
usDeviceTypeOpened = (USHORT)mciSysinfoQueryName.usDeviceOrd;
}
if (ulError)
ShowMCIErrorMessage(ulError);
return;
}
/******************************************************************************
* Name : FindTheDeviceCapability
*
* Description : This procedure will determine whether or not the audio
* device supports all of the items on the Type menu.
* If any of these options are not supported, they will be
* disabled.
*
* Concepts : - Find the capabilities of an audio device.
*
* MMPM/2 API's : mciSendCommand MCI_GETDEVCAPS
*
* Parameters : none
*
* Return : none
*
******************************************************************************/
VOID FindTheDeviceCapability( VOID )
{
ULONG ulRC; /* return code from api */
MCI_WAVE_GETDEVCAPS_PARMS mciAudioCaps; /* Dev Caps data structure */
memset( &mciAudioCaps , 0, sizeof(MCI_WAVE_GETDEVCAPS_PARMS));
/* Set up the fields of the mciAudioCaps structure to see if the
* device supports the different options on the Type menu of this
* sample program. These items include:
* Mono or Stereo, 11 kHz or 22 kHz or 44 kHz, and 8 bit or 16 bit.
* 12 different combinations are possible, so we will
* issue the query 12 times. If any of the options are not supported
* in ONE combination, we will disable that option on the Type menu.
* Play and Record will also be tested with this api, so we can disable
* the Play and Record pushbuttons if the device does not support the
* function.
*/
/* Test to see if the device can play 11 kHz, 8 bit, mono files. */
mciAudioCaps.ulBitsPerSample = 8;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 11025;
mciAudioCaps.ulChannels = 1;
mciAudioCaps.ulFormatMode = MCI_PLAY;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (8, 11025, 1, ulRC);
}
/* Test to see if the device can record 11 kHz, 16 bit, mono files. */
mciAudioCaps.ulBitsPerSample = 16;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 11025;
mciAudioCaps.ulChannels = 1;
mciAudioCaps.ulFormatMode = MCI_RECORD;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (16, 11025, 1, ulRC);
}
/* Test to see if the device can play 22 kHz, 8 bit, mono files. */
mciAudioCaps.ulBitsPerSample = 8;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 22050;
mciAudioCaps.ulChannels = 1;
mciAudioCaps.ulFormatMode = MCI_PLAY;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (8, 22050, 1, ulRC);
}
/* Test to see if the device can record 22 kHz, 16 bit, mono files. */
mciAudioCaps.ulBitsPerSample = 16;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 22050;
mciAudioCaps.ulChannels = 1;
mciAudioCaps.ulFormatMode = MCI_RECORD;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (16, 22050, 1, ulRC);
}
/* Test to see if the device can play 44 kHz, 8 bit, mono files. */
mciAudioCaps.ulBitsPerSample = 8;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 44100;
mciAudioCaps.ulChannels = 1;
mciAudioCaps.ulFormatMode = MCI_PLAY;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (8, 44100, 1, ulRC);
}
/* Test to see if the device can record 44 kHz, 16 bit, mono files. */
mciAudioCaps.ulBitsPerSample = 16;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 44100;
mciAudioCaps.ulChannels = 1;
mciAudioCaps.ulFormatMode = MCI_RECORD;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (16, 44100, 1, ulRC);
}
/* Test to see if the device can record 11 kHz, 8 bit, stereo files. */
mciAudioCaps.ulBitsPerSample = 8;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 11025;
mciAudioCaps.ulChannels = 2;
mciAudioCaps.ulFormatMode = MCI_RECORD;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (8, 11025, 2, ulRC);
}
/* Test to see if the device can support playing 11 kHz, 16 bit, stereo files. */
mciAudioCaps.ulBitsPerSample = 16;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 11025;
mciAudioCaps.ulChannels = 2;
mciAudioCaps.ulFormatMode = MCI_PLAY;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (16, 11025, 2, ulRC);
}
/* Test to see if the device can support recording 22 kHz, 8 bit, stereo files. */
mciAudioCaps.ulBitsPerSample = 8;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 22050;
mciAudioCaps.ulChannels = 2;
mciAudioCaps.ulFormatMode = MCI_RECORD;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (8, 22050, 2, ulRC);
}
/* Test to see if the device can play 22 kHz, 16 bit, stereo files. */
mciAudioCaps.ulBitsPerSample = 16;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 22050;
mciAudioCaps.ulChannels = 2;
mciAudioCaps.ulFormatMode = MCI_PLAY;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (16, 22050, 2, ulRC);
}
/* Test to see if the device can record 44 kHz, 8 bit, stereo files. */
mciAudioCaps.ulBitsPerSample = 8;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 44100;
mciAudioCaps.ulChannels = 2;
mciAudioCaps.ulFormatMode = MCI_RECORD;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (8, 44100, 2, ulRC);
}
/* Test to see if the device can play 44 kHz, 16 bit, stereo files. */
mciAudioCaps.ulBitsPerSample = 16;
mciAudioCaps.ulFormatTag = DATATYPE_WAVEFORM;
mciAudioCaps.ulSamplesPerSec = 44100;
mciAudioCaps.ulChannels = 2;
mciAudioCaps.ulFormatMode = MCI_PLAY;
mciAudioCaps.ulItem = MCI_GETDEVCAPS_WAVE_FORMAT;
ulRC = mciSendCommand (mciOpenParms.usDeviceID, /* Device ID */
MCI_GETDEVCAPS,
MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
| MCI_GETDEVCAPS_ITEM,
(PVOID) &mciAudioCaps,
0);
ulRC &= 0x0000FFFF;
if (ulRC != MCIERR_SUCCESS)
{
EvaluateReturnCode (16, 44100, 2, ulRC);
}
return;
}
/******************************************************************************
* Name : EvaluateReturnCode
*
* Description : This procedure will evaluate the return code from the
* mciSendCommand - MCI_GETDEVCAPS. It will disable the
* appropriate items on the Recorder's main window and on
* the Recorder's Type menu.
*
* Concepts : None
*
* MMPM/2 API's : None
*
* Parameters : ULONG ulBitsPerSample Either 8 or 16
* ULONG ulSampPerSec Either 11025, 22050, or 44100
* ULONG ulChannels Either 1 or 2
* ULONG ulRC Return code to evaluate
*
* Return : VOID
*
******************************************************************************/
VOID EvaluateReturnCode( ULONG ulBitsPerSample,
ULONG ulSampPerSec,
ULONG ulChannels,
ULONG ulRC)
{
/* The return code indicates unsupported samples per second value. */
if (ulRC == MCIERR_UNSUPP_SAMPLESPERSEC)
{
/* Samples per second value was 11.025 kHz */
if (ulSampPerSec == 11025)
{
/* Disable the "Voice" option on the Type menu */
DisableTheOption(
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_VOICE );
fVoiceSupported = FALSE;
}
else
/* Samples per second value was 22.050 kHz */
if (ulSampPerSec == 22050)
{
/* Disable the "Music" option on the Type menu */
DisableTheOption(
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_MUSIC );
fMusicSupported = FALSE;
}
else
/* Samples per second value was 44.100 kHz */
{
/* Disable the "High Fidelity" option on the Type menu */
DisableTheOption(
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_HIGH_FIDELITY );
fHiFiSupported = FALSE;
}
}
/* The return code indicates unsupported bits per sample value. */
if (ulRC == MCIERR_UNSUPP_BITSPERSAMPLE)
{
/* Samples per second value was 8 */
if (ulBitsPerSample == 8)
{
/* Disable the "Low quality" item on the Options menu. */
DisableTheOption(
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_LOW_QUALITY );
fLoQualitySupported = FALSE;
}
else
/* Samples per second value was 16 */
{
/* Disable the "High quality" item on the Options menu. */
DisableTheOption(
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_HIGH_QUALITY );
fHighQualitySupported = FALSE;
}
}
/* The return code indicates unsupported channels value. */
if (ulRC == MCIERR_UNSUPP_CHANNELS)
{
/* Stereo is not supported */
if (ulChannels == 2)
{
DeselectTheOption( IDM_STEREO ); /* Deselect the "Stereo" option*/
DisableTheOption(
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_STEREO );
SelectTheOption( IDM_MONO ); /* Select the "Mono" option */
usStereoMono = MONO; /* Set the usStereoMono to Mono*/
fStereoSupported = FALSE;
}
else /* Mono is not supported */
{
DeselectTheOption( IDM_MONO ); /* Deselect the "Stereo" option*/
DisableTheOption(
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_MONO );
SelectTheOption( IDM_STEREO ); /* Select the "Mono" option */
usStereoMono = STEREO; /* Set the usStereoMono to Mono*/
fMonoSupported = FALSE;
}
}
/* The return code indicates unsupported mode value. */
if (ulRC == MCIERR_UNSUPP_FORMAT_MODE)
{
/*
* If the device doesn't support either play or record,
* then do the following disables.
*/
WinEnableWindow (hwndPlayPB, FALSE); /* Disable the Play pushbutton. */
WinEnableWindow (hwndRecordPB, FALSE);/* Disable the Record pushbutton.*/
DisableTheOption( /* Disable the "New" option */
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_FILE_NEW );
DisableTheOption( /* Disable the "Save" option */
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_FILE_SAVE );
DisableTheOption( /* Disable the "Save as" option */
WinWindowFromID(
WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
IDM_FILE_SAVE_AS );
}
return;
}
/******************************************************************************
* Name : PlayTheAudio
*
* Description : This procedure will begin the playing of an audio file.
* It is invoked when the user selects the Play pushbutton
* on the Recorders main window.
*
* Concepts : Playing a audio file using the MCI interface.
*
* MMPM/2 API's : mciSendCommand MCI_PLAY
*
* Parameters : hwnd - Handle for the Main dialog box.
*
* Return : TRUE - if the operation was initiated without error.
* FALSE - if an error occurred.
*
******************************************************************************/
BOOL PlayTheAudio( HWND hwnd)
{
ULONG ulError; /* error value from mci calls */
MCI_PLAY_PARMS mciPlayParms; /* play parms for MCI_PLAY */
/*
* In this sample program we are always going to play the audio from the
* begining of the file.
*/
if (!SeekTheAudio( hwnd, MCI_TO_START ))
return( FALSE );
eState = ST_PLAYING; /* set state to PLAYING */
SetAudioVolume(hwnd); /* set the starting volume */
/*
* Initialize MCI_PLAY_PARMS structure with the pertinent information then
* issue an MCI_PLAY command via mciSendCommand. A MM_MCINOTIFY message
* will be sent to the window specified in hwndCallback field when the
* operation is completed. Since we want the whole audio file to be played,
* we won't specify flags MCI_FROM or MCI_TO.
*/
mciPlayParms.hwndCallback = hwnd; /* notify our window */
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_PLAY,
MCI_NOTIFY,
(PVOID) &mciPlayParms,
UP_PLAY);
if (ulError)
{
/*
* If we couldn't play - we need to display the error to the user, halt
* audio gracefully and get to stable, known state.
*/
ShowMCIErrorMessage( ulError);
eState = ST_STOPPED;
StopTheDevice(hwnd);
return ( FALSE );
}
return( TRUE );
} /* end of PlayTheAudio */
/******************************************************************************
* Name : RecordTheAudio
*
* Description : This procedure records an audio file. In order to do this
* it first configures the device settings (such as input level
* and input source) and file attributes (such as sample size
* and sample rate). Finally, it records the audio data. It is
* invoked when the user selects the record pushbutton from the
* Recorder's main window.
*
* Concepts : - Record an audio file using MCI interface.
* - Setup device and file for recording.
*
* MMPM/2 API's : mciSendCommand MCI_SET
* MCI_CONNECTION
* MCI_CONNECTOR
* MCI_RECORD
*
*
* Parameters : hwnd - Handle for the Main dialog box.
*
* Return : TRUE - if the operation was initiated without error.
* FALSE - if an error occurred.
******************************************************************************/
BOOL RecordTheAudio( HWND hwnd )
{
MCI_RECORD_PARMS mciRecordParms; /* for MCI_RECORD */
MCI_CONNECTOR_PARMS mciConnectorParms; /* for MCI_CONNECTOR */
MCI_WAVE_SET_PARMS mciWaveSetParms; /* for MCI_SET, waveform devices */
MCI_GENERIC_PARMS mciGenericParms; /* for MCI_ACQUIRE */
MCI_AMP_SET_PARMS mciAmpSetParms; /* for MCI_SET, amp/mix devices */
MCI_CONNECTION_PARMS mciConnectionParms; /* for MCI_CONNECTION */
USHORT usAmpMixerDeviceID; /* for amp/mix device ID */
LONG lmmioAPIRc; /* MMIO API return codes */
ULONG ulError; /* for error return code */
memset( &mciWaveSetParms, /* Object to fill with zeros. */
0, /* Value to place into the object. */
sizeof( mciWaveSetParms ) ); /* How many zero's to use. */
/*
* Set up parameters for the audio data file (such as stereo/mono, sample
* rate and sample size).
*
* First, initialize MCI_WAVE_SET_PARMS structure with the pertinent
* information then issue an MCI_SET command via mciSendCommand.
*/
mciWaveSetParms.usChannels = (USHORT) usStereoMono; /* specify MONO/STEREO*/
mciWaveSetParms.ulSamplesPerSec =
(ULONG) usQualityType; /* used for waveform */
mciWaveSetParms.usBitsPerSample = (USHORT) usBitType;/* bits per sample */
ulError =
mciSendCommand( mciOpenParms.usDeviceID,
MCI_SET,
MCI_WAIT | MCI_WAVE_SET_CHANNELS |
MCI_WAVE_SET_SAMPLESPERSEC |
MCI_WAVE_SET_BITSPERSAMPLE,
(PVOID) &mciWaveSetParms,
UP_SET );
if (ulError)
{
ShowMCIErrorMessage( ulError);
return( FALSE);
}
/*
* Initialize MCI_CONNECTOR_PARMS structure with zero's
*/
memset( &mciConnectorParms, /* Object to fill with zeros. */
0, /* Value to place into the object. */
sizeof( mciConnectorParms ) ); /* How many zero's to use. */
/*
* Set up input source - microphone or line in.
* initialize MCI_CONNECTOR_PARMS structure with the pertinent
* information then issue an MCI_CONNECTOR command via mciSendCommand.
*/
mciConnectorParms.ulConnectorType = usDeviceType; /* microphone/linein */
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_CONNECTOR,
MCI_WAIT | MCI_CONNECTOR_TYPE |
MCI_ENABLE_CONNECTOR,
(PVOID) &mciConnectorParms,
0 );
if (ulError)
{
ShowMCIErrorMessage( ulError);
return( FALSE);
}
/*
* Initialize MCI_CONNECTION_PARMS structure with zero's
*/
memset( &mciConnectionParms, /* Object to fill with zeros. */
0, /* Value to place into the object. */
sizeof( mciConnectionParms ) );/* How many zero's to use. */
/*
* Get the Amp/Mixer device ID.
*
* First, initialize MCI_CONNECTION_PARMS structure ulConnectorType with
* the MCI_WAVE_STREAM_CONNECTOR. The digital input or output for the
* waveform audio device is streamed to an Amp/Mixer device.
*/
mciConnectionParms.ulConnectorType = MCI_WAVE_STREAM_CONNECTOR;
/*
* Next, issue an MCI_CONNECTION command via mciSendCommand. This will
* return the Amp/Mixer device ID.
*/
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_CONNECTION,
MCI_WAIT | MCI_QUERY_CONNECTION |
MCI_CONNECTOR_TYPE,
(PVOID) &mciConnectionParms,
UP_CONNECTION );
if (ulError)
{
ShowMCIErrorMessage( ulError);
return( FALSE);
}
/*
* Amp/Mixer device ID is needed to control the "Monitor input" and the
* "Input level" off of the Options menu.
*/
usAmpMixerDeviceID = mciConnectionParms.usToDeviceID;
/*
* Initialize MCI_AMP_SET_PARMS structure with zero's
*/
memset( &mciAmpSetParms, /* Object to fill with zeros. */
0, /* Value to place into the object. */
sizeof( mciAmpSetParms ) ); /* How many zero's to use. */
/*
* Set the Monitor on if the user requested it.
*/
if ( fMonitor )
{
/*
* User selected the "Monitor input" item from the Options menu - turn
* the monitor ON.
* First, initialize MCI_AMP_SET_PARMS structure ulItem with
* MCI_AMP_SET_MONITOR. Using this in conjunction with the MCI_SET_ON
* flag will instruct the ampmix device to monitor the currently
* selected connector. This item is used to listen to (monitor) a
* source while it is being recorded.
*/
mciAmpSetParms.ulItem = MCI_AMP_SET_MONITOR;
/*
* Next, issue an MCI_SET command via mciSendCommand. This message will
* turn the monitor ON.
*/
ulError = mciSendCommand( usAmpMixerDeviceID,
MCI_SET,
MCI_WAIT | MCI_SET_ITEM | MCI_SET_ON,
(PVOID) &mciAmpSetParms,
UP_SETMONITOR );
}
else
{
/*
* User deselected the "Monitor input" item from the Options menu - turn
* the monitor OFF.
* First, initialize MCI_AMP_SET_PARMS structure ulItem with
* MCI_AMP_SET_MONITOR. Using this in conjunction with the MCI_SET_OFF
* flag will instruct the ampmix device to NOT to monitor the currently
* selected connector.
*/
mciAmpSetParms.ulItem = MCI_AMP_SET_MONITOR;
/*
* Next, issue an MCI_SET command via mciSendCommand. This message will
* turn the monitor OFF.
*/
ulError = mciSendCommand( usAmpMixerDeviceID,
MCI_SET,
MCI_WAIT | MCI_SET_ITEM | MCI_SET_OFF,
(PVOID) &mciAmpSetParms,
UP_SETMONITOR );
}
if (ulError)
{
ShowMCIErrorMessage( ulError);
return( FALSE);
}
/*
* Set the appropriate input level.
* Initialize MCI_AMP_SET_PARMS structure with the pertinent
* information then issue an MCI_SET command via mciSendCommand.
*/
mciAmpSetParms.ulAudio = MCI_SET_AUDIO_ALL; /* all the channels. */
mciAmpSetParms.ulLevel = (ULONG) usInputLevel; /* set audio level. */
ulError = mciSendCommand( usAmpMixerDeviceID,
MCI_SET,
MCI_WAIT | MCI_SET_AUDIO | MCI_AMP_SET_GAIN,
(PVOID) &mciAmpSetParms,
UP_SETAMP );
if (ulError)
{
ShowMCIErrorMessage( ulError);
return( FALSE);
}
/*
* Now all the setup is done - Ready to Record.
*
* First, initialize MCI_RECORD_PARMS structure with zero's
*/
memset( &mciRecordParms, /* Object to fill with zeros. */
0, /* Value to place into the object. */
sizeof( mciRecordParms ) ); /* How many zero's to use. */
/*
* Next, initialize MCI_RECORD_PARMS structure with the pertinent
* information then issue an MCI_RECORD command via mciSendCommand.
*/
mciRecordParms.hwndCallback = hwnd; /* notify main window */
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_RECORD,
MCI_NOTIFY | MCI_RECORD_OVERWRITE, /* flags */
(PVOID) &mciRecordParms,
UP_RECORD );
if (ulError)
{
ShowMCIErrorMessage( ulError );
StopTheDevice(hwnd);
return(FALSE);
}
else
{
fModified = TRUE;
eState = ST_RECORDING;
UpdateTheStatusLine(hwnd, IDS_RECORDING);
/*
* Start record button animation
*/
WinSendMsg ( hwndRecordPB, /* Record push button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(TRUE), /* Animation flag */
NULL ); /* Ignore return data */
}
return( TRUE );
} /* End of RecordTheAudio*/
/******************************************************************************
* Name : SeekTheAudio
*
* Description : This procedure will Seek to the specified position in
* an audio file.
*
* Concepts : Changing the current position in an audio file using the
* MCI interface.
*
* MMPM/2 API's : mciSendCommand MCI_SEEK
*
* Parameters : hwnd - Handle for the Main dialog box.
* ulPosition - seeking position.
*
* Return : TRUE - if the operation was initiated without error.
* FALSE - if an error occurred.
*
******************************************************************************/
BOOL SeekTheAudio(HWND hwnd, ULONG ulPosition )
{
MCI_SEEK_PARMS mciSeekParms; /* for MCI_SEEK */
ULONG ulError; /* return value for mci command */
BOOL bReturn = TRUE; /* function return value */
memset( &mciSeekParms, /* Object to fill with zeros. */
0, /* Value to place into the object. */
sizeof( mciSeekParms ) ); /* How many zero's to use. */
mciSeekParms.hwndCallback = hwnd;
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_SEEK,
MCI_WAIT | ulPosition,
(PVOID) &mciSeekParms,
UP_SEEK);
/*
* If the recorder is currently recording
*/
if (eState == ST_RECORDING)
{
/*
* Stop the record button animation
*/
WinSendMsg ( hwndRecordPB, /* Record push button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(FALSE), /* Animation flag */
NULL ); /* Ignore return data */
eState = ST_STOPPED; /* Set state to stopped */
}
/*
* If the recorder is currently playing
*/
else if (eState == ST_PLAYING)
{
/*
* Stop the play button animation
*/
WinSendMsg( hwndPlayPB, /* Play push button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(FALSE), /* Animation flag */
NULL ); /* Ignore return data */
eState = ST_STOPPED; /* Set state to stopped */
}
if (ulError) { /* If an error */
ShowMCIErrorMessage( ulError);
bReturn = FALSE;
}
/*
* Update the status line with appropriate message.
*/
UpdateTheStatusLine(hwnd, IDS_STOPPED);
return( bReturn );
} /* end of SeekTheAudio */
/******************************************************************************
* Name : StopTheDevice
*
* Description : This procedure will stop the device that is playing or
* recording.
*
* Concepts : Stopping a device using the MCI interface.
*
* MMPM/2 API's : mciSendCommand MCI_STOP
*
* Parameters : hwnd - Handle for the Main dialog box.
*
* Return : nothing.
*
******************************************************************************/
VOID StopTheDevice(HWND hwnd)
{
ULONG ulError; /* return value for mci command */
MCI_GENERIC_PARMS mciGenericParms; /* info data structure for cmd. */
/*
* To stop the device , we will issue an MCI_STOP command via mciSendCommand
* using an MCI_GENERIC_PARMS structure. This stop command is done for
* the device ID.
*/
mciGenericParms.hwndCallback = hwndMainDialogBox;
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_STOP,
MCI_WAIT,
(PVOID) &mciGenericParms,
UP_STOP);
if (ulError)
ShowMCIErrorMessage( ulError);
if (eState == ST_RECORDING)
{
/*
* Stop the record button animation
*/
WinSendMsg ( hwndRecordPB, /* Record push button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(FALSE), /* Animation flag */
NULL ); /* Ignore return data */
}
else
{
/*
* Stop the play button animation
*/
WinSendMsg( hwndPlayPB, /* Play push button handle */
GBM_ANIMATE, /* Animation control */
MPFROMSHORT(FALSE), /* Animation flag */
NULL ); /* Ignore return data */
}
/*
* Update the status line with appropriate message.
*/
UpdateTheStatusLine(hwnd, IDS_STOPPED);
eState = ST_STOPPED;
return;
} /* end of StopTheDevice */
/******************************************************************************
* Name : SaveTheAudio
*
* Description : This procedure will save the audio file that is currently
* loaded.
*
* Concepts : Save an audio file using MCI interface.
*
* MMPM/2 API's : mciSendCommand MCI_SAVE
*
* Parameters : hwnd - Handle for the Main dialog box.
*
* Return : nothing.
*
******************************************************************************/
VOID SaveTheAudio(HWND hwnd)
{
ULONG ulError; /* return value for mci command */
MCI_GENERIC_PARMS mciGenericParms; /* info data structure for cmd. */
MCI_SAVE_PARMS mciSaveParms;
/*
* Change pointer to a waiting pointer first, since this might take a
* couple of seconds.
*/
WinSetPointer ( HWND_DESKTOP, hptrWait );
/*
* Update the status line with appropriate message.
*/
UpdateTheStatusLine(hwnd, IDS_SAVINGFILE);
memset( &mciSaveParms, /* Object to fill with zeros. */
0, /* Value to place into the object. */
sizeof( mciSaveParms ) ); /* How many zero's to use. */
/*
* Initialize the MCI_SAVE_PARMS data structure with the pertinent
* information then issue an MCI_SAVE command via mciSendCommand
* to save the currently opened audio file.
*/
mciSaveParms.hwndCallback = hwnd;
mciSaveParms.pszFileName = (PSZ)szFileName; /* audio file to save */
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_SAVE,
MCI_WAIT | MCI_SAVE_FILE,
(PVOID) &mciSaveParms,
0 );
/*
* Change the pointer back to an arrow and update the status line with the
* appropriate message.
*/
WinSetPointer ( HWND_DESKTOP, hptrArrow );
UpdateTheStatusLine(hwnd, IDS_STOPPED);
if (ulError)
{
MessageBox( IDS_CANNOT_SAVE_FILE, /* ID of the message */
MB_OK | MB_ERROR | MB_MOVEABLE); /* style */
return;
}
/*
* Get the currently loaded file header information and check the correct
* options disable all the other option options in the Type menu pulldown.
*/
SetTheOptions(EXISTING_FILE);
/*
* File has been saved. Set the flags.
*/
fTempFileInUse = FALSE;
fModified = FALSE;
return;
}
/******************************************************************************
* Name : CloseTheDevice
*
* Description : This procedure will close the audio device.
*
* Concepts : Closing a device using MCI interface.
*
* MMPM/2 API's : mciSendCommand MCI_CLOSE
*
* Parameters : None.
*
* Return : nothing.
*
******************************************************************************/
VOID CloseTheDevice( VOID)
{
ULONG ulError; /* return value for mci command */
MCI_GENERIC_PARMS mciGenericParms; /* info data structure for cmd. */
/*
* Now, we close the device. This is done by issuing MCI_CLOSE command.
*/
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_CLOSE,
MCI_WAIT,
(PVOID) &mciGenericParms,
UP_CLOSE);
if (ulError)
ShowMCIErrorMessage( ulError);
mciOpenParms.usDeviceID = (USHORT) NULL;
return;
} /* end of CloseTheDevice */
/******************************************************************************
* Name : MessageBox
*
* Description : This procedure will display messages for the application
* based upon string IDs passed in. The actual text will be
* loaded from the string table in the resource.
*
* Concepts : None.
*
* MMPM/2 API's : None.
*
* Parameters : usMessageID - ID of the message string
* ulStyle - Style of the message box (WinMessageBox)
*
* Return : TRUE - if the operation was initiated without error.
* FALSE - if an error occurred.
*
******************************************************************************/
USHORT MessageBox( USHORT usMessageID, ULONG ulStyle)
{
CHAR achMessage[LEN_ERROR_MESSAGE];
USHORT usResult;
/*
* Get the string from the Resource defined string table and show it
* in the message box.
*/
WinLoadString(
hab, /* HAB for this dialog box. */
(HMODULE) NULL, /* Get the string from the .exe file. */
usMessageID, /* Which string to get. */
(SHORT) sizeof( achMessage), /* The size of the buffer. */
achMessage ); /* The buffer to place the string. */
usResult =
WinMessageBox(
HWND_DESKTOP, /* Parent handle of the message box. */
hwndMainDialogBox, /* Owner handle of the message box. */
achMessage, /* String to show in the message box. */
achMsgBoxTitle, /* Title to shown in the message box. */
(USHORT) ID_MESSAGEBOX, /* Message Box Id. */
ulStyle ); /* The style of the message box. */
return( usResult );
} /* End of MessageBox */
/******************************************************************************
* Name : ShowMCIErrorMessage
*
* Description : This window procedure displays an MCI error message
* based upon a ulError return code. The MCI function
* mciGetErrorString is used to convert the error code into
* a text string and the title is pulled from the resource
* based upon a string id.
*
* Concepts : Using mciGetErrorString to convert an error code into
* a textual message.
*
* MMPM/2 API's : mciGetErrorString
*
* Parameters : ulError - MCI error code.
*
* Return : nothing
*
******************************************************************************/
VOID ShowMCIErrorMessage( ULONG ulError)
{
CHAR achBuffer[LEN_ERROR_MESSAGE];
switch(mciGetErrorString( ulError, (PSZ)achBuffer, sizeof( achBuffer)))
{
case MCIERR_SUCCESS:
/*
* This is what we want. We were able to use mciGetErrorString to
* retrieve a textual error message we can show in a message box.
*/
WinMessageBox( HWND_DESKTOP,
hwndMainDialogBox,
achBuffer,
achMsgBoxTitle,
(USHORT) ID_MESSAGEBOX,
MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
break;
case MCIERR_INVALID_DEVICE_ID:
case MCIERR_OUTOFRANGE:
case MCIERR_INVALID_BUFFER:
default:
MessageBox( IDS_UNKNOWN,
MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
break;
}
return;
} /* end of ShowMCIErrorMessage */
/******************************************************************************
* Name : DoesFileExist
*
* Description : This helper function determines if a file with a given
* file name exists.
*
* Concepts : Using MMIO interface to access a data file.
*
* MMPM/2 API's : mmioOpen
* mmioClose
*
* Parameters : none
*
* Return : TRUE - if a file exists matching szFilename
* FALSE - if the file does not exist
*
******************************************************************************/
BOOL DoesFileExist( VOID )
{
BOOL bReturn; /* function return value */
HMMIO hFile; /* handle to file */
/*
* Notice that these MMIO functions are analogous to the standard
* C functions, fopen and fclose.
*/
hFile = mmioOpen( szFileName, (PMMIOINFO) NULL, MMIO_READ);
if (hFile != (HMMIO) NULL)
{
mmioClose( hFile, 0);
bReturn = TRUE;
}
else
bReturn = FALSE;
return( bReturn);
}
/******************************************************************************
* Name : SetAudioVolume
*
* Description : This helper function sets the audio file volume based upon
* the position of the volume slider. The slider will be
* queried and the audio file volume will be set.
*
* Concepts : Setting the volume of a device.
*
* MMPM/2 API's : mciSendCommand MCI_SET
*
* Parameters : hwnd - Handle for the Main dialog box.
*
* Return : nothing.
*
******************************************************************************/
VOID SetAudioVolume( HWND hwnd )
{
ULONG ulError; /* error value for mci returns */
MCI_WAVE_SET_PARMS mspSet; /* set values for volume, etc. */
if ((!fPassedDevice) && (eState==ST_PLAYING || eState==ST_RECORDING))
{
/*
* To set the volume, first, the MCI_SET_PARMS structure must be
* filled with the necessary values. Then an MCI_SET command
* should be issued to the device to perform the volume change.
*/
mspSet.hwndCallback = hwnd;
mspSet.ulAudio = MCI_SET_AUDIO_ALL; /* set all channels */
mspSet.ulLevel = (ULONG) sVolumeLevel; /* volume level desired */
ulError = mciSendCommand( mciOpenParms.usDeviceID,
MCI_SET,
MCI_NOTIFY | MCI_SET_AUDIO | MCI_SET_VOLUME,
(PVOID) &mspSet,
UP_VOLUME);
if (ulError)
ShowMCIErrorMessage( ulError);
}
return;
} /* end of SetAudioVolume */
/******************************************************************************
*
* Name : UpdateTitleText
*
* Description : Updates the text in the main window's title bar to
* display the app name, followed by the separator,
* followed by the file name.
*
* Concepts : none
*
* MMPM/2 API's: none
*
* Parameters : hwnd = Frame window handle
* pszFileName = filename to update the title bar
*
* Return : none
*
******************************************************************************/
VOID UpdateTitleText(HWND hwnd, PSZ pszFileName)
{
CHAR szBuffer[ /* To store the program name*/
MAXNAMEL+TITLESEPARATORLEN+CCHMAXPATH];/* + separator + file name */
CHAR szSeparator[TITLESEPARATORLEN+1]; /* To store the separator */
PCHAR pcFileName; /* Buffer for file name */
/*
* Load the program title into the szBuffer.
*/
WinLoadString(hab, (HMODULE)0, IDS_PROGRAM_TITLE, MAXNAMEL, szBuffer);
/*
* Load the title separator into the szSeparator.
*/
WinLoadString( hab,
(HMODULE)0,
IDS_TITLEBARSEPARATOR,
TITLESEPARATORLEN,
szSeparator);
/*
* pszFileName is the fully qualified file name. Parse it to get just
* the file name to display it on the title bar.
*/
pcFileName = strrchr(((PCHAR)pszFileName + 1), '\\');
if (!pcFileName)
pcFileName = pszFileName;
else
pcFileName++;
strcat(szBuffer, szSeparator);/* First append the separator to the title */
strcat(szBuffer, pcFileName); /* Next append the audio file name */
/*
* Display the title on the program title bar.
*/
WinSetWindowText(WinWindowFromID(hwnd, FID_TITLEBAR), szBuffer);
} /* End of UpdateTitleText */
/******************************************************************************
*
* Name : FileSaveAs
*
* Description : Processes the File menu's Save as item. Called whenever
* SAVE AS from the FILE menu is selected. Routine prompts the
* user for the name of the file, then saves the file.
*
* Concepts : None
*
* MMPM/2 API's : None
*
* Parameters : hwnd - Handle for the Main dialog box.
*
* Return : TRUE - if the operation was initiated without error.
* FALSE - if an error occurred.
*
*************************************************************************/
BOOL FileSaveAs(HWND hwnd)
{
USHORT usResult;
/*
* Display Save As Dialog box.
*/
if ( !ShowStandardFileDlg(IDM_FILE_SAVE_AS) )
{
return( FALSE );
}
/*
* if the selected file exists, ask if we want to overwrite it
*/
if ( DoesFileExist() )
{
usResult =
MessageBox( IDS_FILE_EXISTS, MB_QUERY | MB_OKCANCEL);
/*
* If the user wants to overwrite the file, call the SaveTheAudio routine.
*/
if( usResult == MBID_OK )
SaveTheAudio(hwnd);
/*
* If the user doesnot want to overwrite the file, put up the Save As
* dialog box again to enter a new name.
*/
else if ( usResult == MBID_CANCEL )
FileSaveAs(hwnd);
else
return( FALSE );
}
/*
* The selected file name does not exist in the path. Save the currently
* loaded file with the selected file name.
*/
else
SaveTheAudio(hwnd);
return( TRUE );
} /* End of FileSaveAs */
/******************************************************************************
* Name : ShowStandardFileDlg
*
* Description : Based upon the parameters passed in, show the user either
* the Open dialog box or the Save as dialog box.
*
* Concepts : None.
*
* MMPM/2 API's : None.
*
* Parameters : usSelection - Indicates which dlg to display-Open or Save as
*
* Return : TRUE - if the a file open is success.
* FALSE - if could not open the file.
*
******************************************************************************/
BOOL ShowStandardFileDlg( USHORT usSelection)
{
FILEDLG fileDialog; /* Open file dialog structure. */
CHAR szTitle[FILE_NAME_SIZE]; /* Application title. */
CHAR szButtonText[FILE_NAME_SIZE]; /* Save as dialog box button text. */
USHORT usResult = 0; /* To store return result. */
/*
* Initialize the structure
*/
memset( &fileDialog, /* Object to fill with zeros. */
0, /* Value to place into the object. */
sizeof(fileDialog)); /* How many zero's to use. */
fileDialog.cbSize = sizeof(FILEDLG);
fileDialog.pfnDlgProc = (PFNWP)OpenFileDlgProc;
fileDialog.ulUser = (ULONG) hwndMainDialogBox;
switch (usSelection)
{
case IDM_FILE_OPEN :
WinLoadString(hab,(HMODULE)0,IDS_FILEOPEN_TITLE,CCHMAXPATH,szTitle);
fileDialog.pszTitle = szTitle;
fileDialog.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_OPEN_DIALOG;
fileDialog.usDlgId = IDD_FILEWINDOW;
WinLoadString(hab, (HMODULE)0, IDS_FILEOPENEXT, CCHMAXPATH,
fileDialog.szFullFile);
break;
case IDM_FILE_SAVE_AS :
WinLoadString(hab, (HMODULE)0, IDS_SAVE_AS, CCHMAXPATH, szButtonText);
WinLoadString(hab,(HMODULE)0,IDS_FILESAVEAS_TITLE,CCHMAXPATH,szTitle);
fileDialog.pszTitle = szTitle;
fileDialog.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_SAVEAS_DIALOG;
fileDialog.usDlgId = FILESAVE;
fileDialog.pszOKButton = (PSZ) szButtonText;
break;
}
/*
*Call the standard file dialog to get the file
*/
usResult = WinFileDlg(HWND_DESKTOP, hwndMainDialogBox, &fileDialog);
if (usResult != 0)
{
if (fileDialog.lReturn == DID_OK)
{
/*
* initialize szFileName variable to get a new file name.
*/
memset( szFileName, 0, sizeof(szFileName ));
strncpy( (PCHAR)szFileName, fileDialog.szFullFile,
min( strlen( &fileDialog.szFullFile[0]),
CCHMAXPATH ));
}
else if (fileDialog.lReturn == DID_CANCEL)
{
return( FALSE );
}
}
return( TRUE );
}
/******************************************************************************
* Name : OpenFileDlgProc
*
* Description : This function displays the standard open dialog box.
* Concepts : None.
*
* MMPM/2 API's : None.
*
* Parameters : hwnd - Handle for the File dialog box.
* msg - Message received by the dialog box.
* mp1 - Parameter 1 for the just received message.
* mp2 - Parameter 2 for the just received message.
*
* Return : result of default processing.
******************************************************************************/
MRESULT EXPENTRY OpenFileDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
return WinDefFileDlgProc(hwnd, msg, mp1, mp2);
}
/******************************************************************************
* Name : SaveTheChanges
*
* Description : If the file has been modified, this function asks the user
* if he wants to save the changes or not.
*
* Concepts : none
*
* MMPM/2 API's : none
*
* Parameters : hwnd - Handle to the main dialog box.
*
* Return : TRUE - if changes saved or not saved .
* FALSE - if cancel out.
*************************************************************************/
USHORT SaveTheChanges( HWND hwnd )
{
USHORT usResult;
/*
* Display a message box asking the user to save the changes made to the
* audio file or not.
*/
usResult =
MessageBox( IDS_FILE_CHANGED,
MB_WARNING | MB_YESNOCANCEL | MB_MOVEABLE | MB_HELP);
if (usResult == MBID_YES)
{
/*
* User wants to save the changes made to the audio file. If the
* currently loaded file is a tempfile display Save as dialog box for
* the file name. Else call SaveTheAudio routine to save the audio file.
*/
if (fTempFileInUse)
FileSaveAs(hwnd);
else
SaveTheAudio(hwnd);
}
/*
* If the user does not want to save the changes made to the file set the
* flags.
*/
else if (usResult == MBID_NO)
{
fModified = FALSE;
fTempFileInUse = FALSE;
}
return( usResult );
}