TMMPlayer - base class for Multimedia operations.
Version .95 beta
Author:	Kent Reisdorph, 75522,1174
	1418 N. Lloyd
	Aberdeen, SD
	605-225-2751, 605-225-3602
Copyright  1995 by Kent Reisdorph
All Rights Reserved

Hello,

Overview
TMMPlayer is a class for playing and (in the case of wave files) recording multimedia. I will not attempt to educate you on the uses of the MCI command structure but there are a couple of things you should be aware of. Your on-line help for Windows API can fill you in on the details.

What does it cost?
TMMPlayer is distributed as Charity Ware (although I don't like that term). What this means is that if you use it regularly and if you think it is worth something than please send me a contribution. If you are in a financial position that precludes your sending me real money than consider it free. I trust you will be fair with me.<g> 

Flags used in TMMPlayer
The WIN API function mciSendCommand requires flags as one parameter. All of the TMMPlayer member functions set default flags. The two flags to be familiar with are MCI_WAIT and MCI_NOTIFY.

MCI_WAIT specifies that Windows should wait until the mci action is completed before returning control to the application. This means that if you have a midi file several minutes long mci will not return control to the system while that file is playing. In the case of wave files this is sometimes desirable. In other cases such as midi playing, wave recording, etc. it is not. Use the MCI_WAIT only if you want mci to take control of the system while the command is being executed. If MCI_WAIT is not set then Windows executes the mci command and immediately returns control to the calling application. This is desirable, for instance, if you want to play a midi file in the background.

MCI_NOTIFY specifies that Windows should post the MM_MCINOTIFY message when the command is finished. You can handle this message in whatever way you see fit. The HWND that you pass to TMMPlayer in the constructor is the window that will receive this message.

MCI_NOTIFY is roughly equivalent to SND_ASYNC used in sndPlaySound. MCI_WAIT |
MCI_NOTIFY is equivalent to SND_SYNC. For this reason I have #defined two flags as follows:
	#define MM_ASYNC MCI_NOTIFY  // return immediately to the calling application
	#define MM_SYNC MCI_NOTIFY | MCI_WAIT // wait for the command to finish before returning to the app
It has been my experience that if you do not want to use MCI_WAIT then you should still pass MCI_NOTIFY even if you dont handle the MM_MCINOTIFY message. This is to prevent the flags from being set to NULL. I seem to recall negative results with the flags being set to NULL. Just a precaution.

The TMMPlayer::Play() command sets the default flags to MCI_WAIT | MCI_NOTIFY. If you dont want the MCI_WAIT behavior then you should call Play with, Play(MCI_NOTIFY);

Using TMMPlayer
The following example demonstrates the use of  TMMPlayer.
	
//construct object
TMMPlayer Player(HWindow);
//open a file
//only the filename is necessary as mci will choose the appropriate driver based on the extension
Player.Open("sound.wav");
//play with default flags
Player.Play();
//rewind
Player.Rewind();
//play again - the rewind is necessary for multiple playings of the same file
Player.Play();
//get the length of the file - default is milliseconds
DWORD length = Player.GetMediaLength();
DWORD pos = length/2;
//start at middle of file
Player.SetPosition(pos);
Player.Play();
//this is the same as above
Player.Play(pos, length);
//play first half
Player.Play(0, pos);
Player.Close();
//open for recording
Player.Open("","waveaudio");
//record for two seconds
Player.Record(0, 2000);
Player.Save("test.wav");
Player.Rewind();
Player.Play();

Member Functions
For the most part member functions can be easily figured out by reading the source code and comments. My apologies for not providing descriptions at this time.

Error Reporting
By default TMMPlayer reports errors in a message box. In addition nearly all member functions return 0 in the case of success or the MCI error code if an error occurred. Error reporting is handy for debugging but you may opt to handle errors in the calling app. Either way you can set error reporting on or off with SetErrorReporting(TRUE) or FALSE.

Example Program
I have provided an example program (RECORDER.IDE) with some disclaimers:

1. I use the example to test TMMPlayer as well as other techniques. A couple of the modules are a bit strange.<g> Many TMMPlayer functions are used in recorder.cpp.

2. Since it is an ongoing test program it is not bug free by any means. In particular the markers you can set do not function as they should.

3. The example uses many TMMPlayer functions and thus is not intended to be a simple, easy-to-follow program. See the above example for a simple example.

Known Shortcomings
1. Due to the diversity of mci devices the complexity of this class could be much worse than it is. The idea was to provide a basic functionality and let derived classes handle the specifics of avi video, midi, cd audio, etc. I will write the inherited classes as time and need dictate.

2. CD audio playback is possible but only the most basic sense. I have done very little testing regarding CD audio.

3. TMMPlayer should have a function to set the input level for recording wave files.

4. Waveform audio and Midi have low level functions that provide more flexibility than mciSendCommand provides. These functions could be used in classes dedicated to their use. This is not a shortcoming in TMMPlayer, but rather a fact to be aware of.

5. Documentation. I work on the documentation as time allows. I hope to provide complete descriptions of all member functions.

TMMPlayer - base class for Multimedia operations.
Version .95 beta
Author:	Kent Reisdorph, 75522,1174
	1418 N. Lloyd
	Aberdeen, SD
	605-225-2751, 605-225-3602
Copyright  1995 by Kent Reisdorph
All Rights Reserved

Header File
mmplayer.h

Description
TMMPlayer is a class that provides for playing of multimedia devices. It also allows for recording of wave files. Although TMMPlayer provides enough functionality to be used as-is for simple multimedia operations, it is expected that classes can be inherited from TMMPlayer to provide added functionality for the specifics of midi, avi video, animations, cd audio, etc.

Public constructors
form 1: TMMPlayer(HWND hWnd);
form 2: TMMPlayer(HWND hWnd, const char* device);
form 3: TMMPlayer::TMMPlayer(HWND hWnd, const char* filename, const char* device, DWORD flags);

form 1: Sets the data member hWindow to hWnd. 
form 2: Opens the particular device (device).
form 3: One step play constructor. Sets hWindow, opens the filename and plays the file. device parameter can be set to "". I havent tested this much. The device parameter is probably unnecessary as MCI will open the correct device based on the file extension anyway. This constructor approximates the Windows sndPlaySound() function.

Destructor
The destructor closes the file if it was left open.

Returns
Nearly all functions return an MCI error code on an error or 0 on success. The exceptions are the status and device capability functions which return the requested item. Also most functions return MCIERR_DEVICE_NOT_READY if the device is not open.

Public Member Functions by category

MCI Command Functions & Basic MM Functions
DWORD Open(const char* filename, const char* device = 0)
DWORD Open(const char* filename, const char* device, HWND parent, DWORD style);
DWORD Close();
DWORD Play(DWORD flags = MCI_NOTIFY | MCI_WAIT);
DWORD Play(const char* filename, DWORD flags = MCI_NOTIFY | MCI_WAIT);
DWORD Play(DWORD from, DWORD to, DWORD flags = MCI_NOTIFY | MCI_WAIT);
DWORD Record(DWORD flags = MCI_NOTIFY | MCI_RECORD_OVERWRITE, DWORD from = 0, DWORD to =0);
DWORD Save(const char* filename = 0, DWORD flags = MCI_SAVE_FILE | MCI_WAIT);
DWORD Load(const char* filename = 0, DWORD flags = MCI_LOAD_FILE | MCI_WAIT);
DWORD Delete(DWORD from = 0, DWORD to = 0);
DWORD Stop();
DWORD Seek(DWORD to = 0, DWORD flags = MCI_SEEK_TO_START);
DWORD Pause(DWORD flags = MCI_WAIT);
DWORD Resume();
DWORD Erase();
DWORD Rewind();
DWORD FastForward();
DWORD Cut(DWORD flags = 0);
DWORD Paste(DWORD flags = 0);
DWORD Copy(DWORD flags = MCI_WAIT);
Device Capability Functions
DWORD GetDeviceCaps(DWORD item);
BOOL	CanEject();
BOOL	CanPlay();
BOOL	CanRecord();
BOOL	CanSave();
BOOL	HasAudio();
BOOL	HasVideo();
BOOL	UsesFiles();
Device Status and Information Functions
DWORD GetStatusItem(DWORD item);
BOOL	IsOpen();
BOOL	IsReady();
DWORD IsMediaPresent();
DWORD GetSysInfoItem(DWORD item, char* info, int dev);
DWORD GetInfoItem(DWORD item, char* info);
DWORD GetDeviceName(char* name);
DWORD GetDeviceType();
DWORD GetFileName(char* info);
DWORD GetPosition();
DWORD GetLength();
DWORD GetMode();
DWORD GetTimeFormat();
DWORD GetVolume();
DWORD GetStatus();
MCI Set Functions
DWORD Set(DWORD flags, DWORD options = 0);
DWORD SetAudioOff();
DWORD SetAudioOn();
DWORD SetTimeFormat(DWORD format);
DWORD SetVideoOff();
DWORD SetVideoOn();
DWORD SetPosition(DWORD position);
Misc. Functions
void SetParent(HWND hWnd);
DWORD SetVolume(int volume);
DWORD SetVolume(int lvol, int rvol);
void SetErrorReporting(BOOL err);

Private Member Function
void ReportError(const char* title = "MultiMedia Error");

Private Data Members
HWND hWindow;
UINT DeviceID;
BOOL DeviceOpen;
UINT ErrorReporting;
char ErrMsg[255];
