2011-12-20 4 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, но я не понимаю, как они достигли вышеуказанного.

Любая помощь очень ценится.

EDIT:

Вот основной югу до сих пор, я не включил код, объявляя переменные и свойства и т.д.

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. Читайте бит 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, и я верю, что кто-то придумает что-то для вас. –

+0

Добавлен мой текущий код и дополнительная информация. – mheptinstall

+0

Добавлен ответ. –

ответ

0

Here is подробное объяснение кадров и формула о том, как данные хранятся в заголовке, первые 4 байта кадра. Я не уверен, что вы пытаетесь выполнить, но, на всякий случай, here you go. Нет смысла изобретать колесо.

.Net имеет класс под названием BitArray, который вы использовали бы для хранения своих бит.

+0

Я могу прочитать первые 4 байта, но я не знаю, как перевести биты в эти байты в соответствующие переменные. – mheptinstall

+0

Я столкнулся с похожим проектом, который использует функцию для преобразования бит в строку.Очевидно, я могу использовать этот метод, подумал, что мне интересно, существует ли альтернативный метод с использованием BitArray. – mheptinstall

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 start, чтобы намереваться и возвращает строку. Вы можете прочитать его в другой бит-массив и вместо этого вернуть бит-массив. –

+0

Я не понимаю, почему вы читаете бит-массив в другой бит-массив? Я изменил функцию выше, сначала она считывает биты из начального и конечного аргументов, преобразует в строку и затем преобразует в целое число. – mheptinstall

+0

Почему бы просто не разобрать строку на первом месте, а затем преобразовать в int? –