// Test application for TMidiFile
unit MidiTest;
interface
uses
Windows,
Messages,
SysUtils,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ExtCtrls,
Grids,
MidiFile,
MidiOut,
MidiType,
MidiScope;
type
TMidiPlayer = class(TForm)
OpenDialog1: TOpenDialog;
Button1: TButton;
Button3: TButton;
Button4: TButton;
MidiOutput1: TMidiOutput;
cmbInput: TComboBox;
MidiFile1: TMidiFile;
MidiScope1: TMidiScope;
Label3: TLabel;
edtBpm: TEdit;
Memo2: TMemo;
edtTime: TEdit;
Button2: TButton;
TrackGrid: TStringGrid;
TracksGrid: TStringGrid;
edtLength: TEdit;
procedure Button1Click(Sender: TObject);
procedure MidiFile1MidiEvent(event: PMidiEvent);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure cmbInputChange(Sender: TObject);
procedure MidiFile1UpdateEvent(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure edtBpmKeyPress(Sender: TObject; var Key: char);
procedure TracksGridSelectCell(Sender: TObject; Col, Row: integer;
var CanSelect: boolean);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
MidiOpened : boolean;
procedure SentAllNotesOff;
procedure MidiOpen;
procedure MidiClose;
public
{ Public declarations }
end;
var
MidiPlayer: TMidiPlayer;
implementation
{$R *.DFM}
procedure TMidiPlayer.Button1Click(Sender: TObject);
var
i, j: integer;
track: TMidiTrack;
event: PMidiEvent;
begin
if opendialog1.execute then
begin
midifile1.filename := opendialog1.filename;
midifile1.readfile;
// label1.caption := IntToStr(midifile1.NumberOfTracks);
edtBpm.text := IntToStr(midifile1.Bpm);
// TracksGrid.cells.clear;
for i := 0 to midifile1.NumberOfTracks-1 do
begin
track := midifile1.getTrack(i);
TracksGrid.cells[0,i] := 'Tr: '+ track.getName + ' '+ track.getInstrument ;
end;
edtLength.Text := MyTimeToStr(MidiFile1.GetTrackLength);
end;
end;
procedure TMidiPlayer.MidiFile1MidiEvent(event: PMidiEvent);
var
mEvent: TMyMidiEvent;
begin
mEvent := TMyMidiEvent.Create;
if not (event.event = $FF) then
begin
mEvent.MidiMessage := event.event;
mEvent.data1 := event.data1;
mEvent.data2 := event.data2;
midioutput1.PutMidiEvent(mEvent);
end
else
if (event.data1 >= 1) and (event.data1 < 15) then
memo2.Lines.add(IntToStr(event.data1) + ' '+ event.str);
midiScope1.MidiEvent(event.event,event.data1,event.data2);
mEvent.Destroy;
end;
procedure TMidiPlayer.SentAllNotesOff;
var
mEvent: TMyMidiEvent;
channel: integer;
begin
mEvent := TMyMidiEvent.Create;
for channel:= 0 to 15 do
begin
mEvent.MidiMessage := $B0 + channel;
mEvent.data1 := $78;
mEvent.data2 := 0;
if MidiOpened then
midioutput1.PutMidiEvent(mEvent);
midiScope1.MidiEvent(mEvent.MidiMessage,mEvent.data1,mEvent.data2);
end;
mEvent.Destroy;
end;
procedure TMidiPlayer.Button3Click(Sender: TObject);
begin
midifile1.StartPlaying;
end;
procedure TMidiPlayer.Button4Click(Sender: TObject);
begin
midifile1.StopPlaying;
SentAllNotesOff;
end;
procedure TMidiPlayer.MidiOpen;
begin
if not (cmbInput.Text = '') then
begin
MidiOutput1.ProductName := cmbInput.Text;
MidiOutput1.OPEN;
MidiOpened := true;
end;
end;
procedure TMidiPlayer.MidiClose;
begin
if MidiOpened then
begin
MidiOutput1.Close;
MidiOpened := false;
end;
end;
procedure TMidiPlayer.FormCreate(Sender: TObject);
var
thisDevice: integer;
begin
for thisDevice := 0 to MidiOutput1.NumDevs - 1 do
begin
MidiOutput1.DeviceID := thisDevice;
cmbInput.Items.Add(MidiOutput1.ProductName);
end;
cmbInput.ItemIndex := 0;
MidiOpened := false;
MidiOpen;
end;
procedure TMidiPlayer.cmbInputChange(Sender: TObject);
begin
MidiClose;
MidiOPen;
end;
procedure TMidiPlayer.MidiFile1UpdateEvent(Sender: TObject);
begin
edtTime.Text := MyTimeToStr(MidiFile1.GetCurrentTime);
edtTime.update;
if MidiFile1.ready then
begin
midifile1.StopPlaying;
SentAllNotesOff;
end;
end;
procedure TMidiPlayer.Button2Click(Sender: TObject);
begin
MidiFile1.ContinuePlaying;
end;
procedure TMidiPlayer.edtBpmKeyPress(Sender: TObject; var Key: char);
begin
if Key = char(13) then
begin
MidiFile1.Bpm := StrToInt(edtBpm.Text);
edtBpm.text := IntToStr(midifile1.Bpm);
abort;
end;
end;
procedure TMidiPlayer.TracksGridSelectCell(Sender: TObject; Col,
Row: integer; var CanSelect: boolean);
var
MidiTrack: TMidiTrack;
i, j: integer;
event: PMidiEvent;
begin
CanSelect := false;
if Row < MidiFile1.NumberOfTracks then
begin
CanSelect := true;
MidiTrack := MidiFile1.GetTrack(Row);
TrackGrid.RowCount := 2;
TrackGrid.RowCount := MidiTrack.getEventCount;
j := 1;
for i := 0 to MidiTrack.GetEventCount-1 do
begin
event := MidiTrack.getEvent(i);
if not (event.len = -1) then
begin // do not print when
TrackGrid.cells[0,j] := IntToStr(i);
TrackGrid.cells[1,j] := MyTimeToStr(event.time);
TrackGrid.cells[2,j] := IntToHex(event.event,2);
if not (event.event = $FF) then
begin
TrackGrid.cells[3,j] := IntToStr(event.len);
TrackGrid.cells[4,j] := KeyToStr(event.data1);
TrackGrid.cells[5,j] := IntToStr(event.data2);
end
else
begin
TrackGrid.cells[3,j] := IntToStr(event.data1);
TrackGrid.cells[4,j] := '';
TrackGrid.cells[5,j] := event.str;
end;
inc(j);
end;
end;
TrackGrid.RowCount := j;
end;
end;
procedure TMidiPlayer.FormShow(Sender: TObject);
begin
TrackGrid.ColWidths[0] := 30;
TrackGrid.ColWidths[2] := 30;
TrackGrid.ColWidths[3] := 30;
TrackGrid.ColWidths[4] := 30;
TrackGrid.ColWidths[5] := 100;
end;
end.