unit fMetronome;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, ExtCtrls, Buttons, ActnList, ImgList, Spin,
  PianoPluginIntf;

type
  TfrmMetronome = class(TForm)
    Panel3: TPanel;
    Panel4: TPanel;
    lblStep: TLabel;
    lblSpeed: TLabel;
    StaticText2: TStaticText;
    StaticText4: TStaticText;
    TrackBar1: TTrackBar;
    ImageList1: TImageList;
    ActionList1: TActionList;
    actStart: TAction;
    actStop: TAction;
    actClose: TAction;
    actPause: TAction;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    BitBtn3: TBitBtn;
    BitBtn4: TBitBtn;
    Timer1: TTimer;
    SpinEdit1: TSpinEdit;
    Label1: TLabel;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Timer1Timer(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure actStopExecute(Sender: TObject);
    procedure actPauseExecute(Sender: TObject);
    procedure actStartExecute(Sender: TObject);
    procedure actCloseExecute(Sender: TObject);
  private
    procedure SendMidiEvent(Index, Total: Byte);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmMetronome: TfrmMetronome;

implementation

{$R *.dfm}

uses PianoPlugin;

procedure TfrmMetronome.SendMidiEvent(Index, Total: Byte);
var
  Event, Data1, Data2: Byte;
begin
  case index of
    0: begin // MIDI_PROGRAMCHANGE
        Event := $C9;
        Data1 := $00;
        Data2 := $00;
      end;
    1: begin // 38: Acoustic Snare
        Event := $99;
        Data1 := $26;
        Data2 := $50;
        Tag := Data1;
      end;
    2: begin // 44: Pedal Hi-Hat
        Event := $99;
        Data1 := $2C;
        Data2 := $50;
        Tag := Data1;
      end;
    3: begin
        Event := $99;
        Data1 := $2C;
        Data2 := $50;
        Tag := Data1;
      end;
    4: begin
        Event := $99;
        Data1 := $2C;
        Data2 := $50;
        Tag := Data1;
      end;
    5: begin // Last note off
        Event := $89;
        Data1 := Tag;
        Data2 := $40;
      end;
  end;
  SendMessage(HostHandle, WM_PLUGIN_MIDI,
    MakeLong(Event, MakeWord(Data1, Data2)),
    MakeLong(0, $FFFF));
end;

procedure TfrmMetronome.actCloseExecute(Sender: TObject);
begin
  Close;
end;

procedure TfrmMetronome.actPauseExecute(Sender: TObject);
begin
  Timer1.Enabled := False;
  SendMidiEvent(5, 0);
end;

procedure TfrmMetronome.actStartExecute(Sender: TObject);
begin
  Timer1.Enabled := True;
  TrackBar1Change(nil);
  SendMidiEvent(0, 0);
end;

procedure TfrmMetronome.actStopExecute(Sender: TObject);
begin
  Timer1.Tag := 0;
  Timer1.Enabled := False;
  SendMidiEvent(5, 0);
end;

procedure TfrmMetronome.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  actStop.Execute;
end;

procedure TfrmMetronome.Timer1Timer(Sender: TObject);
begin
  Timer1.Tag := Timer1.Tag + 1;
  if Timer1.Tag > SpinEdit1.Value then
    Timer1.Tag := 1;
  SendMidiEvent(5, 0);
  SendMidiEvent(Timer1.Tag, SpinEdit1.Value);
  lblStep.Caption := IntToStr(Timer1.Tag);
end;

procedure TfrmMetronome.TrackBar1Change(Sender: TObject);
begin
  lblSpeed.Caption := IntToStr(TrackBar1.Position);
  Timer1.Interval := 60000 div TrackBar1.Position;
end;

end.

