Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
I am (for my sins) the maintainer of Audio::TagLib. There, I said it. My question arises out of constructing code that creates a 32-bit header for MPEG files. The header consists of bit fields of various widths.

This question concerns the ordering of bits in a 8-bit byte, packed into an integer. If I number the bits 7..0, the assignment results in a value when unpacked with 'b*' gives me the expected result: 11110010, with bit #7 on the left. The TagLib C++ library with which I communicate expects the field to look like this: 01001111, which is what one gets when unpacking with B*.

A pointer to doc that explains what's behind b vs B decoding would be greatly appreciated.

The actual code is attached.

Thanks.

#!/usr/bin/perl # Reference taglib-1.9.1 doc TagLib::MPEG::Header # and http://www.mp3-tech.org/programmer/frame_header.html package MPEG_Header; my %header = ( 'FrameSync' => [31,21], # Frame sync (all bits m +ust be set) 'VersionID' => [20,19], # MPEG Audio version ID 'Layer' => [18,17], # Layer description 'Protection' => [16,16], # Protection bit 'BitRate' => [15,12], # Bitrate index 'SamplingRate' => [11,10], # Sampling rate frequenc +y index 'Padding' => [9,9], # Padding bit 'Private' => [8,8], # Private bit. This one +is only informative. 'ChannelMode' => [7,6], # Channel Mode 'ModeExtension' => [5,4], # Mode extension (Only u +sed in Joint stereo) 'Copyright' => [3,3], # Copyright 'Original' => [2,2], # Original 'Emphasis' => [1,0], # Emphasis ); my %VersionID = ('2.5' => 0b00, '2' => 0b10, '1' => 0b11, ); my %Layer = ('III' => 0b01, 'II' => 0b10, 'I' => 0b11, ); my %Padding = ('Pad' => 0b1, 'NoPad' => 0b0, ); my %Protection = ('Protected' => 0b0, 'NotProtected' => 0b1, ); my %ChannelMode = ('Stereo' => 0b00, 'JointStereo' => 0b01, 'DualChannel' => 0b10, 'SingleChannel' => 0b11, ); my %Copyright = ('No', => 0b0, 'Yes' => 0b1, ); my %Original = ('Copy' => 0b0, 'Original' => 0b1, ); my %Emphasis = ('None' => 0b00, '5015' => 0b01, 'CCIT' => 0b11, ); sub _set_header_field { my ($hdr, $field, $value) = @_; warn "Field $field is not defined in the MPEG header\n" unless $he +ader{$field}; my $first = $header{$field}->[0]; my $last = $header{$field}->[1]; $hdr = pack("B*", "0"x32) unless defined $hdr; my ($pos, $off); if ( defined $value ) { # Field value assignment # Possible symbolic reference no strict 'refs'; # For symbolic reference $value = $$field{$value} if exists $$field{$value}; my $width = $first - $last + 1; for ($pos = $first; $width; $width --, $pos --) { $off = 31 - $pos; vec($hdr, $off, 1) = vec($value, $width - 1, 1); } return $hdr; } # Fill field with 1s for ($pos = $first; $pos >= $last; $pos --) { $off = 31 - $pos; vec($hdr, $off, 1) = 1; } return $hdr; } sub build_header { my %args = @_; my $header; $header = _set_header_field( $header, 'FrameSync' ); # All headers + have this foreach my $key ( keys %args ) { $header = _set_header_field( $header, $key, $args{$key} ); } return $header; } 1; =if 0 #! /usr/bin/perl use lib '.'; use MPEG_Header; my $mpeg_header = MPEG_Header::build_header( 'VersionID' => 2, 'Layer' => 'III', 'Protection' => 'NotPro +tected', 'BitRate' => 0b1000, + # 64 kbps for V2 and L3 'SamplingRate' => 0b10, # + 16000 Hz for V2 'Padding' => 'Pad', 'ChannelMode' => 'Stereo +', 'Copyright' => 'No', 'Original' => 'Yes', 'Emphasis' => 'CCIT', ); printf "b %-s\n", unpack("b*", $mpeg_header); printf "B %-s\n", unpack("B*", $mpeg_header); Spaces added. Unpack with b vs B. b 11111111 11110010 10001000 11000111 00001100 B 11111111 01001111 00010001 11100011 00110000 =cut

In reply to Bit order in bytes by geoffleach

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2024-04-19 19:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found