1) I am not at all sure that STDIN can even be opened in binary mode at all! I mean CTL-C, CTL-Z mean things to STDIN although these are certainly valid binary values.

2)If you want to read binary data, open a file in binmode... local $/ = undef; is not needed.

3)Once you are dealing with binary data, study page 758 of "Programming Perl, 3rd edition" very carefully. One thing to be aware of is for example: "big-endian" vs "little-endian" order. Some machines put the most significant 16 bits first of 32 bits and some put it vice-versa. IBM has many machines and some do it one way and some another.

In your situation, look at nN and vV and the other options.

Perl can do binary editing quite well.

I offer one of the very first Perl subs that I wrote. This is from more than a decade ago. I would do some things differently now. But this does slam multiple Windows .wav files of the same type together into a new .wav file. This is just a simple example of binary editing.

sub cat_waves(@){ my ($out, @list)=@_; my $me = whoami(); # $me is like "Util::cat_waves", i.e "this" subr +outine name my $BUFSIZE = 8 * 2**10; myprint ("$me: Creating \"$out\" using ".scalar@list." input \".wav +\" files..."); unless ( (defined ($out)) && (@list >0) ){ showfailed( "$me - Internal Error: not enough arguments supplied +"); return; } # The final output file format will be: # "RIFF" (4 bytes) # riff size (4 bytes) (total bytes that follow from here) # voice format info (42 bytes) #some weird voodoo is in here # "data" (4 bytes) # data size (4 bytes) (voice bytes that follow from here) # all of the voice data (n bytes), must be word aligned. # EOF # 4 byte integers are Intel, VAX "little endian" convention. # Some of the standard company voice edited .wav files contain othe +r # weird segments after the voice data segment. These will be delete +d in # the final concatentated .wav file. my ($new_data_size, @data_file_info) = get_data_sizes(@list); my $new_riff_size = $new_data_size + 42+8; #allow for wave format +info + DATA header myprint ("New File: \"$out\" will be created now..."); myprint (" total file size = ",$new_riff_size + 8); myprint (" RIFF segment size = $new_riff_size"); myprint (" DATA segment size = $new_data_size"); open (OUTBIN, ">$out") || showfailed("$me: unable to open $out"); binmode(OUTBIN) || showfailed("$me: unable to set binmode $out +"); my $buff; # write the new RIFF header to the output file. my $header_file = $list[0]; #"steal" the header from first input f +ile myprint ("Using header info from file: $header_file"); open(INBIN, "<$header_file") || showfailed("$me: unable to open $he +ader_file"); binmode(INBIN) || showfailed("$me: unable to set binm +ode $header_file"); my $n_bytes = read(INBIN, $buff, $BUFSIZE); ($n_bytes > 58) || showfailed("$me: too few bytes ($n_ +bytes) in $header_file"); my $rsize = pack("V4", $new_riff_size); # "V4" means Vax or Intel " +little endian" substr($buff,4,4) = substr($rsize,0,4); my $data_size = pack("V4", $new_data_size); substr($buff,54,4)= substr($data_size,0,4); print OUTBIN substr($buff,0,58); close INBIN || showfailed("$me: unable to close $header +_file"); #now just extract the data from all the .wav files and append to OU +TBIN while (@data_file_info){ my ($wave, $xfer) = @data_file_info; open(INBIN, "<$wave") || showfailed ("$me: unable to open $wave" +); binmode(INBIN) || showfailed ("$me: unable to set binmode + $wave"); myprint ("Appending voice data from $wave..."); my $i_buf_low=58; #don't transfer the initial header stuff in +the RIFF files. while ($xfer>0){ my $n_buf_bytes = read(INBIN, my $buff, $BUFSIZE); my $n = $n_buf_bytes - $i_buf_low; if ($xfer-$n <0 ){$n = $xfer;} #don't xfer past the end of +current data segment. $xfer -= $n; print OUTBIN substr($buff,$i_buf_low,$n); $i_buf_low = 0; } close (INBIN) || showfailed ("$me: unable to close $wave") +; } #end of while (@data_file_info) close(OUTBIN) || showfailed ("$me: unable to close $out"); myprint ("$me: Success \"$out\" has been created!"); return; } #end of cat_waves()

In reply to Re: Mysteries of unpack("a", ...) by Marshall
in thread Mysteries of unpack("a", ...) by pspinler

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



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.