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: 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:haut mir auf die Augen. Versuch doch da z.b.IF MID$(dat$,i&,1)=CHR$(255) THEN code: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".IF peek(i&)=255 then 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: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: 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:Aber sind schneller, oder? Hast du mal einen vergleich bei solch großen Dateien gemacht? Zitat: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:Ä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: 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. : -- 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: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: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.abcd% = abcdefgh% / 16 efgh% = abcdefgh% - abcd% * 16 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: 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: 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: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: Zja, was soll ich tippen. So gut bin ich in der Sache auch nicht. Ein paar kleines Beispiel: code:Dies ist übrigens vorallem an de MaikG gerichtet. MaikG, erkennst du Teile vom 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 [...] 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. 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:Nein, auf dem Amiga brauchst Du nichts zu drehen. Was genau läuft denn nicht? Zitat: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: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 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. |