Recording via the MCI

The VCL offers the TMediaPlayer component that serves the needs of common multimedia tasks.  However, there are times when it is prudent to use the MCI (Media Control Interface) directly.  Recording sounds is a good example of this.  Although the TMediaPlayer component is capable of recording, its functionality is severly limited.  Indeed, the MCI offers ways around these limitations.  The example below is a simple demonstration of using the MCI to record waveform data, then saving this data was a .wav file.

KEYWORDS: timeGetDevCaps(), timeSetEvent(), timeKillEvent().
 



 
//---------------------------------------------------------------------------

// in header...

    int MediaID;
    int MCIWavOpenNew();
    long int MCIWavRecordNew(int MediaID);
    long int MCIWavStop(int MediaID);
    long int MCIWavPlayRecording(int MediaID);
    long int MCIWavSave(int MediaID, AnsiString FileName);
    void __fastcall MMMcnotify(TMessage &Msg);

BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(MM_MCINOTIFY, TMessage, MMMcnotify)
END_MESSAGE_MAP(TForm)
 

//---------------------------------------------------------------------------

 


 

//---------------------------------------------------------------------------

#include <mmsystem.h>
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    MediaID = 0;
}
 

void __fastcall TForm1::MMMcnotify(TMessage &Msg)
{
    // perform special notification
    // processing here if needed
    TForm::Dispatch(&Msg);
}
 

// open the wave device for a new file
int TForm1::MCIWavOpenNew()
{
  MCI_OPEN_PARMS mciOp;

  // Specify the device type
  mciOp.lpstrDeviceType = "waveaudio";

  // Specify a new file using an empty string
  mciOp.lpstrElementName = "";

  // open MCI device
  long int result = mciSendCommand(0, MCI_OPEN, MCI_NOTIFY |
                                   MCI_OPEN_ELEMENT | MCI_OPEN_TYPE,
                                   (LPARAM)&mciOp);

  // result is zero if successful
  if (result == 0) return mciOp.wDeviceID;
  else return 0;
}
 

// start recording
long int TForm1::MCIWavRecordNew(int MediaID)
{
    MCI_RECORD_PARMS mciRp;

    // tell the MCI device to send callback messages
    // to this window procedure (MMMcnotify message handler)
    mciRp.dwCallback = MAKELONG(Handle, 0);
 
    // start recording
    long int result = mciSendCommand(MediaID, MCI_RECORD,
                                     MCI_NOTIFY, (LONG)&mciRp);

    // result is zero if successful
    if (result != 0)
        mciSendCommand(MediaID, MCI_CLOSE, 0, NULL);
    return result;
}
 

// this function will stop the recording process
long int TForm1::MCIWavStop(int MediaID)
{
    MCI_GENERIC_PARMS mciGp;
    long int result = mciSendCommand(MediaID, MCI_STOP,
                                     MCI_NOTIFY, (LONG)&mciGp);

    // result is zero if successful
    if (result != 0)
        mciSendCommand(MediaID, MCI_CLOSE, 0, NULL);
    return result;
}

// this will playback the recorded wave data
long int TForm1::MCIWavPlayRecording(int MediaID)
{
    MCI_PLAY_PARMS mciPp;
    mciPp.dwFrom = 0L;
    long int result = mciSendCommand(MediaID, MCI_PLAY, MCI_FROM |
                                     MCI_WAIT, (LONG)&mciPp);
    if (result != 0)
        mciSendCommand(MediaID, MCI_CLOSE, 0, NULL);
    return result;
}

// this will save the buffer to disk
long int TForm1::MCIWavSave(int MediaID, AnsiString FileName)
{
    MCI_SAVE_PARMS mciSp;
    mciSp.lpfilename = FileName.c_str();
    long int result = mciSendCommand(MediaID, MCI_SAVE,
                                     MCI_SAVE_FILE | MCI_WAIT,
                                     (LONG)&mciSp);
    if (result != 0)
        mciSendCommand(MediaID, MCI_CLOSE, 0, NULL);
    return result;
}
 
 

//---------------------------------------------------------------------------
// The following are methods demonstrating use of the above functions
//--------------------------------------------------------------------------- 
void __fastcall TForm1::RecordButtonClick(TObject *Sender)
{
    if (MediaID != 0) mciSendCommand(MediaID, MCI_CLOSE, 0, NULL);

    MediaID = MCIWavOpenNew();
    if (MediaID != 0)
    {
        long int result = MCIWavRecordNew(MediaID);
        if (result != 0) ShowMessage("Error Recording");
    }
    else ShowMessage("error opening");
}
 

void __fastcall TForm1::StopButtonClick(TObject *Sender)
{
    long int result = MCIWavStop(MediaID);
    if (result != 0) ShowMessage("Error Stopping");
}
 

void __fastcall TForm1::PlayButtonClick(TObject *Sender)
{
    if (MediaID != 0)
    {
        long int result = MCIWavPlayRecording(MediaID);
        if (result != 0) ShowMessage("Error Playing");
    }
    else ShowMessage("No device open");
}
 

void __fastcall TForm1::SaveButtonClick(TObject *Sender)
{
    if (MediaID != 0)
    {
        if (SaveDialog1->Execute())
        {
            long int result = MCIWavSave(MediaID, SaveDialog1->FileName);
            if (result != 0) ShowMessage("Error Saving");
        }
    }
    else ShowMessage("No device open");
}
 

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
    if (MediaID != 0) mciSendCommand(MediaID, MCI_CLOSE, 0, NULL);
}