Version:0.9
StartHTML:0000000105
EndHTML:0000302398
StartFragment:0000000141
EndFragment:0000302362
// still on work - next is form - done
// by Robert Rossmair, June 5 0
// by Robert Rossmair, June 5 2002
// by Max, August 2024 , November 2024
//ref: https://github.com/project-jedi/jcl/blob/master/jcl/source/common/JclMIDI.pas
//https://github.com/project-jedi/jcl/blob/master/jcl/examples/common/multimedia/MidiOutExampleMain.pas
unit MidiOutExampleMain_Form_Tuning_14;
interface
{uses
SysUtils, Classes, Controls, Forms, Menus, StdCtrls, ComCtrls, Buttons, Spin,
JclMIDI; }
const
MIDI_NOTE_ON = $90;
MIDI_NOTE_OFF = $80;
MIDI_CHANGE_INSTRUMENT = $C0;
MIDI_DEVICE = 0;
MIDI_VEL = 108;
MIDI_PERCUSSION_CHANNEL = 9;
type
TTuningDialog = {class(}TForm;
var
OKBtn: TButton;
CancelBtn: TButton;
Bevel1: TBevel;
MIDIFreq: TEdit;
FreqHertz: TEdit;
MIDIFreqLabel: TLabel;
FreqLabel: TLabel;
MIDIKey: TSpinEdit;
MIDIKeyLabel: TLabel;
NoteLabel: TLabel;
procedure TTuningDialogMIDIKeyChange(Sender: TObject);
procedure TTuningDialogMIDIFreqChange(Sender: TObject);
procedure TTuningDialogFreqHertzChange(Sender: TObject);
procedure TTuningDialogMIDIFreqExit(Sender: TObject);
procedure TTuningDialogFreqHertzExit(Sender: TObject);
//private
var
FInMIDIFreqChange: Boolean;
FInFreqHertzChange: Boolean;
FChangingFrequency: Boolean;
FChangingMidiFrequency: Boolean;
FFrequency: Single;
FMidiFrequency: Single;
procedure SetFrequency(Value: Single);
procedure SetMidiFrequency(Value: Single);
//public
var
{property} Frequency: Single;// read FFrequency write SetFrequency; // Hertz
{property} MidiFrequency: Single; // read FMidiFrequency write SetMidiFrequency;
//end;
var
TuningDialog: TTuningDialog;
type
TKeyboard = {class(}TForm;
var
Key48: TSpeedButton;
Key49: TSpeedButton;
Key51: TSpeedButton;
Key50: TSpeedButton;
Key55: TSpeedButton;
Key54: TSpeedButton;
Key53: TSpeedButton;
Key52: TSpeedButton;
Key58: TSpeedButton;
Key56: TSpeedButton;
Key59: TSpeedButton;
Key57: TSpeedButton;
MidiProgramNum: TSpinEdit;
Label1: TLabel;
KeyMenu: TPopupMenu;
TuningItem: TMenuItem;
Key72: TSpeedButton;
Key74: TSpeedButton;
Key76: TSpeedButton;
Key77: TSpeedButton;
Key73: TSpeedButton;
Key75: TSpeedButton;
Key79: TSpeedButton;
Key81: TSpeedButton;
Key83: TSpeedButton;
Key78: TSpeedButton;
Key80: TSpeedButton;
Key82: TSpeedButton;
Key60: TSpeedButton;
Key62: TSpeedButton;
Key64: TSpeedButton;
Key65: TSpeedButton;
Key61: TSpeedButton;
Key63: TSpeedButton;
Key67: TSpeedButton;
Key69: TSpeedButton;
Key71: TSpeedButton;
Key66: TSpeedButton;
Key68: TSpeedButton;
Key70: TSpeedButton;
PitchBender: TTrackBar;
btnAllNotesOff: TButton;
cbMidiOutSelect: TComboBox;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
ModWheel: TTrackBar;
procedure TKeyboardFormCreate(Sender: TObject);
procedure TKeyboardKeyMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure TKeyboardKeyMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure TKeyboardMidiProgramNumChange(Sender: TObject);
procedure TKeyboardTuningItemClick(Sender: TObject);
procedure TKeyboardPitchBenderChange(Sender: TObject);
procedure TKeyboardKeyClick(Sender: TObject);
procedure TKeyboardbtnAllNotesOffClick(Sender: TObject);
procedure TKeyboardcbMidiOutSelectChange(Sender: TObject);
procedure TKeyboardModWheelChange(Sender: TObject);
//private
var
FMidiOut: IJclMidiOut;
FChannel: TMidiChannel;
//Keys: array[TMidiNote] of TSpeedButton;
Keys: array[48..83] of TSpeedButton;
procedure InitKeyboard;
procedure AllNotesOff;
// end;
var
Keyboard: TKeyboard;
implementation
//uses MidiOutExampleTuningDlg;
//{$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
result := TwoToY((MIDINote - MidiMiddleA) / HalftonesPerOctave) * MiddleA;
end;
function MIDINote(Hertz: Extended): Extended;
begin
if Hertz < 1.0 then
result := mininteger //minint; //Low(Integer)
else
result := LogBase2(Hertz / MiddleA) * HalftonesPerOctave + MidiMiddleA;
end;
procedure TTuningDialogMIDIKeyChange(Sender: TObject);
begin
MIDIFrequency := MIDIKey.Value;
NoteLabel.Caption := MidiNoteToStr(MIDIKey.Value);
end;
{$DEFINE COMPILER6_UP}
procedure TTuningDialogMIDIFreqChange(Sender: TObject);
var
F: Double;
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}
FMidiFrequency := F;
SetMidiFrequency(F);
finally
FInMIDIFreqChange := False;
end;
end;
procedure TTuningDialogFreqHertzChange(Sender: TObject);
var
F: Double; //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}
FFrequency := F;
SetFrequency(F);
finally
FInFreqHertzChange := False;
end;
end;
procedure 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, 6);
MidiFrequency := MIDINote(Value);
finally
FChangingFrequency := False;
end;
end;
procedure 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, 6);
Frequency := Hertz(Value);
finally
FChangingMidiFrequency := False;
end;
end;
procedure TTuningDialogMIDIFreqExit(Sender: TObject);
begin
MIDIFreq.Text := FloatToStrF(MidiFrequency, ffFixed, 9, 6);
end;
procedure TTuningDialogFreqHertzExit(Sender: TObject); //2012 D
begin
FreqHertz.Text := FloatToStrF(Frequency, ffFixed, 9,6);
end;
//----------------------------TKeyboard----------------------------------//
procedure TKeyboardFormCreate(Sender: TObject);
begin
FChannel := 1;
GetMidiOutputs(cbMidiOutSelect.Items);
cbMidiOutSelect.ItemIndex := 0;
TKeyboardcbMidiOutSelectChange(Self);
InitKeyboard;
end;
procedure InitKeyboard;
var
Note: TMidiNote;
begin
for Note := Low(Keys) to High(Keys) do begin
//writ('debug '+itoa(low(keys))+ ' '+itoa(high(keys)));
//writ('debug: '+itoa(note));
//Keys[Note] := FindComponent2(Format('Key%d', [Note])) as TSpeedButton;
try
//Keys[Note]:= TSpeedButton(FindComponent2('Key69'));
Keys[Note]:= keyboard.FindComponent(Format('Key%d', [Note])) as TSpeedButton;
except
writeln(ExceptionToString(ExceptionType, ExceptionParam));
end;
// writ(objtostr(keys[note]));
if Keys[Note] <> nil then
with Keys[Note] do begin
//objtostr(keys[note]);
//PopupMenu := KeyMenu;
showhint:= true;
Hint := Format('MIDI Note #%d'#13#10'%s', [tag, MidiNoteToStr(tag)]);
end;
end;
end;
procedure {TKeyboard}AllNotesOff;
var
Note: TMidiNote;
begin
if Assigned(FMidiOut) then
FMidiOut.SwitchAllNotesOff(FChannel);
//for Note := Low(Note) to High(Note) do
for Note := 48 to 83 do
if Assigned(Keys[Note]) then
Keys[Note].Down := False;
end;
procedure TKeyboardKeyMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
if (Sender as TSpeedButton).Down then
FMidiOut.SendNoteOff(FChannel, TComponent(Sender).Tag, 127)
else
FMidiOut.SendNoteOn(FChannel, TComponent(Sender).Tag, 127);
writ('note trace: '+MidiNoteToStr(TComponent(Sender).Tag));
end;
procedure TKeyboardKeyMouseUp(
Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
FMidiOut.SendNoteOff(FChannel, TComponent(Sender).Tag, 127);
end;
procedure TKeyboardMidiProgramNumChange(Sender: TObject);
begin
FMidiOut.SendProgramChange(FChannel, MidiProgramNum.Value);
end;
procedure TKeyboardTuningItemClick(Sender: TObject);
begin
{with TuningDialog do
begin
MIDIKey.Value := KeyMenu.PopupComponent.Tag;
if ShowModal = mrOK then
FMidiOut.SendSingleNoteTuningChange(0, 0, [MidiSingleNoteTuningData(MIDIKey.Value, MIDIFrequency)]);
end; }
end;
const MIDIPitchWheelCenter = 1 shl (BitsPerMIDIDataWord - 1);
procedure TKeyboardPitchBenderChange(Sender: TObject);
begin
FMidiOut.SendPitchWheelChange(FChannel, PitchBender.Position + MidiPitchWheelCenter);
end;
procedure TKeyboardModWheelChange(Sender: TObject);
begin
FMidiOut.SendModulationWheelChangeHR(FChannel, ModWheel.Position);
end;
procedure TKeyboardKeyClick(Sender: TObject);
begin
//with Sender as TSpeedButton do
with TSpeedButton(sender) do begin
if Down then
FMidiOut.SendNoteOn(FChannel, TComponent(Sender).Tag, 127)
else
FMidiOut.SendNoteOff(FChannel, TComponent(Sender).Tag, 127);
end;
end;
procedure TKeyboardbtnAllNotesOffClick(Sender: TObject);
begin
AllNotesOff;
end;
procedure TKeyboardcbMidiOutSelectChange(Sender: TObject);
begin
AllNotesOff;
FMidiOut := MidiOut(cbMidiOutSelect.ItemIndex);
FMidiOut.SendProgramChange(FChannel, MidiProgramNum.Value);
end;
{const
HalftonesPerOctave = 12;
MiddleA = 440.0; // Hertz
MidiMiddleA = 69; // A3 = 440 Hertz
Digits = 6;
MIDIFreqMax = 127.99993896;
FreqHertzMin = 8.17579892;
FreqHertzMax = 13289.70346552; }
function Hertz2(MIDINote: Extended): Extended;
begin
result:= TwoToY((MIDINote - MidiMiddleA) / HalftonesPerOctave) * MiddleA;
end;
procedure loadtuningform;
begin
TuningDialog:= TTuningDialog.create(self)
with tuningdialog do begin
Left:= 245
Top:= 108
BorderStyle:= bsDialog
Caption:= 'Tuning'
ClientHeight:= 177
ClientWidth:= 313
Color:= clBtnFace
Font.Charset:= DEFAULT_CHARSET
Font.Color:= clWindowText
Font.Height:= -11
Font.Name:= 'MS Sans Serif'
Font.Style:= []
OldCreateOrder:= True
Position:= poScreenCenter
PixelsPerInch:= 96
//TextHeight:= 13
//Showmodal;
Bevel1:= TBevel.create(tuningdialog)
//end;
with bevel1 do begin
parent:= tuningdialog;
Left:= 8
Top:= 8
Width:= 297
Height:= 117
Shape:= bsFrame
end;
MIDIFreqLabel:= TLabel.create(tuningdialog);
with MIDIFreqLabel do begin
parent:= tuningdialog;
Left:= 36
Top:= 56
Width:= 110
Height:= 13
Caption:= '&MIDI relative frequency'
end;
FreqLabel:= TLabel.create(tuningdialog);
with FreqLabel do begin
parent:= tuningdialog;
Left:= 36
Top:= 84
Width:= 84
Height:= 13
Caption:= 'Frequency [Hertz]'
end;
MIDIKeyLabel:= TLabel.create(tuningdialog);
with MIDIKeyLabel do begin
parent:= tuningdialog;
Left:= 36
Top:= 28
Width:= 81
Height:= 13
Caption:= 'MIDI key number'
end;
noteLabel:= TLabel.create(tuningdialog);
with noteLabel do begin
parent:= tuningdialog;
Left:= 224
Top:= 28
Width:= 49
Height:= 13
Caption:= 'NoteLabel'
end;
OKBtn:= TButton.create(tuningdialog)
with okbtn do begin
parent:= tuningdialog
Left:= 79
Top:= 140
Width:= 75
Height:= 25
Caption:= 'OK'
Default:= True
ModalResult:= 1
TabOrder:= 0
end;
cancelBtn:= TButton.create(tuningdialog)
with cancelbtn do begin
parent:= tuningdialog
Left:= 159
Top:= 140
Width:= 75
Height:= 25
Cancel:= True
Caption:= 'Cancel'
ModalResult:= 2
TabOrder:= 1
end;
MIDIFreq:= TEdit.create(tuningdialog)
with midifreq do begin
parent:= tuningdialog;
Left:= 156
Top:= 52
Width:= 121
Height:= 21
TabOrder:= 2
OnChange:= @TTuningDialogMIDIFreqChange;
OnExit:= @TTuningDialogMIDIFreqExit;
end ;
//object FreqHertz: TEdit
FreqHertz:= TEdit.create(tuningdialog)
with FreqHertz do begin
parent:= tuningdialog;
Left:= 156
Top:= 80
Width:= 121
Height:= 21
TabOrder:= 3
OnChange:= @TTuningDialogFreqHertzChange
OnExit:= @TTuningDialogFreqHertzExit
end ;
MIDIKey:= TSpinEdit.create(tuningdialog)
with midikey do begin
parent:= tuningdialog;
Left:= 156
Top:= 24
Width:= 53
Height:= 22
MaxValue:= 127
MinValue:= 0
TabOrder:= 4
Value:= 0
OnChange:= @TTuningDialogMIDIKeyChange;
end;
showmodal;
end;
end;
procedure loadKeyboardform;
begin
Keyboard:= TKeyboard.create(self)
with keyboard do begin
Left:= 145
Top:= 347
ClientWidth:= 520
ClientHeight:= 223
HorzScrollBar.Range:= 517
VertScrollBar.Range:= 209
ActiveControl:= MidiProgramNum
AutoScroll:= False
icon.loadfromresourcename(hinstance, 'Piano');
Caption:= 'MIDI Keys Example 0.92/ maXbox5'
Color:= clBtnFace
Font.Charset:= DEFAULT_CHARSET
Font.Color:= clWindowText
Font.Height:= 11
Font.Name:= 'MS Sans Serif'
//Font.Pitch:= fpVariable
Font.Style:= []
OldCreateOrder:= True
ShowHint:= True
OnCreate:= @TKeyboardFormCreate;
PixelsPerInch:= 96
//TextHeight:= 13
Show;
Key48:= TSpeedButton.create(keyboard)
with key48 do begin
parent:= keyboard;
Tag:= 48
Left:= 4
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 48
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key50:= TSpeedButton.create(keyboard)
with key50 do begin
parent:= keyboard;
Tag:= 50
Left:= 24
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 50
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key52:= TSpeedButton.create(keyboard)
with key52 do begin
parent:= keyboard;
Tag:= 52
Left:= 44
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 52
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key53:= TSpeedButton.create(keyboard)
with key53 do begin
parent:= keyboard;
Tag:= 53
Left:= 64
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 53
OnMouseDown:= @TKeyboardKeyMouseDown;
end ;
Key49:= TSpeedButton.create(keyboard)
with key49 do begin
parent:= keyboard;
Tag:= 49
Left:= 18
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 49
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key51:= TSpeedButton.create(keyboard)
with key51 do begin
parent:= keyboard;
Tag:= 51
Left:= 38
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 51
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key55:= TSpeedButton.create(keyboard)
with key55 do begin
parent:= keyboard;
Tag:= 55
Left:= 84
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 55
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key57:= TSpeedButton.create(keyboard)
with key57 do begin
parent:= keyboard;
Tag:= 57
Left:= 104
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 57
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key59:= TSpeedButton.create(keyboard)
with key59 do begin
parent:= keyboard;
Tag:= 59
Left:= 124
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 59
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key54:= TSpeedButton.create(keyboard)
with key54 do begin
parent:= keyboard;
Tag:= 54
Left:= 78
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 54
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key56:= TSpeedButton.create(keyboard)
with key56 do begin
parent:= keyboard;
Tag:= 56
Left:= 98
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 56
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key58:= TSpeedButton.create(keyboard)
with key58 do begin
parent:= keyboard;
Tag:= 58
Left:= 118
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 58
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key60:= TSpeedButton.create(keyboard)
with key60 do begin
parent:= keyboard;
Tag:= 60
Left:= 144
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 60
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key62:= TSpeedButton.create(keyboard)
with key62 do begin
parent:= keyboard;
Tag:= 62
Left:= 164
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 62
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key64:= TSpeedButton.create(keyboard)
with key64 do begin
parent:= keyboard;
Tag:= 64
Left:= 184
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 64
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key65:= TSpeedButton.create(keyboard)
with key65 do begin
parent:= keyboard;
Tag:= 65
Left:= 204
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 65
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key61:= TSpeedButton.create(keyboard)
with key61 do begin
parent:= keyboard;
Tag:= 61
Left:= 158
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 61
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key63:= TSpeedButton.create(keyboard)
with key63 do begin
parent:= keyboard;
Tag:= 63
Left:= 178
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 63
OnMouseDown:= @TKeyboardKeyMouseDown;
end ;
Key67:= TSpeedButton.create(keyboard)
with key67 do begin
parent:= keyboard;
name:= 'key67';
//glyph.loadfromresourcename (hinstance, 'C10');
Tag:= 67
Left:= 224
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 67
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key69:= TSpeedButton.create(keyboard)
with key69 do begin
parent:= keyboard;
name:= 'Key69';
Tag:= 69
Left:= 244
Top:= 36
Width:= 21
Height:= 97
color:= clblack;
//glyph.loadfromresourcename (hinstance, 'citymax');
AllowAllUp:= True
GroupIndex:= 69
OnMouseDown:= @TKeyboardKeyMouseDown;
end ;
Key71:= TSpeedButton.create(keyboard)
with key71 do begin
parent:= keyboard;
//glyph.loadfromresourcename (hinstance, 'C10');
name:= 'key71';
Tag:= 71
Left:= 264
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 71
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key66:= TSpeedButton.create(keyboard)
with key66 do begin
parent:= keyboard;
glyph.loadfromresourcename (hinstance, 'citymax');
Tag:= 66
Left:= 218
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 66
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key68:= TSpeedButton.create(keyboard)
with key68 do begin
parent:= keyboard;
name:= 'key68';
glyph.loadfromresourcename (hinstance, 'citymax');
// glyph.loadfromresourcename (hinstance, 'C10');
Tag:= 68
Left:= 238
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 68
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key70:= TSpeedButton.create(keyboard)
with key70 do begin
parent:= keyboard;
name:= 'key70';
glyph.loadfromresourcename (hinstance, 'citymax');
Tag:= 70
Left:= 258
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 70
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key72:= TSpeedButton.create(keyboard)
with key72 do begin
parent:= keyboard;
//glyph.loadfromresourcename (hinstance, 'citymax');
Tag:= 72
Left:= 284
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 72
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key74:= TSpeedButton.create(keyboard)
with key74 do begin
parent:= keyboard;
Tag:= 74
Left:= 304
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 74
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key76:= TSpeedButton.create(keyboard)
with key76 do begin
parent:= keyboard;
Tag:= 76
Left:= 324
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 76
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key77:= TSpeedButton.create(keyboard)
with key77 do begin
parent:= keyboard;
Tag:= 77
Left:= 344
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 77
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key73:= TSpeedButton.create(keyboard)
with key73 do begin
parent:= keyboard;
glyph.loadfromresourcename (hinstance, 'citymax');
Tag:= 73
Left:= 298
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 73
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key75:= TSpeedButton.create(keyboard)
with key75 do begin
parent:= keyboard;
glyph.loadfromresourcename (hinstance, 'citymax');
Tag:= 75
Left:= 318
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 75
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key79:= TSpeedButton.create(keyboard)
with key79 do begin
parent:= keyboard;
//glyph.loadfromresourcename (hinstance, 'citymax');
Tag:= 79
Left:= 364
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 79
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key81:= TSpeedButton.create(keyboard)
with key81 do begin
parent:= keyboard;
Tag:= 81
Left:= 384
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 81
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key83:= TSpeedButton.create(keyboard)
with key83 do begin
parent:= keyboard;
Tag:= 83
Left:= 404
Top:= 36
Width:= 21
Height:= 97
AllowAllUp:= True
GroupIndex:= 83
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key78:= TSpeedButton.create(keyboard)
with key78 do begin
parent:= keyboard;
glyph.loadfromresourcename (hinstance, 'citymax');
Tag:= 78
Left:= 358
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 78
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key80:= TSpeedButton.create(keyboard)
with key80 do begin
parent:= keyboard;
glyph.loadfromresourcename (hinstance, 'citymax');
Tag:= 80
Left:= 378
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 80
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
Key82:= TSpeedButton.create(keyboard)
with key82 do begin
parent:= keyboard;
glyph.loadfromresourcename (hinstance, 'citymax');
Tag:= 82
Left:= 398
Top:= 36
Width:= 13
Height:= 61
AllowAllUp:= True
GroupIndex:= 82
OnMouseDown:= @TKeyboardKeyMouseDown;
end;
with TLabel.create(keyboard) do begin
parent:= keyboard;
Left:= 440
Top:= 9
Width:= 75
Height:= 13
font.color:= clPurple;
font.size:= 8;
font.style2:= fsbold2
Caption:= 'minimax1'
end ;
Label1:= TLabel.create(keyboard)
with label1 do begin
parent:= keyboard;
Left:= 440
Top:= 36
Width:= 75
Height:= 13
Caption:= 'MIDI Program #'
end ;
Label2:= TLabel.create(keyboard)
with label2 do begin
parent:= keyboard;
Left:= 8
Top:= 12
Width:= 43
Height:= 13
Caption:= 'MIDI Out'
end ;
Label3:= TLabel.create(keyboard)
with label3 do begin
parent:= keyboard;
Left:= 8
Top:= 144
Width:= 58
Height:= 13
Caption:= 'Pitch Wheel'
FocusControl:= PitchBender
end;
Label4:= TLabel.create(keyboard)
with label4 do begin
parent:= keyboard;
Left:= 8
Top:= 184
Width:= 58
Height:= 13
Caption:= 'Mod. Wheel'
FocusControl:= ModWheel
end;
MidiProgramNum:= TSpinEdit.create(keyboard)
with MidiProgramNum do begin
parent:= keyboard;
Left:= 440
Top:= 60
Width:= 77
Height:= 22
MaxValue:= 127
MinValue:= 0
TabOrder:= 0
Value:= 0
OnChange:= @TKeyboardMidiProgramNumChange
end ;
PitchBender:= TTrackBar.create(keyboard)
with pitchbender do begin
parent:= keyboard;
Left:= 72
Top:= 136
Width:= 441
Height:= 33
Hint:= 'Pitch bender'
Max:= 8191
Min:= -8192
Orientation:= trHorizontal
PageSize:= 256
Frequency:= 2048
Position:= 0
SelEnd:= 0
SelStart:= 0
TabOrder:= 1
TickMarks:= tmBottomRight
TickStyle:= tsAuto
OnChange:= @TKeyboardPitchBenderChange
end;
btnAllNotesOff:= TButton.create(keyboard)
with btnallnotesoff do begin
parent:= keyboard;
Left:= 440
Top:= 104
Width:= 75
Height:= 25
Caption:= '&All Notes Off'
TabOrder:= 2
OnClick:= @TkeyboardbtnAllNotesOffClick
end ;
cbMidiOutSelect:= TComboBox.create(keyboard)
with cbMidiOutSelect do begin
parent:= keyboard;
Left:= 68
Top:= 8
Width:= 253
Height:= 21
Style:= csDropDownList
ItemHeight:= 13
TabOrder:= 3
OnChange:= @TKeyboardcbMidiOutSelectChange
end ;
modwheel:= TTrackBar.create(keyboard)
with modwheel do begin
parent:= keyboard;
Left:= 73
Top:= 176
Width:= 440
Height:= 33
Hint:= 'Pitch bender'
Max:= 16383
Orientation:= trHorizontal
PageSize:= 256
Frequency:= 2048
Position:= 0
SelEnd:= 0
SelStart:= 0
TabOrder:= 4
TickMarks:= tmBottomRight
TickStyle:= tsAuto
OnChange:= @TkeyboardModWheelChange
end ;
{object KeyMenu: TPopupMenu
Left:= 336
Top:= 8
object TuningItem: TMenuItem
Caption:= 'Tuning...'
OnClick:= TuningItemClick
end;
end }
end ;
TKeyboardFormCreate(self);
end;
procedure TMyFormInitialisePanels(RowCount, ColCount: Integer);
var
Row, Col: Integer;
aLeft, aTop, aWidth, aHeight: Integer;
Panel: TPanel;
FPanels: array of array of TPanel;
begin
//SetLength2(FPanels, RowCount, ColCount);
aTop := 0;
for Row := 0 to RowCount-1 do begin
aLeft := 0;
aHeight := (keyboard.ClientHeight-aTop) div (RowCount-Row);
for Col := 0 to ColCount-1 do begin
Panel := TPanel.Create(Self);
FPanels[Row][ Col] := Panel;
Panel.Parent := Self;
aWidth := (keyboard.ClientWidth-aLeft) div (ColCount-Col);
Panel.SetBounds(aLeft, aTop, aWidth, aHeight);
inc2(aLeft, aWidth);
end;
inc2(aTop, aHeight);
end;
end;
procedure basetone(note: TMidinote; fmidi: IJclMidiOut);
begin
writ(MIDINoteToStr(note+69));
writ(flots(Hertz(69)));
writ(MIDINoteToStr(note+64));
writ(flots(Hertz(64)));
writ(MIDINoteToStr(note+60));
writ(flots(Hertz(60)));
write(MIDINoteToStr(note+72));
write(MIDINoteToStr(note+76));
write(MIDINoteToStr(note+79)+CRLF);
// writ(flots(Hertz(72)));
//offset - 1 Octave
note:= note-12;
fmidi.SendNoteOn(2, note+72, $7f);
fmidi.SendNoteOn(2, note+76, $7f);
fmidi.SendNoteOn(2, note+79, $7f);
sleep(800);
//1. Inversion
write(MIDINoteToStr(note+76));
write(MIDINoteToStr(note+79));
write(MIDINoteToStr(note+84)+CRLF);
//fmidi.SendNoteOn(2, note+72, $7f);
fmidi.SendNoteOn(2, note+76, $7f); //E4
fmidi.SendNoteOn(2, note+79, $7f); //G
fmidi.SendNoteOn(2, note+84,$7f); //C
//writ(MIDINoteToStr(note+84));
sleep(1000);
//2. Inversion
write(MIDINoteToStr(note+79));
write(MIDINoteToStr(note+84));
write(MIDINoteToStr(note+88)+CRLF);
//fmidi.SendNoteOn(2, note+72, $7f);
fmidi.SendNoteOn(2, note+79, $7f);
fmidi.SendNoteOn(2, note+84, $7f);
fmidi.SendNoteOn(2, note+88,$7f);
//writ(MIDINoteToStr(note+84));
sleep(2000);
end;
var
mNotes: array of string;
function StrtoMIDINote(Notename: string; octave: byte): TMIDINote;
var i, fn: integer;
aNoteName: string;
aOctave, NoteIndex: Integer; note: TMidinote;
begin
mnotes:= ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'];
// Find note index
NoteIndex := -1;
//octave:= octave;
fn:= pos('+',notename)
if fn> 0 then begin inc(octave); delete(notename,fn,1); end;
fn:= pos('-',notename)
if fn> 0 then begin dec(octave); delete(notename,fn,1); end;
//writ(notename)
//if pos(notename, '-') > 0 then dec(octave); //}
// Extract note name and octave
//NoteName := UpperCase(Copy(Notename, 1, Length(Notename) - 1));
NoteName := UpperCase(Notename);
//Octave := StrToIntDef(Copy(NoteStr, Length(NoteStr), 1), 4);
for I := 0 to High(mNotes) do
if mNotes[I] = NoteName then begin
NoteIndex:= I;
write(mnotes[i]+' ')
Break;
end;
// writeln(CRLF);
// writeln('basenote octave '+itoa(octave));
// Calculate MIDI note number
if NoteIndex <> -1 then
Result := (Octave + 1) * 12 + NoteIndex
else
Result := -1; // Invalid note
end;
function StrtoMIDINote2(Notestr: string; octave: byte): TMIDINote;
var i, fn: integer;
NoteName,tmp: string;
aOctave, NoteIndex: Integer; note: TMidinote;
begin
mnotes:= ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'];
//writ('sr'+notestr)
//tmp:= Copy(NoteStr, 1, Length(NoteStr) - 1);
//notename:= uppercase(tmp);
NoteName := AnsiUpperCase(Copy(NoteStr, 1, Length(NoteStr) - 1));
//deletestr(NoteStr, 1, Length(NoteStr));
//writ('dd'+notename)
Octave := StrToIntDef(Copy(NoteStr, Length(NoteStr), 1), 4);
//writ('oc'+itoa(octave))
// Find note index
NoteIndex := -1;
// Extract note name and octave
//NoteName := UpperCase(Copy(Notename, 1, Length(Notename) - 1));
//NoteName := UpperCase(Notename);
//Octave := StrToIntDef(Copy(NoteStr, Length(NoteStr), 1), 4);
for I := 0 to High(mNotes) do
if mNotes[I] = NoteName then begin
NoteIndex:= I;
write(mnotes[i]+' ')
Break;
end;
// writeln(CRLF);
// writeln('basenote octave '+itoa(octave));
// Calculate MIDI note number
if NoteIndex <> -1 then
Result := (Octave + 1) * 12 + NoteIndex
else
Result := -1; // Invalid note
end;
procedure playtune(tune: array of string; pause: integer; octave: byte; fin: boolean; fmidi: IJclMidiOut);
var i, anote: integer;
begin
for i:= 0 to High(tune) do begin
anote:= StrtoMIDINote2(tune[i],octave);
fmidi.SendNoteOn(2, anote, $7f);
delay(pause)
fmidi.SendNoteOff(2, anote, $7f);
end;
if fin then sleep(1500);
//writeln(CRLF);
end;
procedure playchord(tune: array of string; pause: integer; fin: boolean; fmidi: IJclMidiOut);
var i, anote: integer;
begin
//for i:= 0 to High(tune) do begin
anote:= StrtoMIDINote2(tune[0],2);
fmidi.SendNoteOn(2, anote, $7f);
anote:= StrtoMIDINote2(tune[1],2);
fmidi.SendNoteOn(2, anote, $7f);
anote:= StrtoMIDINote2(tune[2],2);
fmidi.SendNoteOn(2, anote, $7f);
anote:= StrtoMIDINote2(tune[3],2);
fmidi.SendNoteOn(2, anote, $7f);
delay(pause)
fmidi.SendNoteOff(2, anote, $7f);
//end;
if fin then sleep(1300);
//writeln(CRLF);
end;
procedure basetune(note: TMidinote; fmidi: IJclMidiOut);
begin
//StrToMidiNote('C4');
writeln('strtomidi: '+itoa(StrToMidiNote('C',5)));
// writeln('strtomidi: '+itoa(StrToMidiNote('a')));
writ(MIDINoteToStr(note+72));
writ(flots(Hertz(72)));
write(MIDINoteToStr(note+72)); //ceg
write(MIDINoteToStr(note+76));
write(MIDINoteToStr(note+79)+CRLF);
// writ(flots(Hertz(72)));
//offset - 1 Octave
note:= note-12;
fmidi.SendNoteOn(2, note+72, $7f);
delay(200)
fmidi.SendNoteOn(2, note+76, $7f);
delay(200)
fmidi.SendNoteOn(2, note+79, $7f);
delay(700);
//1. Inversion
write(MIDINoteToStr(note+74)); //dfa
write(MIDINoteToStr(note+77));
write(MIDINoteToStr(note+81)+CRLF);
//fmidi.SendNoteOn(2, note+72, $7f);
fmidi.SendNoteOn(2, note+74, $7f); delay(200); //d4
fmidi.SendNoteOn(2, note+77, $7f); delay(200); //f
fmidi.SendNoteOn(2, note+81,$7f); //a
//writ(MIDINoteToStr(note+84));
delay(700);
//2. Inversion
write(MIDINoteToStr(note+76)); //egh
write(MIDINoteToStr(note+79));
write(MIDINoteToStr(note+83)+CRLF);
//fmidi.SendNoteOn(2, note+72, $7f);
fmidi.SendNoteOn(2, note+76, $7f); delay(200);
fmidi.SendNoteOn(2, note+79, $7f); delay(200);
fmidi.SendNoteOn(2, note+83,$7f);
sleep(700);
//writ(MIDINoteToStr(note+84));
write(MIDINoteToStr(note+77)); //fac
write(MIDINoteToStr(note+81));
write(MIDINoteToStr(note+84)+CRLF);
//fmidi.SendNoteOn(2, note+72, $7f);
fmidi.SendNoteOn(2, note+77, $7f); delay(200);
fmidi.SendNoteOn(2, note+81, $7f); delay(200);
fmidi.SendNoteOn(2, note+84,$7f);
sleep(1500);
end;
procedure setChordProgression(note : integer);
begin
fmidiout.SendNoteOff(2, note+40, $7f);
fmidiout.SendNoteOFF(2, note+42, $7f);
fmidiout.SendNoteOn(2, note+60, $7f);
end;
function MIDIEncodeMessage(Channel, Msg, Param1, Param2: integer): integer;
begin
result:= Channel or Msg + (Param1 shl 8) + (Param2 shl 16);
end;
var mlist: TStringList;
note: Tmidinote; tmidi: TJclMIDIOut;
begin //@main
//-init
maxform1.setconsole;
setdebugcheck(false)
writeln('cpuspeed '+cpuspeed);
//application.icon.loadfromresourcename(hinstance,'XJICON');
writ(MIDINoteToStr(note));
writ(MIDINoteToStr(note+12));
writ(MIDINoteToStr(note+24));
writ(MIDINoteToStr(note+36));
writ(MIDINoteToStr(note+69));
writ(flots(Hertz(69)));
mlist:= THashedStringList.create;
GetMidiOutputs(mlist);
writeln(mlist.text)
mlist.free;
fmidiout:= MIDIOut(0);
//fmidiout.SendMessage(const Data: array of Byte);
fmidiout.SwitchPolyModeOn(16);
//midiOutShortMsg
//MIDIMsgProgramChange = $C0;
//fmidiout.SendProgramChange(2, 7);
//fmidiout.SendProgramChange(2, 1);
//procedure SelectProgram(Channel: TMIDIChannel; BankNum: TMIDIDataWord; ProgramNum: TMIDIDataByte);
//fmidiout.SelectProgram(0,0, 4);
//tmidi:= fmidiout as TJclMIDIOut;
//with tmidi do begin
{ fmidiout.SendNoteOn(2, note+36, $7f);
fmidiout.SendNoteOn(2, note+40, $7f);
fmidiout.SendNoteOn(2, note+42, $7f);
sleep(800) }
{ fmidiout.SendNoteOff(2, note+36, $7f);
fmidiout.SendNoteOff(2, note+40, $7f);
fmidiout.SendNoteOFF(2, note+42, $7f);
fmidiout.SendNoteOn(2, note+60, $7f);
fmidiout.SendNoteOn(2, note+64, $7f);
fmidiout.SendNoteOn(2, note+68, $7f);
sleep(900)
// mid.SendNoteoff(2, note+68, $7f);
fmidiout.SendNoteOn(2, note+72, $7f);
sleep(700);
fmidiout.SendNoteOn(2, note+69, $7f);
fmidiout.SendNoteOn(2, note+79, $7f);
fmidiout.SendNoteOn(2, note+61, $7f);
fmidiout.SendNoteOn(2, note+59, $7f);
fmidiout.SendNoteOn(2, note+55, $7f);
sleep(1900); }
writ(fmidiout.getname);
//basetone(note, fmidiout);
//basetune(note, fmidiout);
{ C Dm Em F G Am Hm-
Step I II III; IV V VI VII
Tunes c e g d f a e g h f a c }
writ(flots(Hertz(72)));
writ(flots(Hertz(84)));
//playTune(['c','e','g','d','f','a','e','g','b','f','a','c+'], 200, 5, true, fmidiout);
// playtune(['c','e','g','d','f','a','e','g','b'],fmidiout);
//F-G-A-B-C-D-E F_Lydisch F Lydischer Modus: F-G-A-B-C-D-E
{for it:= 1 to 5 do
playTune(['f','g','a','b','c','d','e','f'], 200, 5, false, fmidiout);}
//C-Lydisch-Tonleiter c d e f# g a
// playTune(['c','d','e','f#','g','a','b','c+'], 400, 4, true, fmidiout);
//D-Lydisch-Tonleiter d e f# g# a b c# d W-W-W-H-W-W-H
//https://www.hooktheory.com/cheat-sheet/key/d/lydian
//playTune(['d','e','f#','g#','a','b','c#+','d+'], 500, 4, true, fmidiout);
//playTune(['d4','e4','f#4','g#4','a4','b4','c#5','d5'], 500, 4, true, fmidiout);
//E Phrygischer Modus: E-F-G-A-B-C-D H W W W H W W
//https://emastered.com/de/blog/phrygian-mode
//https://www.hooktheory.com/cheat-sheet/key/g/phrygian
// playTune(['g4','ab4','bb4','c5','d5','eb5','f','g'], 500, 4, true, fmidiout);
// playTune(['g4','g#4','a#4','c5','d5','d#5','f5','g5'], 500, 4, true, fmidiout);
//https://www.hooktheory.com/cheat-sheet/key/g/phrygian
{ playChord(['g2','a#3','d4','g4'], 1100, false, fmidiout);
playChord(['g#2','c4','d#4','g#4'], 1000, false, fmidiout);
playChord(['g2','a#3','d4','g4'], 1100, false, fmidiout);
playChord(['f2','c4','f4','g#4'], 1000, true, fmidiout); }
//https://www.hooktheory.com/cheat-sheet/key/g/phrygian
for it:= 1 to 3 do begin
playChord(['g2','a#3','d4','g4'], 1100, false, fmidiout); //gm
playChord(['c3','c4','d#4','g4'], 1100, false, fmidiout); //cm
playChord(['a#2','a#3','d4','f4'], 1000, false, fmidiout); //bflat
playChord(['g#2','c4','d#4','g#4'], 900, true, fmidiout); //aflat
end;
//g a b c d e f# g as g major scale
// playTune(['g','a','b','c+','d+','e+','f#+','g+'], 400, 4, true, fmidiout);
//end of waveframe;
{ loadKeyboardform();
TKeyboardKeyMouseDown(key69, mbleft, [], 0,0);
TKeyboardKeyMouseDown(key79, mbleft, [], 0,0);
TKeyboardKeyMouseDown(key61, mbleft, [], 0,0);
TKeyboardKeyMouseDown(key59, mbleft, [], 0,0);
TKeyboardKeyMouseDown(key55, mbleft, [], 0,0); }
// Key69.click();
//TKeyboardKeyClick(key50);
//loadtuningform();
//PlayMidiFile2('C:\maxbox\maxbox51\examples\schww20240810_104146_f#_hexdorian.mid');
// PlayMidiFile2('C:\maxbox\maxbox51\examples\schww20240810_104146_f#_hexdorian.mid');
// PlayMidiFile2('C:\maxbox\maxbox51\examples\wurm20240818_114553_f#_harmonicminor.mid');
// TJclMIDIOut(fmidiout).free;
fmidiout:= NIL;
//maxform1.Showmidiform(self);
{ sr:= 'abc+df'
it:= pos('+',sr)
writ(itoa(it));
delete(sr,it,1)
writ(sr) //}
//MCISendString('PLAY ' +'"C:\maxbox\maxbox51\examples\schww20240810_104146_f#_hexdorian.mid"', 'nil', 0, 0);
//PlaySound1('C:\maxbox\maxbox51\examples\schww20240810_104146_f#_hexdorian.mid');
//writ(botostr(SndPlaySound('C:\maxbox\maxbox51\examples\schww20240810_104146_f#_hexdorian.mid',1)));
//MCISendString(('play '+'C:\maxbox\maxbox51\examples\schww20240810_104146_f#_hexdorian.mid'), 'nil', 0, 0);
end.
end.
ref: https://de.wikipedia.org/wiki/Modale_Tonleitern#Modi
https://github.com/project-jedi/jcl/blob/master/jcl/source/common/JclMIDI.pas
https://stackoverflow.com/questions/27213327/how-to-access-midi-percussion-on-delphi
https://www.hochweber.ch/theorie/akkordaufbau/akkordaufbau.htm
https://stackoverflow.com/questions/66416799/sending-midi-control-message-via-64-bit-delphi
https://unison.audio/phrygian-scale/
// Registered Parameter Numbers [CC# 65H,64H]
// -----------------------------------------------------------
// CC#65 (MSB) | CC#64 (LSB) | Function
// Hex|Dec| | Hex|Dec| |
// - - - - - - | - - - - - - |- - - - - - - - - - - - - - - -
// 00:= 0 | 00:= 0 | Pitch Bend Sensitivity
// 00:= 0 | 01:= 1 | Channel Fine Tuning
// 00:= 0 | 02:= 2 | Channel Coarse Tuning
// 00 = 0 | 03 = 3 | Tuning Program Change
// 00 = 0 | 04 = 4 | Tuning Bank Select
Reisedatum 12. bis 26. September
The MIDI standard itself does not define any instruments or percussion sounds.
The General MIDI specification defines 128 instruments, and 47 percussion sounds. All channels except
channel 9 (counting from zero) play instruments, channel 9 plays percussion sounds,
with different note numbers resulting in different sounds.
Other specifications (General MIDI 2, GS, XG etc.) define more sounds,
and have mechanisms to select which channel(s) to use for percussion sounds.
To code the StrToMidiNote function in Delphi, you can create a function that converts
a string representation of a musical note to its corresponding MIDI note number.
Here's an implementation: This function does the following:
It defines a constant array of note names.
It extracts the note name and octave from the input string.
It finds the index of the note in the Notes array.
It calculates the MIDI note number using the formula: (Octave + 1) * 12 + NoteIndex.
This implementation assumes that the input string is in the format 'NoteOctave' (e.g., 'C4', 'F#3', 'B5').
It handles both sharp notes (with '#') and natural notes. If an invalid note is provided, the function returns -1.
G9_zeitraum mp3 127 C# Major EbM camelot 3B
EbM Db@
G Mixolydischer Modus: G-A-B-C-D-E-F
Die mixolydische Tonleiter folgt einer bestimmten Formel von Ganz- und Halbtonschritten:
W-W-H-W-W-H-W
Die phrygische Tonleiter folgt einem spezifischen Muster von Ganz- und Halbtonschritten:
H W W W H W W
E Phrygischer Modus: E-F-G-A-B-C-D
code c-lydisch
Lydisch sind alle weißen Tasten auf dem Klavier von F bis zum nächst höheren F.
Die Halbtonschritte liegen zwischen 4. und 5. Stufe sowie zwischen 7. und 8. Stufe.
F Lydischer Modus: F-G-A-B-C-D-E
W-W-W-H-W-W-H
C-lydisch geheimnisvoll und tiefsinnig. Eine kleine Anpassung mit grosser Wirkung.
Wollen wir zum C-Akkord improvisieren, müssen wir die Noten für C-lydisch ermitteln.
C-lydisch ist die 4. Tonstufe der gesuchten Basis-Dur-Tonleiter. Wir zählen nun
von der 4. Tonstufe der Dur-Tonleiter zurück bis zur Tonika.
Name: C-Lydisch-Tonleiter
Intervalle: 1 2+ 3+ #4 5 6+ 7+
Töne: c d e f# g a b c
C-lydisch basiert also auf der G-Dur Tonleiter. Du kannst somit die G-Dur Tonleiter spielen,
allerdings mit C als Ausgangsnote.
g a b c d e f# g
CL.AddTypeS('TExprTokenJ', '( etEof, etNumber, etIdentifier, etUser0, etUser1,'
+' etUser2, etUser3, etUser4, etUser5, etUser6, etUser7, etUser8, etUser9, e'
+'tUser10, etUser11, etUser12, etUser13, etUser14, etUser15, etUser16, etUse'
+'r17, etUser18, etUser19, etUser20, etUser21, etUser22, etUser23, etUser24,'
+' etUser25, etUser26, etUser27, etUser28, etUser29, etUser30, etUser31, etN'
+'otEqual, etLessEqual, etGreaterEqual, etBang, etDoubleQuote, etHash, etDol'
+'lar, etPercent, etAmpersand, etSingleQuote, etLParen, etRParen, etAsterisk'
+', etPlus, etComma, etMinus, etDot, etForwardSlash, etColon, etSemiColon, e'
+'tLessThan, etEqualTo, etGreaterThan, etQuestion, etAt, etLBracket, etBackS'
+'lash, etRBracket, etArrow, etBackTick, etLBrace, etPipe, etRBrace, etTilde'
+', et127, etEuro, et129, et130, et131, et132, et133, et134, et135, et136, e'
+'t137, et138, et139, et140, et141, et142, et143, et144, et145, et146, et147'
+', et148, et149, et150, et151, et152, et153, et154, et155, et156, et157, et'
+'158, et159, et160, et161, et162, et163, et164, et165, et166, et167, et168,'
+' et169, et170, et171, et172, et173, et174, et175, et176, et177, et178, et1'
+'79, et180, et181, et182, et183, et184, et185, et186, et187, et188, et189, '
+'et190, et191, et192, et193, et194, et195, et196, et197, et198, et199, et20'
+'0, et201, et202, et203, et204, et205, et206, et207, et208, et209, et210, e'
+'t211, et212, et213, et214, et215, et216, et217, et218, et219, et220, et221'
+', et222, et223, et224, et225, et226, et227, et228, et229, et230, et231, et'
+'232, et233, et234, et235, et236, et237, et238, et239, et240, et241, et242,'
+' et243, et244, et245, et246, et247, et248, et249, et250, et251, et252, et2'
+'53, et254, et255, etInvalid )');
This means that Our intelligence is shaped by the selection of billions of years of life on Earthin which it has been
and continues to be put to the test by the dangers present on our planet. The strategy of our genes and our
development has been to select a flexible organwhich can adapt to most contexts to be able to challenge any problem
that arises. Artificial intelligence is not able to do this for now, and resigns itself to performing (very well)
only the tasks for which it was designed.
https://de.slideshare.net/slideshow/ekon28_modernregex_12_regular_expressions-pdf/271055222
<iframe src="https://www.slideshare.net/slideshow/embed_code/key/2aLvlPkWAtlfcR?hostedIn=slideshare&page=upload"
width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
https://de.slideshare.net/slideshow/ekon28_maps_api_12_google_openstreetmaps-pdf/271055221
<iframe src="https://www.slideshare.net/slideshow/embed_code/key/6es0FlJNIh47sv?hostedIn=slideshare&page=upload"
width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>