unit InstrumentEditor;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, SoundEnginePlayer,
  Spin, Synth;

type
  TInstrumentEditorForm = class(TForm)
    OKButton: TButton;
    CancelButton: TButton;
    NameGroupBox: TGroupBox;
    NameEdit: TEdit;
    GroupBoxWaveForm: TGroupBox;
    ComboBoxWaveForm: TComboBox;
    GroupBoxVolume: TGroupBox;
    EditVolume: TEdit;
    GroupBoxVolumeFactor: TGroupBox;
    EditVolumeFactor: TEdit;
    GroupBoxPhaseFactor: TGroupBox;
    EditPhaseFactor: TEdit;
    GroupBoxOutVolume: TGroupBox;
    EditOutputVolume: TEdit;
    GroupBoxLinkVolume: TGroupBox;
    EditLinkVolume: TEdit;
    GroupBoxLink: TGroupBox;
    ComboBoxLink: TComboBox;
    GroupBoxAttackStep: TGroupBox;
    EditAttackStep: TEdit;
    GroupBoxDecayStep: TGroupBox;
    EditDecayStep: TEdit;
    GroupBoxDestDecay: TGroupBox;
    EditDestDecay: TEdit;
    GroupBoxReleaseStep: TGroupBox;
    EditReleaseStep: TEdit;
    CheckBoxSustain: TCheckBox;
    StartButton: TButton;
    StopButton: TButton;
    LinkTypeGroupBox: TGroupBox;
    ComboBoxLinkType: TComboBox;
    GroupBoxCopyFrom: TGroupBox;
    ComboBoxCopyFrom: TComboBox;
    ButtonCopyFrom: TButton;
    procedure OKButtonClick(Sender: TObject);
    procedure CancelButtonClick(Sender: TObject);
    procedure NameEditChange(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure ComboBoxWaveFormChange(Sender: TObject);
    procedure EditVolumeExit(Sender: TObject);
    procedure EditVolumeKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EditVolumeFactorExit(Sender: TObject);
    procedure EditVolumeFactorKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EditPhaseFactorExit(Sender: TObject);
    procedure EditPhaseFactorKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EditOutputVolumeExit(Sender: TObject);
    procedure EditOutputVolumeKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EditLinkVolumeExit(Sender: TObject);
    procedure EditLinkVolumeKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ComboBoxLinkChange(Sender: TObject);
    procedure EditAttackStepExit(Sender: TObject);
    procedure EditAttackStepKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EditDecayStepExit(Sender: TObject);
    procedure EditDecayStepKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EditDestDecayExit(Sender: TObject);
    procedure EditDestDecayKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EditReleaseStepExit(Sender: TObject);
    procedure EditReleaseStepKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure CheckBoxSustainClick(Sender: TObject);
    procedure StartButtonClick(Sender: TObject);
    procedure StopButtonClick(Sender: TObject);
    procedure ComboBoxLinkTypeChange(Sender: TObject);
    procedure ComboBoxCopyFromDrawItem(Control: TWinControl;
      Index: Integer; Rect: TRect; State: TOwnerDrawState);
    procedure ButtonCopyFromClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    OK:BOOLEAN;
    Track:TTrack;
    Instrument:TInstrument;
    Nr:BYTE;
    PROCEDURE SetInstrument(AInstrument:TInstrument);
    procedure DrawADSR;
  end;

var
  InstrumentEditorForm: TInstrumentEditorForm;

implementation

{$R *.DFM}

FUNCTION STR2FLOAT(S:STRING):SINGLE;
VAR C:INTEGER;
BEGIN
 VAL(S,RESULT,C);
END;

PROCEDURE TInstrumentEditorForm.SetInstrument(AInstrument:TInstrument);
BEGIN
 Instrument:=AInstrument;
 DoubleBuffered:=TRUE;
 NameEdit.Text:=Instrument.Name;
 DrawADSR;
END;

procedure TInstrumentEditorForm.OKButtonClick(Sender: TObject);
begin
 OK:=TRUE;
 CLOSE;
end;

procedure TInstrumentEditorForm.CancelButtonClick(Sender: TObject);
begin
 OK:=FALSE;
 CLOSE;
end;

procedure TInstrumentEditorForm.NameEditChange(Sender: TObject);
begin
 Instrument.Name:=NameEdit.Text;
 ComboBoxCopyFrom.Invalidate;
end;

procedure TInstrumentEditorForm.DrawADSR;
BEGIN
END;

procedure TInstrumentEditorForm.FormShow(Sender: TObject);
VAR S:STRING;
begin
 ComboBoxCopyFrom.ItemIndex:=Nr;
 ComboBoxWaveForm.ItemIndex:=Track.SynthData.FileData.WaveForm[Nr];
 STR(Track.SynthData.FileData.StartVolume[Nr]:1:24,S);
 EditVolume.Text:=S;
 STR(Track.SynthData.FileData.StartVolumeFactor[Nr]:1:24,S);
 EditVolumeFactor.Text:=S;
 STR(Track.SynthData.FileData.StartPhaseFactor[Nr]:1:24,S);
 EditPhaseFactor.Text:=S;
 STR(Track.SynthData.FileData.OutFactor[Nr]:1:24,S);
 EditOutputVolume.Text:=S;
 STR(Track.SynthData.FileData.LinkFactor[Nr]:1:24,S);
 EditLinkVolume.Text:=S;
 STR(Track.SynthData.ADSRData.AttackStep[Nr]:1:24,S);
 EditAttackStep.Text:=S;
 STR(Track.SynthData.ADSRData.DecayStep[Nr]:1:24,S);
 EditDecayStep.Text:=S;
 STR(Track.SynthData.ADSRData.DestDecay[Nr]:1:24,S);
 EditDestDecay.Text:=S;
 STR(Track.SynthData.ADSRData.ReleaseStep[Nr]:1:24,S);
 EditReleaseStep.Text:=S;
 CheckBoxSustain.Checked:=Track.SynthData.ADSRData.Sustain[Nr];
 IF Track.SynthData.FileData.Link[Nr]<>$FF THEN BEGIN
  IF (Track.SynthData.FileData.Link[Nr] AND $80)<>0 THEN BEGIN
   ComboBoxLink.ItemIndex:=(Track.SynthData.FileData.Link[Nr] AND $F)+17;
  END ELSE BEGIN
   ComboBoxLink.ItemIndex:=(Track.SynthData.FileData.Link[Nr] AND $F)+1;
  END;
  ComboBoxLinkType.ItemIndex:=Track.SynthData.FileData.Link[Nr] SHR 4;
 END ELSE BEGIN
  ComboBoxLink.ItemIndex:=0;
  ComboBoxLinkType.ItemIndex:=0;
 END;
end;

procedure TInstrumentEditorForm.ComboBoxWaveFormChange(Sender: TObject);
begin
 IF ComboBoxWaveForm.ItemIndex<>Track.SynthData.FileData.WaveForm[Nr] THEN BEGIN
  Track.SynthData.FileData.WaveForm[Nr]:=ComboBoxWaveForm.ItemIndex;
 END;
end;

procedure TInstrumentEditorForm.EditVolumeExit(Sender: TObject);
begin
 Track.SynthData.FileData.StartVolume[Nr]:=STR2FLOAT(EditVolume.Text);
end;

procedure TInstrumentEditorForm.EditVolumeKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
 Track.SynthData.FileData.StartVolume[Nr]:=STR2FLOAT(EditVolume.Text);
end;

procedure TInstrumentEditorForm.EditVolumeFactorExit(Sender: TObject);
begin
 Track.SynthData.FileData.StartVolumeFactor[Nr]:=STR2FLOAT(EditVolumeFactor.Text);
end;

procedure TInstrumentEditorForm.EditVolumeFactorKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
 Track.SynthData.FileData.StartVolumeFactor[Nr]:=STR2FLOAT(EditVolumeFactor.Text);
end;

procedure TInstrumentEditorForm.EditPhaseFactorExit(Sender: TObject);
begin
 Track.SynthData.FileData.StartPhaseFactor[Nr]:=STR2FLOAT(EditPhaseFactor.Text);
end;

procedure TInstrumentEditorForm.EditPhaseFactorKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
 Track.SynthData.FileData.StartPhaseFactor[Nr]:=STR2FLOAT(EditPhaseFactor.Text);
end;

procedure TInstrumentEditorForm.EditOutputVolumeExit(Sender: TObject);
begin
 Track.SynthData.FileData.OutFactor[Nr]:=STR2FLOAT(EditOutputVolume.Text);
end;

procedure TInstrumentEditorForm.EditOutputVolumeKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
 Track.SynthData.FileData.OutFactor[Nr]:=STR2FLOAT(EditOutputVolume.Text);
end;

procedure TInstrumentEditorForm.EditLinkVolumeExit(Sender: TObject);
begin
 Track.SynthData.FileData.LinkFactor[Nr]:=STR2FLOAT(EditLinkVolume.Text);
end;

procedure TInstrumentEditorForm.EditLinkVolumeKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
 Track.SynthData.FileData.LinkFactor[Nr]:=STR2FLOAT(EditLinkVolume.Text);
end;

procedure TInstrumentEditorForm.ComboBoxLinkChange(Sender: TObject);
begin
 CASE ComboBoxLink.ItemIndex OF
  1..16:Track.SynthData.FileData.Link[Nr]:=ComboBoxLink.ItemIndex-1;
  17..33:Track.SynthData.FileData.Link[Nr]:=(ComboBoxLink.ItemIndex-17) OR $80;
  ELSE Track.SynthData.FileData.Link[Nr]:=$FF;
 END;
 IF Track.SynthData.FileData.Link[Nr]<>$FF THEN BEGIN
  Track.SynthData.FileData.Link[Nr]:=Track.SynthData.FileData.Link[Nr] OR (ComboBoxLinkType.ItemIndex SHL 4);
 END ELSE BEGIN
  ComboBoxLinkType.ItemIndex:=0;
 END;
end;

procedure TInstrumentEditorForm.EditAttackStepExit(Sender: TObject);
begin
 Track.SynthData.ADSRData.AttackStep[Nr]:=STR2FLOAT(EditAttackStep.Text);
end;

procedure TInstrumentEditorForm.EditAttackStepKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
 Track.SynthData.ADSRData.AttackStep[Nr]:=STR2FLOAT(EditAttackStep.Text);
end;

procedure TInstrumentEditorForm.EditDecayStepExit(Sender: TObject);
begin
 Track.SynthData.ADSRData.DecayStep[Nr]:=STR2FLOAT(EditDecayStep.Text);
end;

procedure TInstrumentEditorForm.EditDecayStepKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
 Track.SynthData.ADSRData.DecayStep[Nr]:=STR2FLOAT(EditDecayStep.Text);
end;

procedure TInstrumentEditorForm.EditDestDecayExit(Sender: TObject);
begin
 Track.SynthData.ADSRData.DestDecay[Nr]:=STR2FLOAT(EditDestDecay.Text);
end;

procedure TInstrumentEditorForm.EditDestDecayKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
 Track.SynthData.ADSRData.DestDecay[Nr]:=STR2FLOAT(EditDestDecay.Text);
end;

procedure TInstrumentEditorForm.EditReleaseStepExit(Sender: TObject);
begin
 Track.SynthData.ADSRData.ReleaseStep[Nr]:=STR2FLOAT(EditReleaseStep.Text);
end;

procedure TInstrumentEditorForm.EditReleaseStepKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
 Track.SynthData.ADSRData.ReleaseStep[Nr]:=STR2FLOAT(EditReleaseStep.Text);
end;

procedure TInstrumentEditorForm.CheckBoxSustainClick(Sender: TObject);
begin
 Track.SynthData.ADSRData.Sustain[Nr]:=CheckBoxSustain.Checked;
end;

procedure TInstrumentEditorForm.StartButtonClick(Sender: TObject);
begin
 Track.Enter;
 SynthInitData(Track.SynthData);
 SynthSetNote(Track.SynthData,Nr,49,Track.Frequency);
 Track.Leave;
end;

procedure TInstrumentEditorForm.StopButtonClick(Sender: TObject);
begin
 Track.Enter;
 SynthSetNote(Track.SynthData,Nr,$80,Track.Frequency);
 Track.Leave;
end;

procedure TInstrumentEditorForm.ComboBoxLinkTypeChange(Sender: TObject);
begin
 IF Track.SynthData.FileData.Link[Nr]<>$FF THEN BEGIN
  Track.SynthData.FileData.Link[Nr]:=(Track.SynthData.FileData.Link[Nr] AND $8F) OR (ComboBoxLinkType.ItemIndex SHL 4);
 END ELSE BEGIN
  ComboBoxLinkType.ItemIndex:=0;
 END;
end;

procedure TInstrumentEditorForm.ComboBoxCopyFromDrawItem(
  Control: TWinControl; Index: Integer; Rect: TRect;
  State: TOwnerDrawState);
begin
 with (Control as TComboBox).Canvas do begin
  FillRect(Rect);
  IF Index=Nr THEN BEGIN
   TextOut(Rect.Left,Rect.Top,Inttostr(Index+1)+'. '+Instrument.Name);
  END ELSE BEGIN
   TextOut(Rect.Left,Rect.Top,Inttostr(Index+1)+'. '+Track.Instruments[Index].Name);
  END;
 end;
end;

procedure TInstrumentEditorForm.ButtonCopyFromClick(Sender: TObject);
var Index:integer;
begin
 Index:=ComboBoxCopyFrom.ItemIndex;
 IF (Index>=0) AND (Index<MaxSynthChannels) AND (Index<>Nr) THEN BEGIN
  Track.SynthData.RealtimeData.WaveForm[Nr]:=Track.SynthData.RealtimeData.WaveForm[Index];
  Track.SynthData.FileData.WaveForm[Nr]:=Track.SynthData.FileData.WaveForm[Index];
  Track.SynthData.FileData.StartVolume[Nr]:=Track.SynthData.FileData.StartVolume[Index];
  Track.SynthData.FileData.StartVolumeFactor[Nr]:=Track.SynthData.FileData.StartVolumeFactor[Index];
  Track.SynthData.FileData.StartPhaseFactor[Nr]:=Track.SynthData.FileData.StartPhaseFactor[Index];
  Track.SynthData.FileData.OutFactor[Nr]:=Track.SynthData.FileData.OutFactor[Index];
  Track.SynthData.FileData.LinkFactor[Nr]:=Track.SynthData.FileData.LinkFactor[Index];
  Track.SynthData.ADSRData.AttackStep[Nr]:=Track.SynthData.ADSRData.AttackStep[Index];
  Track.SynthData.ADSRData.DecayStep[Nr]:=Track.SynthData.ADSRData.DecayStep[Index];
  Track.SynthData.ADSRData.DestDecay[Nr]:=Track.SynthData.ADSRData.DestDecay[Index];
  Track.SynthData.ADSRData.ReleaseStep[Nr]:=Track.SynthData.ADSRData.ReleaseStep[Index];
  Track.SynthData.ADSRData.Sustain[Nr]:=Track.SynthData.ADSRData.Sustain[Index];
  Track.SynthData.FileData.Link[Nr]:=Track.SynthData.FileData.Link[Index];
  FormShow(NIL);
  ComboBoxCopyFrom.ItemIndex:=Index;
 END ELSE IF Index=Nr THEN BEGIN
  Application.MessageBox('You cann''t copy this instrument to itself!',pchar(Application.Title),MB_OK OR MB_ICONERROR);
 END;
end;

end.
