📄 midioutexampletuningdlg.pas
字号:
//
// Robert Rossmair, 2002
//
unit MidiOutExampleTuningDlg;
{$I jcl.inc}
interface
uses
Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
Buttons, ExtCtrls, Spin,
JclMath, JclMidi;
type
TTuningDialog = class(TForm)
OKBtn: TButton;
CancelBtn: TButton;
Bevel1: TBevel;
MIDIFreq: TEdit;
FreqHertz: TEdit;
MIDIFreqLabel: TLabel;
FreqLabel: TLabel;
MIDIKey: TSpinEdit;
MIDIKeyLabel: TLabel;
NoteLabel: TLabel;
procedure MIDIKeyChange(Sender: TObject);
procedure MIDIFreqChange(Sender: TObject);
procedure FreqHertzChange(Sender: TObject);
procedure MIDIFreqExit(Sender: TObject);
procedure FreqHertzExit(Sender: TObject);
private
FInMIDIFreqChange: Boolean;
FInFreqHertzChange: Boolean;
FChangingFrequency: Boolean;
FChangingMidiFrequency: Boolean;
FFrequency: Single;
FMidiFrequency: Single;
procedure SetFrequency(Value: Single);
procedure SetMidiFrequency(Value: Single);
public
property Frequency: Single read FFrequency write SetFrequency; // Hertz
property MidiFrequency: Single read FMidiFrequency write SetMidiFrequency;
end;
var
TuningDialog: TTuningDialog;
implementation
{$R *.dfm}
const
HalftonesPerOctave = 12;
MiddleA = 440.0; // Hertz
MidiMiddleA = 69; // A3 = 440 Hertz
Digits = 6;
MIDIFreqMax = 127.99993896;
FreqHertzMin = 8.17579892;
FreqHertzMax = 13289.70346552;
function Hertz(MIDINote: Extended): Extended;
begin
Hertz := TwoToY((MIDINote - MidiMiddleA) / HalftonesPerOctave) * MiddleA;
end;
function MIDINote(Hertz: Extended): Extended;
begin
if Hertz < 1.0 then
MIDINote := Low(Integer)
else
MIDINote := LogBase2(Hertz / MiddleA) * HalftonesPerOctave + MidiMiddleA;
end;
procedure TTuningDialog.MIDIKeyChange(Sender: TObject);
begin
MIDIFrequency := MIDIKey.Value;
NoteLabel.Caption := MidiNoteToStr(MIDIKey.Value);
end;
procedure TTuningDialog.MIDIFreqChange(Sender: TObject);
var
F: Extended;
begin
if FInFreqHertzChange or (MIDIFreq.Text = '') then
Exit;
FInMIDIFreqChange := True;
try
{$IFDEF COMPILER6_UP}
if TryStrToFloat(MidiFreq.Text, F) then
{$ELSE}
if TextToFloat(PChar(MidiFreq.Text), F, fvExtended) then
{$ENDIF COMPILER6_UP}
MidiFrequency := F;
finally
FInMIDIFreqChange := False;
end;
end;
procedure TTuningDialog.FreqHertzChange(Sender: TObject);
var
F: Extended;
begin
if FInMIDIFreqChange or (FreqHertz.Text = '') then
Exit;
FInFreqHertzChange := True;
try
{$IFDEF COMPILER6_UP}
if TryStrToFloat(FreqHertz.Text, F) then
{$ELSE}
if TextToFloat(PChar(FreqHertz.Text), F, fvExtended) then
{$ENDIF COMPILER6_UP}
Frequency := F;
finally
FInFreqHertzChange := False;
end;
end;
procedure TTuningDialog.SetFrequency(Value: Single);
begin
if FChangingFrequency or (Value = Frequency) then
Exit;
FChangingFrequency := True;
try
if Value < FreqHertzMin then
Value := FreqHertzMin
else
if Value > FreqHertzMax then
Value := FreqHertzMax;
FFrequency := Value;
if not FInFreqHertzChange then
FreqHertz.Text := FloatToStrF(Value, ffFixed, 9, Digits);
MidiFrequency := MIDINote(Value);
finally
FChangingFrequency := False;
end;
end;
procedure TTuningDialog.SetMidiFrequency(Value: Single);
begin
if FChangingMidiFrequency then
// or (Value = MidiFrequency) then
Exit;
if Value < 0 then
Value := 0
else
if Value > MidiFreqMax then
Value := MidiFreqMax;
FChangingMidiFrequency := True;
try
FMidiFrequency := Value;
if not FInMidiFreqChange then
MIDIFreq.Text := FloatToStrF(Value, ffFixed, 9, Digits);
Frequency := Hertz(Value);
finally
FChangingMidiFrequency := False;
end;
end;
procedure TTuningDialog.MIDIFreqExit(Sender: TObject);
begin
MIDIFreq.Text := FloatToStrF(MidiFrequency, ffFixed, 9, Digits);
end;
procedure TTuningDialog.FreqHertzExit(Sender: TObject);
begin
FreqHertz.Text := FloatToStrF(Frequency, ffFixed, 9, Digits);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -