Länge von Musik: CD, WAV und MP3
Übersicht BlitzBasic FAQ und Tutorials
sdjhBetreff: Länge von Musik: CD, WAV und MP3 |
Mi, Sep 26, 2007 12:32 Antworten mit Zitat |
|
---|---|---|
Ahoi.
Da irgendwo letzte Woche die Frage aufkam, wie man die Länge von MP3s ausliest und irgendwie keiner darauf geantwortet hat und irgendwann vielleicht wieder jemand solche Fragen stellt weil aus irgend einem Grund keiner nach den alten Threats sucht, noch mal alles kompakt auf einem Punkt. Wenn sich jetzt jemand fragt "Boah ej, wie hat der dat denn jemacht?". Auch darauf gibt es eine Antwort von mir: http://www.wotsit.org/ Weitere Formate werden wahrscheinlich folgen (aac, mp4, m4p, wma, mid, mod, etc) Wenn jetzt jemand rummeckert, weil das Dateiformat Soundso Version 0.02 alpha von 1963 auf Comodore, dass nach keinen 4 Wochen wieder aus dem Umlauf genommen wurde, werde ich böse. Dann folgen keine weitere Formate mehr. Gleiches gilt, wenn ich heute abend sehe, dann meine PN-Box explodiert, weil man ja bereits "5 Stunden gewartet" hat. Gutes Hacken braucht eben seine Zeit und der Programmierer seinen Tee. Wenn sich jetzt einer ertappt fühlt: bitte SOFORT die "Zurück"-Naviagtion im Browser klicken! Für alle anderen: wir legen los, hurra! Einmal strecken und räkeln, Rollos hochziehen und tief Luft holen. Schritt 1: unsere Standartbibliothek zum Konvertieren der Zeit und sonstigem Schabernack (standart.bb) Code: [AUSKLAPPEN] ;die absolut wichtigste Funktion um nachher das errechnete Zahlenwirrwar wieder in lesbare Ziffern zu formatieren. ;gibt Zeiten in Millisekunden in MM:SS.ms aus (gut ist das) Function milli2min$(i) t=i/1000 t2=t*1000 m2$=Str(i-t2) If Len(m2$)=2 Then m2$="0"+m2$ If Len(m2$)=1 Then m2$="00"+m2$ mt=t/60 t2=mt*60 m$=Str(mt) s$=Str(t-t2) If Len(s$)=1Then s$="0"+s$ Return m$+":"+s$+"."+m2$ End Function ;wird später für MP3s benötigt. Lest selber nach, wenn's euch interessiert Function readchars$(f,l) r$="" For x=1To l r$=r$+Chr(ReadByte(f)) Next Return Trim(r$) End Function ;Eine Liste mit allen als standart definierten MP3-Genres. Damit habt ihr mehr, als so mancher Soundplayer Function getgenre$(b) Select b Case 0:Return "Blues" Case 1:Return "Classic Rock" Case 2:Return "Country" Case 3:Return "Dance" Case 4:Return "Disco" Case 5:Return "Funk" Case 6:Return "Grunge" Case 7:Return "Hip-Hop" Case 8:Return "Jazz" Case 9:Return "Metal" Case 10:Return "New Age" Case 11:Return "Oldies" Case 12:Return "Other" Case 13:Return "Pop" Case 14:Return "R&B" Case 15:Return "Rap" Case 16:Return "Reggae" Case 17:Return "Rock" Case 18:Return "Techno" Case 19:Return "Industrial" Case 20:Return "Alternitive" Case 21:Return "Ska" Case 22:Return "Death Metal" Case 23:Return "Pranks" Case 24:Return "Soundtrack" Case 25:Return "Euro-Techno" Case 26:Return "Ambient" Case 27:Return "Trip-Hop" Case 28:Return "Vocal" Case 29:Return "Jazz+Funk" Case 30:Return "Fusion" Case 31:Return "Trance" Case 32:Return "Classical" Case 33:Return "Instrumental" Case 34:Return "Acid" Case 35:Return "House" Case 36:Return "Game" Case 37:Return "Sound Clip" Case 38:Return "Gospel" Case 39:Return "Noise" Case 40:Return "AlternRock" Case 41:Return "Bass" Case 42:Return "Soul" Case 43:Return "Punk" Case 44:Return "Space" Case 45:Return "Meditative" Case 46:Return "Instrumental Pop" Case 47:Return "Instrumental Rock" Case 48:Return "Ethnic" Case 49:Return "Gothic" Case 50:Return "Darkwave" Case 51:Return "Techno-Industrial" Case 52:Return "Electronic" Case 53:Return "Pop-Folk" Case 54:Return "Eurodance" Case 55:Return "Dream" Case 56:Return "Southern-Rock" Case 57:Return "Comedy" Case 58:Return "Cult" Case 59:Return "Gangsta" Case 60:Return "Top 40" Case 61:Return "Christian Rap" Case 62:Return "Pop/Funk" Case 63:Return "Jungle" Case 64:Return "Native American" Case 65:Return "Cabaret" Case 66:Return "New Wave" Case 67:Return "Psychadelic" Case 68:Return "Rave" Case 69:Return "Showtunes" Case 70:Return "Trailer" Case 71:Return "Lo-Fi" Case 72:Return "Tribal" Case 73:Return "Acid Punk" Case 74:Return "Acid Jazz" Case 75:Return "Polka" Case 76:Return "Retro" Case 77:Return "Musical" Case 78:Return "Rock & Roll" Case 79:Return "Hard Rock" Default Return "Unknown" End Select End Function diese Funktion (WICHTIG) bitte immer in den nachfolgenden Codes einfügen. Alle warm geworden? Dann weiter! Eine leichte Fingerübung... und CD nicht vergessen! Schritt 2: Titellänge einer Audio-CD lesen Code: [AUSKLAPPEN] Include "./standart.bb" ;wie gesagt: WICHTIG filename$="" ;hier den Titel eingeben (sowas wie: D:\Track01.cda) Print milli2min(getCDAlength(filename$)*1000) Input End Function getCDAlength(f$) file=ReadFile(f$) If Not file Then Return SeekFile(file,41) ;uns interessieren die Infos an dieser Stelle sec=ReadByte(file) ;... namentlich Sekunde min=ReadByte(file)*60 ;... und Minute - aber bitte gleich in Sekunden formatiert Return min+sec ;und ab damit End Function Jaja, wie gut, dass uns Herr Microsoft da Dateien suggeriert, wo eigendlich keine sind. Deshalb ausnahmsweise, sowas tu ich wirklich nicht häuft: Danke, danke, danke nach Redmont. Ziel schon erreicht? Pah, gerade erst angezogen. Also: Ab unter die Dusche Schritt 3: Ich liebe Wavedateien - wenn sie zerlegt sind Code: [AUSKLAPPEN] Include "./standart.bb" ; Eins nach dem anderen: ;1) Einen Pfad in 'filename$' angeben: filename$="C:\..." ;2) Laenge ermitteln (unsere eigendlich Aufgabe): Print milli2min(getwavelength(filename$)*1000) ;3) Input und End wegnehmen und ein Wunder erleben: Input End ;4) blah, blah, blah Type wave Field size Field fsize Field format Field compressed Field channels Field samplessec Field avgbytessec Field blockalign Field bitssample Field length# Field img Field w,h,midpos End Type Graphics 640,480,32,2 SetBuffer BackBuffer() ;5) oh, interessant... img=visualizewave(filename$,640,480) w.wave=First wave pxsec#=Float(640)/(w\length#*1000) PlayMusic(filename$) oldtime=MilliSecs() While Not KeyDown(1) diff=MilliSecs()-oldtime Color 0,255,0 Rect 0,0,pxsec#*diff,1024 DrawImage img,0,0 Color 0,0,0 w.wave=First wave Text 0,0,"Hz: "+w\samplessec Text 0,15,"Ch: "+w\channels Text 0,30,"Bt: "+w\bitssample*8 Text 0,45,"Ps: "+pxsec# Flip Wend End Function getwavelength#(f$) file=ReadFile(f$) If Not file Then Return pos=0 s$=" " Repeat s$=Right(s$,3) b=ReadByte(file) s$=s$+Chr(b) If s$="fmt " size=ReadInt(file) Print "SZ: "+size format=ReadShort(file) Print "FT: "+format compressed=True If format=1Then compressed=False channels=ReadShort(file) Print "CH: "+channels samplessec=ReadShort(file) Print "SS: "+samplesec avgbytessec=ReadShort(file) blockalign=ReadShort(file) bitssample=ReadShort(file) Print "BS: "+bitssample If bitssample=0Then bitssample=1 EndIf If s$="data" fsize=FileSize(f$) length#=(Float(fsize)-FilePos(file))/bitssample/2/44100 CloseFile(file) Return length# EndIf Until Eof(file) CloseFile(file) Return 0 End Function Function visualizewave(f$,wh,h) w.wave=New wave w\w=wh w\h=h w\midpos=w\h/2 w\img=CreateImage(wh,h) SetBuffer ImageBuffer(w\img) For y=0To w\midpos Color 255-y*128/w\midpos,64,64 Line 0,w\midpos+y,640,w\midpos+y Line 0,w\midpos-y,640,w\midpos-y Next Color 0,0,0 Line 0,240,800,240 file=ReadFile(f$) pos=0 s$=" " Repeat s$=Right(s$,3) b=ReadByte(file) s$=s$+Chr(b) If s$="fmt " w\size=ReadInt(file) w\format=ReadShort(file) w\compressed=True If w\format=1Then w\compressed=False w\channels=ReadShort(file) w\samplessec=ReadShort(file) w\avgbytessec=ReadShort(file) w\blockalign=ReadShort(file) w\bitssample=ReadShort(file) If w\bitssample=0Then w\bitssample=1 EndIf If s$="data" Color 0,0,0 w\fsize=FileSize(f$) w\length#=(Float(w\fsize)-FilePos(file))/w\bitssample/2/44100 Text 640-100,20,w\length# ;yfaktor=128/w\midpos yfaktor=5 If w\bitssample=2Then yfaktor=32768/w\midpos maxpix=w\fsize/4 div#=maxpix/w\w v=0 oyp=-1 oyn=-1 Repeat For x=1To w\channels If w\bitssample=1 ;8Bit d=ReadByte(file) EndIf If w\bitssample=2 ;16Bit d=32768-ReadShort(file) If d<0 d=d+32768 ElseIf d>0 d=d-32768 EndIf EndIf Color 255,255,255 If Float(d)/Float(yfaktor)<0 ; If oyn>=0Then Line v/4,w\midpos+Float(d)/Float(yfaktor)-1,(v-1)/4,oyn oyn=w\midpos+Float(d)/Float(yfaktor)-1 EndIf If Float(d)/Float(yfaktor)>0 ; If oyp>=0Then Line v/4,w\midpos+Float(d)/Float(yfaktor)+1,(v-1)/4,oyp oyp=w\midpos+Float(d)/Float(yfaktor)+1 EndIf Color 0,0,0 Line v/4,w\midpos+Float(d)/Float(yfaktor),v/4,w\midpos If w\channels=1 Line v/4,w\midpos-Float(d)/Float(yfaktor),v/4,w\midpos EndIf Next v=v+1 SeekFile file,40+div*v-(div*v Mod 4) Until Eof(file) CloseFile(file) SetBuffer BackBuffer() Return w\img EndIf If s$="cue " Print "Cuechunk found" EndIf If s$="plst" Print "Playlistchunk found" EndIf If s$="list" Print "Listchunk found" EndIf If s$="labl" Print "Labelchunk found" EndIf If s$="note" Print "Notechunk found" EndIf If s$="smpl" Print "Sampelchunk found" EndIf If s$="inst" Print "Instrumentchunk found" EndIf If s$="labl" Print "Labelchunk found" EndIf Until Eof(file) CloseFile(file) End Function Aha, aha, das kann man ja schon gebrauchen. Bitte schön, dafür ist es da. Aber bei Napstar werden wir damit ausgelacht. Wer tauscht denn auch schon Waves? Also kopfüber in unser Lieblingsformat: der MP3 Schritt 4: Wie lang ist denn bitte meine Festplatte? Code: [AUSKLAPPEN] Include "./standart.bb" filename$="" Print milli2min(getmp3laenge(filename$)) Input() End Function mp3version$(i) Select i Case 1: Return "1" Case 2: Return "2" Case 3: Return "2.5" End Select End Function ;Romanzahlen? Was soll das denn? Function romannb$(i) Select i Case 1: Return "I" Case 2: Return "II" Case 3: Return "III" Case 4: Return "IV" Case 5: Return "V" End Select End Function Function getmp3laenge(f$,h=0) vbr=0 f1=ReadFile(f$) x=0 p=0 start=0 Repeat b=ReadByte(f1) If b=255 b=ReadByte(f1) c=b And 224 If c=224 error=0 d=b And 24 d=d Shr 3 If d=0Then version=3 If d=1Then error=1 If d=2Then version=2 If d=3Then version=1 d=b And 6 d=d Shr 1 If d=0Then error=1 If d=1Then layer=3 If d=2Then layer=2 If d=3Then layer=1 b=ReadByte(f1) d=b Shr 4 bitrate=0 If version=1 If layer=3 If d=0 Then bitrate=-1 If d=1 Then bitrate=32 If d=2 Then bitrate=40 If d=3 Then bitrate=48 If d=4 Then bitrate=56 If d=5 Then bitrate=64 If d=6 Then bitrate=80 If d=7 Then bitrate=96 If d=8 Then bitrate=112 If d=9 Then bitrate=128 If d=10 Then bitrate=160 If d=11 Then bitrate=192 If d=12 Then bitrate=224 If d=13 Then bitrate=256 If d=14 Then bitrate=320 If d=15 Then bitrate=-1 EndIf EndIf d=b And 12 d=d Shr 2 If version=1 If d=0Then frequenz=44100 If d=1Then frequenz=48000 If d=2Then frequenz=32000 EndIf d=b And 2 d=d Shr 1 padding=d If bitrate<=0 Or error=1 x=x-1 Else If x=0 Then start=FilePos(f1)-3 totbit=totbit+bitrate SeekFile(f1,FilePos(f1)-8+(bitrate*1000*144/frequenz+padding)) EndIf x=x+1 EndIf EndIf Until Eof(f1) CloseFile(f1) vbr=totbit/x Return (FileSize(f$)-start)*8/vbr End Function Function getid3tags$(f$) f1=ReadFile(f$) If Not f1 Then Return start=0 Repeat b=ReadByte(f1) If b=255 b=ReadByte(f1) c=b And 224 If c=224 error=0 d=b And 24 d=d Shr 3 If d=0Then version=3 If d=1Then error=1 If d=2Then version=2 If d=3Then version=1 d=b And 6 d=d Shr 1 If d=0Then error=1 If d=1Then layer=3 If d=2Then layer=2 If d=3Then layer=1 b=ReadByte(f1) d=b Shr 4 bitrate=0 If version=1 If layer=3 If d=0 Then bitrate=-1 If d=1 Then bitrate=32 If d=2 Then bitrate=40 If d=3 Then bitrate=48 If d=4 Then bitrate=56 If d=5 Then bitrate=64 If d=6 Then bitrate=80 If d=7 Then bitrate=96 If d=8 Then bitrate=112 If d=9 Then bitrate=128 If d=10 Then bitrate=160 If d=11 Then bitrate=192 If d=12 Then bitrate=224 If d=13 Then bitrate=256 If d=14 Then bitrate=320 If d=15 Then bitrate=-1 EndIf EndIf d=b And 12 d=d Shr 2 If version=1 If d=0Then frequenz=44100 If d=1Then frequenz=48000 If d=2Then frequenz=32000 EndIf d=b And 2 d=d Shr 1 padding=d If bitrate<=0 Or error=1 x=x-1 Else If x=0 Then start=FilePos(f1)-3 totbit=totbit+bitrate SeekFile(f1,FilePos(f1)-8+(bitrate*1000*144/frequenz+padding)) EndIf x=x+1 EndIf EndIf Until Eof(f1) ; Anmerkung: ;Die Variable 'start' wird wie in 'getmp3laenge' ermittelt ;Wer also die Infos eh in einem Type speichert, kann sich deie Function bishierhin sparen. For p=1To start b=ReadByte(f1) If b=73 If ReadByte(f1)=68 And ReadByte(f1)=51 ReadInt(f1) ReadShort(f1) ReadInt(f1) ReadInt(f1) For x=1To 11 l=ReadInt(f1) t$=readchars(f1,l-1) Select x Case 1:interpret$=t$ Case 2:title$=t$ Case 3:album$=t$ Case 4:track$=t$ Case 5:year$=t$ Case 6:genre$=t$ End Select ReadByte(f1) ReadByte(f1) ReadByte(f1) ReadByte(f1) ReadByte(f1) ReadByte(f1) ReadByte(f1) Next Return EndIf EndIf Next SeekFile(f1,FileSize(f$)-128) If ReadByte(f1)=84 If ReadByte(f1)=65 And ReadByte(f1)=71 title$=readchars(f1,30) interpret$=readchars(f1,30) album$=readchars(f1,30) year$=readchars(f1,4) comment$=readchars(f1,30) genre$=getgenre(ReadByte(f1)) ; Exit EndIf EndIf End Function Alles Tutti. Das wäre nun auch geklärt. Zum letzten Quelltext noch: das Auslesen der ID3-Tags sollte man natürlich in Types machen (siehe auch https://www.blitzforum.de/foru...hp?t=25321). Dann kann man sich nämlich auch die Infos schön gruppieren und leicht ausgeben. Ich habe es aber weggenommen, weil es ja nicht das eigendliche Anliegen des Tutorials ist. Schritt 5: Was kann ich damit alles machen? Macht den Media Player nieder, zerlegt iTunes, übertrumpft WinAMP. Es ist möglich. Erfahrung: selbstgemacht. Ich habe eine Jukebox (für die ich diese Funktionen auch geschrieben habe), die ich gerne auf Partys mitnehme. Mit einer 80GB (bei mir leider nur 30 davon belegt) externen Festplatte (alles MP3s in VBR à 160KBits) und einem kleinen Studium von BlitzBass, lässt sich schon so manche Party schmeissen. Also nur Mut. Wer eigene Hacks geschrieben hat, kann sie gerne hier posten. Von mir kommt sicherlich auch noch etwas in Wochen und Monaten, so wie sich es eben gerade ergibt. Viel Spaß, viel Erfolg und haut rein, Mädels und Jungs! |
||
Übersicht BlitzBasic FAQ und Tutorials
Powered by phpBB © 2001 - 2006, phpBB Group