mp3 VBR histogram?

Ian Smith smithi at nimnet.asn.au
Thu Aug 6 19:17:26 UTC 2009


On Wed, 5 Aug 2009, b. f. wrote:
 > On 8/5/09, b. f. <bf1783 at googlemail.com> wrote:
 > > On 8/5/09, Ian Smith <smithi at nimnet.asn.au> wrote:
 > >> On Wed, 5 Aug 2009, b. f. wrote:
 > > ...
 > >>  >
 > >>  > I've dumped frame bitrates of mp3 files before from the command-line
 > >>  > using audio/mp3_check and something like:
 > >>  >
 > >>  > mp3_check -avv sample.mp3 | awk '/BitRate/ { print $2  }' -
 > >>
 > >
 > >>
 > >> That works well for extracting the raw frame bitrates, might try
 > >> scripting up a simple histogram from that, the next rainy day.
 > >
 > > Oh, I thought you wanted the numbers.  Well, awk is still your friend.
 > >  You could use something like:
 > >
 > > mp3_check -avv sample.mp3 | awk -v minbr=32 -v maxbr=448 -v
 > > maxwidth=80 -v dispchar="*" '/BitRate/ {
 > > Num=int(($2-minbr)/(maxbr-minbr)*maxwidth); bar=""; for (i=0; i < Num;
 > > i++) bar=bar dispchar; print bar } '
 > >
 > > instead (and probably there are more elegant ways to do this if you
 > > know awk well).

I now know at least twice as much awk as I did yesterday, thanks :)

 > I definitely need that cup of coffee.  Histogram, not temporal history
 > -- right.  <gnashes teeth>  You can use, for a simple numerical
 > histogram:
 > 
 > mp3_check -avv sample.mp3 | awk '/BitRate/ { nbr[$2]=nbr[$2]+1 } END {
 > for (br in nbr) print br, nbr[br] }' | sort -g

Before I read this your second message - thought it was the list copy of 
your prior, but I'm not getting those for some reason(?) - I'd hacked up 
the script below which shows all I need, except maybe the average:

smithi on sola% mp3_check ~/0/music/rf_livin.mp3

FILE_NAME           /home/smithi/0/music/rf_livin.mp3
GOOD_FRAMES         12073
BAD_FRAMES          0
LAST_BYTE_CHECKED   6322173
VBR_HIGH            320
VBR_LOW             32
VBR_AVERAGE         160
SONG_LENGTH         05:15.37

USER_TIME           0.18s
SYS_TIME            0.03s

smithi on sola% ./mp3histo ~/0/music/rf_livin.mp3
[ 32] 1
[ 40] 0
[ 48] 0
[ 56] 0
[ 64] 0
[ 80] 2
[ 96] 23
[112] 677       ******
[128] 2526      ************************
[160] 6540      ****************************************************************
[192] 1281      ************
[224] 680       ******
[256] 273       **
[320] 70
[all] 12073

=======
#!/bin/sh	# mp3histo v0.5 7/8/9
usage() {
	[ "$1" ] && echo $1
	echo "usage: `basename $0` filename.mp3"; exit 1
}
[ "$1" ] || usage
[ -r "$1" ] || usage "no file $1"	# "$1" may have spaces
stem=${1%.mp3}; [ "${stem}.mp3" = "$1" ] || usage "$1 not *.mp3"
tmpf=/tmp/`basename "$1"`		# avoid using subshell

brtab='32 40 48 56 64 80 96 112 128 160 192 224 256 320'
for i in $brtab max all; do eval count_$i=0; done

mp3_check -avv "${stem}.mp3" | awk '/BitRate/ { print $2 }' > $tmpf
while read br; do
	[ "${brtab% $br*}" = "$brtab" ] && echo "bad rate $br" && continue
	eval count_$br=\$\(\(\$count_$br + 1\)\)
done < $tmpf	# ; rm $tmpf

for br in $brtab; do
	eval i=\$count_$br
	[ $i -gt $count_max ] && count_max=$i  
	count_all=$(($count_all + $i))
done

[ -f "$stem.histo" ] && rm "$stem.histo"
for br in $brtab; do
	[ $br -gt 96 ] && f='' || f=' '
	eval echo -n "$br \$count_$br" \
	| awk -v max=$count_max -v t="	" -v f="$f" -v width=64 -v ch="*" \
		' { len=int($2/max*width); bar=""; OFS="";
		for (i=0; i<len; i++) bar=bar ch;
		print "[",f,$1,"] ",$2, t bar } ' >> "$stem.histo"
done
echo "[all] $count_all" >> "$stem.histo"

touch -r "$stem.mp3" "$stem.histo"
cat "$stem.histo"
exit 0
=======

thanks again for the awk-foo,

cheers, Ian


More information about the freebsd-multimedia mailing list