amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > MP3 VBR Laufzeit berechnen [ - Suche - Neue Beiträge - Registrieren - Login - ]

1 2 3 -4- 5 6 7 [ - Beitrag schreiben - ]

06.08.2005, 18:09 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Yep, wie ich schon sagte, der library-Teil und der Datei-Einleseteil müssen angepaßt werden. Aber das sollte ja unproblematisch sein, da das Einlesen des kompletten files auch schon in den anderen Beispiel-Programmen in MBasic-Syntax enthalten ist.
Für weitere Fehler-Analysen brauche ich natürlich genauere Fehlerbeschreibungen.
Ich habe gerade das Überspringen von ID3v2 Headern eingebaut und bau jetzt Xing-Unterstützung ein und wenn's dann dergestalt optimiert ist, lasse ich es mal testweise über meine komplette mp3-Sammlung laufen, um mögliche Problemfälle zu finden :)


Sagenhaft.

Ich werde mein Prog erst mal auf die Halde werfen und mir dein Programm annehmen und es auf MBasic umlegen. Bin schon gespannt. :)

Achja, MBasic kann man *frei* aus dem Aminet runterladen. Es funktioniert 100%tig, auch speichern. Allerdings nur bis 256Zeilen. Aber das erreicht ja dieses Programm hier nicht.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

06.08.2005, 18:26 Uhr

Ralf27
Posts: 2779
Nutzer
Es läuft! :dance2: :itchy: :itchy: :bounce: :bounce: :bounce: :itchy: :itchy:

Yes. Hab es eben auch nochmal etwas optimiert. Aber es rennt. Und das wirklich sehr schnell. Gefällt mir. :)
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

06.08.2005, 18:30 Uhr

Holger
Posts: 8116
Nutzer
Na dann kommt jetzt der Nachschlag mit ID3V2 und Xing.
code:
DEFINT a-z

LIBRARY "exec.library"
DECLARE FUNCTION AllocVec&(size&,flags&) LIBRARY
DECLARE FUNCTION FreeVec(mem&) LIBRARY
LIBRARY "dos.library"
DECLARE FUNCTION _Read&(handle&,buffer&,size&) LIBRARY
DECLARE FUNCTION Seek&(handle&,pos&,rel&) LIBRARY
DECLARE FUNCTION IoErr&() LIBRARY
DECLARE FUNCTION PrintFault(code&, header&) LIBRARY
REM LIBRARY OPEN "dos.library"
REM LIBRARY OPEN "exec.library"

VERBOSE = 0

DIM tbl&(2,4,15):REM MPEG,Layer,Bitrate
FOR z=0 TO 1
 FOR y=1 TO 3
  FOR x=1 TO 14
   READ a&
   tbl&(z,y,x)=a&*1000:REM kHz, also mal 1000
  NEXT
 NEXT
NEXT
REM MPEG1
DATA 32,64,96,128,160,192,224,256,288,320,352,384,416,448
DATA 32,48,56,64,80,96,112,128,160,192,224,256,320,384
DATA 32,40,48,56,64,80,96,112,128,160,192,224,256,320
REM MPEG2
DATA 32,48,56,64,80,96,112,128,144,160,176,192,224,256
DATA 8,16,24,32,40,48,56,64,80,96,112,128,144,160
DATA 8,16,24,32,40,48,56,64,80,96,112,128,144,160

DIM Freq&(2,3):REM MPEG,Wert
FOR z=0 TO 1
 FOR x=0 TO 2
  READ Freq&(z,x)
 NEXT
NEXT

DATA 44100,48000,32000
DATA 22050,24000,16000

SUB failed(msg$)
  CLOSE #1
  PRINT "! "+msg$
  GOTO Ende
END SUB
DECLARE SUB isID%(ptr&,readable$)
DECLARE SUB extractInt28&(ptr&)
DECLARE SUB secToTime$(sec&)

IF ARGCOUNT>0 AND ARG$(ARGCOUNT)="VERBOSE" THEN VERBOSE=-1
IF ARGCOUNT>0 THEN
 filename$=ARG$(1)
ELSE
 filename$="mp3:copied/Thievery Corporation - The Cosmic Game/"
 filename$=filename$+"02 - Warning Shots (Featuring Sleepy Wonder And Gunjan).mp3"
END IF

 mpeg=0
 id3=0
 xing=0
 buf&=0

 IF VERBOSE THEN PRINT "Lese "filename$
REM OPEN filename$ FOR INPUT AS 1
OPEN "I",#1,filename$
Dateilaenge&=LOF(1)
IF Dateilaenge&=0 THEN CALL failed(filename$+" too small")
buf&=AllocVec&(Dateilaenge&,1)
IF buf&=0 THEN CALL failed("alloc buffer failed")
rd&=_Read&(HANDLE(1),buf&,Dateilaenge&)
IF Dateilaenge&>rd& THEN
  code&=ERR
  IF code&=0 THEN code&=IoErr&()
  IF code&<>0 THEN CALL PrintFault(code&, "Beim Lesen von "+filename$)
  IF code&<>0 THEN END
END IF
IF VERBOSE THEN PRINT rd&" von "Dateilaenge&" gelesen, puffer 0x"+HEX$(buf&)
Dateilaenge&=rd&
CLOSE #1

IF Dateilaenge&<10 THEN GOTO Ende

IF VERBOSE THEN PRINT"Durchsuche"

FIRST=-1
i&=0
frames&=0
REM Skip ID3v2 if present
IF isID%(buf&, "ID3") THEN
  i&=extractInt28&(buf&+6)+10
  IF VERBOSE THEN PRINT "Skipping ID3v2 Tag,"i&" bytes"
  id3=-1
END IF
WHILE i& < Dateilaenge& AND PEEK(buf&+i&)<>255
  i&=i&+1
WEND
WHILE i& < Dateilaenge&
  IF VERBOSE AND FIRST THEN
    IF i&>0 THEN
      IF i&>1 THEN PRINT PEEK(buf&+i&-2);CHR$(9);
      PRINT PEEK(buf&+i&-1);CHR$(9);
    END IF
    PRINT "> ";PEEK(buf&+i&);CHR$(9);
    PRINT PEEK(buf&+i&+1);CHR$(9); PEEK(buf&+i&+2)
  END IF
  IF PEEK(buf&+i&)<>255 OR (PEEK(buf&+i&+1) AND 224)<>224 GOTO Ende
  IF i& >= Dateilaenge& GOTO Ende
  b=PEEK(buf&+i&)
  a=PEEK(buf&+i&+1)
  IF b=255 AND (a AND 224)=224 THEN
    mpeg=-1
    REM Frame gefunden
    IF VERBOSE AND FIRST THEN PRINT "Mpeg Frame at "i&
    frames&=frames&+1
    ID=(a AND 24)8:REM 11 = MPEG 1, 00 10 = MPEG 2(.5), 01 invalid
    IF ID=3 THEN ID=0 ELSE ID=1
    Layer=4-(a AND 6)2
    IF VERBOSE AND FIRST THEN PRINT "Layer"Layer", Mpeg";(ID+1);
REM    Check=(a AND 1)
    a=PEEK(buf&+i&+2)
    IF VERBOSE AND FIRST THEN PRINT ", RateIx ";((a AND 240)16);
    Bitrate&=tbl&(ID,Layer,(a AND 240)16)
    IF VERBOSE AND FIRST THEN PRINT ", C Bitrate "Bitrate&;
    Frequenz&=Freq&(ID,(a AND 12)4)
    IF VERBOSE AND FIRST THEN PRINT ", Frequenz "Frequenz&;
    Padding=(a AND 2)2
    IF VERBOSE AND FIRST THEN PRINT ", Padding "Padding
    IF FIRST THEN
      mode%=PEEK(buf&+i&+3)64
      IF ID=0 XOR mode%<>3 THEN
        infolen%=17
      ELSE
        IF ID=0 THEN infolen%=32 ELSE infolen%=9
      END IF
      metapos&=infolen%+4+buf&+i&
      REM Info = Xing, Info := CBR, Xing := VBR
      IF isID%(metapos&, "Xing") OR isID%(metapos&, "Info") THEN
        IF VERBOSE THEN PRINT "Xing tag found"
        xing=-1
        IF PEEK(metapos&+7) AND 1 THEN
          IF VERBOSE THEN PRINT "  has frame info"
          frames&=PEEKL(metapos&+8)
          IF PEEK(metapos&+7) AND 2 THEN Dateilaenge&=PEEKL(metapos&+12)
          GOTO Ende
        END IF
      END IF
    END IF
    IF Bitrate&<=0 OR Frequenz&=0 THEN GOTO Ende
 
    IF Layer=1 THEN
      REM 384 Samples bei Layer1
      frameLength&=(12*Bitrate&Frequenz&+Padding)*4
    ELSE IF Layer=2 OR ID=0 THEN
        REM 1152 Samples Layer2 oder L3+MPEG1
        frameLength&=144*Bitrate&Frequenz&+Padding
      ELSE
        REM 576 Samples Layer3, MPEG 2 oder MPEG2.5
        frameLength&=72*Bitrate&Frequenz&+Padding
      END IF
    END IF
    IF frameLength&=0 GOTO Ende
    i&=i&+frameLength&;
  END IF
  FIRST=0
WEND

Ende:
IF buf& THEN CALL FreeVec(buf&)

IF mpeg THEN
 IF frames&<>0 AND Frequenz&<>0 THEN
   IF VERBOSE THEN PRINT"Scanned "frames&" frames"
   IF Layer=1 THEN
     REM 384 Samples bei Layer1
     sec%=384*frames&/Frequenz&
   ELSE IF Layer=2 OR ID=0 THEN
       REM 1152 Samples Layer2 oder L3+MPEG1
       sec%=1152*frames&/Frequenz&
     ELSE
       REM 576 Samples Layer3, MPEG 2 oder MPEG2.5
       sec%=576*frames&/Frequenz&
     END IF
   END IF

   PRINT filename$", Dauer:"secToTime$(sec%);
   IF id3  THEN PRINT ", (id3)";
   IF xing THEN PRINT ", (xing)";
   IF sec%<>0 THEN PRINT ", avg Bitrate:";Dateilaenge&sec%125;"kBit/s" ELSE?
 ELSE
   PRINT "invalid or unusable data"
END IF
ELSE
 PRINT filename$": no mpeg header found"
END IF
END

SUB id&(readable$)
  ptr&=SADD(readable$)
  shift&=(4-LEN(readable$))*256
  long&=PEEKL(ptr&)
  IF shift& THEN long&=long&shift&
  id&=long&
END SUB
SUB isID%(ptr&,readable$)
  cmp&=SADD(readable$)
  stp&=ptr&+LEN(readable$)
  isID%=0
  WHILE ptr&<>stp&
    IF PEEK(ptr&)<> PEEK(cmp&) THEN EXIT SUB
    ptr&=ptr&+1
    cmp&=cmp&+1
  WEND
  isID%=1
END SUB
SUB extractInt28&(ptr&)
VAL&=PEEK(ptr&) AND 127
VAL&=(VAL&*128) OR (PEEK(ptr&+1) AND 127)
VAL&=(VAL&*128) OR (PEEK(ptr&+2) AND 127)
VAL&=(VAL&*128) OR (PEEK(ptr&+3) AND 127)
extractInt28&=VAL&
END SUB
SUB secToTime$(sec&)
 min%=sec&60
 sec$=str$(sec&-min%*60)
 IF LEN(sec$)<3 THEN sec$=":0"+right$(sec$,1) ELSE sec$=":"+right$(sec$,2)
 secToTime$=str$(min%)+sec$
END SUB

Iss immer noch nicht 100%, aber 90% aller mp3s aus meiner Sammlung...

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 07.08.2005 um 13:28 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

06.08.2005, 18:37 Uhr

Holger
Posts: 8116
Nutzer
Fehlt noch ein bißchen code Aufräumen und das Einladen in kleinere Einheiten zu zerlegen, wenn man die Bitrate aus dem Header gewinnen kann, muß man ja nicht mehr die gesamte Datei einlesen.
Und den full-scan optional machen, meist sind files ohne Xing Tag ja CBR. Na ja, und die Fehler bei den "exoten" finden.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

06.08.2005, 18:37 Uhr

Ralf27
Posts: 2779
Nutzer
Hm, eins wundert mich jetzt noch: Die ID ob MPEG1 oder MPEG2.
Die wird ja jetzt nochmal gedreht, aber stimmen da dann auch die Daten in denn Datenfeldern? Z.b. Bitrate, Frequenz???
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

06.08.2005, 18:51 Uhr

Ralf27
Posts: 2779
Nutzer
Hier mal die Version in MBasic:

code:
DEFINT a-z

REM $window
REM $noerrors
REM $nolines
REM $library
REM $nodebug
REM $nobreak
REM $noevent
REM $nooverflow
REM $novarchecks
REM $noautodim
REM $noaddicon
REM $noarray
REM $nostack

REM $INCLUDE exec.bh
REM $INCLUDE dos.bh

LIBRARY OPEN "dos.library"
LIBRARY OPEN "exec.library"

DIM tbl&(2,4,15):REM MPEG,Layer,Bitrate
FOR z=0 TO 1
 FOR y=1 TO 3
  FOR x=1 TO 14
   READ a&
   tbl&(z,y,x)=a&*1000:REM kHz, also mal 1000
  NEXT
 NEXT
NEXT
REM MPEG1
DATA 32,64,96,128,160,192,224,256,288,320,352,384,416,448
DATA 32,48,56,64,80,96,112,128,160,192,224,256,320,384
DATA 32,40,48,56,64,80,96,112,128,160,192,224,256,320
REM MPEG2
DATA 32,48,56,64,80,96,112,128,144,160,176,192,224,256
DATA 8,16,24,32,40,48,56,64,80,96,112,128,144,160
DATA 8,16,24,32,40,48,56,64,80,96,112,128,144,160

DIM Freq&(2,3):REM MPEG,Wert
FOR z=0 TO 1
 FOR x=0 TO 2
  READ Freq&(z,x)
 NEXT
NEXT

DATA 44100,48000,32000
DATA 22050,24000,16000

 filename$="mp3:mp3/Badesalz/17-SanftGeburt.mp3"

 Datei&=xOpen&(SADD(filename$+CHR$(0)),MODE_OLDFILE&)
 IF Datei&=0 THEN END
 REM laenge ermitteln
 junk&=Seek&(Datei&,0,OFFSET_END&)
 Dateilaenge&=Seek&(Datei&,0,OFFSET_BEGINNING&)
 buf&=AllocMem&(Dateilaenge&,MEMF_PUBLIC&)
 IF buf& THEN rLen&=xRead&(Datei&,buf&,Dateilaenge&)
 junk&=xClose&(Datei&)
 IF buf&=0 THEN END

 PRINT "Durchsuche"
 i&=0
 frames&=0
 rates&=0
 WHILE i&<Dateilaenge& AND NOT(PEEK(buf&+i&)=255 AND (PEEK(buf&+i&+1)AND 224)=224)
  INCR i&
 WEND
 t!=TIMER
 WHILE i&<Dateilaenge& AND PEEK(buf&+i&)=255 AND (PEEK(buf&+i&+1)AND 224)=224
  a=PEEK(buf&+i&+1)
  b=PEEK(buf&+i&+2)
  IF frames&=0 THEN
   ID=(a AND 24)8
   IF ID=3 THEN ID=0 ELSE ID=1
   Layer=4-(a AND 6)2
   Frequenz&=Freq&(ID,(b AND 12)4)
  END IF
  INCR frames&
  Bitrate&=tbl&(ID,Layer,(b AND 240)16)
  rates&=rates&+Bitrate&1000
  Padding=(b AND 2)2
  IF Bitrate&=0 THEN Ende
  IF Layer=1 THEN
   REM 384 Samples bei Layer1
   frameLength&=(12*Bitrate&Frequenz&+Padding)*4
  ELSE 
   IF Layer=2 OR ID=0 THEN
    REM 1152 Samples Layer2 oder L3+MPEG1
    frameLength&=144*Bitrate&Frequenz&+Padding
   ELSE
    REM 576 Samples Layer3, MPEG 2 oder MPEG2.5
    frameLength&=72*Bitrate&Frequenz&+Padding
   END IF
  END IF
  REM IF frameLength&=0 GOTO Ende
  i&=i&+frameLength&
 WEND

Ende:
 t!=TIMER-t!
FreeMem! buf&,Dateilaenge&

 IF Frames&=0 OR Frequenz&=0 THEN PRINT "Fehler!":END

 PRINT"Scanned "frames&" frames"
 PRINT "Layer "Layer", ID "ID
 PRINT "Frequenz: "Frequenz&

 IF Layer=1 THEN
  sec=384*(frames&/Frequenz&) :REM 384 Samples bei Layer1
 ELSE
  IF Layer=2 OR ID=0 THEN
   sec=1152*(frames&/Frequenz&) :REM 1152 Samples Layer2 oder L3+MPEG1
  ELSE
   sec=576*(frames&/Frequenz&) :REM 576 Samples Layer3, MPEG 2 oder MPEG2.5
  END IF
 END IF

 mi=sec60
 sec=sec-mi*60
 IF sec<10 THEN pad$=":0" ELSE pad$=":"
 PRINT"Dauer:"STR$(mi)+pad$+RIGHT$(STR$(sec),3-LEN(pad$))
 PRINT"Avg Bitrate:"rates&/frames&"kBit/s"
 PRINT"Scandauer: "t!"sec"


EDIT: Neue Version. Ich hoffe das es richtig ist das sich die Frequenz, der Layertyp und der MPEGTyp im Stream nicht verändert.

--
http://www.alternativercomputerclub.de.vu

[ Dieser Beitrag wurde von Ralf27 am 06.08.2005 um 20:15 Uhr editiert. ]

[ Dieser Beitrag wurde von Ralf27 am 07.08.2005 um 12:41 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

06.08.2005, 19:09 Uhr

Ralf27
Posts: 2779
Nutzer
Hm, eigentlich verändert sich die Frequenz, die ID und der Layertyp im ganzen Stream nicht. Also könnte man da auch noch optimieren. Oder sind da doch Anderungen im Stream möglich?
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

06.08.2005, 20:40 Uhr

MaikG
Posts: 5172
Nutzer
>Hm, eigentlich verändert sich die Frequenz, die ID und der
>Layertyp im ganzen Stream nicht. Also könnte man da auch
>noch optimieren. Oder sind da doch Anderungen im Stream
>möglich?

Ändert sich nix, wird in meinem 1.PRG auch nur 1x
ausgelesen.
Aber das Programm läuft trotzdem nicht.
Brücksichtigst du auch das der Framesync so:
1111 1111 1111
und so
1111 1111 1110
aussehen kann?

[ - Antworten - Zitieren - Direktlink - ]

06.08.2005, 20:45 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von MaikG:
>Hm, eigentlich verändert sich die Frequenz, die ID und der
>Layertyp im ganzen Stream nicht. Also könnte man da auch
>noch optimieren. Oder sind da doch Anderungen im Stream
>möglich?

Ändert sich nix, wird in meinem 1.PRG auch nur 1x
ausgelesen.
Aber das Programm läuft trotzdem nicht.
Brücksichtigst du auch das der Framesync so:
1111 1111 1111
und so
1111 1111 1110
aussehen kann?


Nur MPEG1 und MPEG2 und kein MPEG2.5. Ich sollte es wohl doch soweit erweitern das auch MPEG2.5 läuft. :)

Also statt 240-> 224 und dann die ID mit 2 Bits auslesen statt 1 Bit.

--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

06.08.2005, 22:09 Uhr

Ralf27
Posts: 2779
Nutzer
@Holger:

code:
SUB failed(msg$)
  CLOSE #1
  PRINT "! "+msg$
  GOTO Ende
END SUB


Nun, das läuft zwar so, aber man darf so nicht aus einem Unterprogramm rausspringen. -> Stackkiller. Vor ein paar Tagen lief hier auch ein Thread wegen sowas. :)


code:
VAL&=(VAL&*128) OR (PEEK(ptr&+1) AND 127)


Leider wird hier auch einiges vom Forumskript zerhackt. Ich kann leider mit dieser Zeile recht wenig anfangen. Ich glaube auch nicht das diese im Orignal so aussieht.

Kann man im Forum nicht texte anzeigen ohne das sie verändert werden? Selbst mit dem Code-Tag geht es nicht...

--
http://www.alternativercomputerclub.de.vu

[ Dieser Beitrag wurde von Ralf27 am 06.08.2005 um 22:13 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 12:17 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Hm, eins wundert mich jetzt noch: Die ID ob MPEG1 oder MPEG2.
Die wird ja jetzt nochmal gedreht, aber stimmen da dann auch die Daten in denn Datenfeldern? Z.b. Bitrate, Frequenz???

Nun, wenn Du die Datenfelder mal mit der ursprünglichen Variante vergleichst, wirst Du feststellen, daß ich sie teilweise gedreht habe, weil sie inkonsistent waren (Bitraten und Frequenzen).
Naja, und auch fehlerhafte Daten enthielten...

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 12:28 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Nun, das läuft zwar so, aber man darf so nicht aus einem Unterprogramm rausspringen. -> Stackkiller. Vor ein paar Tagen lief hier auch ein Thread wegen sowas. :)

Nun, es handelt sich um eine Routine zum Beenden des Programms. Da ist der Stack nicht so wichtig. Ich war mir der Problematik durchaus bewußt, aber habe keine Möglichkeit gefunden, es anders zu machen.
Zumindest ace-Basic weigert sich, ein END zwischen SUB und END SUB zu akzeptieren.
Zitat:
code:
VAL&=(VAL&*128) OR (PEEK(ptr&+1) AND 127)

Leider wird hier auch einiges vom Forumskript zerhackt. Ich kann leider mit dieser Zeile recht wenig anfangen. Ich glaube auch nicht das diese im Orignal so aussieht.
Doch, die sieht genau so aus. Die Längenangabe des ID3-Tags besteht aus vier bytes, von denen nur die jeweils unteren sieben bits genutzt werden. Eine Art Zahlensystem zur Basis 128. Wenn Du den Code mit Zahlensystem-Umrechnungsroutinen vergleichst, wird er Dir Dir vertraut vorkommen.
Der Zweck ist, nebenbei gesagt, zu verhindern, daß durch bestimmte Zahlenkombination ein falscher Mpeg-Header entsteht. Im ID3v2 Tag steht niemals ein 255-byte.
Wenn ich mit die Zeile so ansehen, ist AND 127 wahrscheinlich unnötig. Aber frißt auch kein Brot bei einer maximal einmal aufgerufenen Funktion.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 12:32 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Nur MPEG1 und MPEG2 und kein MPEG2.5. Ich sollte es wohl doch soweit erweitern das auch MPEG2.5 läuft. :)

Also statt 240-> 224 und dann die ID mit 2 Bits auslesen statt 1 Bit.

Der erste Teil ist in meinem Code schon vollzogen. Habe nur beim Auslesen gespart, weil es ganz praktisch ist, Mpeg 2 und 2.5 an diversen Code-Stellen gleich zu behandeln. Ich glaube, die Frequenz ist die einzige Stelle, bei der man unterscheiden muß.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 12:33 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
code:
VAL&=(VAL&*128) OR (PEEK(ptr&+1) AND 127)

Leider wird hier auch einiges vom Forumskript zerhackt. Ich kann leider mit dieser Zeile recht wenig anfangen. Ich glaube auch nicht das diese im Orignal so aussieht.
Doch, die sieht genau so aus. Die Längenangabe des ID3-Tags besteht aus vier bytes, von denen nur die jeweils unteren sieben bits genutzt werden. Eine Art Zahlensystem zur Basis 128. Wenn Du den Code mit Zahlensystem-Umrechnungsroutinen vergleichst, wird er Dir Dir vertraut vorkommen.
Der Zweck ist, nebenbei gesagt, zu verhindern, daß durch bestimmte Zahlenkombination ein falscher Mpeg-Header entsteht. Im ID3v2 Tag steht niemals ein 255-byte.
Wenn ich mit die Zeile so ansehen, ist AND 127 wahrscheinlich unnötig. Aber frißt auch kein Brot bei einer maximal einmal aufgerufenen Funktion.
[/quote]

Es ist eigentlic unglaublich. :) Schau dir mal denn Code von dir hier im Forum an wie er an dieser stelle aussieht. Ich hab gerade diesen herrauskopiert und dann in einm (code)-Tag eingepackt und hier gepostet. Da sah es dann auf einmal richtig aus. Interesant. :)

EDIT: Ich muß eingestehn das ich nach dem Posten denn Post von mir nicht durchgesehn habe, sonst wäre mir das aufgefallen das der Code nach dem Wandeln vom (code)-Tag wieder normal aussieht.

--
http://www.alternativercomputerclub.de.vu

[ Dieser Beitrag wurde von Ralf27 am 07.08.2005 um 12:34 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 12:37 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von Ralf27:
Hm, eins wundert mich jetzt noch: Die ID ob MPEG1 oder MPEG2.
Die wird ja jetzt nochmal gedreht, aber stimmen da dann auch die Daten in denn Datenfeldern? Z.b. Bitrate, Frequenz???

Nun, wenn Du die Datenfelder mal mit der ursprünglichen Variante vergleichst, wirst Du feststellen, daß ich sie teilweise gedreht habe, weil sie inkonsistent waren (Bitraten und Frequenzen).
Naja, und auch fehlerhafte Daten enthielten...

Das ist mir gar nicht aufgefallen. Aber das mit den fehlerhaften Daten ist wieder sowas mit den Infos aus deutschen Webseiten.

Dann ist es auch kein wunder das mein ursprüngliches Programm wirklich überhaupt nicht lief.

Inzwischen suche ich bei Infos zu Programmtechnischen Dingen auch Englische Seiten mit Google ab, die dann Google aber übersetzt. Hin und wieder recht witzig, aber auch teilweise etwas verwirrend, klar...
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 12:42 Uhr

Holger
Posts: 8116
Nutzer
PS: Wenn Du meinst, daß irgendwo noch Stellen sind, die vom Forum zerhackt wurden, immer heraus damit. Ich hoffe ja, mein Script irgendwann so weit zu bekommen, daß es die Probleme alle umschiffen kann.
Größtes Problem sind momentan lange Zeilen. Da scheint bei der http-Übertragung ein erzwungenen Leerzeichen eingefügt zu werden.

mfg

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 12:45 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
PS: Wenn Du meinst, daß irgendwo noch Stellen sind, die vom Forum zerhackt wurden, immer heraus damit. Ich hoffe ja, mein Script irgendwann so weit zu bekommen, daß es die Probleme alle umschiffen kann.
Größtes Problem sind momentan lange Zeilen. Da scheint bei der http-Übertragung ein erzwungenen Leerzeichen eingefügt zu werden.

mfg


Vielleicht liegt an IBrowse, aber das glaub ich weniger.

Schau dir einfach mal die Zeile ob an, die ich dir als Beispiel gezeigt habe. Mit zerhackt meine ich, das diese Zeile verändert worden ist.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 12:58 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Vielleicht liegt an IBrowse, aber das glaub ich weniger.

Hab's mit FireFox, AWeb und IExplorer angesehen. Sieht genau so aus, wie es aussehen sollte. Inkl. highlighting. Die Veränderungen im Quellkode beruhen höchstwahrscheinlich gar nicht auf dem Forum, sondern auf meiner Konvertierung, die genau solche Probleme vermeiden soll. So werden Klammern/Zeichenkombinationen, die das Forum gerne in Smilies o.ä. umwandelt, in Html-Entities verpackt.
Ist nur blöd, wenn IBrowse diese seit ca. zehn Jahren gültigen Html-Entities nicht versteht.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 13:02 Uhr

Ralf27
Posts: 2779
Nutzer
so sieht die Zeile aus:

VAL&=(VAL&*128) OR (PEEK(ptr&+1) AND 127)

Und ich hoffe das jetzt das Forum das nicht wieder zurechtbiegt. :)

Was könnte das nur sein? Also das ) ?
(Mal sehn was daraus wird wenn ich das poste. :) )
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 13:09 Uhr

Holger
Posts: 8116
Nutzer
Habs gerade mit IBrowse angesehen.
Ja, das ist das Ergebnis meines Scripts, nicht des Forums. Eine 8, gefolgt ). Das wurde umgewandelt (warum wohl 8) ). Und zwar wurde die runde Klammer umgewandelt zu ), was die einfache Ascii-Umschreibung ist, die mit jedem Browser (außer IBrowse offenbar) funktioniert, und zwar schon so lange, daß ich gar nicht weiß, wann sie in Html eingeführt wurde (Html 2? oder war es schon Html 1, bzw. von Anfang an definiert? )

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 07.08.2005 um 13:10 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 13:15 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Und ich hoffe das jetzt das Forum das nicht wieder zurechtbiegt. :)

Das Forum hat's nicht "zurechtgebogen", aber trotzdem sehen nur IBrowse-Benutzer, was Du meinst...

mfg

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 13:15 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Habs gerade mit IBrowse angesehen.
Ja, das ist das Ergebnis meines Scripts, nicht des Forums. Eine 8, gefolgt ). Das wurde umgewandelt (warum wohl 8) ). Und zwar wurde die runde Klammer umgewandelt zu ), was die einfache Ascii-Umschreibung ist, die mit jedem Browser (außer IBrowse offenbar) funktioniert, und zwar schon so lange, daß ich gar nicht weiß, wann sie in Html eingeführt wurde (Html 2? oder war es schon Html 1, bzw. von Anfang an definiert? )


Wollte mich eben an das übersetzen deines Programmes nach MBasic machen, aber leider ist das Programm im Forum fehlerhaft und ich kann ja kaum raten wie es im Orginal aussieht. :)

Könntest du es mir bitte via EMail zukommen lassen?

EDIT: Hab es eben mit AWEB getestet. Die eine besagte Zeile geht zwar, aber dafür sind auch andere Fehlerhaft. Z.b.

IF PEEK(ptr&)<>PEEK(cmp&a mp;) THEN

Kann ja so wohl kaum laufen. :)
--
http://www.alternativercomputerclub.de.vu

[ Dieser Beitrag wurde von Ralf27 am 07.08.2005 um 13:19 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 13:26 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Könntest du es mir bitte via EMail zukommen lassen?

Schon passiert.

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 13:31 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
EDIT: Hab es eben mit AWEB getestet. Die eine besagte Zeile geht zwar, aber dafür sind auch andere Fehlerhaft. Z.b.

IF PEEK(ptr&)<>PEEK(cmp&a mp;) THEN

Das sind die schon erwähnten Leerstellen, die bei der http-Übertragung sporadisch eingefügt werden. Hab's korrigiert, noch irgendwelche Stellen?

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 14:06 Uhr

Ralf27
Posts: 2779
Nutzer
Hab eben das aktuelle Prog auf MB "portiert". Insofern hab ich auch mal portierarbeit geleistet. :)

Werde es noch ein wenig sortieren, dann hier posten.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 14:21 Uhr

Ralf27
Posts: 2779
Nutzer
Hier nun die aktuelle Version in MBasic:
code:
DEFINT a-z

REM $window
REM $errors
REM $lines
REM $library
REM $nodebug
REM $nobreak
REM $noevent
REM $nooverflow
REM $novarchecks
REM $noautodim
REM $noaddicon
REM $noarray
REM $nostack

REM $INCLUDE exec.bh
REM $INCLUDE dos.bh

LIBRARY OPEN "dos.library"
LIBRARY OPEN "exec.library"

VERBOSE=1

DIM tbl&(2,4,15):REM MPEG,Layer,Bitrate
FOR z=0 TO 1
 FOR y=1 TO 3
  FOR x=1 TO 14
   READ a&
   tbl&(z,y,x)=a&*1000:REM kHz, also mal 1000
  NEXT
 NEXT
NEXT
REM MPEG1
DATA 32,64,96,128,160,192,224,256,288,320,352,384,416,448
DATA 32,48,56,64,80,96,112,128,160,192,224,256,320,384
DATA 32,40,48,56,64,80,96,112,128,160,192,224,256,320
REM MPEG2
DATA 32,48,56,64,80,96,112,128,144,160,176,192,224,256
DATA 8,16,24,32,40,48,56,64,80,96,112,128,144,160
DATA 8,16,24,32,40,48,56,64,80,96,112,128,144,160

DIM Freq&(2,3):REM MPEG,Wert
FOR z=0 TO 1
 FOR x=0 TO 2
  READ Freq&(z,x)
 NEXT
NEXT

DATA 44100,48000,32000
DATA 22050,24000,16000

 filename$=COMMAND$
 IF filename$="" THEN filename$="mp3:mp3/Badesalz/17-SanftGeburt.mp3"

 id3=0
 xing=0
 
 xPRINT "Lese "+filename$

 Datei&=xOpen&(SADD(filename$+CHR$(0)),MODE_OLDFILE&)
 IF Datei&=0 THEN END
 REM laenge ermitteln
 junk&=Seek&(Datei&,0,OFFSET_END&)
 Dateilaenge&=Seek&(Datei&,0,OFFSET_BEGINNING&)
 bufl&=Dateilaenge&
 buf&=AllocMem&(bufl&,MEMF_PUBLIC&)
 IF buf& THEN rLen&=xRead&(Datei&,buf&,Dateilaenge&)
 junk&=xClose&(Datei&)
 IF buf&=0 THEN END

 IF Dateilaenge&>rLen& THEN
  code&=ERR
  IF code&=0 THEN code&=IoErr&()
  IF code& THEN PRINT code&, "Beim Lesen von "+filename$:END
 END IF
 IF VERBOSE THEN PRINT rLen&" von "Dateilaenge&" gelesen, puffer 0x"+HEX$(buf&)
 IF Dateilaenge&<10 THEN Ende
 
 FUNCTION isID(ptr&,readable$)
  cmp&=SADD(readable$)
  stp&=ptr&+LEN(readable$)
  isID=0
  WHILE ptr&<>stp&
   IF PEEK(ptr&)<>PEEK(cmp&)THEN EXIT FUNCTION
   INCR ptr&
   INCR cmp&
  WEND
  isID=1
 END FUNCTION
 FUNCTION extractInt28&(ptr&)
  a&=PEEK(ptr&) AND 127
  a&=(a&*128)OR(PEEK(ptr&+1)AND 127)
  a&=(a&*128)OR(PEEK(ptr&+2)AND 127)
  a&=(a&*128)OR(PEEK(ptr&+3)AND 127)
  extractInt28&=a&
 END FUNCTION

 xPRINT "Durchsuche"

 i&=0
 frames&=0
 REM Skip ID3v2 if present
 IF isID(buf&,"ID3") THEN
  i&=extractInt28&(buf&+6)+10
  xPRINT "Skipping ID3v2 Tag,"+STR$(i&)+" bytes"
  id3=-1
 END IF
 WHILE i&<Dateilaenge& AND PEEK(buf&+i&)<>255
  INCR i&
 WEND
 
 WHILE i&<Dateilaenge& AND PEEK(buf&+i&)=255 AND (PEEK(buf&+i&+1) AND 224)=224
  a=PEEK(buf&+i&+1)
  b=PEEK(buf&+i&+2)
  REM Frame gefunden
  INCR frames&
  IF frames&=1 THEN
   IF VERBOSE THEN
    IF i&>0 THEN
      IF i&>1 THEN PRINT PEEK(buf&+i&-2);CHR$(9);
      PRINT PEEK(buf&+i&-1);CHR$(9);
    END IF
    PRINT "> ";PEEK(buf&+i&);CHR$(9);
    PRINT PEEK(buf&+i&+1);CHR$(9);PEEK(buf&+i&+2)
   END IF
   ID=(a AND 24)8:REM 11 = MPEG 1, 00 10 = MPEG 2(.5), 01 invalid
   IF ID=3 THEN ID=0 ELSE ID=1
   Layer=4-(a AND 6)2
   Frequenz&=Freq&(ID,(b AND 12)4)
   IF VERBOSE THEN
    PRINT "Mpeg Frame bei"i&
    PRINT "Layer"Layer"MPEG"ID+1
    PRINT "Frequenz:"Frequenz&" Hz"
   END IF
  END IF
  Bitrate&=tbl&(ID,Layer,(b AND 240)16)
  Padding=(b AND 2)2
  
  IF frames&=1 THEN
   mode=PEEK(buf&+i&+3)64
   IF ID=0 XOR mode<>3 THEN
    infolen=17
   ELSE
    IF ID=0 THEN infolen=32 ELSE infolen=9
   END IF
   metapos&=infolen+4+buf&+i&
   REM Info = Xing, Info := CBR, Xing := VBR
   IF isID(metapos&,"Xing") OR isID(metapos&,"Info")THEN
    xPRINT"Xing gefunden"
    xing=-1
    IF PEEK(metapos&+7) AND 1 THEN
     xPRINT "hat FrameInfo"
     frames&=PEEKL(metapos&+8)
     IF PEEK(metapos&+7) AND 2 THEN Dateilaenge&=PEEKL(metapos&+12)
     GOTO Ende
    END IF
   END IF
  END IF
  IF Bitrate&<=0 OR Frequenz&=0 THEN Ende
 
  IF Layer=1 THEN
   REM 384 Samples bei Layer1
   frameLength&=(12*Bitrate&Frequenz&+Padding)*4
  ELSE
   IF Layer=2 OR ID=0 THEN
    REM 1152 Samples Layer2 oder L3+MPEG1
    frameLength&=144*Bitrate&Frequenz&+Padding
   ELSE
    REM 576 Samples Layer3, MPEG 2 oder MPEG2.5
    frameLength&=72*Bitrate&Frequenz&+Padding
   END IF
  END IF
  IF frameLength&=0 GOTO Ende
  i&=i&+frameLength&  
 WEND

Ende:
 IF buf& THEN FreeMem! buf&,bufl&

 IF frames& THEN
  IF frames& AND Frequenz& THEN
   xPRINT "Scanned"+STR$(frames&)+" frames"
   IF Layer=1 THEN
    REM 384 Samples bei Layer1
    sec=384*(frames&/Frequenz&)
   ELSE
    IF Layer=2 OR ID=0 THEN
     REM 1152 Samples Layer2 oder Layer3+MPEG1
     sec=1152*(frames&/Frequenz&)
    ELSE
     REM 576 Samples Layer3, MPEG 2 oder MPEG2.5
     sec=576*(frames&/Frequenz&)
    END IF
   END IF

   PRINT filename$", Dauer:"secToTime$(sec);
   IF id3  THEN PRINT ", (id3)";
   IF xing THEN PRINT ", (xing)";
   IF sec THEN PRINT ", avg Bitrate:";Dateilaenge&sec125;"kBit/s"
  ELSE
   PRINT "invalid or unusable data"
 END IF
ELSE
 PRINT filename$": no mpeg header found"
END IF
END

SUB xPRINT(t$)STATIC
 SHARED VERBOSE
 IF VERBOSE THEN PRINT t$
END SUB

SUB secToTime$(sec&)
 min%=sec&60
 sec$=str$(sec&-min%*60)
 IF LEN(sec$)<3 THEN sec$=":0"+right$(sec$,1) ELSE sec$=":"+right$(sec$,2)
 secToTime$=str$(min%)+sec$
END SUB

--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 14:39 Uhr

Holger
Posts: 8116
Nutzer
Gibt es einen wesentlichen Unterschied zwischen SUB und FUNCTION, den man kennen sollte?

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 14:45 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Gibt es einen wesentlichen Unterschied zwischen SUB und FUNCTION, den man kennen sollte?


Ich kann da jetzt nur für MBasic tippen und auch nur so wie ich es kenne:

SUBs sind nur Unterprogramme die keine Werte zurückliefern können wie die FUNCTIONs. Man kann zwar das auch machen über die Variablen bei den SUBs, aber nicht so wie du es oben im Programm gemacht hast. Dafür sollte man in MBasic die FUNCTIONs benutzen.

EDIT:
Nun, eben hab ich wirklich Bauklötze gestaunt:
secToTimes$ liefert als SUB auch bei MBasic einen Wert wie die FUNCTIONs zurück! Achgott, das geht ja auch. Immer wieder mal was neues mit MBasic. :)

EDIT2:
Das geht aber nicht mit SUBs wenn man da auch noch Strings übergibt. Also doch lieber bei FUNCTIONs bleiben, wenn sowas ist.

--
http://www.alternativercomputerclub.de.vu

[ Dieser Beitrag wurde von Ralf27 am 07.08.2005 um 15:04 Uhr editiert. ]

[ Dieser Beitrag wurde von Ralf27 am 07.08.2005 um 15:09 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 15:13 Uhr

Ralf27
Posts: 2779
Nutzer
Folgende Zeile irritiert mich auch etwas:
PRINT Dateilaenge&sec125;"kBit/s"
Da werden also auch die Header, Checksummen und sonstige Tags miteingerechnet bei der Laufzeit? Dann dürften da die kBits pro Sekunde doch eigentlich fehlerhaft sein. Oder sind diese wirklich mit allem drum und dran zu verstehn? Also auch mit Header etc.?

--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

07.08.2005, 15:38 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Dann dürften da die kBits pro Sekunde doch eigentlich fehlerhaft sein. Oder sind diese wirklich mit allem drum und dran zu verstehn? Also auch mit Header etc.?

avg steht für average, also durchschnittliche. Ob die BitRate inkl. header ist oder nicht, ist mir relativ wurscht, wenn ich z.B. die Kompression mit WAV oder CDDA vergleiche, haben die keinen solchen Header-Overhead und es wäre sinnvoll, es so zu vergleichen.
Letztendlich bezweifle ich aber, daß die Header einen sichtbaren Unterschied in der BitRate produzieren können. Deshalb spare ich mir das.
Es sei denn, Du meinst nicht die Mpeg, sondern den ID3v2 Header. Der wird zumindest für Dateien mit Xing-Tag indirekt abgezogen, weil die Dateilänge auf die effektiven Länge aus dem Tag gesetzt wird. Für Dateien ohne Xing-Tag wäre es sinnvoll, den ID3v2-Header von der Dateilänge abzuziehen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]


1 2 3 -4- 5 6 7 [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > MP3 VBR Laufzeit berechnen [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.