Created
October 9, 2014 06:15
-
-
Save mdchaney/9adcf006b23a9adc10d6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# By Michael Chaney, Michael Chaney Consulting Corporation | |
# Copyright 2006, Michael Chaney Consulting Corporation, all rights reserved | |
# read wav chunks, see what each chunk is | |
use strict; | |
use POSIX qw(strftime); | |
my $header; | |
my $chunk; | |
if (scalar @ARGV != 1) { | |
print STDERR "Usage: $0 filename\n"; | |
exit 1; | |
} | |
open F, "<$ARGV[0]" or die "Cannot open $ARGV[0]: $!"; | |
read F, $header, 12; | |
my ($riff, $filelen, $wave) = unpack('A4VA4', $header); | |
printf STDERR "%s - %s (%d bytes)\n", $riff, $wave, $filelen-4; | |
if ($riff eq 'RIFF' && $wave eq 'WAVE') { | |
# it's a wave! let's read the chunks | |
while (!eof(F)) { | |
read F, $header, 8; | |
if ($header) { | |
my ($type, $len) = unpack('A4V', $header); | |
printf STDERR " %s (%d)\n", $type, $len; | |
if ($type eq 'bext') { | |
read F, $chunk, $len; | |
# further parse the bwav chunk | |
my ($description, $originator, $originator_reference, | |
$origination_date, $origination_time, $time_ref_low, | |
$time_ref_high, $version, $smpte_umid, $res, $history)= | |
unpack('A256 A32 A32 A10 A8 V V v a64 A190 A*', $chunk); | |
my @smpte_umid=unpack('C*', $smpte_umid); | |
printf STDERR | |
" Description: %s | |
Originator: %s | |
Originator Ref: %s | |
Origination Date: %s | |
Origination Time: %s | |
Time Ref Low: %d | |
Time Ref High: %d | |
BWF Version: %d | |
SMPTE UMID Bytes: %s | |
Coding History: %s\n", | |
$description, $originator, $originator_reference, | |
$origination_date, $origination_time, | |
$time_ref_low, $time_ref_high, | |
$version, | |
join(' ', @smpte_umid), $history; | |
} elsif ($type eq 'fmt') { | |
read F, $chunk, $len; | |
my ($format_tag, $channels, $samples_per_sec, | |
$avg_bytes_per_sec, $block_align, $bits_per_sample) = | |
unpack('v v V V v v', $chunk); | |
printf STDERR | |
" Format Tag: %d | |
Channels: %d | |
Samples per sec: %d | |
Avg bytes per sec: %d | |
Block align: %d | |
Bits per sample: %d\n", | |
$format_tag, $channels, $samples_per_sec, | |
$avg_bytes_per_sec, $block_align, $bits_per_sample; | |
} elsif ($type eq 'fact') { | |
read F, $chunk, $len; | |
my ($samples) = unpack('V', $chunk); | |
printf STDERR " Samples: %d\n", $samples; | |
} else { | |
seek F, $len, 1; | |
} | |
} | |
} | |
} | |
close F; | |
sub min { | |
my ($a,$b)=@_; | |
if ($a<$b) { return $a; } else { return $b; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please note that this parser is not completely accurate as it's possible for a wav file to have a chunk with an odd length and chunks have to start on an even word boundary. This does not compensate for that. I will update it one day to handle that.