VB -> BB

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Eingeproggt

Betreff: VB -> BB

BeitragSa, März 31, 2007 20:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo alle miteinander!

Ich habe mir folgenden Link von Vertex zu Gemüte geführt:
http://www.shadoware.de/vb/mp3infos.html

Und daraus folgenden BB-Code geformt:

Code: [AUSKLAPPEN]

Dim bitraten(85)
mp3length("C:\Dokumente und Einstellungen\Admin\Eigene Dateien\Eigene Musik\beispiel.mp3")

Function mp3length(file$)
   ;Bitraten-Informationen
         bitrate_data$="032,032,032,032,008,008,064,048,040,048,016,016,096,056,048,056,024,024,128,064,056,064,032,032,160,080,064,080,040,040,192,096,080,096,048,048,224,112,096,112,056,056,256,128,112,128,064,064,288,160,128,144,080,080,320,192,160,160,096,096,352,224,192,176,112,112,384,256,224,192,128,128,416,320,256,224,144,144,448,384,320,256,160,160,"
   For i=0 To 82
      bitraten(i)=Left(bitrate_data,3)
    bitrate_data=Right(bitrate_data,Len(bitrate_data)-4)
   Next
   size=FileSize(file)
   Reader=Readfile(file)
   For i=0 To 4095
      header$=header+Chr(ReadByte(Reader))
   Next
   
   For i=1 To 4096
      d1=Asc(Mid(header,i,1))
      d2=Asc(Mid(header,i+1,1))
     
      If d1=256 And (d2 And 240)=240 Then
            temp_string$=Mid(header,i+1,3)
        mp3bits$=ShiftBits$(Mid(header,i+1,3))
        Exit
      End If

      dSHIFT$=ShiftBits$(Mid(header,i,3))
      dd1=Asc(Left(dSHIFT,1))
      dd2=Asc(Right(dSHIFT,1))
     
      If dd1=256 And (dd2 And 240)=240 Then
            mp3bits$=Mid(header,i+2,3)
            Exit
      End If
   Next
   
End Function

Function ShiftBits$(Strin)
   sd1=Asc(Left(Strin,1))
   sd2=Asc(Mid(Strin,2,1))
   sd3=Asc(Right(Strin,1))
   
   do1=((sd1 And 15)*16) Or ((sd2 And 240)/16)
   do2=((sd2 And 16)*16) Or ((sd3 And 240)/16)
 
  Return Chr(do1)+Chr(do2)
End Function


Und wie nicht anders zu erwarten will das Ding nicht so, wie es soll.
Genauer gesagt wird die 2. For-Schleife nie durch das Exit beendet (Die Abfrage ist nie erfüllt). Somit gibt es kein "mp3bits". Kann mich jemand korrigieren? (Bzw weiterschreiben? Very Happy )

MFG
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSo, Apr 01, 2007 0:14
Antworten mit Zitat
Benutzer-Profile anzeigen
FF ist 255 nicht 256

If dd1=255 And (dd2 And 240)=240 Then[/code]

Probier mal!
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

Eingeproggt

BeitragSo, Apr 01, 2007 11:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke, das war schonmal ein Fehler.

Hab weitergemacht und es geht schon wieder nicht. Diesmal liegt der Hund irgendwo im Arrayzugriff begraben.

Ich testete eine Datei, aus der eine Bitrate von 15 herausgelesen wurde.
Wenn man jetzt in der letzten Zeile auf das 15. Element zugreifen will, kommt 0 heraus, weil in der For-Schleife am Anfang nur bis 14 gezählt wird. Was kann ich dagegen tun? (Die Funktionalität soll natürlich beibehalten werden Smile )

Code: [AUSKLAPPEN]

Dim bitraten(7,15)
mp3length("C:\Dokumente und Einstellungen\Christoph\Eigene Dateien\Eigene Musik\2 Hearts.mp3")
Delay 5000
End

Function mp3length(file$)
   ;Bitraten-Informationen
   bitrate_data$=bitrate_data+"032,032,032,032,008,008,"
   bitrate_data$=bitrate_data+"064,048,040,048,016,016,"
   bitrate_data$=bitrate_data+"096,056,048,056,024,024,"
   bitrate_data$=bitrate_data+"128,064,056,064,032,032,"
   bitrate_data$=bitrate_data+"160,080,064,080,040,040,"
   bitrate_data$=bitrate_data+"192,096,080,096,048,048,"
   bitrate_data$=bitrate_data+"224,112,096,112,056,056,"
   bitrate_data$=bitrate_data+"256,128,112,128,064,064,"
   bitrate_data$=bitrate_data+"288,160,128,144,080,080,"
   bitrate_data$=bitrate_data+"320,192,160,160,096,096,"
   bitrate_data$=bitrate_data+"352,224,192,176,112,112,"
   bitrate_data$=bitrate_data+"384,256,224,192,128,128,"
   bitrate_data$=bitrate_data+"416,320,256,224,144,144,"
   bitrate_data$=bitrate_data+"448,384,320,256,160,160,"
   
   For Y=1 To 14
      For X=7 To 5 Step -1
         bitraten(X,Y)=Left(bitrate_data,3)
         bitrate_data=Right(bitrate_data,Len(bitrate_data)-4)
      Next
      For X=3 To 1 Step -1
         bitraten(X,Y)=Left(bitrate_data,3)
         bitrate_data=Right(bitrate_data,Len(bitrate_data)-4)
      Next
   Next
   
  size=FileSize(file)
  Reader=Readfile(file)
  For i=0 To 4095
      header$=header+Chr(ReadByte(Reader))
  Next
   
  For i=1 To 4096
    d1=Asc(Mid(header,i,1))
    d2=Asc(Mid(header,i+1,1))
   
    If d1=255 And (d2 And 240)=240 Then
         temp_string$=Mid(header,i+1,3)
         mp3bits$=ShiftBits$(Mid(header,i+1,3))
         Exit
      End If

      dSHIFT$=ShiftBits$(Mid(header,i,3))
      dd1=Asc(Left(dSHIFT,1))
      dd2=Asc(Right(dSHIFT,1))
     
      If dd1=255 And (dd2 And 240)=240 Then
         mp3bits$=Mid(header,i+2,3)
         Exit
      End If
   Next
   
   ;Das 1. Bit ist die ID; 0 = MPG-2, 1 = MPG-1
   mp3_id=(128 And Asc(Left(mp3bits,1)))/128
   ;Die nächsten 2 Bits sind Layer
   mp3_layer=(96 And Asc(Left(mp3bits,1)))/32
   ;Das nächste Bit ist Schutz
   mp3_prot=16 And Asc(Left(mp3bits,1))
   ;Die nächsten 4 Bits beschreiben die Bitrate
   mp3_bitrate=15 And Asc(Left(mp3bits,1))
   ;Die nächsten 2 Bits legen die Frequenz fest
   mp3_freq=192 And Asc(Mid(mp3bits,2,1))
   ;Das nächste Bit ist Padding
   mp3_pad=(32 And Asc(Mid(mp3bits, 2,1)))/2
   actual_bitrate=1000*(bitraten((mp3_id*4) Or mp3_layer,mp3_bitrate))
   DebugLog actual_bitrate
   
End Function

Function ShiftBits$(Strin)
   sd1=Asc(Left(Strin,1))
   sd2=Asc(Mid(Strin,2,1))
   sd3=Asc(Right(Strin,1))
   
   do1=((sd1 And 15)*16) Or ((sd2 And 240)/16)
   do2=((sd2 And 16)*16) Or ((sd3 And 240)/16)
   
  Return Chr(do1)+Chr(do2)
End Function
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

Vertex

BeitragSo, Apr 01, 2007 19:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Bin gerade selber am Verzweifeln OO

Also der Frameheader ist 32 Bit groß, passt also in eine simple Integervariable.

Theoretisch muss man die MP3 solange durchgehen, bis man auf ein Header stößt, den man per Sync erkennt.

Hier mein erster Test:
Code: [AUSKLAPPEN]
Const HEADER_SYNC%          = %00000000000000000000011111111111
Const HEADER_ID%            = %00000000000000000001100000000000
Const HEADER_LAYER%         = %00000000000000000110000000000000
Const HEADER_PROTECTION%    = %00000000000000001000000000000000
Const HEADER_BITRATE%       = %00000000000011110000000000000000
Const HEADER_SAMPLINGRATE%  = %00000000001100000000000000000000
Const HEADER_PADDING%       = %00000000010000000000000000000000
Const HEADER_PRIVATE%       = %00000000100000000000000000000000
Const HEADER_CHANNELMODE%   = %00000011000000000000000000000000
Const HEADER_MODEEXTENSION% = %00001100000000000000000000000000
Const HEADER_COPYRIGHT%     = %00010000000000000000000000000000
Const HEADER_ORIGINAL%      = %00100000000000000000000000000000
Const HEADER_EMPHASIS%      = %11000000000000000000000000000000

Global Size%, Stream%, Buffer%, Offset%, Header%
Global Found%

Size = FileSize("test.mp3")

Stop()
Stream = ReadFile("test.mp3")
If Not Stream Then RuntimeError("Unable to open file")

Buffer = CreateBank(Size)
ReadBytes(Buffer, Stream, 0, Size)
CloseFile(Stream)

Found = False
For Offset = 0 To Size - 5
   Header = PeekInt(Buffer, Offset)
   DebugLog Bin(Header)
   If (Header And HEADER_SYNC%) = HEADER_SYNC% Then
      Stop()
      Found = True
      Exit
   EndIf
Next
If Not Found Then RuntimeError("No MP3 file")

Global ID%, Layer%, Protection%, Bitrate%, Samplingrate%
Global Padding%, Private%, ChannelMode%, ModeExtension%
Global Copyright%, Original%, Emphasis%

ID            = (Header And HEADER_ID) Shr 11
Layer         = (Header And HEADER_LAYER) Shr 13
Protection    = (Header And HEADER_PROTECTION) Shr 15
Bitrate       = (Header And HEADER_BITRATE) Shr 16
Samplingrate  = (Header And HEADER_SAMPLINGRATE) Shr 20
Padding       = (Header And HEADER_PADDING) Shr 22
Private       = (Header And HEADER_PRIVATE) Shr 23
ChannelMode   = (Header And HEADER_CHANNELMODE) Shr 24
ModeExtension = (Header And HEADER_MODEEXTENSION) Shr 26
Copyright     = (Header And HEADER_COPYRIGHT) Shr 28
Original      = (Header And HEADER_ORIGINAL) Shr 29
Emphasis      = (Header And HEADER_EMPHASIS) Shr 30

WaitKey()
End

.Bitrates
; MPEG 1, Layer I
Data -1, 32, 64, 96, 128, 160, 192, 224
Data 256, 288, 320, 352, 384, 416, 448, -1

; MPEG 1, Layer II
Data -1, 32, 48, 56, 64, 80, 96, 112
Data 128, 160, 192, 224, 256, 320, 384, -1

; MPEG 1, Layer III
Data -1, 32, 40, 48, 56, 64, 80, 96
Data 112, 128, 160, 192, 224, 256, 320, -1

; MPEG 2/2.5, Layer I
Data -1, 32, 48, 56, 64, 80, 96, 112
Data 128, 144, 160, 176, 192, 224, 256, -1

; MPEG 2/2.5, Layer II/III
Data -1, 8, 16, 24, 32, 40, 48, 56
Data 64, 80, 96, 112, 128, 144, 160, -1

.Samplingrates
; MPEG 1
Data 44100, 22050, 11025, -1

; MPEG 2
Data 48000, 24000, 12000, -1

; MPEG 2.5
Data 32000, 16000, 8000, -1


Aber der vergleich mit Winamp besagt was anderes. Auch die Bits mal umzudrehen hat nix gebracht:

Code: [AUSKLAPPEN]
Const HEADER_SYNC%          = %11111111111000000000000000000000
Const HEADER_ID%            = %00000000000110000000000000000000
Const HEADER_LAYER%         = %00000000000001100000000000000000
Const HEADER_PROTECTION%    = %00000000000000010000000000000000
Const HEADER_BITRATE%       = %00000000000000001111000000000000
Const HEADER_SAMPLINGRATE%  = %00000000000000000000110000000000
Const HEADER_PADDING%       = %00000000000000000000001000000000
Const HEADER_PRIVATE%       = %00000000000000000000000100000000
Const HEADER_CHANNELMODE%   = %00000000000000000000000011000000
Const HEADER_MODEEXTENSION% = %00000000000000000000000000110000
Const HEADER_COPYRIGHT%     = %00000000000000000000000000001000
Const HEADER_ORIGINAL%      = %00000000000000000000000000000100
Const HEADER_EMPHASIS%      = %00000000000000000000000000000011

Global Size%, Stream%, Buffer%, Offset%, Header%
Global Found%

Size = FileSize("test.mp3")

Stop()
Stream = ReadFile("test.mp3")
If Not Stream Then RuntimeError("Unable to open file")

Buffer = CreateBank(Size)
ReadBytes(Buffer, Stream, 0, Size)
CloseFile(Stream)

Found = False
For Offset = 0 To Size - 5
   Header = PeekInt(Buffer, Offset)
   DebugLog Bin(Header)
   If (Header And HEADER_SYNC%) = HEADER_SYNC% Then
      Stop()
      Found = True
      Exit
   EndIf
Next
If Not Found Then RuntimeError("No MP3 file")

Global ID%, Layer%, Protection%, Bitrate%, Samplingrate%
Global Padding%, Private%, ChannelMode%, ModeExtension%
Global Copyright%, Original%, Emphasis%

ID            = (Header And HEADER_ID) Shr 19
Layer         = (Header And HEADER_LAYER) Shr 17
Protection    = (Header And HEADER_PROTECTION) Shr 16
Bitrate       = (Header And HEADER_BITRATE) Shr 12
Samplingrate  = (Header And HEADER_SAMPLINGRATE) Shr 10
Padding       = (Header And HEADER_PADDING) Shr 9
Private       = (Header And HEADER_PRIVATE) Shr 8
ChannelMode   = (Header And HEADER_CHANNELMODE) Shr 6
ModeExtension = (Header And HEADER_MODEEXTENSION) Shr 4
Copyright     = (Header And HEADER_COPYRIGHT) Shr 3
Original      = (Header And HEADER_ORIGINAL) Shr 2
Emphasis      = (Header And HEADER_EMPHASIS)

WaitKey()
End

.Bitrates
; MPEG 1, Layer I
Data -1, 32, 64, 96, 128, 160, 192, 224
Data 256, 288, 320, 352, 384, 416, 448, -1

; MPEG 1, Layer II
Data -1, 32, 48, 56, 64, 80, 96, 112
Data 128, 160, 192, 224, 256, 320, 384, -1

; MPEG 1, Layer III
Data -1, 32, 40, 48, 56, 64, 80, 96
Data 112, 128, 160, 192, 224, 256, 320, -1

; MPEG 2/2.5, Layer I
Data -1, 32, 48, 56, 64, 80, 96, 112
Data 128, 144, 160, 176, 192, 224, 256, -1

; MPEG 2/2.5, Layer II/III
Data -1, 8, 16, 24, 32, 40, 48, 56
Data 64, 80, 96, 112, 128, 144, 160, -1

.Samplingrates
; MPEG 1
Data 44100, 22050, 11025, -1

; MPEG 2
Data 48000, 24000, 12000, -1

; MPEG 2.5
Data 32000, 16000, 8000, -1


Ich schaue mir ID, layer und Bitrate im Debugger an, und vergleiche. Keine Chance, warum auch immer.

Ich halte mich an http://www.wotsit.org/download...=228746691
und
http://de.wikipedia.org/wiki/Mp3

hmmm

mfg olli
vertex.dreamfall.at | GitHub

Vertex

BeitragSo, Apr 01, 2007 22:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh man, anscheinend sind die im BigEndian Format abgespeichert:
Hier, das geht halbwegs:
Code: [AUSKLAPPEN]
Const HEADER_SYNC%          = %11111111111000000000000000000000
Const HEADER_ID%            = %00000000000110000000000000000000
Const HEADER_LAYER%         = %00000000000001100000000000000000
Const HEADER_PROTECTION%    = %00000000000000010000000000000000
Const HEADER_BITRATE%       = %00000000000000001111000000000000
Const HEADER_SAMPLINGRATE%  = %00000000000000000000110000000000
Const HEADER_PADDING%       = %00000000000000000000001000000000
Const HEADER_PRIVATE%       = %00000000000000000000000100000000
Const HEADER_CHANNELMODE%   = %00000000000000000000000011000000
Const HEADER_MODEEXTENSION% = %00000000000000000000000000110000
Const HEADER_COPYRIGHT%     = %00000000000000000000000000001000
Const HEADER_ORIGINAL%      = %00000000000000000000000000000100
Const HEADER_EMPHASIS%      = %00000000000000000000000000000011

Global Size%, Stream%, Header%, Found%, X%, Y%
Dim BitrateTable(4, 15)
Dim SamplingrateTable(2, 3)

Size = FileSize("test.mp3")
Stream = ReadFile("test.mp3")
If Not Stream Then RuntimeError("Unable to open file")

While Not Eof(Stream)
   Header = LittleEndian(ReadInt(Stream))
   If (Header And HEADER_SYNC) = HEADER_SYNC Then
      Print "Header found at offset " + (FilePos(Stream) - 4)
      Found = True
      Exit
   EndIf
   SeekFile(Stream, FilePos(Stream) - 3)
Wend

CloseFile(Stream)
If Not Found Then RuntimeError("Maybe no MP3 file")

Global ID%, Layer%, Protection%, Bitrate%, Samplingrate%
Global Padding%, Private%, ChannelMode%, ModeExtension%
Global Copyright%, Original%, Emphasis%, FrameSize%

Restore Bitrates
For X = 0 To 4
   For Y = 0 To 15
      Read BitrateTable(X, Y)
   Next
Next

Restore Samplingrates
For X = 0 To 2
   For Y = 0 To 3
      Read SamplingrateTable(X, Y)
   Next
Next

ID            = (Header And HEADER_ID) Shr 19
Layer         = (Header And HEADER_LAYER) Shr 17
Protection    = (Header And HEADER_PROTECTION) Shr 16
Bitrate       = (Header And HEADER_BITRATE) Shr 12
Samplingrate  = (Header And HEADER_SAMPLINGRATE) Shr 10
Padding       = (Header And HEADER_PADDING) Shr 9
Private       = (Header And HEADER_PRIVATE) Shr 8
ChannelMode   = (Header And HEADER_CHANNELMODE) Shr 6
ModeExtension = (Header And HEADER_MODEEXTENSION) Shr 4
Copyright     = (Header And HEADER_COPYRIGHT) Shr 3
Original      = (Header And HEADER_ORIGINAL) Shr 2
Emphasis      = (Header And HEADER_EMPHASIS)

Print "ID:"
Select ID
   Case 0 Print " MPEG Version 2.5"
   Case 1 Print " Reserved"
   Case 2 Print " MPEG Version 2"
   Case 3 Print " MPEG Version 1"
End Select

Print "Layer:"
Select Layer
   Case 0 Print " Reserved"
   Case 1 Print " Layer III"
   Case 2 Print " Layer II"
   Case 3 Print " Layer I"
End Select

Print "Bitrate:"
Print " " + GetBitrate() + " kBits/s"

Print "Samplingrate:"
Print " " + GetSamplingrate%() + " Hz"

Print "Channel mode:"
Select ChannelMode
   Case 0 Print " Stereo"
   Case 1 Print " Joint Stereo"
   Case 2 Print " Dual channel"
   Case 3 Print " Single Channel"
End Select

FrameSize = 144*GetBitrate()*1000/GetSamplingrate() + Padding
Print "Length:"
Print " " + Size/FrameSize/38.5 + " Seconds"

WaitKey()
End

.Bitrates
; MPEG 1, Layer I
Data -1, 32, 64, 96, 128, 160, 192, 224
Data 256, 288, 320, 352, 384, 416, 448, -1

; MPEG 1, Layer II
Data -1, 32, 48, 56, 64, 80, 96, 112
Data 128, 160, 192, 224, 256, 320, 384, -1

; MPEG 1, Layer III
Data -1, 32, 40, 48, 56, 64, 80, 96
Data 112, 128, 160, 192, 224, 256, 320, -1

; MPEG 2/2.5, Layer I
Data -1, 32, 48, 56, 64, 80, 96, 112
Data 128, 144, 160, 176, 192, 224, 256, -1

; MPEG 2/2.5, Layer II/III
Data -1, 8, 16, 24, 32, 40, 48, 56
Data 64, 80, 96, 112, 128, 144, 160, -1

.Samplingrates
; MPEG 1
Data 44100, 22050, 11025, -1

; MPEG 2
Data 48000, 24000, 12000, -1

; MPEG 2.5
Data 32000, 16000, 8000, -1

Function LittleEndian(Big%)
   Return (Big And $FF) Shl 24 Or (Big Shr 8 And $FF) Shl 16 Or (Big Shr 16 And $FF) Shl 8 Or (Big Shr 24 And $FF)
End Function

Function GetBitrate%()
   Local X%

   Select ID
      Case 0
         Select Layer
            Case 0 Return -1
            Case 1 X = 4
            Case 2 X = 4
            Case 3 X = 3
         End Select
      
      Case 1
         Return -1
      
      Case 2
         Select Layer
            Case 0 Return -1
            Case 1 X = 4
            Case 2 X = 4
            Case 3 X = 3
         End Select
      
      Case 3
         Select Layer
            Case 0 Return -1
            Case 1 X = 2
            Case 2 X = 1
            Case 3 X = 0
         End Select
   End Select

   Return BitrateTable(X, Bitrate)
End Function

Function GetSamplingrate%()
   Select ID
      Case 0 X = 2
      Case 1 Return -1
      Case 2 X = 1
      Case 3 X = 0
   End Select

   Return SamplingrateTable(X, Samplingrate)
End Function


Halbwegs deswegen, da noch nicht ID3 Tags aus der Dateigröße herausgerechnet wurden.

mfg olli
vertex.dreamfall.at | GitHub

Eingeproggt

BeitragDi, Apr 03, 2007 15:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab mir deinen Code angesehen. (Hab lang gebraucht, bis ich ihn verstanden hab...)
Hat JEDE MP3-Datei einen Header? Ohne die kleinste Ausnahme?
Ich will nämlich die Runtimeerrors rausnehmen und trotzdem ein stabiles Programm haben.

Zur Funktionalität:
Ich will nicht meckern, weil ich hätts nicht besser hingekriegt, aber von allen Liedern, wo ich mir den Aufwand angetan habe nachzuschauen, stimmt die Länge (um die es mir geht) bei ca ein Drittel nicht.
In diesen Fällen stimmts absolut nicht, 2sek Toleranz hatte ich gewährt.

EDIT: Liegt das an der variablen Bitrate? Das glaub ich zwar nicht, weil ein paar falsche Ergebnisse auch bei alten MP3s auftraten.
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

Vertex

BeitragDi, Apr 03, 2007 23:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Jup, variable Bitlängen sind tötlich für den obrigen Code. Es berechnet ja nur die Länge für den ersten Frame rechnet diese auf die gesamte Datei hoch. Du müsstest praktisch jeden Frame durchgehen, und dessen Länge berechnen.

Ansonsten ja, jede MP3 besteht aus Frames, die einen Header zuvor haben. Einen eigentlichen Dateiheader gibt es nicht, auch kein Dateicontainer wie Ogg bei Vorbis oder RIFF bei WAV Dateien.

mfg olli
vertex.dreamfall.at | GitHub

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group