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 Letzte [ - Beitrag schreiben - ]

02.08.2005, 19:16 Uhr

MaikG
Posts: 5172
Nutzer
Weiss jemand wie man von mp3s mit Variabler Bitrate die
Laufzeit effektiv berechnen kann?

Die ganze Datei zu laden, jedes Frame raussuchen,
dann mit der durchschnittlichen Bitrate zu rechnen
dauert ein wenig lange. MakeCD und Amplifier wissen
die Laufzeit schon nach <1 sekunde. Daher müsste
es einen weg geben.

[ - Antworten - Zitieren - Direktlink - ]

02.08.2005, 20:19 Uhr

Holger
Posts: 8116
Nutzer
Es gibt zwar ein spezielles Tag, das die Information vorhält, aber nicht jedes mp3-file enthält dieses Tag. Das ist vom verwendeten encoder und natürlich auch von den verwendeten Optionen abhängig.
Bei vielen files ist das Scannen aller frames tatsächlich die einzige Möglichkeit. Trotzdem kann man das in weniger als einer Sekunde erledigen. Die Datei wird ja nicht dekodiert, sondern nur einmal linear durchsucht. Ein durchschittliches 4MB file sollte auch der älteste Amiga in eine Sekunde bewältigen.

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

[ - Antworten - Zitieren - Direktlink - ]

02.08.2005, 22:59 Uhr

DrNOP
Posts: 4118
Nutzer
Oder du schätzt. ;)
Nimm die Bitrate der ersten paar Frames, schau die Dateigröße an und schätze, wie lange das Lied wohl spielen wird ... (Es gibt sogar mindestens ein käufliches Produkt, das so vorgeht ...)
--
Es gibt keine Notbremse für all den technischen Humbug, mit dem wir unsere Zeit vertrödeln.

[ - Antworten - Zitieren - Direktlink - ]

02.08.2005, 23:11 Uhr

MaikG
Posts: 5172
Nutzer
>Es gibt zwar ein spezielles Tag, das die Information
>vorhält, aber nicht jedes mp3-file enthält dieses Tag.

Wie lautet dieser?

>Die Datei wird ja nicht dekodiert, sondern nur einmal
>linear durchsucht. Ein durchschittliches 4MB file sollte
>auch der älteste Amiga in eine Sekunde bewältigen.

Mein Programm braucht dafür mind. 2 Minuten, 0,5Min schon
zum laden in den Speicher.
Ich könnte das noch Optimieren aber auf eine Sekunde
werde ich dadurch nicht kommen

Der Source geht so bei VBR:

IF a$="Xing" THEN
OPEN Datei$ FOR INPUT AS 1
dat$=INPUT$(Dateilaenge&,#1)
CLOSE #1

FOR i&=1 TO Dateilaenge&
IF MID$(dat$,i&,1)=CHR$(255) THEN
a$=MID$(dat$,i&+1,1)
tmp$=RIGHT$("0000"+BIN$(ASC(a$)),8)
IF LEFT$(tmp$,4)<>"1111" AND LEFT$(tmp$,4)<>"1110" THEN 199
a$=MID$(dat$,i&+2,1)
tmp$=BIN$(ASC(a$))
Bitrate$=LEFT$(tmp$,4)
IF layer$="01" THEN taby%=3
IF layer$="10" THEN taby%=2
IF layer$="11" THEN taby%=1
IF bitrate$="0001" THEN tabx%=1
IF bitrate$="0010" THEN tabx%=2
IF bitrate$="0011" THEN tabx%=3
IF bitrate$="0100" THEN tabx%=4
IF bitrate$="0101" THEN tabx%=5
IF bitrate$="0110" THEN tabx%=6
IF bitrate$="0111" THEN tabx%=7
IF bitrate$="1000" THEN tabx%=8
IF bitrate$="1001" THEN tabx%=9
IF bitrate$="1010" THEN tabx%=10
IF bitrate$="1011" THEN tabx%=11
IF bitrate$="1100" THEN tabx%=12
IF bitrate$="1101" THEN tabx%=13
IF bitrate$="1110" THEN tabx%=14
bitrate&=tbl%(tabx%,taby%)

Bitraten&=Bitraten&+Bitrate&
INCR frameanz&


[ Dieser Beitrag wurde von MaikG am 02.08.2005 um 23:12 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 00:14 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von MaikG:
>Es gibt zwar ein spezielles Tag, das die Information
>vorhält, aber nicht jedes mp3-file enthält dieses Tag.

Wie lautet dieser?

>Die Datei wird ja nicht dekodiert, sondern nur einmal
>linear durchsucht. Ein durchschittliches 4MB file sollte
>auch der älteste Amiga in eine Sekunde bewältigen.

Mein Programm braucht dafür mind. 2 Minuten, 0,5Min schon
zum laden in den Speicher.
Ich könnte das noch Optimieren aber auf eine Sekunde
werde ich dadurch nicht kommen

Der Source geht so bei VBR:

IF a$="Xing" THEN
OPEN Datei$ FOR INPUT AS 1
dat$=INPUT$(Dateilaenge&,#1)
CLOSE #1

FOR i&=1 TO Dateilaenge&
IF MID$(dat$,i&,1)=CHR$(255) THEN
a$=MID$(dat$,i&+1,1)
tmp$=RIGHT$("0000"+BIN$(ASC(a$)),8)
IF LEFT$(tmp$,4)<>"1111" AND LEFT$(tmp$,4)<>"1110" THEN 199
a$=MID$(dat$,i&+2,1)
tmp$=BIN$(ASC(a$))
Bitrate$=LEFT$(tmp$,4)
IF layer$="01" THEN taby%=3
IF layer$="10" THEN taby%=2
IF layer$="11" THEN taby%=1
IF bitrate$="0001" THEN tabx%=1
IF bitrate$="0010" THEN tabx%=2
IF bitrate$="0011" THEN tabx%=3
IF bitrate$="0100" THEN tabx%=4
IF bitrate$="0101" THEN tabx%=5
IF bitrate$="0110" THEN tabx%=6
IF bitrate$="0111" THEN tabx%=7
IF bitrate$="1000" THEN tabx%=8
IF bitrate$="1001" THEN tabx%=9
IF bitrate$="1010" THEN tabx%=10
IF bitrate$="1011" THEN tabx%=11
IF bitrate$="1100" THEN tabx%=12
IF bitrate$="1101" THEN tabx%=13
IF bitrate$="1110" THEN tabx%=14
bitrate&=tbl%(tabx%,taby%)

Bitraten&=Bitraten&+Bitrate&
INCR frameanz&


[ Dieser Beitrag wurde von MaikG am 02.08.2005 um 23:12 Uhr editiert. ]


Also, an diesem Code kann man noch einiges optimieren damit es schneller läuft, wenn es schneller, übersichtlicher laufen soll.

1. benutze die Dos-Funktionen
2. wandle nicht laufend hin und her. Vorallem das
code:
IF MID$(dat$,i&,1)=CHR$(255) THEN

haut mir auf die Augen. :) Versuch doch da z.b.
code:
IF peek(i&)=255 then

Wobei i& einfach ein Zeiger auf die Position im Speicher ist. Der Rest noch überarbeiten. Wobei es doch besser wäre einfacher mit AllocMem einen Speicher zu holen. Das ganze frist doch so unglaublich viel Stringspeicher. Und außerdem wäre es eigentlich "richtiger". :)
Das dürfte da schon einiges bewirken. Und vorallem nicht laufend hin und hier wandeln. Das frist einiges an CPU.
3. durchschau dir nochmal den code. Da gibt es einiges zu überarbeiten und da wirst du gleich um Faktoren schneller. :)
Im allgemeinen müßte man eigentlich den ganzen Code da oben überarbeiten. Die ganzen Erfahrungen hab ich übrigens mit meinem BMP-Reader gemacht, der auch immer schneller wird. Da sieht man mal was man alles falsch Programmieren kann was zwar auch geht, aber halt nicht alles aus MBasic rausholt. :)

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

[ Dieser Beitrag wurde von Ralf27 am 03.08.2005 um 00:24 Uhr editiert. ]

[ Dieser Beitrag wurde von Ralf27 am 03.08.2005 um 00:30 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 00:28 Uhr

Ralf27
Posts: 2779
Nutzer
Was für ein Programm schreibst du denn eben in MBasic? Wie schon geschrieben bin ich sehr an einem Erfahrungsaustausch interesiert.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 10:35 Uhr

MaikG
Posts: 5172
Nutzer
>1. benutze die Dos-Funktionen

Die meisten Dosfunktionen sind erst bei 10000 durchläufen schneller.

>2. wandle nicht laufend hin und her. Vorallem das

Das Problem ist MB hat keine Funktion wie &b für Variablen,
das umgekehrte schon.

>haut mir auf die Augen. :) Versuch doch da z.b.
> code:
> IF peek(i&)=255 then

Gut, mal gucken ob ich noch mit den Dos Funktionen klar komme.


>Was für ein Programm schreibst du denn eben in MBasic? Wie schon
>geschrieben bin ich sehr an einem Erfahrungsaustausch interesiert.

Eins das mir die Laufzeit von MP3 Liedern ausgibt. Ohne VBR
ja kein Problem mit muss man ebend die ganze Datei verarbeiten.

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 11:40 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Leider habe ich von Basic nicht mehr so den Plan und verstehe dein Listing nicht ganz aber ich weiss nicht ob es notwendig ist z.B. das ganze File in den Speicher zu laden und ob es nicht möglich ist mittels Seek einfach nur an die Relevanten stellen zu springen?

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 12:10 Uhr

Supimajo
Posts: 1265
Nutzer
Ich verstehe das Listing da oben zwar auch nicht, Habe aber zumindest gefunden wie man vorgehen muß um die VBR zu ermitteln:

Some files are encoded with variable bitrate mode (VBR).
To estimate the length of those files, you have to know the average bitrate of the whole file.
It often differs a lot from the bitrate of the first frame, because the lowest bitrate available is used for silence in music titles (especially at the beginning).
To get this average bitrate, you must go through all the frames in the file and calculate it, by summarizing the bitrates of each frame and dividing it through the number of frames.
Because this isn't a good practice (very slow), there exists additional VBR headers within the data section of the first frame (after the frame header).
They contain the total number of frames in the file from which you can calculate the length in seconds with the following formula:


Length = Number of Frames * Samples Per Frame / Sampling Rate



Vlt. hilt das weiter einen entsprechenden Code zu schreiben.

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 12:29 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Das Problem ist MB hat keine Funktion wie &b für Variablen,
das umgekehrte schon.

Also AmigaBasic hat eine Funktion namens VARPTR(). Bist Du Dir sicher, daß MBasic keine solche Funktion hat?
Abgesehen davon ist das beeindruckend ineffizient, was Du da machst. Du wandelst Zahlen in String-Darstellungenen ihrer Binärwerte um, um sie danach mit einer Abfolge von if... Abfragen wieder zurück in ihre Zahlenform zu wandeln?

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

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 14:02 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von MaikG:
Das Problem ist MB hat keine Funktion wie &b für Variablen,
das umgekehrte schon.

Also AmigaBasic hat eine Funktion namens VARPTR(). Bist Du Dir sicher, daß MBasic keine solche Funktion hat?
Abgesehen davon ist das beeindruckend ineffizient, was Du da machst. Du wandelst Zahlen in String-Darstellungenen ihrer Binärwerte um, um sie danach mit einer Abfolge von if... Abfragen wieder zurück in ihre Zahlenform zu wandeln?


MaikG:
Was Du suchst ist SADD() für den String, dann hast du die Adresse im Speicher.

Holger:
Das meinte ist ja, der ganze Code ist unglaublich ineffektiv. Der läuft zwar bestimmt irgendwie, aber nicht sehr schnell.
Ich denke mir auch das heute bestimmt die jungen Entwickler auf ihren GHz-Rechnern genau sowas (in der Art) proggen und da geht es dann auch, frisst aber unglaublich viel unnötige Rechenleistung.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 14:08 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von MaikG:
>1. benutze die Dos-Funktionen

Die meisten Dosfunktionen sind erst bei 10000 durchläufen schneller.

Aber sind schneller, oder? Hast du mal einen vergleich bei solch großen Dateien gemacht?
Zitat:
>2. wandle nicht laufend hin und her. Vorallem das

Das Problem ist MB hat keine Funktion wie &b für Variablen,
das umgekehrte schon.

Das versteh ich jetzt nicht. Ich glaube du denkst da in diesem Punkt nur viel zu kompliziert. Das sieht man ja an der Stringstorry.
Was für eine Funktion fehlt dir denn in MB? PEEK() ?
Zitat:
>haut mir auf die Augen. :) Versuch doch da z.b.
> code:
> IF peek(i&)=255 then

Gut, mal gucken ob ich noch mit den Dos Funktionen klar komme.

Äm, was da oben im Code steht ist komplett MB. PEEK ist ein MB-Befehl. i& ist Adresse im Speicher. Statt das hier i& bei 1 anfängt, fängt es dann bei <Speicheradresse>+0 an.
Zitat:
>Was für ein Programm schreibst du denn eben in MBasic? Wie schon
>geschrieben bin ich sehr an einem Erfahrungsaustausch interesiert.

Eins das mir die Laufzeit von MP3 Liedern ausgibt. Ohne VBR
ja kein Problem mit muss man ebend die ganze Datei verarbeiten.


Ich kenne mich da nicht aus, aber werden da nicht Blöcke benutzt? Wäre da Seek nicht besser? (Vermutung) :)
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 14:21 Uhr

Ralf27
Posts: 2779
Nutzer
Außerdem ist der Code da oben nicht komplett. Ich frag mich z.b. woher layer$ kommt. Das wird bestimmt der Layertyp sein, aber der ändert sich noch nicht wärend des Abspielens. :) Also reicht es auch hier z.b. einmal dies Abzuklären.

Ich würde auch gerne mal denn Code komplett sehn und dann mal sehn wie schnell ich das ganze hin bekomme.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 16:25 Uhr

MaikG
Posts: 5172
Nutzer
>Length = Number of Frames * Samples Per Frame / Sampling Rate


Mh, darauf bin ich auch schon gestossen, nur wenn die
Frameanzahl gegeben ist wo kommt die Sampling Rate her?
Die muss ich ja trotzdem aus der Datei holen.


>Also AmigaBasic hat eine Funktion namens VARPTR(). Bist Du Dir
>sicher, daß MBasic keine solche Funktion hat?

VARPTR, ja aber ich wüsste nicht wie ich die in dem Programm
benutzen kann.

>Abgesehen davon ist das beeindruckend ineffizient, was Du da
>machst. Du wandelst Zahlen in String-Darstellungenen ihrer
>Binärwerte um, um sie danach mit einer Abfolge von if...
>Abfragen wieder zurück in ihre Zahlenform zu wandeln?

Das muss so sein da man anders nicht an ein Teil-Binär wert
kommt. Wüsste jetzt nicht wie. Wenn ich 0101 von 0101xxxx brauche
bekomme ich das nicht anders.

>MaikG:
>Was Du suchst ist SADD() für den String, dann hast du die
>Adresse im Speicher.

SADD ist mir auch bekannt, nur wie bei VARPTR, wie anwenden?

>Aber sind schneller, oder? Hast du mal einen vergleich bei
>solch großen Dateien gemacht?

Okay bringt ca. 20-30 sekunden, benötige aber auch mit
den Dos Funktionen für EINE MP3 Datei 33 sekunden.

>Was für eine Funktion fehlt dir denn in MB? PEEK() ?

Eine Funktion einen Binären wert in einen Dezimalen wert
zu wandeln.



>Äm, was da oben im Code steht ist komplett MB. PEEK ist ein
>MB-Befehl. i& ist Adresse im Speicher. Statt das hier i& bei
>1 anfängt, fängt es dann bei <Speicheradresse>+0 an.

Ich meinte XOPEN,XCLOSE,SEEK usw.


>Ich kenne mich da nicht aus, aber werden da nicht Blöcke
>benutzt? Wäre da Seek nicht besser? (Vermutung) :)

Theoretisch ja. Handelt sich aber nur um ca. 300 Bytes
die man überspringen muss.

>Ich würde auch gerne mal denn Code komplett sehn und dann
>mal sehn wie schnell ich das ganze hin bekomme.

Nicht das ich das Forum sprenge, das Ergebniss weicht übrigens
noch um einige Sekunden der echten Länge ab.


'$INCLUDE exec.bh
'$INCLUDE dos.bh

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


DIM tbl%(14,6)
tbl%(1,1)=32:tbl%(1,2)=32:tbl%(1,3)=32:tbl%(1,4)=32:tbl%(1,5)=32:tbl%( 1,6)=8
tbl%(2,1)=64:tbl%(2,2)=48:tbl%(2,3)=40:tbl%(2,4)=64:tbl%(2,5)=48:tbl%( 2,6)=16
tbl%(3,1)=96:tbl%(3,2)=56:tbl%(3,3)=48:tbl%(3,4)=96:tbl%(3,5)=56:tbl%( 3,6)=24
tbl%(4,1)=128:tbl%(4,2)=64:tbl%(4,3)=56:tbl%(4,4)=128:tbl%(4,5)=64:tbl %(4,6)=32
tbl%(5,1)=160:tbl%(5,2)=80:tbl%(5,3)=64:tbl%(5,4)=160:tbl%(5,5)=80:tbl %(5,6)=64
tbl%(6,1)=192:tbl%(6,2)=96:tbl%(6,3)=80:tbl%(6,4)=192:tbl%(6,5)=96:tbl %(6,6)=80
tbl%(7,1)=224:tbl%(7,2)=112:tbl%(7,3)=96:tbl%(7,4)=224:tbl%(7,5)=112:t bl%(7,6)=56
tbl%(8,1)=256:tbl%(8,2)=128:tbl%(8,3)=112:tbl%(8,4)=256:tbl%(8,5)=128: tbl%(8,6)=64
tbl%(9,1)=288:tbl%(9,2)=160:tbl%(9,3)=128:tbl%(9,4)=288:tbl%(9,5)=160: tbl%(9,6)=128
tbl%(10,1)=320:tbl%(10,2)=192:tbl%(10,3)=160:tbl%(10,4)=320:tbl%(10,5) =192:tbl%(10,6)=160
tbl%(11,1)=352:tbl%(11,2)=224:tbl%(11,3)=192:tbl%(11,4)=352:tbl%(11,5) =224:tbl%(11,6)=112
tbl%(12,1)=384:tbl%(12,2)=256:tbl%(12,3)=224:tbl%(12,4)=384:tbl%(12,5) =256:tbl%(12,6)=128
tbl%(13,1)=416:tbl%(13,2)=320:tbl%(13,3)=256:tbl%(13,4)=416:tbl%(13,5) =320:tbl%(13,6)=256
tbl%(14,1)=448:tbl%(14,2)=384:tbl%(14,3)=320:tbl%(14,4)=448:tbl%(14,5) =384:tbl%(14,6)=320

filename$="Anastacia-SickAndTired.mp3"


Datei& = xOpen&(SADD(filename$ + CHR$(0)), MODE_OLDFILE&)
IF Datei& THEN

'laenge ermitteln
junk& = Seek& (Datei&,0,OFFSET_END&)
dateilaenge& = Seek& (Datei&,0,OFFSET_BEGINNING&)
inbuf& = AllocMem&(dateilaenge&,MEMF_PUBLIC&)
IF inbuf& THEN
rLen& = xRead&(Datei&,inbuf&,dateilaenge&)

FOR i%=1 TO 9216
IF PEEKB(inbuf&+i%)=255 THEN
tmp$=RIGHT$("0000"+BIN$(PEEKB(inbuf&+i%+1)),8)
IF LEFT$(tmp$,4)<>"1111" AND LEFT$(tmp$,4)<>"1110" THEN 99
REM Sync gefunden
ID$=MID$(tmp$,5,1)
Layer$=MID$(tmp$,6,2)
tmp$=BIN$(PEEKB(inbuf&+i%+2))
Bitrate$=LEFT$(tmp$,4)
Frequenz$=MID$(tmp$,5,2)
padding%=VAL(MID$(tmp$,7,1))
GOTO 100
END IF
99 NEXT i%

100
IF id$="1" THEN REM MPG1
IF layer$="01" THEN taby%=3
IF layer$="10" THEN taby%=2
IF layer$="11" THEN taby%=1
IF Frequenz$="00" THEN Freq&=44100
IF Frequenz$="01" THEN Freq&=48000
IF Frequenz$="10" THEN Freq&=32000
END IF

IF id$="0" THEN REM MPG2
IF layer$="01" THEN taby%=6
IF layer$="10" THEN taby%=5
IF layer$="11" THEN taby%=4
IF Frequenz$="00" THEN Freq&=22050
IF Frequenz$="01" THEN Freq&=24000
IF Frequenz$="10" THEN Freq&=16000
END IF

IF bitrate$="0001" THEN tabx%=1
IF bitrate$="0010" THEN tabx%=2
IF bitrate$="0011" THEN tabx%=3
IF bitrate$="0100" THEN tabx%=4
IF bitrate$="0101" THEN tabx%=5
IF bitrate$="0110" THEN tabx%=6
IF bitrate$="0111" THEN tabx%=7
IF bitrate$="1000" THEN tabx%=8
IF bitrate$="1001" THEN tabx%=9
IF bitrate$="1010" THEN tabx%=10
IF bitrate$="1011" THEN tabx%=11
IF bitrate$="1100" THEN tabx%=12
IF bitrate$="1101" THEN tabx%=13
IF bitrate$="1110" THEN tabx%=14

t!=TIMER
FOR j%=i% TO 9216
a&=PEEKL(inbuf&+j%)
IF a&=&h58696E67 THEN
REM XING
FOR i&=1 TO Dateilaenge&
IF PEEKB(inbuf&+i&)=255 THEN
tmp$=RIGHT$("0000"+BIN$(PEEKB(inbuf&+i&+1)),8)
IF LEFT$(tmp$,4)<>"1111" AND LEFT$(tmp$,4)<>"1110" THEN 199
tmp$=BIN$(PEEKB(inbuf&+i&+2))
Bitrate$=LEFT$(tmp$,4)
IF bitrate$="0001" THEN tabx%=1:GOTO 198
IF bitrate$="0010" THEN tabx%=2:GOTO 198
IF bitrate$="0011" THEN tabx%=3:GOTO 198
IF bitrate$="0100" THEN tabx%=4:GOTO 198
IF bitrate$="0101" THEN tabx%=5:GOTO 198
IF bitrate$="0110" THEN tabx%=6:GOTO 198
IF bitrate$="0111" THEN tabx%=7:GOTO 198
IF bitrate$="1000" THEN tabx%=8:GOTO 198
IF bitrate$="1001" THEN tabx%=9:GOTO 198
IF bitrate$="1010" THEN tabx%=10:GOTO 198
IF bitrate$="1011" THEN tabx%=11:GOTO 198
IF bitrate$="1100" THEN tabx%=12:GOTO 198
IF bitrate$="1101" THEN tabx%=13:GOTO 198
IF bitrate$="1110" THEN tabx%=14:GOTO 198
198 bitrate&=tbl%(tabx%,taby%)
Bitraten&=Bitraten&+Bitrate&
INCR frameanz&
END IF
199 NEXT i&

EXIT FOR
END IF
NEXT j%

PRINT frameanz&
PRINT bitraten&
tmp&=(bitraten&/frameanz&)*1000
tmp&=144*tmp&/48000+padding%

REM FrameHeader abziehen und alles vor dem XING?
PRINT "VBRlaenge";(Dateilaenge&/tmp&)/38.5

bitrate&=tbl%(tabx%,taby%)
bitrate&=bitrate&*1000

PRINT "Dateilänge:";Dateilaenge&
PRINT "Bitrate:";bitrate&
PRINT "Frequenz:";+Freq&

Framesize%=FIX((144*Bitrate&/Freq&)+padding%)
sec%=(Dateilaenge&/Framesize%)/38.5

PRINT "Sekunden:";sec%


FreeMem inbuf&, dateilaenge&
END IF
junk&=xClose&(Datei&)
END IF

[ Dieser Beitrag wurde von MaikG am 03.08.2005 um 16:26 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 21:33 Uhr

David
Posts: 65
Nutzer
Hallo,

mit VBR hatte ich bei meiner id3tag.library auch meine Probleme.
Wenn ich die Sourcen gefunden habe, melde ich mich nochmal.

Ich kann erinnern das ich maximal die ersten 4 oder 6 Frames
aus gewertet habe.


--
mfg
David
http://www.david-mevius.de

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 22:29 Uhr

Ralf27
Posts: 2779
Nutzer
@MaikG:

so, bin eben von der Arbeit gekommen. Ich schau mir das später einmal an. Aber auf dem ersten Blick kann man da wirklich einiges rausholen, bzw. ganz schön kürzen.

Nun, ist auch was neues für mich, die MP3-Story. Da packt es mich wieder. Ist genau das richtige für heute Abend um mich etwas nach der Arbeit auszutoben. : :D :lach:
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 22:46 Uhr

Ralf27
Posts: 2779
Nutzer
MaikG:

Könntest du mir das Programm in einer EMail senden? Ich bekomme das Programm hier aus dem Forum so nicht zum laufen. Da ist wohl irgendwas falsch gelaufen.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 23:04 Uhr

Ralf27
Posts: 2779
Nutzer
Hm, so wie der Code da oben steht kann der eigentlich nie richig laufen. Z.b. Longs auf ungeraden adressen auslesen, etc. Läuft das Programm bei dir richtig?!?
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

03.08.2005, 23:38 Uhr

MaikG
Posts: 5172
Nutzer
>mit VBR hatte ich bei meiner id3tag.library auch meine Probleme.
>Wenn ich die Sourcen gefunden habe, melde ich mich nochmal.

das währe nett.


>Hm, so wie der Code da oben steht kann der eigentlich nie
>richig laufen. Z.b. Longs auf ungeraden adressen auslesen,
>etc. Läuft das Programm bei dir richtig?!?

Läuft wunderbar, ausser das es lahm ist z.zt. 31 sekunden
und das das Ergebniss leicht abweicht.
Habs dir den neusten Source gemailt.

Es ist kein Problem aus ungraden Adressen zu lesen.
Ich nehme doch an das Allocmem Linear allociert? Daher alles
nacheinander kommt und nicht in 2er Schritten.

Im Programm wird das soweit ich sehe nur mit Bytes gemacht.
Mit Peekl oder Peekw ist dies auch zulässig solange man
einen Prozessor >=020 hat.


[ - Antworten - Zitieren - Direktlink - ]

04.08.2005, 14:27 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Das muss so sein da man anders nicht an ein Teil-Binär wert
kommt. Wüsste jetzt nicht wie. Wenn ich 0101 von 0101xxxx brauche
bekomme ich das nicht anders.

Also selbst für AmigaBASIC gibt es Möglichkeiten, wenn man sich mit der Binärarithmetik mal richtig auseinandersetzt.
Wenn Du vom byte abcdefgh den Teil abcd haben willst, mußt Du durch 16 teilen. Wenn Du den Teil efgh haben willst, mußt Du zuerst den abcd Teil ermitteln und dann vom Original abziehen.

code:
abcd% = abcdefgh% / 16
efgh% = abcdefgh% - abcd% * 16

Aber wie hier gerade in einem anderen Thread nachzulesen war, beherrscht MBasic auch shift und binäre Vernüpfungen ala C. Es geht also auch noch effizienter. Also möge doch bitte mal jemand, der MBasic benutzt, die entsprechende Syntax hier posten.

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

[ Dieser Beitrag wurde von Holger am 04.08.2005 um 14:28 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

04.08.2005, 18:37 Uhr

MaikG
Posts: 5172
Nutzer
Ich hab mir sowas gedacht, konnte aber keine Gleichung
finden. Ich hab nur 10 Klassen gemacht, binär haben wir
nur kurz behandelt. :-(
Immerhin lernen Abiturienten hierzulanden nicht mal das.

Ralf Spielt grade mit dem Code, er hat ihn auf
3 Sekunden laufzeit gebracht! Bin schon gespannt drauf.


[ Dieser Beitrag wurde von MaikG am 04.08.2005 um 18:38 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

04.08.2005, 21:29 Uhr

David
Posts: 65
Nutzer
Zitat:
Original von MaikG:
>mit VBR hatte ich bei meiner id3tag.library auch meine Probleme.
>Wenn ich die Sourcen gefunden habe, melde ich mich nochmal.

das währe nett.


habe den Quellcode gefunden, ist in C geschrieben.

Die Funktion 'mp3info_getinfo' analysiert eine MPEG-Frame
und

code:
int ExtractI4(unsigned char *buf)

{
	int x;
	// big endian extract
	x = buf[0];
	x <<= 8;
	x |= buf[1];
	x <<= 8;
	x |= buf[2];
	x <<= 8;
	x |= buf[3];

	return x;
}


/* VBR definitions */

#define FRAMES_FLAG     0x0001
#define BYTES_FLAG      0x0002
#define TOC_FLAG        0x0004
#define VBR_SCALE_FLAG  0x0008

#define FRAMES_AND_BYTES (FRAMES_FLAG | BYTES_FLAG)

int bitraten[2][3][16]=
{
	/* MPEG 2 */
	{
		/* Layer 1 */
		{0,32000,64000,96000,128000,160000,192000,224000,256000,288000,32000 0,352000,384000,416000,448000,0},
		/* Layer 2 */
		{0,32000,48000,56000,64000 ,80000 ,96000 ,112000,128000,160000,192000,224000,256000,320000,384000,0},
		/* Layer 3 */
		{0,8000 ,16000,24000,32000 ,64000 ,80000 ,56000 ,64000 ,128000,160000,112000,128000,256000,320000,0}
   },
	/* MPEG 1  */
	{
		/* Layer 1 */
		{0,32000,64000,96000,128000,160000,192000,224000,256000,288000,32000 0,352000,384000,416000,448000,0},
		/* Layer 2 */
		{0,32000,48000,56000,64000 ,80000 ,96000 ,112000,128000,160000,192000,224000,256000,320000,384000,0},
		/* Layer 3 */
		{0,32000,40000,48000,56000 ,64000 ,80000 ,96000 ,112000,128000,160000,192000,224000,256000,320000,0}
	}
};


long frequency[3][4]=
{
	/* MPEG 1   */
	{44100,48000,32000,0},
	/* MPEG 2   */
	{22050,24000,16000,0},
	/* MPEG 2.5 */
	{11025,12000, 8000,0}
};

 
LONG
mp3info_getinfo(UBYTE *head,struct ID3Tag *id3tag,LONG id3v2size)
{
	UBYTE help=0,help1=0;
	UBYTE *vbr;
	LONG flength=0;
	LONG padding;
	
	/* Version */
   help=4-((head[1]>>3)&0x3);
	if(help==4) id3tag->norm=ID3TagMPEGA_VERSION_2_5;
	else
	if(help==2) id3tag->norm=ID3TagMPEGA_VERSION_2;
	else
	if(help==1) id3tag->norm=ID3TagMPEGA_VERSION_1;
	else
	{
		id3tag->norm=0;
		return 0;
   }
	
   /* Layer  */
	if(head[1]&2 && head[1]&4) id3tag->layer=1;
	else
	if(head[1]&4) id3tag->layer=2;
	else
	if(head[1]&2) id3tag->layer=3;
	else
	{
		id3tag->layer=0;
		return 0;
	}
    
	/* Protection */
	id3tag->crc=(head[1]&1)?0:1;
	
   /* Bitrate  */
	help=(head[2]&16)?1:0;
	help+=(head[2]&32)?2:0;
	help+=(head[2]&64)?4:0;
	help+=(head[2]&128)?8:0;
	id3tag->bitrate=bitraten[(head[1]&8)?1:0][id3tag->layer-1][help];
	if(id3tag->bitrate==0)
	{
		return 0;
	}
    
	/* Frequency */
	help=(head[2]&4)?1:0;
	help+=(head[2]&8)?2:0;
	switch(id3tag->norm)
	{
		case ID3TagMPEGA_VERSION_1: help1=0; break;
		case ID3TagMPEGA_VERSION_2: help1=1; break;
		case ID3TagMPEGA_VERSION_2_5: help1=2; break;
		default: help1=3;
	}
	id3tag->frequency=frequency[help1][help];
	if(id3tag->frequency==0)
	{
		return 0;
	}
	
   /* Padding */
	padding=(head[2]&2)?1:0;
	
   /* Private */
	id3tag->private_bit=(head[2]&1)?1:0;
 
   /* Mode */
	id3tag->mode=(head[3]&64)?1:0;
	id3tag->mode+=(head[3]&128)?2:0;
	
   /* Copyright */
	id3tag->copyright=(head[3]&8)?1:0;
	
   /* Original */
	id3tag->original=(head[3]&4)?1:0;
	
   /* Emphasis  */
	id3tag->emphasis=(head[3]&1)?1:0;
	id3tag->emphasis+=(head[3]&2)?2:0;
	
	/* Frame Length */
	if(id3tag->layer==1)
		flength=(12*id3tag->bitrate/id3tag->frequency+padding)*4;
	else
	if(id3tag->layer==2 || id3tag->layer==3)
		flength=144*id3tag->bitrate/id3tag->frequency+padding;
  
   /* VBR */
	id3tag->vbr=0;
	if(id3tag->norm&1)
	{
		if(id3tag->mode!=3) vbr=&head[32+4];
		else				  vbr=&head[17+4];
	}
	else
	{
		if(id3tag->mode!=3) vbr=&head[17+4];
		else				  vbr=&head[9+4];
	}

	if(vbr[0]=='X' && vbr[1]=='i' && vbr[2]=='n' && vbr[3]=='g')
	{
		int bytes=0, head_flags, frames=0;
		vbr+=4;

		id3tag->vbr=1;
		head_flags=ExtractI4(vbr);
		vbr+=4;
		if(head_flags & FRAMES_FLAG)
		{
			frames=ExtractI4(vbr);
			vbr+=4;
		}
		if(head_flags & BYTES_FLAG)
		{
			bytes=ExtractI4(vbr);
			vbr+=4;
		}
		
		if(frames!=0)
			id3tag->bitrate=(((bytes!=0)?bytes:(id3tag->filesize-id3v2size))/fr ames)*id3tag->frequency/144;
		
   }
 
   return flength;
}



--
mfg
David
http://www.david-mevius.de

[ Dieser Beitrag wurde von David am 04.08.2005 um 21:31 Uhr editiert. ]

[ Dieser Beitrag wurde von David am 04.08.2005 um 21:32 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

04.08.2005, 22:41 Uhr

Palgucker
Posts: 1342
Nutzer
Mal eine Frage nebenbei. Ändern sich innerhalb eines mp3's mit variabler Bitrate eigendlich die Framelängen, oder sind die trotzdem immer gleich?

mfg Palgucker

[ - Antworten - Zitieren - Direktlink - ]

04.08.2005, 23:39 Uhr

MaikG
Posts: 5172
Nutzer
Mit dem C komme ich nicht wirklich klar.
Ich sehe aber wo nach dem Xing gesucht wird und
dort auch irgendwelche weiteren Informationen sein müssen.

>Mal eine Frage nebenbei. Ändern sich innerhalb eines mp3's
>mit variabler Bitrate eigendlich die Framelängen, oder
>sind die trotzdem immer gleich?
Klar die ändern sich eine andere Bitrate benötigt schliesslich
mehr oder weniger Platz.

[ - Antworten - Zitieren - Direktlink - ]

05.08.2005, 00:13 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von MaikG:
Mit dem C komme ich nicht wirklich klar.
Ich sehe aber wo nach dem Xing gesucht wird und
dort auch irgendwelche weiteren Informationen sein müssen.

>Mal eine Frage nebenbei. Ändern sich innerhalb eines mp3's
>mit variabler Bitrate eigendlich die Framelängen, oder
>sind die trotzdem immer gleich?
Klar die ändern sich eine andere Bitrate benötigt schliesslich
mehr oder weniger Platz.


Nun, das stimmt so nicht. Laut Doku ist die Framegröße fest vorgeschrieben:
Framegröße Audio:
Layer1 = 384 Samples = 384 Words(16Bit)
Layer2+3 =1152 Sampels =1152 Words(16Bit)

Insofern kann man recht schnell von Frame zu Frame springen, laut Doku. So kann man innerhalb einer Sekunde sehn (auch mit VBR) wie lange die Spielzeit ist.
Dazu kommt noch 32Bit Header und eventuell Checksumme(steht im Header).

Allerdings laut Theorie. Hab da noch ein kleines Problem. BigEndian? So oder so, irgend etwas stimmt bei mir im Code da noch nicht so ganz und ich find einfach denn Fehler nicht.

Leider komme ich immer erst so spät von der Arbeit und kann erst noch viel später an die Sache ran gehn.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

05.08.2005, 00:18 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Mit dem C komme ich nicht wirklich klar.
Ich sehe aber wo nach dem Xing gesucht wird und
dort auch irgendwelche weiteren Informationen sein müssen.

Nach den vier bytes 'X', 'i', 'n', 'g' folgen weitere vier bytes, die zusammen flags ergeben (big endian). Wenn das unterste Bit gesetzt ist (Flag FRAMES), dann folgt eine weitere vier byte BE Zahl, die die Anzahl der frames mitteilt. Wenn das zweitniedrigste Bit gesetzt ist (Flag BYTES), dann folgt darauf die tatsächliche Anzahl Bytes des mpeg-streams (wieder vier bytes BE, sehr praktisch zur Spieldauerberechnung), wenn es nicht gesetzt ist, muß man eben die Dateilänge nehmen und bekannte header und trailer (wie ID3) abziehen und hoffen, daß nicht allzuviel padding dazwischen ist.
Egal, wie man die Anzahl der bytes ermittelt, sie wird danach durch die Anzahl frames geteilt und mit der Frequenz multipliziert. Das ist die lange Zeile kurz vor Schluß. Die sieht deshalb so kompliziert aus, weil fast alle Klammern überflüssig sind, und eine für Basic-Programmierer ungewöhliche Konstruktion benutzt wird:
bedingung? ausdruck: alternative
Das bedeutet, wenn die Bedingung wahr ist, wird der erste Ausdruck zurückgeliefert, ansonsten die Alternative. Das kann direkt in einen anderen Ausdruck eingesetzt werden, wie in dieser Berechnung.
Also:
bitrate=(bytes!=0? bytes: filesize-id3v2size)/frames*frequency/144
heißt eben nichts anderes bytes/frames*frequency/144, nur daß, wenn die byte Anzahl im Xing-Tag nicht angegeben wurde, die Dateigröße abzüglich des ID3 Header benutzt wird.

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

[ Dieser Beitrag wurde von Holger am 05.08.2005 um 00:25 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

05.08.2005, 00:20 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Also selbst für AmigaBASIC gibt es Möglichkeiten, wenn man sich mit der Binärarithmetik mal richtig auseinandersetzt.
Wenn Du vom byte abcdefgh den Teil abcd haben willst, mußt Du durch 16 teilen. Wenn Du den Teil efgh haben willst, mußt Du zuerst den abcd Teil ermitteln und dann vom Original abziehen.

code:
abcd% = abcdefgh% / 16
efgh% = abcdefgh% - abcd% * 16

Aber wie hier gerade in einem anderen Thread nachzulesen war, beherrscht MBasic auch shift und binäre Vernüpfungen ala C. Es geht also auch noch effizienter. Also möge doch bitte mal jemand, der MBasic benutzt, die entsprechende Syntax hier posten.

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


Zja, was soll ich tippen. So gut bin ich in der Sache auch nicht. Ein paar kleines Beispiel:
code:
[...]
 IF PEEK(buf&+i&)=255 THEN
   a=PEEK(buf&+i&+1)
   IF(a AND 240)=240 THEN
    REM Frame gefunden
    ID=(a AND 8 )8
    Layer=(a AND 6)2
    a=PEEK(buf&+i&+2)
    Bitrate=(a AND 240)16
    Frequenz=(a AND 12)4
    padding=(a AND 2)2
    
    [...]

   END IF

   [...]
   
  END IF
  [...]

Dies ist übrigens vorallem an de MaikG gerichtet. :) MaikG, erkennst du Teile vom Code? :)

Aber jetzt mal eine dumme Frage: BigEndian. Ich muß da doch nichts drehn, oder? (Bytereihenfolge). Ich versteh einfach nicht wieso da mein Code nicht richtig läuft.
--
http://www.alternativercomputerclub.de.vu



Edit:
Ich hab eben gemerkt das selbst in dem mit Code deklarierten Text auch Smilie kommt, obwohl er da nix zu suchen hat? Hammer. :lach:

Achja, vielleicht geht es noch besser mit den Binären Mitteln von MBasic (wie z.b. mit Bitshift), ich weiß aber jetzt auch nicht wie. Das dürfte aber so wie da oben ausreichend sein.

[ Dieser Beitrag wurde von Ralf27 am 05.08.2005 um 00:24 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

05.08.2005, 00:32 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Aber jetzt mal eine dumme Frage: BigEndian. Ich muß da doch nichts drehn, oder? (Bytereihenfolge). Ich versteh einfach nicht wieso da mein Code nicht richtig läuft.

Nein, auf dem Amiga brauchst Du nichts zu drehen. Was genau läuft denn nicht?
Zitat:
Achja, vielleicht geht es noch besser mit den Binären Mitteln von MBasic (wie z.b. mit Bitshift), ich weiß aber jetzt auch nicht wie. Das dürfte aber so wie da oben ausreichend sein.
Das sind doch Binäroperationen, was man in dem Beispiel sieht.

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

[ - Antworten - Zitieren - Direktlink - ]

05.08.2005, 00:37 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Nein, auf dem Amiga brauchst Du nichts zu drehen. Was genau läuft denn nicht?

Nun, irgendwie stimmen die Daten nicht richtig, die ich auslese. Ich hab jetzt einige Dokus verglichen und überalle steht das gleiche z.b. mit Framegröße Audio. Wenn ich diese Blöcke überspringe, dann findet er lange keinen richtigen Header mehr oder falsche Daten. Wenn ich nicht springe, dann sieht es ähnlich aus. Das bringt mich irgendwie zur Verzweiflung. Ich muß mich mal näher einlesen.
Ich bin eben bei MPEG1-2, Layer1-3. MPEG2.5 lass ich mal ausen vor.
Zitat:
Das sind doch Binäroperationen, was man in dem Beispiel sieht.
Das stimmt, aber es geht doch bestimmt noch besser, das meinte ich damit. Es gibt z.b. nicht Bitshift, aber das hab ich quasi noch nie benutzt.

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

[ - Antworten - Zitieren - Direktlink - ]

05.08.2005, 00:50 Uhr

Holger
Posts: 8116
Nutzer
Poste doch mal den kompletten Code. Und sach dabei rasch, was Backslash in (M)Basic bedeutet.

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 Letzte [ - 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.
.