unit UScreenEditSub;
interface
uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText,
ULyrics, Math, OpenGL12, UThemes, MidiOut;
type
TScreenEditSub = class(TMenu)
private
//Variable is True if no SOng is loaded
Error: Boolean;
TextNote: integer;
TextSentence: integer;
TextTitle: integer;
TextArtist: integer;
TextMp3: integer;
TextBPM: integer;
TextGAP: integer;
TextDebug: integer;
TextNStart: integer;
TextNDlugosc: integer;
TextNTon: integer;
TextNText: integer;
AktNuta: integer;
PlaySentence: boolean;
PlaySentenceMidi: boolean;
PlayStopTime: real;
LastClick: integer;
Click: boolean;
CopySrc: integer;
MidiOut: TMidiOutput;
MidiStart: real;
MidiStop: real;
MidiTime: real;
MidiPos: real;
MidiLastNote: integer;
TextEditMode: boolean;
procedure NewBeat;
procedure CzesciDivide;
procedure CzesciMultiply;
procedure LyricsCapitalize;
procedure LyricsCorrectSpaces;
procedure FixTimings;
procedure DivideSentence;
procedure JoinSentence;
procedure DivideNote;
procedure DeleteNote;
procedure TransposeNote(Transpose: integer);
procedure ChangeWholeTone(Tone: integer);
procedure MoveAllToEnd(Move: integer);
procedure MoveTextToRight;
procedure MarkSrc;
procedure PasteText;
procedure CopySentence(Src, Dst: integer);
procedure CopySentences(Src, Dst, Num: integer);
//Note Name Mod
function GetNoteName(Note: Integer): String;
public
Tex_Background: TTexture;
FadeOut: boolean;
Path: string;
FileName: string;
constructor Create; override;
procedure onShow; override;
function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
function ParseInputEditText(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
function Draw: boolean; override;
procedure onHide; override;
end;
implementation
uses UGraphic, UDraw, UMain, USkins, ULanguage;
// Method for input parsing. If False is returned, GetNextWindow
// should be checked to know the next window to load;
function TScreenEditSub.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
var
SDL_ModState: Word;
R: real;
begin
Result := true;
if TextEditMode then begin
Result := ParseInputEditText(PressedKey, ScanCode, PressedDown);
end else begin
SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
If (PressedDown) then begin // Key Down
case PressedKey of
SDLK_ESCAPE:
begin
FadeTo(@ScreenSong);
end;
SDLK_Q:
begin
Result := false;
end;
SDLK_BACKQUOTE:
begin
// Increase Note Length (same as Alt + Right)
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
end;
SDLK_EQUALS:
begin
// Increase BPM
if SDL_ModState = 0 then
AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) + 1) / 5; // (1/20)
if SDL_ModState = KMOD_LSHIFT then
AktSong.BPM[0].BPM := AktSong.BPM[0].BPM + 4; // (1/1)
if SDL_ModState = KMOD_LCTRL then
AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) + 1) / 25; // (1/100)
end;
SDLK_MINUS:
begin
// Decrease BPM
if SDL_ModState = 0 then
AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) - 1) / 5;
if SDL_ModState = KMOD_LSHIFT then
AktSong.BPM[0].BPM := AktSong.BPM[0].BPM - 4;
if SDL_ModState = KMOD_LCTRL then
AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) - 1) / 25;
end;
SDLK_0:
begin
// Increase GAP
if SDL_ModState = 0 then
AktSong.GAP := AktSong.GAP + 10;
if SDL_ModState = KMOD_LSHIFT then
AktSong.GAP := AktSong.GAP + 1000;
end;
SDLK_9:
begin
// Decrease GAP
if SDL_ModState = 0 then
AktSong.GAP := AktSong.GAP - 10;
if SDL_ModState = KMOD_LSHIFT then
AktSong.GAP := AktSong.GAP - 1000;
end;
SDLK_KP_PLUS:
begin
// Increase tone of all notes
if SDL_ModState = 0 then
ChangeWholeTone(1);
if SDL_ModState = KMOD_LSHIFT then
ChangeWholeTone(12);
end;
SDLK_KP_MINUS:
begin
// Decrease tone of all notes
if SDL_ModState = 0 then
ChangeWholeTone(-1);
if SDL_ModState = KMOD_LSHIFT then
ChangeWholeTone(-12);
end;
SDLK_SLASH:
begin
if SDL_ModState = 0 then begin
// Insert start of sentece
if AktNuta > 0 then
DivideSentence;
end;
if SDL_ModState = KMOD_LSHIFT then begin
// Join next sentence with current
if Czesci[0].Akt < Czesci[0].High then
JoinSentence;
end;
if SDL_ModState = KMOD_LCTRL then begin
// divide note
DivideNote;
end;
end;
SDLK_S:
begin
// Save Song
if SDL_ModState = KMOD_LSHIFT then
SaveSong(AktSong, Czesci[0], Path + FileName, true)
else
SaveSong(AktSong, Czesci[0], Path + FileName, false);
{if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL + KMOD_LALT then
// Save Song
SaveSongDebug(AktSong, Czesci[0], 'C:\song.asm', false);}
end;
SDLK_D:
begin
// Divide lengths by 2
CzesciDivide;
end;
SDLK_M:
begin
// Multiply lengths by 2
CzesciMultiply;
end;
SDLK_C:
begin
// Capitalize letter at the beginning of line
if SDL_ModState = 0 then
LyricsCapitalize;
// Correct spaces
if SDL_ModState = KMOD_LSHIFT then
LyricsCorrectSpaces;
// Copy sentence
if SDL_ModState = KMOD_LCTRL then
MarkSrc;
end;
SDLK_V:
begin
// Paste text
if SDL_ModState = KMOD_LCTRL then begin
if Czesci[0].Czesc[Czesci[0].Akt].IlNut >= Czesci[0].Czesc[CopySrc].IlNut then
PasteText
else
beep;
end;
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
CopySentence(CopySrc, Czesci[0].Akt);
end;
end;
SDLK_4:
begin
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
CopySentence(CopySrc, Czesci[0].Akt);
CopySentence(CopySrc+1, Czesci[0].Akt+1);
CopySentence(CopySrc+2, Czesci[0].Akt+2);
CopySentence(CopySrc+3, Czesci[0].Akt+3);
end;
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
CopySentences(CopySrc, Czesci[0].Akt, 4);
end;
end;
SDLK_5:
begin
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
CopySentence(CopySrc, Czesci[0].Akt);
CopySentence(CopySrc+1, Czesci[0].Akt+1);
CopySentence(CopySrc+2, Czesci[0].Akt+2);
CopySentence(CopySrc+3, Czesci[0].Akt+3);
CopySentence(CopySrc+4, Czesci[0].Akt+4);
end;
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
CopySentences(CopySrc, Czesci[0].Akt, 5);
end;
end;
SDLK_T:
begin
// Fixes timings between sentences
FixTimings;
end;
SDLK_F4:
begin
// Enter Text Edit Mode
TextEditMode := true;
end;
SDLK_P:
begin
if SDL_ModState = 0 then begin
// Play Sentence
Click := true;
Music.Stop;
R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
if R <= Music.Length then begin
Music.MoveTo(R);
PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
PlaySentence := true;
Music.Play;
LastClick := -100;
end;
end;
if SDL_ModState = KMOD_LSHIFT then begin
PlaySentenceMidi := true;
MidiTime := USTime.GetTime;
MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
LastClick := -100;
end;
if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then begin
PlaySentenceMidi := true;
MidiTime := USTime.GetTime;
MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
LastClick := -100;
PlaySentence := true;
Click := true;
Music.Stop;
Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote)+0{-0.10});
PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec)+0;
Music.Play;
LastClick := -100;
end;
end;
SDLK_SPACE:
begin
// Play Sentence
PlaySentenceMidi := false; // stop midi
PlaySentence := true;
Click := false;
Music.Stop;
Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start));
PlayStopTime := (GetTimeFromBeat(
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start +
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc));
Music.Play;
LastClick := -100;
end;
SDLK_RETURN:
begin
end;
SDLK_LCTRL:
begin
end;
SDLK_DELETE:
begin
if SDL_ModState = KMOD_LCTRL then begin
// moves text to right in current sentence
DeleteNote;
end;
end;
SDLK_PERIOD:
begin
// moves text to right in current sentence
MoveTextToRight;
end;
SDLK_RIGHT:
begin
// right
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Inc(AktNuta);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
Lyric.Selected := AktNuta;
end;
// ctrl + right
if SDL_ModState = KMOD_LCTRL then begin
if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
if AktNuta = 0 then begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
end;
end;
end;
// shift + right
if SDL_ModState = KMOD_LSHIFT then begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
if AktNuta = 0 then begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
end;
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
end;
// alt + right
if SDL_ModState = KMOD_LALT then begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
end;
// alt + ctrl + shift + right = move all from cursor to right
if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
MoveAllToEnd(1);
end;
end;
SDLK_LEFT:
begin
// left
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Dec(AktNuta);
if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
Lyric.Selected := AktNuta;
end;
// ctrl + left
if SDL_ModState = KMOD_LCTRL then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
if AktNuta = 0 then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
end;
end;
// shift + left
if SDL_ModState = KMOD_LSHIFT then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
// resizing sentences
if AktNuta = 0 then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
end;
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
end;
// alt + left
if SDL_ModState = KMOD_LALT then begin
if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
end;
end;
// alt + ctrl + shift + right = move all from cursor to left
if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
MoveAllToEnd(-1);
end;
end;
SDLK_DOWN:
begin
// skip to next sentence
if SDL_ModState = 0 then begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Inc(Czesci[0].Akt);
AktNuta := 0;
if Czesci[0].Akt > Czesci[0].High then Czesci[0].Akt := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
Lyric.AddCzesc(Czesci[0].Akt);
Lyric.Selected := 0;
Music.Stop;
PlaySentence := false;
end;
// decrease tone
if SDL_ModState = KMOD_LCTRL then begin
TransposeNote(-1);
end;
end;
SDLK_UP:
begin
// skip to previous sentence
if SDL_ModState = 0 then begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Dec(Czesci[0].Akt);
AktNuta := 0;
if Czesci[0].Akt = -1 then Czesci[0].Akt := Czesci[0].High;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
Lyric.AddCzesc(Czesci[0].Akt);
Lyric.Selected := 0;
Music.Stop;
PlaySentence := false;
end;
// increase tone
if SDL_ModState = KMOD_LCTRL then begin
TransposeNote(1);
end;
end;
// Golden Note Patch
SDLK_G:
begin
case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
0: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 2;
1: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 2;
2: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
end; // case
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
end;
// Freestyle Note Patch
SDLK_F:
begin
case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
0:
begin;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
end;
1,2:
begin;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := True;
end;
end; // case
end;
end;
end;
end; // if
end;
function TScreenEditSub.ParseInputEditText(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
var
SDL_ModState: Word;
begin
// used when in Text Edit Mode
Result := true;
SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
If (PressedDown) Then
begin // Key Down
case PressedKey of
SDLK_ESCAPE:
begin
FadeTo(@ScreenSong);
end;
SDLK_F4, SDLK_RETURN:
begin
// Exit Text Edit Mode
TextEditMode := false;
end;
SDLK_0..SDLK_9, SDLK_A..SDLK_Z, SDLK_SPACE, SDLK_MINUS, SDLK_EXCLAIM, SDLK_COMMA, SDLK_SLASH, SDLK_ASTERISK, SDLK_QUESTION, SDLK_QUOTE, SDLK_QUOTEDBL:
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst :=
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst + chr(ScanCode);
end;
SDLK_BACKSPACE:
begin
Delete(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst,
Length(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst), 1);
end;
SDLK_RIGHT:
begin
// right
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Inc(AktNuta);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
Lyric.Selected := AktNuta;
end;
end;
SDLK_LEFT:
begin
// left
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Dec(AktNuta);
if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
Lyric.Selected := AktNuta;
end;
end;
end;
end;
end;
procedure TScreenEditSub.NewBeat;
begin
// click
{ for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeat) then begin
// old}
// Music.PlayClick;
end;
procedure TScreenEditSub.CzesciDivide;
var
C: integer;
N: integer;
begin
AktSong.BPM[0].BPM := AktSong.BPM[0].BPM / 2;
for C := 0 to Czesci[0].High do begin
Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start div 2;
Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote div 2;
Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Koniec div 2;
for N := 0 to Czesci[0].Czesc[C].HighNut do begin
Czesci[0].Czesc[C].Nuta[N].Start := Czesci[0].Czesc[C].Nuta[N].Start div 2;
Czesci[0].Czesc[C].Nuta[N].Dlugosc := Round(Czesci[0].Czesc[C].Nuta[N].Dlugosc / 2);
end; // N
end; // C
end;
procedure TScreenEditSub.CzesciMultiply;
var
C: integer;
N: integer;
begin
AktSong.BPM[0].BPM := AktSong.BPM[0].BPM * 2;
for C := 0 to Czesci[0].High do begin
Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start * 2;
Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote * 2;
Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Koniec * 2;
for N := 0 to Czesci[0].Czesc[C].HighNut do begin
Czesci[0].Czesc[C].Nuta[N].Start := Czesci[0].Czesc[C].Nuta[N].Start * 2;
Czesci[0].Czesc[C].Nuta[N].Dlugosc := Czesci[0].Czesc[C].Nuta[N].Dlugosc * 2;
end; // N
end; // C
end;
procedure TScreenEditSub.LyricsCapitalize;
var
C: integer;
N: integer; // temporary
S: string;
begin
// temporary
{ for C := 0 to Czesci[0].High do
for N := 0 to Czesci[0].Czesc[C].HighNut do
Czesci[0].Czesc[C].Nuta[N].Tekst := AnsiLowerCase(Czesci[0].Czesc[C].Nuta[N].Tekst);}
for C := 0 to Czesci[0].High do begin
S := AnsiUpperCase(Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1));
S := S + Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, Length(Czesci[0].Czesc[C].Nuta[0].Tekst)-1);
Czesci[0].Czesc[C].Nuta[0].Tekst := S;
end; // C
end;
procedure TScreenEditSub.LyricsCorrectSpaces;
var
C: integer;
N: integer;
begin
for C := 0 to Czesci[0].High do begin
// correct starting spaces in the first word
while Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1) = ' ' do
Czesci[0].Czesc[C].Nuta[0].Tekst := Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, 100);
// move spaces on the start to the end of the previous note
for N := 1 to Czesci[0].Czesc[C].HighNut do begin
while (Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, 1) = ' ') do begin
Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 2, 100);
Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
end;
end; // N
// correct '-' to '- '
for N := 0 to Czesci[0].Czesc[C].HighNut do begin
if Czesci[0].Czesc[C].Nuta[N].Tekst = '-' then
Czesci[0].Czesc[C].Nuta[N].Tekst := '- ';
end; // N
// add space to the previous note when the current word is '- '
for N := 1 to Czesci[0].Czesc[C].HighNut do begin
if Czesci[0].Czesc[C].Nuta[N].Tekst = '- ' then
Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
end; // N
// correct too many spaces at the end of note
for N := 0 to Czesci[0].Czesc[C].HighNut do begin
while Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1, 2) = ' ' do
Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1);
end; // N
// and correct if there is no space at the end of sentence
N := Czesci[0].Czesc[C].HighNut;
if Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst), 1) <> ' ' then
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N].Tekst + ' ';
end; // C
end;
procedure TScreenEditSub.FixTimings;
var
C: integer;
S: integer;
Min: integer;
Max: integer;
begin
for C := 1 to Czesci[0].High do begin
with Czesci[0].Czesc[C-1] do begin
Min := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc;
Max := Czesci[0].Czesc[C].StartNote;
case (Max - Min) of
0: S := Max;
1: S := Max;
2: S := Max - 1;
3: S := Max - 2;
else
if ((Max - Min) > 4) then
S := Min + 2
else
S := Max;
end; // case
Czesci[0].Czesc[C].Start := S;
end; // with
end; // for
end;
procedure TScreenEditSub.DivideSentence;
var
C: integer;
CStart: integer;
CNew: integer;
CLen: integer;
N: integer;
NStart: integer;
NHigh: integer;
NNewL: integer;
begin
// increase sentence length by 1
CLen := Length(Czesci[0].Czesc);
SetLength(Czesci[0].Czesc, CLen + 1);
Inc(Czesci[0].Ilosc);
Inc(Czesci[0].High);
// move needed sentences to one forward. newly has the copy of divided sentence
CStart := Czesci[0].Akt;
for C := CLen-1 downto CStart do
Czesci[0].Czesc[C+1] := Czesci[0].Czesc[C];
// clear and set new sentence
CNew := CStart + 1;
NStart := AktNuta;
Czesci[0].Czesc[CNew].Start := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
Czesci[0].Czesc[CNew].StartNote := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
Czesci[0].Czesc[CNew].Lyric := '';
Czesci[0].Czesc[CNew].LyricWidth := 0;
Czesci[0].Czesc[CNew].Koniec := 0;
Czesci[0].Czesc[CNew].BaseNote := 0; // 0.5.0: we modify it later in this procedure
Czesci[0].Czesc[CNew].IlNut := 0;
Czesci[0].Czesc[CNew].HighNut := -1;
SetLength(Czesci[0].Czesc[CNew].Nuta, 0);
// move right notes to new sentences
NHigh := Czesci[0].Czesc[CStart].HighNut;
for N := NStart to NHigh do begin
NNewL := Czesci[0].Czesc[CNew].IlNut;
SetLength(Czesci[0].Czesc[CNew].Nuta, NNewL + 1);
Czesci[0].Czesc[CNew].Nuta[NNewL] := Czesci[0].Czesc[CStart].Nuta[N];
// increase sentence counters
Inc(Czesci[0].Czesc[CNew].IlNut);
Inc(Czesci[0].Czesc[CNew].HighNut);
Czesci[0].Czesc[CNew].Koniec := Czesci[0].Czesc[CNew].Nuta[NNewL].Start +
Czesci[0].Czesc[CNew].Nuta[NNewL].Dlugosc;
end;
// clear old notes and set sentence counters
Czesci[0].Czesc[CStart].HighNut := NStart - 1;
Czesci[0].Czesc[CStart].IlNut := Czesci[0].Czesc[CStart].HighNut + 1;
Czesci[0].Czesc[CStart].Koniec := Czesci[0].Czesc[CStart].Nuta[NStart-1].Start +
Czesci[0].Czesc[CStart].Nuta[NStart-1].Dlugosc;
SetLength(Czesci[0].Czesc[CStart].Nuta, Czesci[0].Czesc[CStart].IlNut);
// 0.5.0: modify BaseNote
Czesci[0].Czesc[CNew].BaseNote := 120;
for N := 0 to Czesci[0].Czesc[CNew].IlNut do
if Czesci[0].Czesc[CNew].Nuta[N].Ton < Czesci[0].Czesc[CNew].BaseNote then
Czesci[0].Czesc[CNew].BaseNote := Czesci[0].Czesc[CNew].Nuta[N].Ton;
Czesci[0].Akt := Czesci[0].Akt + 1;
AktNuta := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.JoinSentence;
var
C: integer;
N: integer;
NStart: integer;
NDst: integer;
begin
C := Czesci[0].Akt;
// set new sentence
NStart := Czesci[0].Czesc[C].IlNut;
Czesci[0].Czesc[C].IlNut := Czesci[0].Czesc[C].IlNut + Czesci[0].Czesc[C+1].IlNut;
Czesci[0].Czesc[C].HighNut := Czesci[0].Czesc[C].HighNut + Czesci[0].Czesc[C+1].IlNut;
SetLength(Czesci[0].Czesc[C].Nuta, Czesci[0].Czesc[C].IlNut);
// move right notes to new sentences
for N := 0 to Czesci[0].Czesc[C+1].HighNut do begin
NDst := NStart + N;
Czesci[0].Czesc[C].Nuta[NDst] := Czesci[0].Czesc[C+1].Nuta[N];
end;
// increase sentence counters
NDst := Czesci[0].Czesc[C].HighNut;
Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Nuta[NDst].Start +
Czesci[0].Czesc[C].Nuta[NDst].Dlugosc;
// move needed sentences to one backward.
for C := Czesci[0].Akt + 1 to Czesci[0].High - 1 do
Czesci[0].Czesc[C] := Czesci[0].Czesc[C+1];
// increase sentence length by 1
SetLength(Czesci[0].Czesc, Length(Czesci[0].Czesc) - 1);
Dec(Czesci[0].Ilosc);
Dec(Czesci[0].High);
end;
procedure TScreenEditSub.DivideNote;
var
C: integer;
N: integer;
NLen: integer;
begin
C := Czesci[0].Akt;
NLen := Czesci[0].Czesc[C].IlNut + 1;
SetLength(Czesci[0].Czesc[C].Nuta, NLen);
Inc(Czesci[0].Czesc[C].HighNut);
Inc(Czesci[0].Czesc[C].IlNut);
// we copy all notes including selected one
for N := Czesci[0].Czesc[C].HighNut downto AktNuta+1 do begin
Czesci[0].Czesc[C].Nuta[N] := Czesci[0].Czesc[C].Nuta[N-1];
end;
// me slightly modify new note
Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc := 1;
Inc(Czesci[0].Czesc[C].Nuta[AktNuta+1].Start);
Dec(Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc);
Czesci[0].Czesc[C].Nuta[AktNuta+1].Tekst := '- ';
Czesci[0].Czesc[C].Nuta[AktNuta+1].Color := 0;
end;
procedure TScreenEditSub.DeleteNote;
var
C: integer;
N: integer;
NLen: integer;
begin
C := Czesci[0].Akt;
//Do Not delete Last Note
if (Czesci[0].High > 0) OR (Czesci[0].Czesc[C].HighNut > 0) then
begin
// we copy all notes from the next to the selected one
for N := AktNuta+1 to Czesci[0].Czesc[C].HighNut do begin
Czesci[0].Czesc[C].Nuta[N-1] := Czesci[0].Czesc[C].Nuta[N];
end;
NLen := Czesci[0].Czesc[C].IlNut - 1;
if (NLen > 0) then
begin
SetLength(Czesci[0].Czesc[C].Nuta, NLen);
Dec(Czesci[0].Czesc[C].HighNut);
Dec(Czesci[0].Czesc[C].IlNut);
// me slightly modify new note
if AktNuta > Czesci[0].Czesc[C].HighNut then Dec(AktNuta);
Czesci[0].Czesc[C].Nuta[AktNuta].Color := 1;
end
//Last Note of current Sentence Deleted - > Delete Sentence
else
begin
//Move all Sentences after the current to the Left
for N := C+1 to Czesci[0].High do
Czesci[0].Czesc[N-1] := Czesci[0].Czesc[N];
//Delete Last Sentence
SetLength(Czesci[0].Czesc, Czesci[0].High);
Czesci[0].High := High(Czesci[0].Czesc);
Czesci[0].Ilosc := Length(Czesci[0].Czesc);
AktNuta := 0;
if (C > 0) then
Czesci[0].Akt := C - 1
else
Czesci[0].Akt := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
end;
end;
end;
procedure TScreenEditSub.TransposeNote(Transpose: integer);
begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton, Transpose);
end;
procedure TScreenEditSub.ChangeWholeTone(Tone: integer);
var
C: integer;
N: integer;
begin
for C := 0 to Czesci[0].High do begin
Czesci[0].Czesc[C].BaseNote := Czesci[0].Czesc[C].BaseNote + Tone;
for N := 0 to Czesci[0].Czesc[C].HighNut do
Czesci[0].Czesc[C].Nuta[N].Ton := Czesci[0].Czesc[C].Nuta[N].Ton + Tone;
end;
end;
procedure TScreenEditSub.MoveAllToEnd(Move: integer);
var
C: integer;
N: integer;
NStart: integer;
begin
for C := Czesci[0].Akt to Czesci[0].High do begin
NStart := 0;
if C = Czesci[0].Akt then NStart := AktNuta;
for N := NStart to Czesci[0].Czesc[C].HighNut do begin
Inc(Czesci[0].Czesc[C].Nuta[N].Start, Move); // move note start
if N = 0 then begin // fix beginning
Inc(Czesci[0].Czesc[C].Start, Move);
Inc(Czesci[0].Czesc[C].StartNote, Move);
end;
if N = Czesci[0].Czesc[C].HighNut then // fix ending
Inc(Czesci[0].Czesc[C].Koniec, Move);
end; // for
end; // for
end;
procedure TScreenEditSub.MoveTextToRight;
var
C: integer;
N: integer;
NHigh: integer;
begin
{ C := Czesci[0].Akt;
for N := Czesci[0].Czesc[C].HighNut downto 1 do begin
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
end; // for
Czesci[0].Czesc[C].Nuta[0].Tekst := '- ';}
C := Czesci[0].Akt;
NHigh := Czesci[0].Czesc[C].HighNut;
// last word
Czesci[0].Czesc[C].Nuta[NHigh].Tekst := Czesci[0].Czesc[C].Nuta[NHigh-1].Tekst + Czesci[0].Czesc[C].Nuta[NHigh].Tekst;
// other words
for N := NHigh - 1 downto AktNuta + 1 do begin
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
end; // for
Czesci[0].Czesc[C].Nuta[AktNuta].Tekst := '- ';
end;
procedure TScreenEditSub.MarkSrc;
begin
CopySrc := Czesci[0].Akt;
end;
procedure TScreenEditSub.PasteText;
var
C: integer;
N: integer;
begin
C := Czesci[0].Akt;
for N := 0 to Czesci[0].Czesc[CopySrc].HighNut do
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[CopySrc].Nuta[N].Tekst;
end;
procedure TScreenEditSub.CopySentence(Src, Dst: integer);
var
N: integer;
Time1: integer;
Time2: integer;
TD: integer;
begin
Time1 := Czesci[0].Czesc[Src].Nuta[0].Start;
Time2 := Czesci[0].Czesc[Dst].Nuta[0].Start;
TD := Time2-Time1;
SetLength(Czesci[0].Czesc[Dst].Nuta, Czesci[0].Czesc[Src].IlNut);
Czesci[0].Czesc[Dst].IlNut := Czesci[0].Czesc[Src].IlNut;
Czesci[0].Czesc[Dst].HighNut := Czesci[0].Czesc[Src].HighNut;
for N := 0 to Czesci[0].Czesc[Src].HighNut do begin
Czesci[0].Czesc[Dst].Nuta[N].Tekst := Czesci[0].Czesc[Src].Nuta[N].Tekst;
Czesci[0].Czesc[Dst].Nuta[N].Dlugosc := Czesci[0].Czesc[Src].Nuta[N].Dlugosc;
Czesci[0].Czesc[Dst].Nuta[N].Ton := Czesci[0].Czesc[Src].Nuta[N].Ton;
Czesci[0].Czesc[Dst].Nuta[N].Start := Czesci[0].Czesc[Src].Nuta[N].Start + TD;
end;
N := Czesci[0].Czesc[Src].HighNut;
Czesci[0].Czesc[Dst].Koniec := Czesci[0].Czesc[Dst].Nuta[N].Start + Czesci[0].Czesc[Dst].Nuta[N].Dlugosc;
end;
procedure TScreenEditSub.CopySentences(Src, Dst, Num: integer);
var
C: integer;
begin
// create place for new sentences
SetLength(Czesci[0].Czesc, Czesci[0].Ilosc + Num - 1);
// moves sentences next to the destination
for C := Czesci[0].High downto Dst + 1 do begin
Czesci[0].Czesc[C + Num - 1] := Czesci[0].Czesc[C];
end;
// prepares new sentences: sets sentence start and create first note
for C := 1 to Num-1 do begin
Czesci[0].Czesc[Dst + C].Start := Czesci[0].Czesc[Dst + C - 1].StartNote +
(Czesci[0].Czesc[Src + C].StartNote - Czesci[0].Czesc[Src + C - 1].StartNote);
SetLength(Czesci[0].Czesc[Dst + C].Nuta, 1);
Czesci[0].Czesc[Dst + C].IlNut := 1;
Czesci[0].Czesc[Dst + C].HighNut := 0;
Czesci[0].Czesc[Dst + C].Nuta[0].Start := Czesci[0].Czesc[Dst + C].Start;
Czesci[0].Czesc[Dst + C].Nuta[0].Dlugosc := 1;
Czesci[0].Czesc[Dst + C].StartNote := Czesci[0].Czesc[Dst + C].Start;
Czesci[0].Czesc[Dst + C].Koniec := Czesci[0].Czesc[Dst + C].Start + 1;
end;
// increase counters
Czesci[0].Ilosc := Czesci[0].Ilosc + Num - 1;
Czesci[0].High := Czesci[0].High + Num - 1;
for C := 0 to Num-1 do
CopySentence(Src + C, Dst + C);
end;
constructor TScreenEditSub.Create;
begin
inherited Create;
SetLength(Player, 1);
// linijka
AddStatic(20, 10, 80, 30, 0, 0, 0, Skin.GetTextureFileName('ButtonF'), 'JPG', 'Font Black');
AddText(40, 17, 1, 6, 1, 1, 1, 'Line');
TextSentence := AddText(120, 14, 1, 8, 0, 0, 0, '0 / 0');
// nuta
AddStatic(220, 10, 80, 30, 0, 0, 0, Skin.GetTextureFileName('ButtonF'), 'JPG', 'Font Black');
AddText(242, 17, 1, 6, 1, 1, 1, 'Note');
TextNote := AddText(320, 14, 1, 8, 0, 0, 0, '0 / 0');
// file info
AddStatic(150, 50, 500, 150, 0, 0, 0, Skin.GetTextureFileName('Bar'), 'JPG', 'Font Black');
AddStatic(151, 52, 498, 146, 1, 1, 1, Skin.GetTextureFileName('Bar'), 'JPG', 'Font Black');
AddText(180, 65, 0, 8, 0, 0, 0, 'Title:');
AddText(180, 90, 0, 8, 0, 0, 0, 'Artist:');
AddText(180, 115, 0, 8, 0, 0, 0, 'Mp3:');
AddText(180, 140, 0, 8, 0, 0, 0, 'BPM:');
AddText(180, 165, 0, 8, 0, 0, 0, 'GAP:');
TextTitle := AddText(250, 65, 0, 8, 0, 0, 0, 'a');
TextArtist := AddText(250, 90, 0, 8, 0, 0, 0, 'b');
TextMp3 := AddText(250, 115, 0, 8, 0, 0, 0, 'c');
TextBPM := AddText(250, 140, 0, 8, 0, 0, 0, 'd');
TextGAP := AddText(250, 165, 0, 8, 0, 0, 0, 'e');
{ AddInteraction(2, TextTitle);
AddInteraction(2, TextArtist);
AddInteraction(2, TextMp3);
AddInteraction(2, TextBPM);
AddInteraction(2, TextGAP);}
// note info
AddText(20, 190, 0, 8, 0, 0, 0, 'Start:');
AddText(20, 215, 0, 8, 0, 0, 0, 'Duration:');
AddText(20, 240, 0, 8, 0, 0, 0, 'Tone:');
AddText(20, 265, 0, 8, 0, 0, 0, 'Text:');
TextNStart := AddText(120, 190, 0, 8, 0, 0, 0, 'a');
TextNDlugosc := AddText(120, 215, 0, 8, 0, 0, 0, 'b');
TextNTon := AddText(120, 240, 0, 8, 0, 0, 0, 'c');
TextNText := AddText(120, 265, 0, 8, 0, 0, 0, 'd');
// debug
TextDebug := AddText(30, 550, 0, 8, 0, 0, 0, '');
end;
procedure TScreenEditSub.onShow;
begin
Log.LogStatus('Initializing', 'TEditScreen.onShow');
try
ResetSingTemp;
Error := not LoadSong(Path + FileName);
except
Error := True;
end;
if Error then
begin
//Error Loading Song -> Go back to Song Screen and Show some Error Message
FadeTo(@ScreenSong);
ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
Exit;
end
else begin
MidiOut := TMidiOutput.Create(nil);
if Ini.Debug = 1 then
MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
MidiOut.Open;
Text[TextTitle].Text := AktSong.Title;
Text[TextArtist].Text := AktSong.Artist;
Text[TextMp3].Text := AktSong.Mp3;
Czesci[0].Akt := 0;
AktNuta := 0;
Czesci[0].Czesc[0].Nuta[0].Color := 1;
Music.Open(Path + AktSong.Mp3);
//Set Down Music Volume for Better hearability of Midi Sounds
//Music.SetVolume(40);
Lyric.Clear;
Lyric.X := 400;
Lyric.Y := 500;
Lyric.Align := 1;
Lyric.Size := 14;
Lyric.ColR := 0;
Lyric.ColG := 0;
Lyric.ColB := 0;
Lyric.ColSR := Skin_FontHighlightR;
Lyric.ColSG := Skin_FontHighlightG;
Lyric.ColSB := Skin_FontHighlightB;
Lyric.Style := 0;
Lyric.AddCzesc(0);
Lyric.Selected := 0;
NotesH := 7;
NotesW := 4;
end;
// Interaction := 0;
TextEditMode := false;
end;
function TScreenEditSub.Draw: boolean;
var
Min: integer;
Sec: integer;
Tekst: string;
Pet: integer;
AktBeat: integer;
begin
glClearColor(1,1,1,1);
// midi music
if PlaySentenceMidi then begin
MidiPos := USTime.GetTime - MidiTime + MidiStart;
// stop the music
if (MidiPos > MidiStop) then begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
end;
// click
AktBeat := Floor(GetMidBeat(MidiPos - AktSong.GAP / 1000));
Text[TextDebug].Text := IntToStr(AktBeat);
if AktBeat <> LastClick then begin
for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin
LastClick := AktBeat;
if Pet > 0 then
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet-1].Ton + 60, 127);
MidiOut.PutShort($91, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Ton + 60, 127);
MidiLastNote := Pet;
end;
end;
end; // if PlaySentenceMidi
// mp3 music
if PlaySentence then begin
// stop the music
if (Music.Position > PlayStopTime) then begin
Music.Stop;
PlaySentence := false;
end;
// click
if (Click) and (PlaySentence) then begin
// AktBeat := Floor(AktSong.BPM[0].BPM * (Music.Position - AktSong.GAP / 1000) / 60);
AktBeat := Floor(GetMidBeat(Music.Position - AktSong.GAP / 1000));
Text[TextDebug].Text := IntToStr(AktBeat);
if AktBeat <> LastClick then begin
for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin
Music.PlayClick;
LastClick := AktBeat;
end;
end;
end; // click
end; // if PlaySentence
Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].IlNut);
// Song info
Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4);
Text[TextGAP].Text := FloatToStr(AktSong.GAP);
//Error reading Variables when no Song is loaded
if not Error then
begin
// Note info
Text[TextNStart].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
Text[TextNDlugosc].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
Text[TextNTon].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' ( ' + GetNoteName(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' )';
Text[TextNText].Text := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
end;
// Text Edit Mode
if TextEditMode then
Text[TextNText].Text := Text[TextNText].Text + '|';
// draw static menu
inherited Draw;
// draw notes
SingDrawNoteLines(20, 300, 780, 15);
//Error Drawing when no Song is loaded
if not Error then
begin
SingDrawBeatDelimeters(40, 300, 760, 0);
EditDrawCzesc(40, 405, 760, 0, 15);
end;
// draw text
Lyric.Draw;
end;
procedure TScreenEditSub.onHide;
begin
MidiOut.Close;
MidiOut.Free;
//Music.SetVolume(100);
end;
function TScreenEditSub.GetNoteName(Note: Integer): String;
var N1, N2: Integer;
begin
N1 := Note mod 12;
N2 := Note div 12;
case N1 of
0: Result := 'c';
1: Result := 'c#';
2: Result := 'd';
3: Result := 'd#';
4: Result := 'e';
5: Result := 'f';
6: Result := 'f#';
7: Result := 'g';
8: Result := 'g#';
9: Result := 'a';
10: Result := 'b';
11: Result := 'h';
end;
case N2 of
0: Result := UpperCase(Result); //Normal Uppercase Note, 1: Normal lowercase Note
2: Result := Result + ''''; //One Striped
3: Result := Result + ''''''; //Two Striped
4: Result := Result + ''''''''; //etc.
5: Result := Result + '''''''''';
6: Result := Result + '''''''''''';
7: Result := Result + '''''''''''''';
end;
end;
end.