aboutsummaryrefslogtreecommitdiffstats
path: root/src/screens/UScreenEditConvert.pas
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/screens/UScreenEditConvert.pas827
1 files changed, 0 insertions, 827 deletions
diff --git a/src/screens/UScreenEditConvert.pas b/src/screens/UScreenEditConvert.pas
deleted file mode 100644
index b2fb7773..00000000
--- a/src/screens/UScreenEditConvert.pas
+++ /dev/null
@@ -1,827 +0,0 @@
-{* UltraStar Deluxe - Karaoke Game
- *
- * UltraStar Deluxe is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *}
-
-unit UScreenEditConvert;
-
-{*
- * See
- * MIDI Recommended Practice (RP-017): SMF Lyric Meta Event Definition
- * http://www.midi.org/techspecs/rp17.php
- * MIDI Recommended Practice (RP-026): SMF Language and Display Extensions
- * http://www.midi.org/techspecs/rp26.php
- * MIDI File Format
- * http://www.sonicspot.com/guide/midifiles.html
- * KMIDI File Format
- * http://gnese.free.fr/Projects/KaraokeTime/Fichiers/karfaq.html
- * http://journals.rpungin.fotki.com/karaoke/category/midi
- *
- * There are two widely spread karaoke formats:
- * - KMIDI (.kar), an inofficial midi extension by Tune 1000
- * - Standard Midi files with lyric meta-tags (SMF with lyrics, .mid).
- *
- * KMIDI uses two tracks, the first just contains a header (mostly track 2) and
- * the second the lyrics (track 3). It uses text meta tags for the lyrics.
- * SMF uses just one track (normally track 1) and uses lyric meta tags for storage.
- *
- * Most files are in the KMIDI format. Some Midi files contain both lyric types.
- *}
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- math,
- UMenu,
- SDL,
- {$IFDEF UseMIDIPort}
- MidiFile,
- MidiOut,
- {$ENDIF}
- ULog,
- USongs,
- USong,
- UMusic,
- UThemes,
- UPath;
-
-type
- TMidiNote = record
- Event: integer;
- EventType: integer;
- Channel: integer;
- Start: real;
- Len: real;
- Data1: integer;
- Data2: integer;
- Str: UTF8String; // normally ASCII
- end;
-
- TLyricType = (ltKMIDI, ltSMFLyric);
-
- TTrack = record
- Note: array of TMidiNote;
- Name: UTF8String; // normally ASCII
- Status: set of (tsNotes, tsLyrics); //< track contains notes, lyrics or both
- LyricType: set of TLyricType;
- NoteType: (ntNone, ntAvail);
- end;
-
- TNote = record
- Start: integer;
- Len: integer;
- Tone: integer;
- Lyric: UTF8String;
- NewSentence: boolean;
- end;
-
- TArrayTrack = array of TTrack;
-
- TScreenEditConvert = class(TMenu)
- private
- Tracks: TArrayTrack; // current track
- ColR: array[0..100] of real;
- ColG: array[0..100] of real;
- ColB: array[0..100] of real;
- Len: real;
- SelTrack: integer; // index of selected track
- fFileName: IPath;
-
- {$IFDEF UseMIDIPort}
- MidiFile: TMidiFile;
- MidiOut: TMidiOutput;
- {$ENDIF}
-
- BPM: real;
- Ticks: real;
- Note: array of TNote;
-
- procedure AddLyric(Start: integer; LyricType: TLyricType; Text: UTF8String);
- procedure Extract(out Song: TSong; out Lines: TLines);
-
- {$IFDEF UseMIDIPort}
- procedure MidiFile1MidiEvent(event: PMidiEvent);
- {$ENDIF}
-
- function CountSelectedTracks: integer;
-
- public
- constructor Create; override;
- procedure OnShow; override;
- function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override;
- function Draw: boolean; override;
- procedure OnHide; override;
- end;
-
-implementation
-
-uses
- SysUtils,
- TextGL,
- gl,
- UDrawTexture,
- UFiles,
- UGraphic,
- UIni,
- UMain,
- UPathUtils,
- USkins,
- ULanguage,
- UTextEncoding,
- UUnicodeUtils;
-
-const
- // MIDI/KAR lyrics are specified to be ASCII only.
- // Assume backward compatible CP1252 encoding.
- DEFAULT_ENCODING = encCP1252;
-
-const
- MIDI_EVENTTYPE_NOTEOFF = $8;
- MIDI_EVENTTYPE_NOTEON = $9;
- MIDI_EVENTTYPE_META_SYSEX = $F;
-
- MIDI_EVENT_META = $FF;
- MIDI_META_TEXT = $1;
- MIDI_META_LYRICS = $5;
-
-function TScreenEditConvert.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean;
-{$IFDEF UseMIDIPort}
-var
- SResult: TSaveSongResult;
- Playing: boolean;
- MidiTrack: TMidiTrack;
- Song: TSong;
- Lines: TLines;
-{$ENDIF}
-begin
- Result := true;
- if (PressedDown) then
- begin // Key Down
- // check normal keys
- case UCS4UpperCase(CharCode) of
- Ord('Q'):
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- {$IFDEF UseMIDIPort}
- if (MidiFile <> nil) then
- MidiFile.StopPlaying;
- {$ENDIF}
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenEdit);
- end;
-
- SDLK_RETURN:
- begin
- if Interaction = 0 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- ScreenOpen.Filename := GamePath.Append('file.mid');
- ScreenOpen.BackScreen := @ScreenEditConvert;
- FadeTo(@ScreenOpen);
- end
- else if Interaction = 1 then
- begin
- {$IFDEF UseMIDIPort}
- if (MidiFile <> nil) then
- begin
- MidiFile.OnMidiEvent := MidiFile1MidiEvent;
- //MidiFile.GoToTime(MidiFile.GetTrackLength div 2);
- MidiFile.StartPlaying;
- end;
- {$ENDIF}
- end
- else if Interaction = 2 then
- begin
- {$IFDEF UseMIDIPort}
- if (MidiFile <> nil) then
- begin
- MidiFile.OnMidiEvent := nil;
- MidiFile.StartPlaying;
- end;
- {$ENDIF}
- end
- else if Interaction = 3 then
- begin
- {$IFDEF UseMIDIPort}
- if CountSelectedTracks > 0 then
- begin
- Extract(Song, Lines);
- SResult := SaveSong(Song, Lines, fFileName.SetExtension('.txt'),
- false);
- FreeAndNil(Song);
- if (SResult = ssrOK) then
- ScreenPopupInfo.ShowPopup(Language.Translate('INFO_FILE_SAVED'))
- else
- ScreenPopupError.ShowPopup(Language.Translate('ERROR_SAVE_FILE_FAILED'));
- end
- else
- begin
- ScreenPopupError.ShowPopup(Language.Translate('EDITOR_ERROR_NO_TRACK_SELECTED'));
- end;
- {$ENDIF}
- end;
-
- end;
-
- SDLK_SPACE:
- begin
- {$IFDEF UseMIDIPort}
- if (MidiFile <> nil) then
- begin
- if (Tracks[SelTrack].NoteType = ntAvail) and
- (Tracks[SelTrack].LyricType <> []) then
- begin
- if (Tracks[SelTrack].Status = []) then
- Tracks[SelTrack].Status := [tsNotes]
- else if (Tracks[SelTrack].Status = [tsNotes]) then
- Tracks[SelTrack].Status := [tsLyrics]
- else if (Tracks[SelTrack].Status = [tsLyrics]) then
- Tracks[SelTrack].Status := [tsNotes, tsLyrics]
- else if (Tracks[SelTrack].Status = [tsNotes, tsLyrics]) then
- Tracks[SelTrack].Status := [];
- end
- else if (Tracks[SelTrack].NoteType = ntAvail) then
- begin
- if (Tracks[SelTrack].Status = []) then
- Tracks[SelTrack].Status := [tsNotes]
- else
- Tracks[SelTrack].Status := [];
- end
- else if (Tracks[SelTrack].LyricType <> []) then
- begin
- if (Tracks[SelTrack].Status = []) then
- Tracks[SelTrack].Status := [tsLyrics]
- else
- Tracks[SelTrack].Status := [];
- end;
-
- Playing := (MidiFile.GetCurrentTime > 0);
- MidiFile.StopPlaying();
- MidiTrack := MidiFile.GetTrack(SelTrack);
- if tsNotes in Tracks[SelTrack].Status then
- MidiTrack.OnMidiEvent := MidiFile1MidiEvent
- else
- MidiTrack.OnMidiEvent := nil;
- if (Playing) then
- MidiFile.ContinuePlaying();
- end;
- {$ENDIF}
- end;
-
- SDLK_RIGHT:
- begin
- InteractNext;
- end;
-
- SDLK_LEFT:
- begin
- InteractPrev;
- end;
-
- SDLK_DOWN:
- begin
- Inc(SelTrack);
- if SelTrack > High(Tracks) then
- SelTrack := 0;
- end;
- SDLK_UP:
- begin
- Dec(SelTrack);
- if SelTrack < 0 then
- SelTrack := High(Tracks);
- end;
- end;
- end;
-end;
-
-procedure TScreenEditConvert.AddLyric(Start: integer; LyricType: TLyricType; Text: UTF8String);
-var
- N: integer;
-begin
- // find corresponding note
- N := 0;
- while (N <= High(Note)) do
- begin
- if Note[N].Start = Start then
- Break;
- Inc(N);
- end;
-
- // check if note was found
- if (N > High(Note)) then
- Exit;
-
- // set text
- if (LyricType = ltKMIDI) then
- begin
- // end of paragraph
- if Copy(Text, 1, 1) = '\' then
- begin
- Delete(Text, 1, 1);
- end
- // end of line
- else if Copy(Text, 1, 1) = '/' then
- begin
- Delete(Text, 1, 1);
- Note[N].NewSentence := true;
- end;
- end
- else // SMFLyric
- begin
- // Line Feed -> end of paragraph
- if Copy(Text, 1, 1) = #$0A then
- begin
- Delete(Text, 1, 1);
- end
- // Carriage Return -> end of line
- else if Copy(Text, 1, 1) = #$0D then
- begin
- Delete(Text, 1, 1);
- Note[N].NewSentence := true;
- end;
- end;
-
- // overwrite lyric or append
- if Note[N].Lyric = '-' then
- Note[N].Lyric := Text
- else
- Note[N].Lyric := Note[N].Lyric + Text;
-end;
-
-procedure TScreenEditConvert.Extract(out Song: TSong; out Lines: TLines);
-
-var
- T: integer;
- C: integer;
- N: integer;
- Nu: integer;
- NoteTemp: TNote;
- Move: integer;
- Max, Min: integer;
- LyricType: TLyricType;
- Text: UTF8String;
-begin
- // song info
- Song := TSong.Create();
- Song.Clear();
- Song.Resolution := 4;
- SetLength(Song.BPM, 1);
- Song.BPM[0].BPM := BPM*4;
- SetLength(Note, 0);
-
- // extract notes
- for T := 0 to High(Tracks) do
- begin
- if tsNotes in Tracks[T].Status then
- begin
- for N := 0 to High(Tracks[T].Note) do
- begin
- if (Tracks[T].Note[N].EventType = MIDI_EVENTTYPE_NOTEON) and
- (Tracks[T].Note[N].Data2 > 0) then
- begin
- Nu := Length(Note);
- SetLength(Note, Nu + 1);
- Note[Nu].Start := Round(Tracks[T].Note[N].Start / Ticks);
- Note[Nu].Len := Round(Tracks[T].Note[N].Len / Ticks);
- Note[Nu].Tone := Tracks[T].Note[N].Data1 - 12*5;
- Note[Nu].Lyric := '-';
- end;
- end;
- end;
- end;
-
- // extract lyrics (and artist + title info)
- for T := 0 to High(Tracks) do
- begin
- if not (tsLyrics in Tracks[T].Status) then
- Continue;
-
- for N := 0 to High(Tracks[T].Note) do
- begin
- if (Tracks[T].Note[N].Event = MIDI_EVENT_META) then
- begin
- // determine and validate lyric meta tag
- if (ltKMIDI in Tracks[T].LyricType) and
- (Tracks[T].Note[N].Data1 = MIDI_META_TEXT) then
- begin
- Text := Tracks[T].Note[N].Str;
-
- // check for meta info
- if (Length(Text) > 2) and (Text[1] = '@') then
- begin
- case Text[2] of
- 'L': Song.Language := Copy(Text, 3, Length(Text)); // language
- 'T': begin // title info
- if (Song.Artist = '') then
- Song.Artist := Copy(Text, 3, Length(Text))
- else if (Song.Title = '') then
- Song.Title := Copy(Text, 3, Length(Text));
- end;
- end;
- Continue;
- end;
-
- LyricType := ltKMIDI;
- end
- else if (ltSMFLyric in Tracks[T].LyricType) and
- (Tracks[T].Note[N].Data1 = MIDI_META_LYRICS) then
- begin
- LyricType := ltSMFLyric;
- end
- else
- begin
- // unknown meta event
- Continue;
- end;
-
- AddLyric(Round(Tracks[T].Note[N].Start / Ticks), LyricType, Tracks[T].Note[N].Str);
- end;
- end;
- end;
-
- // sort notes
- for N := 0 to High(Note) do
- for Nu := 0 to High(Note)-1 do
- if Note[Nu].Start > Note[Nu+1].Start then
- begin
- NoteTemp := Note[Nu];
- Note[Nu] := Note[Nu+1];
- Note[Nu+1] := NoteTemp;
- end;
-
- // move to 0 at beginning
- Move := Note[0].Start;
- for N := 0 to High(Note) do
- Note[N].Start := Note[N].Start - Move;
-
- // copy notes
- SetLength(Lines.Line, 1);
- Lines.Number := 1;
- Lines.High := 0;
- Lines.Current := 0;
- Lines.Resolution := 0;
- Lines.NotesGAP := 0;
- Lines.ScoreValue := 0;
-
- C := 0;
- N := 0;
- Lines.Line[C].HighNote := -1;
-
- for Nu := 0 to High(Note) do
- begin
- if Note[Nu].NewSentence then // new line
- begin
- SetLength(Lines.Line, Length(Lines.Line)+1);
- Lines.Number := Lines.Number + 1;
- Lines.High := Lines.High + 1;
- C := C + 1;
- N := 0;
- SetLength(Lines.Line[C].Note, 0);
- Lines.Line[C].HighNote := -1;
-
- //Calculate Start of the Last Sentence
- if (C > 0) and (Nu > 0) then
- begin
- Max := Note[Nu].Start;
- Min := Note[Nu-1].Start + Note[Nu-1].Len;
-
- case (Max - Min) of
- 0: Lines.Line[C].Start := Max;
- 1: Lines.Line[C].Start := Max;
- 2: Lines.Line[C].Start := Max - 1;
- 3: Lines.Line[C].Start := Max - 2;
- else
- if ((Max - Min) > 4) then
- Lines.Line[C].Start := Min + 2
- else
- Lines.Line[C].Start := Max;
-
- end; // case
-
- end;
- end;
-
- // create space for new note
- SetLength(Lines.Line[C].Note, Length(Lines.Line[C].Note)+1);
- Inc(Lines.Line[C].HighNote);
-
- // initialize note
- Lines.Line[C].Note[N].Start := Note[Nu].Start;
- Lines.Line[C].Note[N].Length := Note[Nu].Len;
- Lines.Line[C].Note[N].Tone := Note[Nu].Tone;
- Lines.Line[C].Note[N].Text := DecodeStringUTF8(Note[Nu].Lyric, DEFAULT_ENCODING);
- Lines.Line[C].Note[N].NoteType := ntNormal;
- Inc(N);
- end;
-end;
-
-function TScreenEditConvert.CountSelectedTracks: integer;
-var
- T: integer; // track
-begin
- Result := 0;
- for T := 0 to High(Tracks) do
- if tsNotes in Tracks[T].Status then
- Inc(Result);
-end;
-
-{$IFDEF UseMIDIPort}
-procedure TScreenEditConvert.MidiFile1MidiEvent(event: PMidiEvent);
-begin
- //Log.LogStatus(IntToStr(event.event), 'MIDI');
- try
- MidiOut.PutShort(event.event, event.data1, event.data2);
- except
- MidiFile.StopPlaying();
- end;
-end;
-{$ENDIF}
-
-constructor TScreenEditConvert.Create;
-var
- P: integer;
-begin
- inherited Create;
- AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(15, 5, 0, 0, 0, 'Open');
- //Button[High(Button)].Text[0].Size := 11;
-
- AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(25, 5, 0, 0, 0, 'Play');
-
- AddButton(280, 20, 200, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(25, 5, 0, 0, 0, 'Play Selected');
-
- AddButton(500, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(20, 5, 0, 0, 0, 'Save');
-
- fFileName := PATH_NONE;
-
- for P := 0 to 100 do
- begin
- ColR[P] := Random(10)/10;
- ColG[P] := Random(10)/10;
- ColB[P] := Random(10)/10;
- end;
-
-end;
-
-procedure TScreenEditConvert.OnShow;
-var
- T: integer; // track
- N: integer; // note
- {$IFDEF UseMIDIPort}
- MidiTrack: TMidiTrack;
- MidiEvent: PMidiEvent;
- {$ENDIF}
- FileOpened: boolean;
- KMIDITrackIndex, SMFTrackIndex: integer;
-begin
- inherited;
-
- Interaction := 0;
-
-{$IFDEF UseMIDIPort}
- MidiOut := TMidiOutput.Create(nil);
- Log.LogInfo(MidiOut.ProductName, 'MIDI');
- MidiOut.Open;
- MidiFile := nil;
- SetLength(Tracks, 0);
-
- // Filename is only <> PATH_NONE if we called the OpenScreen before
- fFilename := ScreenOpen.Filename;
- if (fFilename = PATH_NONE) then
- Exit;
- ScreenOpen.Filename := PATH_NONE;
-
- FileOpened := false;
- if fFileName.Exists then
- begin
- MidiFile := TMidiFile.Create(nil);
- MidiFile.Filename := fFileName;
- try
- MidiFile.ReadFile;
- FileOpened := true;
- except
- MidiFile.Free;
- end;
- end;
-
- if (not FileOpened) then
- begin
- ScreenPopupError.ShowPopup(Language.Translate('ERROR_FILE_NOT_FOUND'));
- Exit;
- end;
-
- Len := 0;
- SelTrack := 0;
- BPM := MidiFile.Bpm;
- Ticks := MidiFile.TicksPerQuarter / 4;
-
- KMIDITrackIndex := -1;
- SMFTrackIndex := -1;
-
- SetLength(Tracks, MidiFile.NumberOfTracks);
- for T := 0 to MidiFile.NumberOfTracks-1 do
- Tracks[T].LyricType := [];
-
- for T := 0 to MidiFile.NumberOfTracks-1 do
- begin
- MidiTrack := MidiFile.GetTrack(T);
- MidiTrack.OnMidiEvent := nil;
- Tracks[T].Name := DecodeStringUTF8(MidiTrack.getName, DEFAULT_ENCODING);
- Tracks[T].NoteType := ntNone;
- Tracks[T].Status := [];
-
- SetLength(Tracks[T].Note, MidiTrack.getEventCount());
- for N := 0 to MidiTrack.getEventCount-1 do
- begin
- MidiEvent := MidiTrack.GetEvent(N);
-
- Tracks[T].Note[N].Start := MidiEvent.time;
- Tracks[T].Note[N].Len := MidiEvent.len;
- Tracks[T].Note[N].Event := MidiEvent.event;
- Tracks[T].Note[N].EventType := MidiEvent.event shr 4;
- Tracks[T].Note[N].Channel := MidiEvent.event and $0F;
- Tracks[T].Note[N].Data1 := MidiEvent.data1;
- Tracks[T].Note[N].Data2 := MidiEvent.data2;
- Tracks[T].Note[N].Str := DecodeStringUTF8(MidiEvent.str, DEFAULT_ENCODING);
-
- if (Tracks[T].Note[N].Event = MIDI_EVENT_META) then
- begin
- case (Tracks[T].Note[N].Data1) of
- MIDI_META_TEXT: begin
- // KMIDI lyrics (uses MIDI_META_TEXT events)
- if (StrLComp(PAnsiChar(Tracks[T].Note[N].Str), '@KMIDI KARAOKE FILE', 19) = 0) and
- (High(Tracks) >= T+1) then
- begin
- // The '@KMIDI ...' mark is in the first track (mostly named 'Soft Karaoke')
- // but the lyrics are in the second track (named 'Words')
- Tracks[T+1].LyricType := Tracks[T+1].LyricType + [ltKMIDI];
- KMIDITrackIndex := T+1;
- end;
- end;
- MIDI_META_LYRICS: begin
- // lyrics in Standard Midi File format found (uses MIDI_META_LYRICS events)
- Tracks[T].LyricType := Tracks[T].LyricType + [ltSMFLyric];
- SMFTrackIndex := T;
- end;
- end;
- end
- else if (Tracks[T].Note[N].EventType = MIDI_EVENTTYPE_NOTEON) then
- begin
- // notes available
- Tracks[T].NoteType := ntAvail;
- end;
-
- if Tracks[T].Note[N].Start + Tracks[T].Note[N].Len > Len then
- Len := Tracks[T].Note[N].Start + Tracks[T].Note[N].Len;
- end;
- end;
-
- // set default lyric track. Prefer KMIDI.
- if (KMIDITrackIndex > -1) then
- Tracks[KMIDITrackIndex].Status := Tracks[KMIDITrackIndex].Status + [tsLyrics]
- else if (SMFTrackIndex > -1) then
- Tracks[SMFTrackIndex].Status := Tracks[SMFTrackIndex].Status + [tsLyrics];
-{$ENDIF}
-end;
-
-function TScreenEditConvert.Draw: boolean;
-var
- Count: integer;
- Count2: integer;
- Bottom: real;
- X: real;
- Y: real;
- Height: real;
- YSkip: real;
- TrackName: UTF8String;
-begin
- // draw static menu
- inherited Draw;
-
- Y := 100;
-
- Height := min(480, 40 * Length(Tracks));
- Bottom := Y + Height;
-
- YSkip := Height / Length(Tracks);
-
- // highlight selected track
- DrawQuad(10, Y+SelTrack*YSkip, 780, YSkip, 0.8, 0.8, 0.8);
-
- // track-selection info
- for Count := 0 to High(Tracks) do
- if Tracks[Count].Status <> [] then
- DrawQuad(10, Y + Count*YSkip, 50, YSkip, 0.8, 0.3, 0.3);
- glColor3f(0, 0, 0);
- for Count := 0 to High(Tracks) do
- begin
- if Tracks[Count].NoteType = ntAvail then
- begin
- if tsNotes in Tracks[Count].Status then
- glColor3f(0, 0, 0)
- else
- glColor3f(0.7, 0.7, 0.7);
- SetFontPos(25, Y + Count*YSkip + 10);
- SetFontSize(15);
- glPrint('N');
- end;
- if Tracks[Count].LyricType <> [] then
- begin
- if tsLyrics in Tracks[Count].Status then
- glColor3f(0, 0, 0)
- else
- glColor3f(0.7, 0.7, 0.7);
- SetFontPos(40, Y + Count*YSkip + 10);
- SetFontSize(15);
- glPrint('L');
- end;
- end;
-
- DrawLine( 10, Y, 10, Bottom, 0, 0, 0);
- DrawLine( 60, Y, 60, Bottom, 0, 0, 0);
- DrawLine(790, Y, 790, Bottom, 0, 0, 0);
-
- for Count := 0 to Length(Tracks) do
- DrawLine(10, Y + Count*YSkip, 790, Y + Count*YSkip, 0, 0, 0);
-
- for Count := 0 to High(Tracks) do
- begin
- SetFontPos(65, Y + Count*YSkip);
- SetFontSize(15);
- glPrint(Tracks[Count].Name);
- end;
-
- for Count := 0 to High(Tracks) do
- begin
- for Count2 := 0 to High(Tracks[Count].Note) do
- begin
- if Tracks[Count].Note[Count2].EventType = MIDI_EVENTTYPE_NOTEON then
- DrawQuad(60 + Tracks[Count].Note[Count2].Start/Len * 725,
- Y + (Count+1)*YSkip - Tracks[Count].Note[Count2].Data1*35/127,
- 3, 3,
- ColR[Count], ColG[Count], ColB[Count]);
- if Tracks[Count].Note[Count2].EventType = 15 then
- DrawLine(60 + Tracks[Count].Note[Count2].Start/Len * 725, Y + 0.75 * YSkip + Count*YSkip,
- 60 + Tracks[Count].Note[Count2].Start/Len * 725, Y + YSkip + Count*YSkip,
- ColR[Count], ColG[Count], ColB[Count]);
- end;
- end;
-
- // playing line
- {$IFDEF UseMIDIPort}
- if (MidiFile <> nil) then
- X := 60 + MidiFile.GetCurrentTime/MidiFile.GetTrackLength*730;
- {$ENDIF}
- DrawLine(X, Y, X, Bottom, 0.3, 0.3, 0.3);
-
- Result := true;
-end;
-
-procedure TScreenEditConvert.OnHide;
-begin
-{$IFDEF UseMIDIPort}
- FreeAndNil(MidiFile);
- MidiOut.Close;
- FreeAndNil(MidiOut);
-{$ENDIF}
-end;
-
-end.