Link to home
Start Free TrialLog in
Avatar of harry_haller
harry_haller

asked on

how to make automatic edit of a text file

hello, i have a little problem..
first i will tell you what i try to do: i have .cue files that look like this (in notepad):
PERFORMER "Stravinsky"
TITLE "Igor Stravinsky Edition, Vol. 03 of 12, Ballets Vol. I (Disc 2 of 3)"
FILE "CDImage2.ape" APE
  TRACK 01 AUDIO
    TITLE "Petrushka - Scene 1 - I. The Shrove-Tide Fair"
    PERFORMER "Stravinsky"
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    TITLE "Petrushka - Scene 1 - II. The Crowds"
    PERFORMER "Stravinsky"
    INDEX 01 00:50:30
and so on..
i need them to be in a text file like this (open the .cue file edit it and save as new text file):

Igor Stravinsky Edition, Vol. 03 of 12, Ballets Vol. I (Disc 2 of 3) ([Total Time])
Performer: Stravinsky

01. "Petrushka - Scene 1 - I. The Shrove-Tide Fair" (0:50)
02. "Petrushka - Scene 1 - II. The
 Crowds" (4:19)


i was doing this manually at first but i closed notepad by accident after editing 3 cue files and i just thought theres gotta be an easier way...
besides i have a lot of music and it will be really annoying to do it manually when it could be done automatically.
i really have no idea of how to make this and any help or idea will be appreciated.
Avatar of harry_haller
harry_haller

ASKER

so i was thinking about it and i guess it would have to be something like this: search for a string and then assign the text inside quotes next to the string as a variable.
so it reads the text in the file:
PERFORMER "someone"
TITLE "something"
FILE "file.."
  TRACK 01 AUDIO
    TITLE "songtitle1"
    PERFORMER "aguy"
    INDEX (time stuff)
  TRACK 02 AUDIO
    TITLE "songtitle2"
    PERFORMER "aguy"
    INDEX (time stuff)
and then it would write a new textfile like this:
something
someone
01. songtitle1
02. songtitle2

and the time stuff next to each song.

p.d: i know maybe its not so clear, its kinda hard to explain too, ill wait for ur ideas, code or whatever =)

may be u can open the cue file and save information in variables, then opened a new text file and write out the values
I dont have Delphi opened at the moment
But it can be something like this (there might be some syntax errors =P)

procedure readfile;
var inF: TextFile;
     s: string;
     pos1,pos2: integer;
begin
 assignfile(inF,'bla.cue');
reset(inF);
readln(inF,s);

// extract "someone"
pos1:=pos(s, '"'); //position of first "
pos2:=posex(s,'"',pos1+1); //position of second "
performer := midstr(s,pos1+1,pos2-pos1-1); // the value between " "

// extract title...

// read tracks into array (eg. arrTrack)
while not eof(inF) do
begin
//read each track number
//read track title
//read track performer
//read track index
end;

end;

procedure writefile
var outF: textfile;
begin
  assignfile(outF,'newbla.txt');
  rewrite(outF);
writeln(outF,title);
writeln(outF,performer);

for i:=0 to Length(arrTrack) do
begin
  //write out each track
end;

end;
unit Unit1_Q_21789082;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls, StrUtils;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox_txt: TListBox;
    Memo_cue: TMemo;
    Button2: TButton;
    OpenDialog: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    private
      FN_cue: string;
      FN_txt: string;
    { Private declarations }
    public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog.Execute then
  begin
    FN_cue := OpenDialog.FileName;
    Memo_cue.Lines.LoadFromFile(FN_cue);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  B:      Integer;
  E:      Integer;
  L:      Integer;
  PP:     Integer;
  Cnt:    Integer;
  S:      string;
  T:      string;
  R:      string;
  PR:     string;
  RR:     string;
  function  Get_Text(ST: string; F: Boolean): string;
  var
    I:      Integer;
    J:      Integer;
  begin
    B := 0;
    E := 0;
    S := '';
    try
      if F then
        PP := Pos(ST, T)
      else
        PP := PosEx(ST, T, PP+Length(ST));
      if (PP>0) then
      begin
        J := PP + 5;
        while ((J<L) and (E=0)) do
        begin
          if (T[J]='"') then
          begin
            if (B=0) then
              B := J
            else
              E := J;
          end;
          Inc(J);
        end;
        SetLength(S, E-B+1);
        for I := B to E do
          S[I-B+1] := T[I];
      end;
    finally
      Result := S;
    end;
  end;
begin
  if (FN_cue<>'') then
  begin
    PP := 0;
    R := '';
    ListBox_txt.Clear;
    T := Memo_cue.Text;
    L := Length(T);
    FN_txt := ExtractFileName(FN_cue) + '.txt';

    PR := Get_Text('PERFORMER', True);
    PP := 0;
    Cnt := 0;
    R := Get_Text('TITLE', True);
    if (R<>'') then
    begin
      ListBox_txt.Items.Add(R);
      ListBox_txt.Items.Add(PR);
      repeat
        R := '';
        R := Get_Text('TITLE', False);
        if (R<>'') then
        begin
          Inc(Cnt);
          RR := IntToSTr(Cnt);
          while (Length(RR)<2) do
            RR := '0' + RR;
          RR := RR + '. ';
          ListBox_txt.Items.Add(RR + R);
        end;
      until (R='');
    end;
  end;
end;

end.
download an example from
page:        http://www.geocities.com/esoftbg/
  link:        Q_21789082.zip                how to make automatic edit of a text file
just one little problem:
i dunno why i got an error like this in that example when i tried to test it:
Undeclared identifier : PosEx
im using delphi 6, by the way.
im only missing that before i can test it :(
uses
  //.................................................
  , StrUtils;

PosEx is declared in StrUtils unit.

But you may download the complete example from the link above ....
Oh, may be PosEx is in Delphi 7, I don't know ....
That is the function declared into the Delphi's 7 unit StrUtils:

function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
var
  I,X: Integer;
  Len, LenSubStr: Integer;
begin
  if Offset = 1 then
    Result := Pos(SubStr, S)
  else
  begin
    I := Offset;
    LenSubStr := Length(SubStr);
    Len := Length(S) - LenSubStr + 1;
    while I <= Len do
    begin
      if S[I] = SubStr[1] then
      begin
        X := 1;
        while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do
          Inc(X);
        if (X = LenSubStr) then
        begin
          Result := I;
          exit;
        end;
      end;
      Inc(I);
    end;
    Result := 0;
  end;
end;
yea i guess it was because i use delphi 6, i added the PosEx function and it compiled fine.
im still trying to figure out how to do the time stuff; i get this:
01. "PETRUSHKA (SUITE)--The Shrove-tide Fair" 00:00:00
02. "The Crowds"  00:50:52
.
.
.
33. "Berceuse (The Firebird)"  67:34:27
34. "Final Hymn"  71:27:67

thats the time when the song starts only.
but it should be like this:

01. "PETRUSHKA (SUITE)--The Shrove-tide Fair" 00:50:52
02. "The Crowds"  00:04:17
.
.
.
33. "Berceuse (The Firebird)"  00:03:53
34. "Final Hymn"  (3:22)

and for the last one i would have to get the FILE string from the cue file and get the total time out of the .ape id tag, cuz the total time isnt showed in the .cue file

im trying to get each song time right now but i dunno how to get the total time so i can get the final song time..

btw, esoftbg u got the 300 points for that part of the answer (cuz it was nice :P), but i will add 100 more points for the time part.
when i get that part, ill split.

ill be trying to figure out that stuff, maybe ill solve it myself :D.. lol
well i did try to solve the time part, but this is as far as i got.
this is what i get with esoftbg's demo:
"A Change of Seasons"
"dream theater"
01. "a change of seasons"  00:00:00
02. "funeral for a friend-love lies bleeding"  23:08:54
03. "perfect strangers"  33:57:72
04. "the lover-achilles last stand-the song remains the same"  39:31:12
05. "the big medley"  47:00:02

the time shown is just the starting time not the time the song lasts.
all i managed to do is to take the string time (i.e:'23:08:54' and then convert it to seconds->1389 so i can then get the difference between this one and the next ('33:57:72'->2038)
so then all that would be needed is to make this:  minutes:= (2038-1389) DIV 60;
seconds:= (2038-1389) MOD 60;
and then rewrite it in the min:sec format.
and i would have the second's song time.

BUT.., the problem is that to get a song's duration it need to get the next song starting time as well..
so i would need to alter a bit the code.

besides that, i found a method to get all .cue files in a directory or root dir (for example 'E:\' ) and list them on a memo, so that way i can process them all with only one click :p

well, ill keep thinking about that tomorrow, now im really sleepy (YAWN).
ASKER CERTIFIED SOLUTION
Avatar of esoftbg
esoftbg
Flag of Bulgaria image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
dam u solved it :'(
i knew u could just alter ur functions, thats why i wanted to solve it before i fell asleep (and my code was really messy actually).
well theres still the total time issue but i just remembered that its not part of the question (edit textfile, not read ape file info :p) so this is a PAQ now XD.
thanks a lot esoftbg =)
you are welcome !
I think that the duration of the last track is impossible to be calculated :-((
mmm i thought i could get the filepath out of the .cue file and then maybe i could get the total time from the ape file.
i actually found this: http://www.torry.net/authorsmore.php?id=3243
and i thought that could do it, but i don't know why it doesn't get the right time T_T. it does get the compression info and that stuff but not the time.
its actually funny because i open the .ogg test and it did calculate the duration right, only the .ape test didn't.
so i guess ill process all my files first and then ill add the total time manually xD