Чтение MP3 Frameheader - присвоение битовых значений переменным - PullRequest
0 голосов
/ 21 декабря 2011

Я изучаю Visual Basic .NET и пытаюсь перевести некоторый исходный код Java в проект vb.net.Проект читает данные в формате mp3, а затем точно разделяет файл в соответствии с данными заголовка кадра и т. Д.

Мой вопрос касается чтения заголовка кадра файлов MP3.Я понимаю, что сведения о кадре содержатся в первых 4 (32-битных) байтах кадра, и определенные биты представляют определенные значения, как подробно описано здесь: http://www.mp3 -tech.org / programmer / frame_header.html

Используя FileStream, я смог прочитать эти данные и отобразить их в двоичном виде в текстовом поле.

Я ищу помощи по чтению битов и присвоению их переменным в моем классе.Я не уверен, что будет правильной процедурой для этого, так как некоторые значения имеют длину 1, 2 или 4 бита, например, биты 19-20 = MpegType, биты 12-15 = BitrateIndex, бит 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.Прочитайте биты 14 и 15 для значения layerID и т. Д.

Надеюсь, что это понятнее.

Код 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;
    }
}

Ответы [ 2 ]

0 голосов
/ 22 декабря 2011

Я сталкивался с похожим проектом, который использует функцию для преобразования битов в строку. Я объединил этот код с другим примером, который я нашел, который изменил двоичную строку на целое число Хотите услышать об альтернативных методах?

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 голосов
/ 21 декабря 2011

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

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

...