#!/usr/bin/perl -w
# music flac -> mp3 converter
use strict;
use File::Find; # for recursion down dirs of flac files

my $source_dir = '/home/doug/Music/CDRipsA';
my $dest_dir = '/home/doug/Music/MP3';
my $infofilename = ">/home/doug/flac2mp3.txt";
my $tempfilename = "/fasttmp/tempa.wav";

### tags
my $artist_name;
my $album_name;
my $song_name;
my $track_number;
my @tags;



my $i = 0; # doesn't everyone use this?

### find all the source directories and create target ones at the new base
sub process_dirs
{
 my $newdir; # path for new directory
 
# print LOG $File::Find::name, -d && '/', "\n"; # debug

# see if it's a directory.  If so, create one at target if not already existing
 if (-d) # it's a directory
 {
 #create alternate path at destination base dir 
 ($newdir = $File::Find::name) =~ s/$source_dir/$dest_dir/;

 # create new if not already existing
  if (! -d $newdir) # doesn't exist
  {
#   print LOG "making dir:$newdir\n";
   mkdir $newdir;
  } else
  {
   # exists, warn
#   print LOG "$newdir already exists\n";
  }  
 } # end if directory
} # end process_dirs
############################
# process files, dirs assumed set up

### @@@ add test to skip already-converted files up top, so this can  be run
# and re-run later to (only) finish up.  Hmm. What if stopped in the middle
# of a file?  Signals?  Can't control them to the other programs, which
# are what runs nearly all the time, not us.

sub convert_file
{
 my $dest_path;
 my @args;
 unless (-d) # it's a directory, we did that already
 {
  ($dest_path = $File::Find::name) =~ s/$source_dir/$dest_dir/; #almost right
  if (m/.mp3/i) # converted already, just copy it 
  {
   
   $dest_path =~ s/$_//; # strip off actual name for cp
#   print LOG "copying $File::Find::name to $dest_path\n";
   @args =('cp','-f',"$File::Find::name","$dest_path");
   system (@args) == 0 or die "copy failed:$?";
   return; # get out, nothing more required
  } 
  
#  if ($i++ >= 20) {die "Test count reached:$i\n";} # debug limit

  $artist_name=`metaflac --show-tag=artist "$File::Find::name" | cut -d \= -f 2`;
  $album_name=`metaflac --show-tag=album "$File::Find::name" | cut -d \= -f 2`;
  $song_name=`metaflac --show-tag=title "$File::Find::name" | cut -d \= -f 2`;
  $track_number=`metaflac --show-tag=tracknumber "$File::Find::name" | cut -d \= -f 2`;
  chomp $artist_name;
  chomp $album_name;
  chomp $song_name;
  chomp $track_number;
  @tags =("-a $artist_name","-A $album_name","-s $song_name","-t $track_number"); 
#  print "Tags: @tags\n"; # debug


#  print LOG "decoding: $File::Find::name, base:$_\n";
  @args =('flac', '-d', '-f', "$File::Find::name",'-o', "$tempfilename");
  system(@args) == 0 or die "decode failed $?";
  
  $dest_path =~ s/.flac/.mp3/;
#  print LOG "converting $_ to mp3\n";
  @args = ('lame', '-m', 'auto', '--vbr-new','--preset', 'fast', 'standard', # standard ~192kb/sec
  '--disptime', '1', "$tempfilename","$dest_path");
  #preset medium, standard, extreme, are possible
# bash line  lame -m auto --preset $quality "$2" "$3" 2>&1 
  system(@args) == 0 or die "lame failed $?";

#Note, this can be done in lame above with a more-complex line accding to man.
#bash line: id3tag "${mp3_fields[@]}" "$2"
  @args = ('id3tag',@tags,"$dest_path");  
#  print LOG "Tag args:@args\n"; # debug
  system(@args) == 0 or die "id3tags failed $?";
  # remove temp file just in case
  @args = ('rm', '-f',"$tempfilename");
  system(@args) == 0 or die "rm didn't fly $?";
 }

}

############# main program
#open LOG, $infofilename or die "Can't create log: $infofilename: $!";
# first set up destination dirs
find (\&process_dirs,$source_dir); # only needed? first time, but...works quick
# make searching log easier
#print LOG "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n";

find (\&convert_file,$source_dir); # do the conversions


