unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  PatternEditor, Menus, ComCtrls, ToolWin, ExtCtrls, SoundEnginePlayer,
  StdCtrls, PatternOrderEditor, Grids, Globals, Spin, Registry, Synth;

type
   TPatternThread=CLASS(Classes.TThread)
      PRIVATE
       Track:TTrack;
      PROTECTED
       PROCEDURE Execute; OVERRIDE;
      PUBLIC
       CONSTRUCTOR Create(CreateSuspended:BOOLEAN;ATrack:TTrack);
       DESTRUCTOR Destroy; OVERRIDE;
       PROCEDURE DoThat;
      END;
      
  TMainForm = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    TopPanel: TPanel;
    StatusBar: TStatusBar;
    PatternPanel: TPanel;
    PatternEditorPanel: TPanel;
    ChannelScrollBar: TScrollBar;
    RowScrollBar: TScrollBar;
    PatternOrderPanel: TPanel;
    ChannelsGroupBox: TGroupBox;
    InstrumentListBox: TListBox;
    InstrumentEditButton: TButton;
    InstrumentLoadButton: TButton;
    InstrumentSaveButton: TButton;
    New1: TMenuItem;
    Open1: TMenuItem;
    Saveas1: TMenuItem;
    N1: TMenuItem;
    Exit1: TMenuItem;
    CopyrightC2004BenjaminRosseaux1: TMenuItem;
    Player1: TMenuItem;
    Play1: TMenuItem;
    PlayPattern1: TMenuItem;
    Playat1: TMenuItem;
    Stop1: TMenuItem;
    OpenDialog: TOpenDialog;
    PatternGroupBox: TGroupBox;
    RowHighlightMinorLabel: TLabel;
    RowHighlightMajorLabel: TLabel;
    RowHighlightMinorEdit: TSpinEdit;
    RowHighlightMajorEdit: TSpinEdit;
    OctaveLabel: TLabel;
    OctaveEdit: TSpinEdit;
    LeftChipKeyboardPanel: TPanel;
    KeyboardRadioGroup: TRadioGroup;
    SaveDialog: TSaveDialog;
    InstrumentOpenDialog: TOpenDialog;
    InstrumentSaveDialog: TSaveDialog;
    InstrumentClearButton: TButton;
    MarkAllButton: TButton;
    UnmarkAllButton: TButton;
    ClearButton: TButton;
    OscilPanel: TPanel;
    OscilImage: TImage;
    N2: TMenuItem;
    ExportasWAV1: TMenuItem;
    WAVSaveDialog: TSaveDialog;
    Normalexport1: TMenuItem;
    Loopexport1: TMenuItem;
    ExportasB4M1: TMenuItem;
    B4MSaveDialog: TSaveDialog;
    SpaceRightPanel: TPanel;
    GroupBoxSongName: TGroupBox;
    EditSongName: TEdit;
    GroupBoxSongMessage: TGroupBox;
    MemoSongMessage: TMemo;
    GroupBoxSongAuthor: TGroupBox;
    EditSongAuthor: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure RowScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode;
      var ScrollPos: Integer);
    procedure ChannelScrollBarScroll(Sender: TObject;
      ScrollCode: TScrollCode; var ScrollPos: Integer);
    procedure ChannelScrollBarChange(Sender: TObject);
    procedure RowScrollBarChange(Sender: TObject);
    procedure InstrumentListBoxDrawItem(Control: TWinControl;
      Index: Integer; Rect: TRect; State: TOwnerDrawState);
    procedure InstrumentListBoxClick(Sender: TObject);
    procedure InstrumentEditButtonClick(Sender: TObject);
    procedure ChipEmulationModeRadioGroupClick(Sender: TObject);
    procedure Exit1Click(Sender: TObject);
    procedure New1Click(Sender: TObject);
    procedure Play1Click(Sender: TObject);
    procedure Stop1Click(Sender: TObject);
    procedure Open1Click(Sender: TObject);
    procedure OctaveEditChange(Sender: TObject);
    procedure RowHighlightMinorEditChange(Sender: TObject);
    procedure RowHighlightMajorEditChange(Sender: TObject);
    procedure KeyboardRadioGroupClick(Sender: TObject);
    procedure Saveas1Click(Sender: TObject);
    procedure Playat1Click(Sender: TObject);
    procedure PlayPattern1Click(Sender: TObject);
    procedure InstrumentLoadButtonClick(Sender: TObject);
    procedure InstrumentSaveButtonClick(Sender: TObject);
    procedure InstrumentClearButtonClick(Sender: TObject);
    procedure UnmarkAllButtonClick(Sender: TObject);
    procedure MarkAllButtonClick(Sender: TObject);
    procedure ClearButtonClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Normalexport1Click(Sender: TObject);
    procedure Loopexport1Click(Sender: TObject);
    procedure ExportasB4M1Click(Sender: TObject);
    procedure EditSongNameChange(Sender: TObject);
    procedure MemoSongMessageChange(Sender: TObject);
    procedure EditSongAuthorChange(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    Track:TTrack;
    PatternEditor:TPatternEditor;
    PatternOrderEditor:TPatternOrderEditor;
    PatternEditorMemory:TPatternEditorMemoryRows;
    PatternMemory:TPattern;
    PatternMemoryOk:BOOLEAN;
    PatternThread:TPatternThread;
    procedure DataChange;
    procedure DataUpdate;
  end;

var
  MainForm: TMainForm;

implementation

uses InstrumentEditor,Oscil, ExportStatus;

{$R *.DFM}

CONSTRUCTOR TPatternThread.Create(CreateSuspended:BOOLEAN;ATrack:TTrack);
BEGIN
 INHERITED Create(TRUE);
 Priority:=Classes.tpNormal;
 Track:=ATrack;
 IF NOT CreateSuspended THEN Resume;
END;

DESTRUCTOR TPatternThread.Destroy;
BEGIN
 INHERITED Destroy;
END;

PROCEDURE TPatternThread.Execute;
BEGIN
 IF ASSIGNED(Track) THEN BEGIN
  WHILE NOT Terminated DO BEGIN
   IF Track.Playing THEN BEGIN
   END;
   Synchronize(DoThat);
   SLEEP(25);
  END;
 END;
END;

PROCEDURE TPatternThread.DoThat;
BEGIN
 WITH MainForm DO BEGIN
  IF Track.Playing THEN BEGIN
   IF PatternOrderEditor.Col<>Track.CurrentPatternOrder THEN BEGIN
    PatternOrderEditor.Col:=Track.CurrentPatternOrder;
    PatternOrderEditor.Invalidate;
   END;
   IF PatternEditor.AktZeile<>Track.CurrentRow THEN BEGIN
    PatternEditor.AktZeile:=Track.CurrentRow;
    PatternEditor.Invalidate;
    RowScrollBar.Position:=Track.CurrentRow;
    RowScrollBar.Invalidate;
   END;
  END;
  DoOscil(MainForm.OscilImage.Canvas.Handle);
  MainForm.OscilImage.Refresh;
 END;
END;

procedure TMainForm.FormCreate(Sender: TObject);
VAR I:INTEGER;
    Reg:TRegIniFile;
begin
 InstrumentListBox.DoubleBuffered:=FALSE;
 InstrumentListBox.Clear;
 InstrumentListBox.Items.BeginUpdate;
 FOR I:=1 TO 16 DO InstrumentListBox.Items.Add('');
 InstrumentListBox.Items.EndUpdate;
 Track:=TTrack.Create(TRUE,44100);
 Track.ConvertOldEffects:=LOWERCASE(PARAMSTR(1))='convertoldeffects';
 PatternEditor:=TPatternEditor.Create(SELF);
 PatternEditor.Parent:=PatternEditorPanel;
 PatternEditor.Align:=alClient;
 PatternEditor.Form:=SELF;
 PatternEditor.Track:=Track;
 PatternEditor.AktPattern:=0;
 PatternEditor.RowScroll:=RowScrollBar;
 PatternEditor.ChannelScroll:=ChannelScrollBar;
 PatternOrderEditor:=TPatternOrderEditor.Create(SELF);
 PatternOrderEditor.ParentWindow:=PatternOrderPanel.Handle;
 PatternOrderEditor.Parent:=PatternOrderPanel;
 PatternOrderEditor.Align:=alClient;
 PatternOrderEditor.Track:=Track;
 PatternOrderEditor.Form:=SELF;
 PatternOrderEditor.FixedRows:=0;
 PatternOrderEditor.FixedCols:=0;
 PatternOrderEditor.RowCount:=1;
 PatternOrderEditor.ColCount:=256;
 PatternOrderEditor.DefaultColWidth:=24;
 PatternOrderEditor.DefaultRowHeight:=24;
 PatternOrderEditor.ScrollBars:=ssHorizontal;
 PatternOrderEditor.Col:=0;
 PatternOrderEditor.Options:=PatternOrderEditor.Options+[goDrawFocusSelected];
 PatternOrderEditor.Options:=PatternOrderEditor.Options-[goRangeSelect];
 PatternOrderEditor.Aktualisieren;
 PatternMemoryOk:=FALSE;
 RowScrollBar.Min:=0;
 RowScrollBar.Max:=63;
 ChannelScrollBar.Min:=0;
 ChannelScrollBar.Max:=15;
 TheSynthData:=@Track.SynthData;
 InitOscil(OscilImage.Canvas.Handle,OscilImage.Width,OscilImage.Height);
 ClearOscil(OscilImage.Canvas.Handle);
 PatternThread:=TPatternThread.Create(TRUE,Track);
 Track.Play;
 Track.Stop;
 Reg:=TRegIniFile.Create;
 Reg.RootKey:=HKEY_CURRENT_USER;
 IF Reg.OpenKey('\Software\Benjamin Rosseaux\T0AST',TRUE) THEN BEGIN
  KeyboardRadioGroup.ItemIndex:=Reg.ReadInteger('keyboard','type',0);
 END;
 Reg.Destroy;
 KeyboardType:=KeyboardRadioGroup.ItemIndex;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
 PatternThread.Terminate;
 PatternThread.WaitFor;
 PatternThread.Destroy;
 UnInitOscil;
 PatternOrderEditor.Destroy;
 PatternEditor.Destroy;
 Track.HardTerminate;
 Track.Destroy;
end;

procedure TMainForm.FormShow(Sender: TObject);
begin
 Track.Stop;
 Track.Resume;
 PatternThread.Resume;
 ActiveControl:=PatternEditor;
 InstrumentListBox.ItemIndex:=0;
 DataChange;
end;

procedure TMainForm.RowScrollBarScroll(Sender: TObject;
  ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
 IF ScrollCode=scEndScroll THEN ActiveControl:=PatternEditor;
end;

procedure TMainForm.ChannelScrollBarScroll(Sender: TObject;
  ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
 IF ScrollCode=scEndScroll THEN ActiveControl:=PatternEditor;
end;

procedure TMainForm.ChannelScrollBarChange(Sender: TObject);
begin
 IF ASSIGNED(PatternEditor) THEN BEGIN
  PatternEditor.AktSichtKanal:=ChannelScrollBar.Position;
  PatternEditor.Invalidate;
 END;
end;

procedure TMainForm.RowScrollBarChange(Sender: TObject);
begin
 IF NOT (Track.Playing AND Track.FollowSong) THEN BEGIN
  PatternEditor.AktZeile:=RowScrollBar.Position;
  PatternEditor.Invalidate;
 END;
end;

procedure TMainForm.InstrumentListBoxDrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
VAR S:STRING;
begin
 WITH (Control AS TListBox).Canvas DO BEGIN
  IF ASSIGNED(Track) THEN BEGIN
   FillRect(Rect);
   IF Index<255 THEN BEGIN
    S:=INTTOSTR(Index+1)+'. '+TRIMRIGHT(Track.Instruments[Index].Name);
   END;
   TextOut(Rect.Left+2,Rect.Top,S);
  END;
 END;
end;

procedure TMainForm.InstrumentListBoxClick(Sender: TObject);
begin
 PatternEditor.CurrentInstrument:=InstrumentListBox.ItemIndex+1;
end;

procedure TMainForm.InstrumentEditButtonClick(Sender: TObject);
var FileData:TSynthFileData;
    ADSRData:TSynthADSRData;
begin
 Track.Enter;
 Track.Playing:=FALSE;
 Track.Stop;
 Track.Leave;
 InstrumentEditorForm.OK:=FALSE;
 InstrumentEditorForm.Track:=Track;
 FileData:=Track.SynthData.FileData;
 ADSRData:=Track.SynthData.ADSRData;
 InstrumentEditorForm.Nr:=InstrumentListBox.ItemIndex;
 InstrumentEditorForm.SetInstrument(Track.Instruments[InstrumentListBox.ItemIndex AND $F]);
 InstrumentEditorForm.ShowModal;
 IF InstrumentEditorForm.OK THEN BEGIN
  Track.Instruments[InstrumentListBox.ItemIndex AND $F]:=InstrumentEditorForm.Instrument;
  InstrumentListBox.Invalidate;
 END ELSE BEGIN
  Track.SynthData.FileData:=FileData;
  Track.SynthData.ADSRData:=ADSRData;
 END;
 Track.Enter;
 Track.Play;
 Track.Stop;
 Track.Leave;
end;

procedure TMainForm.ChipEmulationModeRadioGroupClick(Sender: TObject);
begin
 PatternEditor.AktKanal:=0;
 PatternEditor.AktSichtKanal:=0;
 PatternEditor.Markierung:=FALSE;
 PatternEditor.Invalidate;
 DataUpdate;
end;

procedure TMainForm.Exit1Click(Sender: TObject);
begin
 Close;
end;

procedure TMainForm.DataChange;
begin
 InstrumentListBox.ItemIndex:=0;
 RowHighlightMinorEdit.Value:=Track.RowHilightMinor;
 RowHighlightMajorEdit.Value:=Track.RowHilightMajor;
 EditSongName.Text:=Track.SongName;
 EditSongAuthor.Text:=Track.SongAuthor;
 MemoSongMessage.Text:=Track.SongMessage;
 DataUpdate;
 InstrumentListBox.Invalidate;
 PatternOrderEditor.Col:=0;
 PatternEditor.AktZeile:=0;
 PatternEditor.AktKanal:=0;
 PatternEditor.AktSichtKanal:=0;
 PatternOrderEditor.Invalidate;
 PatternEditor.Markierung:=FALSE;
 PatternEditor.ClearMemory;
 PatternEditor.Invalidate;
end;

procedure TMainForm.DataUpdate;
begin
 Track.Enter;
 Track.DataUpdate;
 Track.Leave;
 PatternOrderEditor.Invalidate;
 PatternEditor.Invalidate;
end;

procedure TMainForm.New1Click(Sender: TObject);
begin
 Track.Enter;
 Track.Playing:=FALSE;
 Track.Stop;
 Track.Leave;
 Track.Enter;
 Track.Clear;
 Track.Changed:=TRUE;
 Track.Leave;
 DataChange;
 PatternOrderEditor.Col:=0;
 PatternOrderEditor.Change;
 PatternEditor.AktZeile:=0;
 PatternOrderEditor.Invalidate;
 PatternEditor.Markierung:=FALSE;
 PatternEditor.Invalidate;
 InstrumentListBox.Invalidate;
 EditSongName.Text:=Track.SongName;
 EditSongAuthor.Text:=Track.SongAuthor;
 MemoSongMessage.Text:=Track.SongMessage;
end;

procedure TMainForm.Play1Click(Sender: TObject);
begin
 Track.Enter;
 Track.Playing:=TRUE;
 Track.Play;
 Track.Leave;
 PatternOrderEditor.Invalidate;
 PatternEditor.Markierung:=FALSE;
 PatternEditor.Invalidate;
end;

procedure TMainForm.Stop1Click(Sender: TObject);
begin
 Track.Enter;
 Track.Playing:=FALSE;
 Track.Stop;
 Track.Leave;
 PatternOrderEditor.Invalidate;
 PatternEditor.Markierung:=FALSE;
 PatternEditor.Invalidate;
end;

procedure TMainForm.Open1Click(Sender: TObject);
begin
 Track.Enter;
 Track.Playing:=FALSE;
 Track.Stop;
 Track.Leave;
 OpenDialog.FileName:='';
 IF OpenDialog.Execute THEN BEGIN
  Track.Enter;
  Track.LoadFile(OpenDialog.FileName);
  Track.Leave;
 END;
 Track.Enter;
 Track.Play;
 Track.Stop;
 Track.Leave;
 DataChange;
 Track.Enter;
 Track.Changed:=FALSE;
 Track.Leave;
 PatternOrderEditor.Col:=0;
 PatternOrderEditor.Change;
 PatternEditor.AktZeile:=0;
 PatternOrderEditor.Invalidate;
 PatternEditor.Markierung:=FALSE;
 PatternEditor.Invalidate;
 InstrumentListBox.Invalidate;
 EditSongName.Text:=Track.SongName;
 EditSongAuthor.Text:=Track.SongAuthor;
 MemoSongMessage.Text:=Track.SongMessage;
end;

procedure TMainForm.OctaveEditChange(Sender: TObject);
begin
 PatternEditor.CurrentOctave:=OctaveEdit.Value;
end;

procedure TMainForm.RowHighlightMinorEditChange(Sender: TObject);
begin
 IF Track.RowHilightMinor<>RowHighlightMinorEdit.Value THEN BEGIN
  Track.Enter;
  Track.RowHilightMinor:=RowHighlightMinorEdit.Value;
  Track.Changed:=TRUE;
  Track.Leave;
  PatternEditor.Invalidate;
 END;
end;

procedure TMainForm.RowHighlightMajorEditChange(Sender: TObject);
begin
 IF Track.RowHilightMajor<>RowHighlightMajorEdit.Value THEN BEGIN
  Track.Enter;
  Track.RowHilightMajor:=RowHighlightMajorEdit.Value;
  Track.Changed:=TRUE;
  Track.Leave;
  PatternEditor.Invalidate;
 END;
end;

procedure TMainForm.KeyboardRadioGroupClick(Sender: TObject);
VAR Reg:TRegIniFile;
begin
 Reg:=TRegIniFile.Create;
 Reg.RootKey:=HKEY_CURRENT_USER;
 IF Reg.OpenKey('\Software\Benjamin Rosseaux\T0AST',TRUE) THEN BEGIN
  Reg.WriteInteger('keyboard','type',KeyboardRadioGroup.ItemIndex);
 END;
 Reg.Destroy;
 KeyboardType:=KeyboardRadioGroup.ItemIndex;
end;

procedure TMainForm.Saveas1Click(Sender: TObject);
begin
 SaveDialog.FileName:='';
 IF SaveDialog.Execute THEN BEGIN
  Track.Enter;
  Track.SaveFile(SaveDialog.FileName);
  Track.Leave;
 END;
end;

procedure TMainForm.Playat1Click(Sender: TObject);
VAR PatternOrder,Row:BYTE;
begin
 PatternOrder:=PatternOrderEditor.Col;
 Row:=PatternEditor.AktZeile;
 Track.Enter;
 Track.Playing:=TRUE;
 Track.Play;
 Track.CurrentPatternOrder:=PatternOrder;
 Track.CurrentRow:=Row;
 Track.NextPatternOrder:=PatternOrder;
 Track.NextRow:=Row;
 Track.Leave;
 PatternOrderEditor.Invalidate;
 PatternEditor.Markierung:=FALSE;
 PatternEditor.Invalidate;
end;

procedure TMainForm.PlayPattern1Click(Sender: TObject);
VAR PatternOrder:BYTE;
begin
 PatternOrder:=PatternOrderEditor.Col;
 Track.Enter;
 Track.Playing:=TRUE;
 Track.Play;
 Track.CurrentPatternOrder:=PatternOrder;
 Track.CurrentRow:=0;
 Track.NextPatternOrder:=PatternOrder;
 Track.NextRow:=0;
 Track.FixedPattern:=TRUE;
 Track.Leave;
 PatternOrderEditor.Invalidate;
 PatternEditor.Markierung:=FALSE;
 PatternEditor.Invalidate;
end;

procedure TMainForm.InstrumentLoadButtonClick(Sender: TObject);
begin
 InstrumentOpenDialog.FileName:='';
 IF InstrumentOpenDialog.Execute THEN BEGIN
  Track.Enter;
  Track.Playing:=FALSE;
  Track.Stop;
  Track.LoadInstrumentFile(PatternEditor.CurrentInstrument,InstrumentOpenDialog.FileName);
  Track.Play;
  Track.Stop;
  Track.Leave;
  InstrumentListBox.Invalidate;
 END;
end;

procedure TMainForm.InstrumentSaveButtonClick(Sender: TObject);
begin
 InstrumentSaveDialog.FileName:='';
 IF InstrumentSaveDialog.Execute THEN BEGIN
  Track.Enter;
  Track.SaveInstrumentFile(PatternEditor.CurrentInstrument,InstrumentSaveDialog.FileName);
  Track.Leave;
 END;
end;

procedure TMainForm.InstrumentClearButtonClick(Sender: TObject);
begin
 Track.Enter;
 Track.Playing:=FALSE;
 Track.Stop;
 FILLCHAR(Track.Instruments[PatternEditor.CurrentInstrument],SIZEOF(TInstrument),#0);
 Track.Play;
 Track.Stop;
 Track.Leave;
 InstrumentListBox.Invalidate;
end;

procedure TMainForm.MarkAllButtonClick(Sender: TObject);
begin
 PatternEditor.Markierung:=TRUE;
 PatternEditor.MarkStartZeile:=0;
 PatternEditor.MarkEndeZeile:=63;
 PatternEditor.MarkStartKanal:=0;
 PatternEditor.MarkEndeKanal:=Track.CountOfChannels-1;
 PatternEditor.Invalidate;
end;

procedure TMainForm.UnmarkAllButtonClick(Sender: TObject);
begin
 PatternEditor.Markierung:=FALSE;
 PatternEditor.Invalidate;
end;

procedure TMainForm.ClearButtonClick(Sender: TObject);
var J,K:INTEGER;
begin
 Track.Enter;
 Track.Playing:=FALSE;
 Track.Stop;
 FILLCHAR(Track.Patterns[PatternEditor.AktPattern AND $FF],SIZEOF(TPattern),#0);
 FOR J:=0 TO 63 DO BEGIN
  FOR K:=0 TO 15 DO BEGIN
   Track.Patterns[PatternEditor.AktPattern AND $FF,J,K].Volume:=$FF;
  END;
 END;
 Track.Leave;
 PatternEditor.Markierung:=FALSE;
 PatternEditor.Invalidate;
end;

procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
 IF Track.Changed THEN BEGIN
  CanClose:=Application.MessageBox(PCHAR('Want you really close this track without to save?'),PCHAR(Application.Title),MB_YESNO OR MB_ICONQUESTION)=IDYES;
 END ELSE BEGIN
  CanClose:=TRUE;
 END;
end;

procedure TMainForm.Normalexport1Click(Sender: TObject);
begin
 IF WAVSaveDialog.Execute THEN BEGIN
  WaveExportStatus.Show;
  Track.WaveStatusReport:=WaveExportStatus.DoStatus;
  Track.ExportToWaveFile(WAVSaveDialog.FileName,FALSE);
  WaveExportStatus.Visible:=FALSE;
 END;
end;

procedure TMainForm.Loopexport1Click(Sender: TObject);
begin
 IF WAVSaveDialog.Execute THEN BEGIN
  WaveExportStatus.Show;
  Track.WaveStatusReport:=WaveExportStatus.DoStatus;
  Track.ExportToWaveFile(WAVSaveDialog.FileName,TRUE);
  WaveExportStatus.Visible:=FALSE;
 END;
end;

procedure TMainForm.ExportasB4M1Click(Sender: TObject);
begin
 IF B4MSaveDialog.Execute THEN BEGIN
  WaveExportStatus.Show;
  Track.WaveStatusReport:=WaveExportStatus.DoStatus;
  Track.ExportToB4MFile(B4MSaveDialog.FileName,FALSE);
  WaveExportStatus.Visible:=FALSE;
 END;
end;

procedure TMainForm.EditSongNameChange(Sender: TObject);
begin
 Track.SongName:=EditSongName.Text;
end;

procedure TMainForm.MemoSongMessageChange(Sender: TObject);
begin
 Track.SongMessage:=MemoSongMessage.Text;
end;

procedure TMainForm.EditSongAuthorChange(Sender: TObject);
begin
 Track.SongAuthor:=EditSongAuthor.Text;
end;

end.
