2011-12-20 100 views
0

我正在學習visual basic .net,我試圖將一些java源代碼轉換爲vb.net項目。該項目讀取的MP3細節,然後根據幀頭細節準確地分裂文件等。閱讀MP3 Frameheader - 將位值分配給變量

我的問題涉及到讀取MP3文件的幀頭。我知道幀詳細信息包含在幀的前4個(32位)字節中,某些位表示某些值,如下所示:http://www.mp3-tech.org/programmer/frame_header.html

使用FileStream我已經能夠讀取此數據並將其顯示在文本框中的二進制文件。

我正在尋找幫助閱讀這些位並將它們分配給我的班級中的變量。我不知道做什麼是正確的過程,因爲一些值的長度爲1,2或4位,例如比特19-20 = MpegType,比特12-15 =比特率索引,比特9 =填充等

我已經看過codeproject.com上的類似項目,但我不明白他們是如何實現上述目標的。

任何幫助,非常感謝。

編輯:

這裏是主要的子至今,當這個運行在格式文本框輸出是因爲我還沒有包括代碼聲明變量和屬性等

Public Sub decode() 
    Dim fs As FileStream 
    Dim bytes(3) As Byte 
    fs = New FileStream(mFilename, FileMode.Open, FileAccess.Read) 

    If fs.CanRead Then 
     fs.Read(bytes, 0, bytes.Length) 
     For i As Integer = 0 To bytes.Length - 1 
      Form1.RichTextBox.Text += Convert.ToString(bytes(i), 2).PadLeft(8, "0"c) & vbCrLf 
     Next 
     fs.Close() 
     fs.Dispose() 
    Else 
     MsgBox("File CANNOT be read!!!") 
    End If 
End Sub 

如下:

11111111 
11111010 
10110011 
01001100 

我想通讀這些位,並將相應的值分配給變量例如

讀取前12位的同步值。 讀取第13位的mpegID值。 讀取bitID值的位14和15等。

希望更清楚。

Java代碼如下:

public FrameHeader() { 
    this.header32 = 0; 
    valid = false; 
} 

public FrameHeader(int header32) { 
    this.header32 = header32; 
    decode(); 
} 

public void setHeader32(int header32) { 
    this.header32 = header32; 
    decode(); 
} 

private void decode() { 
    mpegID = (header32 >> 19) & 3; 
    layerID = (header32 >> 17) & 3; 
    crc16used = (header32 & 0x00010000) == 0; 
    bitrateIndex = (header32 >> 12) & 0xF; 
    samplingrateIndex = (header32 >> 10) & 3; 
    padding = (header32 & 0x00000200) != 0; 
    privateBitSet = (header32 & 0x00000100) != 0; 
    mode = (header32 >> 6) & 3; 
    modeExtension = (header32 >> 4) & 3; 
    copyrighted = (header32 & 0x00000008) != 0; 
    original = (header32 & 0x00000004) == 0; // bit set -> copy 
    emphasis = header32 & 3; 
    valid = (mpegID != ILLEGAL_MPEG_ID) && (layerID != ILLEGAL_LAYER_ID) && (bitrateIndex != 0) 
      && (bitrateIndex != 15) && (samplingrateIndex != ILLEGAL_SR); 
    if (valid) { 
     samplingrateHz = SAMPLING_RATES[samplingrateIndex]; 
     if (mpegID == MPEG2_ID) 
      samplingrateHz >>= 1; // 16,22,48 kHz 
     if (mpegID == MPEG25_ID) 
      samplingrateHz >>= 2; // 8,11,24 kHz 
     channels = (mode == MODE_MONO) ? 1 : 2; 
     bitrateKBPS = BITRATE_MAP[mpegID][layerID][bitrateIndex]; 
     if (layerID == LAYER1_ID) { 
      // layer 1: always 384 samples/frame and 4byte-slots 
      samplesPerFrame = 384; 
      bytesPerSlot = 4; 
     } 
     else { 
      // layer 2: always 1152 samples/frame 
      // layer 3: MPEG1: 1152 samples/frame, MPEG2/2.5: 576 
      // samples/frame 
      samplesPerFrame = ((mpegID == MPEG1_ID) || (layerID == LAYER2_ID)) ? 1152 : 576; 
      bytesPerSlot = 1; 
     } 
     frameSize = ((bitrateKBPS * 125) * samplesPerFrame)/samplingrateHz; 
     if (bytesPerSlot > 1) 
      frameSize -= frameSize % bytesPerSlot; 
     if (padding) 
      frameSize += bytesPerSlot; 
    } 
} 
+0

發佈您的Java和VB源代碼,我相信有人會爲您提供一些東西。 – 2011-12-21 05:07:34

+0

添加了我目前的代碼和一些更多的信息。 – mheptinstall 2011-12-21 19:02:03

+0

添加了回覆。 – 2011-12-21 20:19:40

回答

0

Here is幀的詳細說明和對數據如何在頭保持的公式中,前4個字節的幀的。 我不知道你在做什麼,但是,以防萬一,以防萬一,here you go。重新發明車輪毫無意義。

.Net有一個名爲BitArray的類,您可以使用它來存儲您的位。

+0

我能夠讀取前4個字節,但我不知道如何將這些字節中的位轉換爲適當的變量。 – mheptinstall 2011-12-21 19:03:09

+0

我遇到過類似的項目,它使用函數將位轉換爲字符串。顯然,我可以使用這種方法,我想我是否有使用BitArray的替代方法好奇。 – mheptinstall 2011-12-21 20:35:29

0

我遇到過類似的項目,它使用函數將位轉換爲字符串。我已經將這段代碼與另一個例子結合起來,我發現它將二進制字符串更改爲整數。有興趣聽到其他方法嗎?

Public Function BinaryToInteger(ByVal objBitArray As BitArray, ByVal intStart As Integer, ByVal intEnd As Integer) As Integer 

    Dim BinaryString As String 
    Dim BinaryNum As Integer 
    Dim BitCount As Short 

    BinaryString = "" 

    For i As Integer = intStart To intEnd 
     BinaryString &= IIf(objBitArray.Item(i), "1", "0") 
    Next 

    For BitCount = 1 To Len(BinaryString) 
     BinaryNum = BinaryNum + (CDbl(Mid(BinaryString, Len(BinaryString) - BitCount + 1, 1)) * (2^(BitCount - 1))) 
    Next BitCount 

    BinaryToInteger = BinaryNum 

End Function 
+0

該函數使用一個位數組並從int開始讀取並打算返回一個字符串。您可以將它讀入另一個位數組,然後返回位數組。 – 2011-12-21 21:24:26

+0

我不明白你爲什麼要將位數組讀入另一個位數組?我已經改變了上面的函數,首先它從開始和結束參數中讀取位,轉換爲字符串,然後轉換爲整數。 – mheptinstall 2011-12-22 17:33:59

+0

爲什麼不只是解析字符串的第一個地方,然後轉換爲int? – 2011-12-22 17:57:43