Free Pascal
LAZARUS

Play music files

You can play music files (midi, wav, mp3...) by sending MCI command strings to the Media Control Interface (MCI) of Windows.

You send MCI command strings with the mciSendString function. The values passed and all return values are null-terminated strings, so your application must convert to or from this format.


Some MCI command strings

  • open MMFile alias SomeAlias
    Loads the multimedia file MMFile.
    When an "alias" is specified, this alias must be used in subsequent commands.
    Example:
       var MMFile: string;
      begin
        MMFile := 'C:\sounds\music.mid';
        mciSendString(PChar('open "' + MMFile + '" alias mySound'), nil, 0, 0);
  • play SomeAlias
    Plays a previously loaded file.
    Example:
    mciSendString(PChar('play mySound') , nil, 0, 0);
  • stop SomeAlias
    Stops playing a previously started sound file.
    Example:
    mciSendString(PChar('stop mySound'), nil, 0, 0);
  • status SomeAlias Request
    Request can be: length, position, or some other information.
    Example:
    mciSendString('status mySound length', PChar(S), Len, 0);

Project PlayMusic

For this project, create a folder FPlaz\PlayMusic, download PlayMusic.zip and unzip to this folder.

  1. Start Lazarus and open project PlayMusic.
  2. btnSelect opens a file dialog and lets you select a music file.
  3. After a click on btnStart, the MCI device is initialized.
    Next, the program checks if a file has been selected. If yes, then that file is opened and playback is started.
    The next part is optional: the length of the soundfile is retrieved and saved, and a timer is started.

    procedure TForm1.btnStartClick(Sender: TObject);
    var
      S: String;
    begin
      mciSendString('stop mySound', nil, 0, 0);
      mciSendString('close mySound', nil, 0, 0);
      if lblFile.Caption = '' then
        ShowMessage('Please, select a file')
      else begin
        mciSendString(PChar('open "' + lblFile.Caption + '" alias mySound'),
                      nil, 0, 0);
        mciSendString(PChar('play mySound') , nil, 0, 0);
        // This part is optional:
        // get length of sound
        mciSendString('status mySound length', Pchar(S), 255, 0);
        TryStrToInt(Pchar(S), SoundLen);
        Timer1.Enabled := True;
      end;

    Each time the timer fires, the actual position in the soundfile is retrieved and displayed in a TTrackBar component:

    // This part is optional:
    procedure TForm1.Timer1Timer(Sender: TObject);
    var
      S: String;
      SoundPos: integer;
    begin
      // get actual position in sound
      mciSendString('status mySound position', Pchar(S), 255, 0);
      if TryStrToInt(Pchar(S), SoundPos) then begin
        TrackBar1.Position := Round(100 * SoundPos/SoundLen);
        lblPos.Caption := IntToStr(TrackBar1.Position) + ' %';
      end;
      if Abs(SoundLen - SoundPos) < 5 then begin
        Timer1.Enabled := False;
        lblPos.Caption := '100 %';
      end;
    end;
  4. btnStop simply stops the playback:

    procedure TForm1.btnStopClick(Sender: TObject);
    begin
      mciSendString(PChar('stop mySound'), nil, 0, 0);
    end;