# $Id: Mp3check.pm,v 1.5 2003/12/14 09:43:56 ianb Exp $
package MP3::Archive::Lint::Tools::Mp3check;

use strict;
use warnings;

use vars qw(@ISA $VERSION);
@ISA = qw(MP3::Archive::Lint::Tool);
$VERSION = '0.01';

=head1 mp3check - Tool to check mp3 files using mp3_check (or checkmp3)

Tests integrity of mp3 files using the mp3_check command. If quick
mode (-q) is enabled, silently returns without doing anything.

mp3_check is available from sourceforge, see
L<http:E<sol>E<sol>sourceforge.netE<sol>projectE<sol>?group_id=6126>

See L<mp3lint(1)> for more details on installing needed software.

=head2 Tests

=over 4

=cut

sub new
{
	my $proto=shift;
	my $class=ref($proto) || $proto;
	my $opts=shift;
	my $self=$class->SUPER::new($opts);;
	bless($self,$class);
	
	$self->{cmd}=$self->findprogram("mp3_check");
	unless(-x $self->{cmd})
	{
		$self->{cmd}=$self->findprogram("checkmp3");
		unless(-x $self->{cmd})
		{
			$self->say("mp3_check or checkmp3 not found,test skipped");
			return $self;
		}
	}
	if($self->config->quickscan)
	{
		$self->debug("quick mode enabled, test skipped");
		return $self;
	}
	$self->settests("framecheck");
	return $self;
}


sub initscan
{
	my $self=shift;
	return 0 unless(-f $self->{file});
	return 0 unless($self->{filename}=~/\.mp[23]$/i);
					
	return 1;
}

=item B<framecheck>

Tests integrity of mp3 with mp3_check. As mp3info and mp3_check often
give different numbers of broken frames, both tests are run, and there
are options to specify a minimum number of broken frames before
complaining.

Variables:

=over 4

=item $lint_maxbadframes_mp3check

number of bad frames to accept before complaining

(number, default 0)

=back

=cut

sub framecheck
{
	my $self=shift;
	
	my ($goodframes,$badframes);
	
	unless(open(I,"$self->{cmd} -a $self->{qfile} 2>/dev/null |"))
	{
		$self->say("cannot run mp3_check:$!");
		return;
	}
	
	while(<I>)
	{
		chomp;
		if(/GOOD_FRAMES\s+(.*)/)
		{
			$goodframes=$1;
		}
		if(/BAD_FRAMES\s+(.*)/)
		{
			$badframes=$1;
		}
	}
	close(I);
	
	my $totframes=$goodframes+$badframes;
	if($totframes == 0)
	{
		$self->say("no frames (empty file?)");
	}
	else
	{
		my $percentbad=sprintf("%.2f",$badframes/$totframes*100);
		my $maxbadframes=$self->config->get("lint_maxbadframes_mp3check");
		
		if($badframes>$maxbadframes)
		{
			if($goodframes==0)
			{
				$self->say("mp3 corrupt (0 good frames)");
			}
			else
			{
				$self->say("bad frames:$badframes/$totframes ($percentbad\%)");
			}
		}
	}
}

=back

=cut	

1;
