Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Read strings...need help!

12 views
Skip to first unread message

Michael Eriksson

unread,
Dec 20, 2002, 1:08:41 PM12/20/02
to
Hi all and Merry Christmas

I need help with reading strings out of files, this is the story...The files
are karaokefiles in format .kar (regular midi with lyrics). First I need to
find the characters @T in the file and then go back to the byte before @T
for reading the length of the string and then display the string in an
editbox without the first two characters @T. Then I need to find the next @T
in the file and do the same as above for another editbox. I'm trying to make
a databaseprogram for all my karaokefiles, then I need to read artist and
title from the files. The first @T<title> string contains title and the
second artist. There can be a lot of meta events in a .kar file...

The KAR text meta events start with an @ followed by a character indicating
the type of KAR text meta event, then followed by text for that event. The
following text meta events occur embedded in regular MIDI text events:

FileType: @KMIDI KARAOKE FILE
Version: @V0100
Information: @I<text>
Language: @LENGL
Title 1: @T<title>
Title 2: @T<author>
Title 3: @T<copyright>

So if you can make a Delphiscript that can do this I'll be very happy
because the script I use now dont read the first byte of string (length),
and I dont know how to do it because I,m just a beginner, see the code
below...

procedure TForm1.Button1Click(Sender: TObject);
var fil: TFileStream;
c: Char;
i,j: Byte;
s: String;
done: Boolean;
title: array[1..2] of String;
tempstr: array[1..4] of char;
begin
i:=0;
done:=False;
title[1]:='';
title[2]:='';
if opendialog1.execute then begin
fil:=TFileStream.Create(opendialog1.FileName,fmOpenRead or
fmShareDenyNone);
if(AnsiUpperCase(ExtractFileExt(opendialog1.filename))
=AnsiUpperCase('.kar')) then begin
fil.Read(tempstr,4);
if(tempstr='MThd') then begin
radiobutton1.checked:=true;
while(not(done)) do begin
fil.Read(c,1);
if(fil.Position >= fil.size) then done:=true;
if(c='@') then begin
fil.read(c,1);
if(c='T') then begin
inc(i);
if(i=2) then done:=true;
j:=0;
while((ord(c)<>0) and (j<50)) do begin
fil.read(c,1);
title[i]:=title[i]+c;
inc(j);
end;
end;
end;
end;
end;
if(not(radiobutton1.checked)) then begin
MessageDlg('This is not a .kar file',mtError,[mbOk],0);
end else begin
Edit1.Text:=title[1];
Edit2.Text:=title[2];
Edit3.Text:=ExtractFileName(opendialog1.filename);
s:=edit3.text;
Delete(s,length(edit3.text)+1-length(extractfileext
(edit3.text)),length(extractfileext(edit3.text)));
edit3.text:=s;
end;
end;
fil.Free;
end;
end;
end.

Please, please, please help me ;)
Michael
micke_...@hotmail.com


Ekkehard Domning

unread,
Dec 23, 2002, 7:16:29 AM12/23/02
to
Hello Michael,
I think You want somebody to do Your job. But I assume nobody has the Time for
doing it for nothing :-(

Michael Eriksson schrieb:


>
> Hi all and Merry Christmas
>
> I need help with reading strings out of files, this is the story...The files
> are karaokefiles in format .kar (regular midi with lyrics). First I need to
> find the characters @T in the file and then go back to the byte before @T
> for reading the length of the string and then display the string in an
> editbox without the first two characters @T.

Some hints anyway.

First, what do You want to do with the result. If You need this stuff only
once for information, it might be clever to build a perl script because You
can use there "regular expressions" wich makes lufe sometimes eayier.
If You want to place the result into a Database, ok, do it in a
Delphi-Program.

I dont know how the file works in detail so this must be cleared before
starting.

File analysing is a tricky job because a lot of errors are possible. My way to
do so is a "State-Engine". This State-Engine jumps from one step to the next
depending from the actually state.

Example

// Define all States Your Engine runs thru
const
karStart = 0;
karAT = 1;
karTitle = 2;
...
karDone = 99;

//define a State variable
var State : Integer;

...
// lets go
State := karStart;
while State <> karDone do
begin
case State of
//here comes the State definitions
karStart :
begin
fil.Read(c,1); // read a single Char
if c = '@' then // is it the @
State := karAT; // yes, in the next cycle do something different
end;
karAT :
begin
fil.Read(c,1); // read a single Char
case c of // Test to defined Types
'K': State := karFile;
'V': State := karVersion;
'I': State := karInfo;
'L': State := karLang;
'T': State := karTitle;
...
else
State := karError; //Unknown Tag, report Error, or Abort
end;
end;
karTitle :
begin


while((ord(c)<>0) and (j<50)) do
begin
fil.read(c,1);
title[i]:=title[i]+c;

// Save the Title to someplace
end;
State := karStart;
end;
// kar... // More states here
end;
end;


At first it looks a bit strange, but on the second view You will see that this
will lead You clear through the file.

> Please, please, please help me ;)
> Michael
> micke_...@hotmail.com

Good luck
Ekkehard

--
DomIS Internet Solution - Ekkehard Domning
Im "mCC": Industriestr. 17 - 49740 Haselünne
Mail: e...@domis.de Internet: http://www.domis.de

0 new messages