"Fossies" - the Fresh Open Source Software Archive

Member "pacpl-code/pacpl.in" (9 Feb 2021, 162781 Bytes) of package /linux/privat/pacpl-6.1.3.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "pacpl.in": 6.1.2_vs_6.1.3.

A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.


    1 #!/usr/bin/perl
    2 #
    3 #  Perl Audio Converter
    4 #
    5 #  Copyright (C) 2005-2021 Philip Lyons (vorzox@gmail.com)
    6 #
    7 #    This program is free software; you can redistribute it and/or modify
    8 #    it under the terms of the GNU General Public License as published by
    9 #    the Free Software Foundation; either version 3 of the License, or
   10 #    (at your option) any later version.
   11 #
   12 #    This program is distributed in the hope that it will be useful,
   13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
   14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15 #    GNU General Public License for more details.
   16 #
   17 #    You should have received a copy of the GNU General Public License
   18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
   19 
   20 use strict;
   21 use warnings;
   22 use Getopt::Long;
   23 use File::Basename;
   24 use File::Find;
   25 use File::Spec::Functions qw(rel2abs);
   26 use Parallel::ForkManager;
   27 use String::ShellQuote;
   28 
   29 use feature qw(switch say);
   30 
   31 no if $] >= 5.018, warnings => "experimental::smartmatch";
   32 
   33 # Tagging modules
   34 use MP3::Tag;
   35 use Audio::FLAC::Header;
   36 use Audio::Scan;
   37 
   38 # CDDB module
   39 use CDDB_get qw(get_cddb);
   40 
   41 # non-encoder/decoder related options
   42 my 
   43 (
   44    $to,
   45    $recursive,
   46    $preserve,
   47    $rip,
   48    $help,
   49    $longhelp,
   50    $verbose,
   51    $verinfo,
   52    $dryrun,
   53    $delete,
   54    $keep,
   55    $overwrite,
   56    $formats,
   57    $topdir,
   58    $only,
   59    $first_run,
   60 
   61    @file,
   62    @dir,
   63 
   64    %run,
   65    %lang,
   66 );
   67 
   68 my $silent = "> /dev/null 2>&1";
   69 
   70 # tagging options
   71 my
   72 (
   73    $title,
   74    $track,
   75    $artist,
   76    $album,
   77    $comment,
   78    $year,
   79    $genre,
   80    $taginfo,
   81 );
   82 
   83 # name and version
   84 my $name      = "Perl Audio Converter";
   85 my $version   = "6.1.3";
   86 
   87 # If these options are toggled,  messages/errors will be displayed 
   88 # via kdialog or zenity/notify-send (depending on environment)
   89 my ($gui, $kde, $gnome);
   90 
   91 # Debugging (for developer use only)
   92 my $debug = 0;
   93 
   94 # default configuration.
   95 my %config = (
   96 
   97                IMPORTM      => 0,
   98                JOBS         => 4,
   99 
  100                DEFOPTS      => 1,
  101                EOPTS        => '',
  102                DOPTS        => '',
  103                NOPTS        => '',
  104 
  105                BITRATE      => 128,
  106                FREQ         => 44100,
  107                CHANNELS     => 2,
  108                EFFECT       => '',
  109                FCOMP        => 2,
  110                PCOMP        => 3,
  111                ACOMP        => 3000,
  112                OGGQUAL      => 3,
  113                SPXQUAL      => 8,
  114                AACQUAL      => 100,
  115                MPCQUAL      => 'radio',
  116                OFMODE       => 'normal',
  117                OFOPT        => 'fast',
  118                BRATIO       => 2,
  119                BQUANL       => 1.0,
  120                BPSIZE       => 128,
  121 
  122                USE_CDDB     => 1,
  123                CDDB_HOST    => 'freedb.freedb.org',
  124                CDDB_PORT    => 8880,
  125                CDDB_MODE    => 'cddb',
  126                CDDB_INPUT   => 1,
  127                DEVICE       => '/dev/dvd',
  128                NSCHEME      => '%ar - %ti',
  129 
  130                ZEN_DIR      => 1,
  131                ZEN_OPTS     => 1,               
  132                KDE_DIR      => 1,
  133                KDE_OPTS     => 1,
  134 
  135              );
  136 
  137 # location of configuration file
  138 my $conf_path = "@sysconfdir@/pacpl";
  139 my $po_dir    = "@pkgdatadir@/locale";
  140 my $mod_dir   = "$conf_path/modules";
  141 
  142 my $conf_file;
  143 
  144 # Icon path
  145 my $icon_path = "$conf_path/pacpl.png";
  146 
  147 # load the appropriate locale file
  148 load_lang();
  149 
  150 # try to load configuration file in this order...
  151 my @conf_locations = ( 
  152                        "$ENV{HOME}/.pacplrc",   # Local
  153                        "$conf_path/pacpl.conf", # Global
  154                        "$ENV{PWD}/pacpl.conf",  # Current Directory
  155                      );
  156 
  157 # try to load conf file from one of the above locations
  158 foreach my $i (@conf_locations) {
  159     if (not $conf_file and -e $i) {
  160         $conf_file = $i;
  161         say "$lang{debug} $lang{loaded_config} $conf_file" if $debug == 1;
  162     }
  163 }
  164 
  165 say "$lang{no_config}" if not $conf_file;
  166 
  167 # open config file.
  168 if ($conf_file and -e $conf_file) {
  169 
  170     open(CONF, "$conf_file") or die "$lang{opening_file} $conf_file - $!\n";
  171 
  172     my @conf_opts = <CONF>;
  173        @conf_opts = grep(!/^#|^$/, @conf_opts);
  174 
  175     close(CONF);
  176 
  177     # now read config file options and change default values accordingly.
  178     foreach (@conf_opts) {
  179         chomp;
  180         my ($k, $v) = split(/\s*=\s*/);
  181             $config{$k} = $v if exists($config{$k}) and length($v);
  182             say "$lang{debug} $k = $v" if $debug == 1 and exists($config{$k});
  183     }
  184 }
  185 
  186 my $codecs_conf = "$conf_path/codecs.conf";
  187 
  188 # set default encoders/decoders
  189 sub load_codecs {
  190 
  191     open(CODECS, "$codecs_conf") or die "$lang{opening_file} $codecs_conf - $!\n";
  192         
  193     my @codecs = <CODECS>;
  194        @codecs = grep(!/^$|^#/, @codecs);
  195        @codecs = grep(s/^\s*|\s*$//, @codecs);
  196        
  197     close(CODECS);
  198         
  199        foreach (@codecs) {
  200         
  201             chomp;
  202             my ($k, $v) = split(/\s*=\s*/);
  203             my ($e, $d) = split(/,/, $v);
  204             
  205                 $k =~ tr/A-Z/a-z/;
  206             
  207                 $run{$k}{DEFAULT_ENCODER} = $e if (exists($run{$k}{DEFAULT_ENCODER}));
  208                 $run{$k}{DEFAULT_DECODER} = $d if (exists($run{$k}{DEFAULT_DECODER}));
  209        }
  210 }
  211 
  212 # load po file and store in %lang hash
  213 sub load_lang {
  214 
  215     my $po = "$po_dir/$ENV{LANG}.po";
  216        $po =~ s/\.UTF-8//i      if $po =~ /UTF-8/i; 
  217        $po =~ s/\.utf8//i       if $po =~ /utf8/i;  
  218        $po =~ s/_\w+//          if not -e $po;      
  219        $po = "$po_dir/en_US.po" if not -e $po;      
  220        
  221     open(LANG, "< $po") or die "error: could not open - $po\n$!\n";
  222     
  223     my @data = <LANG>;
  224        @data = grep(!/^#|^$/, @data);
  225        
  226     close(LANG);
  227     
  228     foreach (@data) {
  229          chomp;    
  230          s/=/__EQ__/;
  231          my ($k, $v) = split(/\s*__EQ__\s*/, $_);
  232          $lang{$k} = $v;
  233     }
  234     
  235 }
  236     
  237 my $banner = 1;
  238 
  239 # print error messages
  240 sub perror {
  241     my ($key, $msg) = @_;
  242     say "$name - $version\n";
  243     say "$lang{error}: $lang{$key} $msg" . "\n";
  244     system("kdialog --title \"$name\" --error \"$lang{error}: $lang{$key} $msg\" &") if $gui and $kde;
  245     system("zenity  --title \"$name\" --error \"$lang{error}: $lang{$key} $msg\" &") if $gui and $gnome;
  246     die "$lang{seek_help}\n";
  247 }
  248 
  249 # print notices/warnings
  250 sub pnotice {
  251 
  252     my ($key, $msg, $nm) = @_;
  253 
  254     say "$name - $version\n" if $banner == 1;
  255     print "$lang{$key} $msg";
  256     say ''    if $nm == 1;
  257     say "\n"  if $nm == 2;
  258       
  259     $banner = 0;
  260 }
  261 
  262 # defaults for user variables.
  263 my $outfile;
  264 my $outdir;
  265 my $defopts   = $config{DEFOPTS};
  266 my $eopts     = $config{EOPTS};
  267 my $dopts     = $config{DOPTS};
  268 my $nopts     = $config{NOPTS};
  269 my $normalize = $config{NOPTS};
  270 my $bitrate   = $config{BITRATE};
  271 my $freq      = $config{FREQ};
  272 my $channels  = $config{CHANNELS};
  273 my $effect    = $config{EFFECT};
  274 my $fcomp     = $config{FCOMP};
  275 my $acomp     = $config{ACOMP};
  276 my $oggqual   = $config{OGGQUAL};
  277 my $spxqual   = $config{SPXQUAL};
  278 my $aacqual   = $config{AACQUAL};
  279 my $mpcqual   = $config{MPCQUAL};
  280 my $ofmode    = $config{OFMODE};
  281 my $ofopt     = $config{OFOPT};  
  282 my $bratio    = $config{BRATIO};
  283 my $bquanl    = $config{BQUANL};
  284 my $bpsize    = $config{BPSIZE};
  285 
  286 my $cdinfo;
  287 my $nocddb;
  288 my $noinput;
  289 my $device  = $config{DEVICE};
  290 my $nscheme = $config{NSCHEME};
  291 my $my_encoder;
  292 my $my_decoder;
  293 my $encoder;
  294 my $decoder;
  295 
  296 my $jobs = $config{JOBS};
  297 
  298 # command line options
  299 GetOptions
  300 ( 
  301     't|to=s'      => \$to,
  302     'r|recursive' => \$recursive,
  303     'p|preserve'  => \$preserve,
  304     'h|help'      => \$help,
  305     'l|longhelp'  => \$longhelp,
  306     'v|verbose'   => \$verbose,
  307     'f|formats'   => \$formats,
  308     'o|only=s'    => \$only,
  309     'k|keep'      => \$keep,
  310     'j|jobs=n'    => \$jobs,
  311 
  312     'taginfo'     => \$taginfo,
  313 
  314     'version'     => \$verinfo,
  315     'dryrun'      => \$dryrun,
  316     'delete'      => \$delete,
  317     'overwrite'   => \$overwrite,
  318     'normalize'   => \$normalize,
  319     'encoder=s'   => \$my_encoder,
  320     'decoder=s'   => \$my_decoder,
  321     
  322     'title=s'     => \$title,
  323     'track=n'     => \$track,
  324     'artist=s'    => \$artist,
  325     'album=s'     => \$album,
  326     'comment=s'   => \$comment,
  327     'year=n'      => \$year,
  328     'genre=s'     => \$genre,
  329     
  330     'gui'         => \$gui,
  331     'kde'         => \$kde,
  332     'gnome'       => \$gnome,
  333 
  334     'eopts=s'     => \$eopts,
  335     'dopts=s'     => \$dopts,
  336     'defopts=n'   => \$defopts,
  337     'nopts=s'     => \$nopts,
  338     'outfile=s'   => \$outfile,
  339     'outdir=s'    => \$outdir,
  340 
  341     'bitrate=n'   => \$bitrate,
  342     'freq=n'      => \$freq,
  343     'channels=n'  => \$channels,
  344     'effect=s'    => \$effect,
  345     'fcomp=n'     => \$fcomp,
  346     'acomp=n'     => \$acomp,
  347     'oggqual=n'   => \$oggqual,
  348     'spxqual=n'   => \$spxqual,
  349     'aacqual=n'   => \$aacqual,
  350     'mpcqual=s'   => \$mpcqual,
  351     'ofmode=s'    => \$ofmode,
  352     'ofopt=s'     => \$ofopt,
  353     'bratio=n'    => \$bratio,
  354     'bquanl=n'    => \$bquanl,
  355     'bpsize=n'    => \$bpsize,
  356     
  357         'rip=s'       => \$rip,
  358     'nocddb'      => \$nocddb,
  359     'noinput'     => \$noinput,
  360     'device=s'    => \$device,
  361     'nscheme=s'   => \$nscheme,
  362     'cdinfo'      => \$cdinfo,
  363 );
  364 
  365 if (defined($preserve) && !defined($outdir)) {
  366     die "You must specify --outdir when you use --preserve option. See man page.\n";
  367 }
  368 
  369 $silent = '' if $verbose;
  370 
  371 my $opts;
  372 my $total_converted = 0;
  373 my $total_failed = 0;
  374 
  375 # Initialize the fork manager with a count set through pacpl.conf or via the command line
  376 my $pm = Parallel::ForkManager->new($jobs);
  377 
  378 # conversion options.  when adding a new format, 
  379 # wild card %i = input file and %o = output file
  380 %run = (
  381 
  382      '3g2' => {
  383         
  384                 DEFAULT_ENCODER => 'ffmpeg',
  385                 DEFAULT_DECODER => 'ffmpeg',
  386                 
  387                 ENCODER => { 
  388                              ffmpeg => {
  389                                          NAME => 'ffmpeg',
  390                                          ESTR => sub {
  391                                                        $opts = "-ar 8000 -ac 1" if $defopts == 1;
  392                                                        $opts = '' if $defopts == 0;
  393                                                        "-y -i %i $eopts $opts %o"
  394                                                      },
  395                                          
  396                                          PROMPT => { NONE => 0, },
  397                                        },
  398                                        
  399                              avconv => {
  400                                          NAME => 'avconv',
  401                                          ESTR => sub {
  402                                                        $opts = "-ar 8000 -ac 1" if $defopts == 1;
  403                                                        $opts = '' if $defopts == 0;
  404                                                        "-y -i %i $eopts $opts %o"
  405                                                      },
  406                                          
  407                                          PROMPT => { NONE => 0, },
  408                                        },
  409                                        
  410                            },
  411                            
  412                 DECODER => {
  413                              ffmpeg => {
  414                                          NAME => 'ffmpeg',
  415                                          DSTR => sub { "-y -i %o $dopts %o" },                                         
  416                                        },
  417                                        
  418                              avconv => {
  419                                          NAME => 'avconv',
  420                                          DSTR => sub { "-y -i %o %dopts %o" },
  421                                        },
  422                            },
  423                            
  424                    TAGS => {
  425                              READ   => 0,
  426                              WRITE  => 0,
  427                              MODULE => undef,
  428                            },
  429                    
  430                },
  431        
  432       '3gp' => {
  433         
  434                 DEFAULT_ENCODER => 'ffmpeg',
  435                 DEFAULT_DECODER => 'ffmpeg',
  436                 
  437                 ENCODER => { 
  438                              ffmpeg => {
  439                                          NAME => 'ffmpeg',
  440                                          ESTR => sub {
  441                                                        $opts = "-ar 8000 -ac 1" if $defopts == 1;
  442                                                        $opts = '' if $defopts == 0;
  443                                                        "-y -i %i $eopts $opts %o"
  444                                                      },
  445                                          
  446                                          PROMPT => { NONE => 0, },
  447                                        },
  448                                        
  449                              avconv => {
  450                                          NAME => 'avconv',
  451                                          ESTR => sub {
  452                                                        $opts = "-ar 8000 -ac 1" if $defopts == 1;
  453                                                        $opts = '' if $defopts == 0;
  454                                                        "-y -i %i $eopts $opts %o"
  455                                                      },
  456                                          
  457                                          PROMPT => { NONE => 0, },
  458                                        },
  459                                        
  460                            },
  461                            
  462                 DECODER => {
  463                              ffmpeg => {
  464                                          NAME => 'ffmpeg',
  465                                          DSTR => sub { "-y -i %o $dopts %o" },
  466                                        },
  467                                        
  468                              avconv => {
  469                                          NAME => 'avconv',
  470                                          DSTR => sub { "-y -i %o %dopts %o" },
  471                                        },
  472                            },
  473                            
  474                    TAGS => {
  475                              READ   => 0,
  476                              WRITE  => 0,
  477                              MODULE => undef,
  478                            },
  479                    
  480                },
  481                
  482        aac  => {
  483 
  484                 DEFAULT_ENCODER => "faac",
  485                 DEFAULT_DECODER => "faad",
  486                 
  487                 ENCODER => {
  488                               faac => {
  489                                         NAME => "faac",
  490                                         ESTR => sub { 
  491                                                       $opts = "-q $aacqual" if $defopts == 1;
  492                                                       $opts = '' if $defopts == 0;
  493                                                       "$eopts $opts %i -o %o" 
  494                                                     },
  495                                         PROMPT => { AACQUAL => 1 },
  496                                       },
  497                                       
  498                             ffmpeg => {
  499                                         NAME => 'ffmpeg',
  500                                         ESTR => sub {
  501                                                       $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
  502                                                       $opts = '' if $defopts == 0;
  503                                                       "-y -i %i $eopts $opts %o"
  504                                                     },
  505                                         
  506                                         PROMPT => {
  507                                                     BITRATE  => 1,
  508                                                     FREQ     => 1,
  509                                                     CHANNELS => 1,
  510                                                   },
  511                                       },
  512                                       
  513                             avconv => {
  514                                         NAME => 'avconv',
  515                                         ESTR => sub {
  516                                                       $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
  517                                                       $opts = '' if $defopts == 1,
  518                                                     },
  519                                                     
  520                                         PROMPT => {
  521                                                     BITRATE  => 1,
  522                                                     FREQ     => 1,
  523                                                     CHANNELS => 1,
  524                                                   },
  525                                       },
  526                            },
  527                            
  528                 DECODER => {
  529                               faad => {
  530                                         NAME => "faad",
  531                                         DSTR => sub { "$dopts -o %i %o" },
  532                                       },
  533                               
  534                             ffmpeg => {
  535                                         NAME => "ffmpeg",
  536                                         DSTR => sub { "$dopts -y -i %i %o" },
  537                                       },
  538                                       
  539                             avconv => {
  540                                         NAME => 'avconv',
  541                                         DSTR => sub { "$dopts -y -i %i %o" },
  542                                       },
  543 
  544                            mplayer => {
  545                                         NAME => "mplayer",
  546                                         DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
  547                                       },
  548                            },
  549 
  550                 TAGS    => {
  551                              READ   => 0,
  552                              WRITE  => 0,
  553                              MODULE => undef,
  554                            },
  555                },
  556 
  557         ac3 => {
  558 
  559                 DEFAULT_ENCODER => "ffmpeg",
  560                 DEFAULT_DECODER => "ffmpeg",
  561                 
  562                 ENCODER => {
  563                               ffmpeg => {
  564                                           NAME => "ffmpeg",
  565                                           ESTR => sub { 
  566                                                         $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
  567                                                         $opts = '' if $defopts == 0;
  568                                                         "-y -i %i $eopts $opts %o"
  569                                                       },
  570                                           
  571                                           PROMPT => {
  572                                                       BITRATE  => 1,
  573                                                       FREQ     => 1,
  574                                                       CHANNELS => 1,
  575                                                     },
  576                                         },
  577                                         
  578                               avconv => {
  579                                           NAME => "avconv",
  580                                           ESTR => sub {
  581                                                         $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
  582                                                         $opts = '' if $defopts == 0;
  583                                                         "-y -i %i $eopts $opts %o"
  584                                                       },
  585                                           PROMPT => {
  586                                                       BITRATE  => 1,
  587                                                       FREQ     => 1,
  588                                                       CHANNELS => 1,
  589                                                     },
  590                                         },
  591                                         
  592                                aften => {
  593                                           NAME => "aften",
  594                                           ESTR => sub {
  595                                                         $opts = "-v 1 -q $bitrate -2" if $defopts == 1;
  596                                                         $opts = '' if $defopts == 0;
  597                                                         "$eopts $opts %i %o"
  598                                                       },
  599                                           
  600                                           PROMPT => {
  601                                                       BITRATE => 1,
  602                                                     },
  603                                         },
  604                                                     
  605                            },
  606                            
  607                 DECODER => {
  608                              mplayer => {
  609                                           NAME => "mplayer",
  610                                           DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
  611                                         },
  612                                         
  613                               ffmpeg => {
  614                                           NAME => "ffmpeg",
  615                                           DSTR => sub { "$dopts -y -i %i %o" },
  616                                         },
  617                               
  618                               avconv => {
  619                                           NAME => "avconv",
  620                                           DSTR => sub { "$dopts -y -i %i %o" },
  621                                         },
  622                            },
  623 
  624                 TAGS    => {
  625                              READ   => 0,
  626                              WRITE  => 0,
  627                              MODULE => undef,
  628                            },
  629                },      
  630 
  631        adts => {
  632    
  633                 DEFAULT_ENCODER => 'ffmpeg',
  634                 DEFAULT_DECODER => 'ffmpeg',
  635                 
  636                 ENCODER => {
  637                              ffmpeg => {
  638                                          NAME => 'ffmpeg',
  639                                          ESTR => sub {
  640                                                        $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libfaac" if $defopts == 1;
  641                                                        $opts = '' if $defopts == 0;
  642                                                        "-y -i %i $opts $eopts -strict -2 %o"
  643                                                      },
  644                                         PROMPT => {
  645                                                     BITRATE   => 1,
  646                                                     FREQ      => 1,
  647                                                     CHANNELS  => 1,
  648                                                   },
  649                                         },
  650                               
  651                               avconv => {
  652                                           NAME => 'avconv',
  653                                           ESTR => sub {
  654                                                         $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libfaac" if $defopts == 1;
  655                                                         $opts = '' if $defopts == 0;
  656                                                         "-y -i %i $opts $eopts %o"
  657                                                       },
  658                                           
  659                                           PROMPT => {
  660                                                       BITRATE  => 1,
  661                                                       FREQ     => 1,
  662                                                       CHANNELS => 1,
  663                                                     },                                                    
  664                                         },
  665                            },
  666                                         
  667                 DECODER => {
  668                              ffmpeg => {
  669                                          NAME => 'ffmpeg',
  670                                          DSTR => "$dopts -y -i %i %o",
  671                                        },
  672                              
  673                              avconv => {
  674                                          NAME => 'avconv',
  675                                          DSTR => "$dopts -y -i %i %o",
  676                                        },
  677                             },
  678   
  679                     TAGS => {
  680                               READ   => 0,
  681                               WRITE  => 0,
  682                               MODULE => undef,
  683                             },
  684                },
  685 
  686        ape  => {
  687 
  688                 DEFAULT_ENCODER => "mac",
  689                 DEFAULT_DECODER => "mac",
  690                 
  691                 ENCODER => {
  692                               mac => {
  693                                         NAME => "mac",
  694                                         ESTR => sub { 
  695                                                       $opts = "-c$acomp" if $defopts == 1;
  696                                                       $opts = '' if $defopts == 0;
  697                                                       "%i %o $opts $eopts" 
  698                                                     },
  699 
  700                                         PROMPT => { ACOMP => 1 },
  701                                      },
  702                             },
  703                 
  704                 DECODER => {
  705                               mac => {
  706                                         NAME => "mac",
  707                                         DSTR => sub { "%i %o -d $dopts" },
  708                                      },
  709                                      
  710                            ffmpeg => {
  711                                        NAME => 'ffmpeg',
  712                                        DSTR => sub { "-y -i %i %dopts %o" },
  713                                      },
  714                                      
  715                            avconv => {
  716                                        NAME => 'avconv',
  717                                        DSTR => sub { "-y -i %i $dopts %o" },
  718                                      },
  719                            },
  720 
  721                 TAGS    => {
  722                              READ   => 1,
  723                              WRITE  => 0,
  724                              MODULE => "Audio::Scan",
  725                            },
  726                },
  727                
  728         amr => {
  729         
  730                 DEFAULT_ENCODER => "ffmpeg",
  731                 DEFAULT_DECODER => "ffmpeg",
  732                 
  733                 ENCODER => { 
  734                              ffmpeg => {
  735                                          NAME => "ffmpeg",
  736                                          ESTR => sub {
  737                                                        $opts = "-ar 8000 -ac 1" if $defopts == 1;
  738                                                        $opts = '' if $defopts == 0;
  739                                                        "-y -i %i $eopts $opts %o"
  740                                                      },
  741                                          
  742                                          PROMPT => { NONE => 0, },
  743                                        },
  744                                        
  745                              avconv => {
  746                                          NAME => "avconv",
  747                                          ESTR => sub {
  748                                                        $opts = "-ar 8000 -ac 1" if $defopts == 1;
  749                                                        $opts = '' if $defopts == 0;
  750                                                        "-y -i %i $eopts $opts %o"
  751                                                      },
  752                                          
  753                                          PROMPT => { NONE => 0, },
  754                                        },
  755                                        
  756                            },
  757                            
  758                 DECODER => {
  759                              ffmpeg => {
  760                                          NAME => 'ffmpeg',
  761                                          DSTR => sub { "-y -i %i $dopts %o" },
  762                                        },
  763                                        
  764                              avconv => {
  765                                          NAME => 'ffmpeg',
  766                                          DSTR => sub { "-y -i %i %dopts %o" },
  767                                        },
  768                            },
  769                            
  770                    TAGS => {
  771                              READ   => 0,
  772                              WRITE  => 0,
  773                              MODULE => undef,
  774                            },
  775                    
  776                },
  777                
  778       bonk  => {
  779 
  780                 DEFAULT_ENCODER => "bonk",
  781                 DEFAULT_DECODER => "bonk",
  782                 
  783                 ENCODER => {
  784                               bonk => {
  785                                         NAME => "bonk",
  786                                         ESTR => sub { 
  787                                                       $opts = "-q $bquanl -b $bratio -s $bpsize" if $defopts == 1;
  788                                                       $opts = '' if $defopts == 0;
  789                                                       "encode $eopts $opts %i -o %o" 
  790                                                     },
  791                                         
  792                                         PROMPT => {
  793                                                     BQUANL => 1,
  794                                                     BRATIO => 1,
  795                                                     BPSIZE => 1,
  796                                                   },
  797                                       },
  798                            },
  799                 
  800                 DECODER => {
  801                               bonk => {
  802                                         NAME => "bonk",
  803                                         DSTR => sub { "decode %i -o %o" },
  804                                       },
  805                            },
  806 
  807                 TAGS    => {
  808                              READ   => 0,
  809                              WRITE  => 0,
  810                              MODULE => undef,
  811                            },
  812                },
  813 
  814        dsf  => {
  815 
  816                 DEFAULT_ENCODER => undef,
  817                 DEFAULT_DECODER => "sacd",
  818                 
  819                 DECODER => {
  820                                       
  821                  sacd => {
  822                                        NAME => "sacd",
  823                                        DSTR => sub { "-i %i" },
  824                                      },
  825                },
  826 
  827                 TAGS    => {
  828                              READ   => 1,
  829                              WRITE  => 0,
  830                              MODULE => "Audio::Scan",
  831                            },
  832                },
  833 
  834         dts => {
  835        
  836                 DEFAULT_ENCODER => 'ffmpeg',
  837                 DEFAULT_DECODER => 'ffmpeg',
  838                 
  839                 ENCODER => {
  840                              ffmpeg => {
  841                                          NAME => 'ffmpeg',
  842                                          ESTR => sub {
  843                                                        $opts = '' if $defopts == 1;
  844                                                        $opts = '' if $defopts == 0;
  845                                                        "-y -i %i $opts $eopts -strict -2 -codec:a libfaac %o"
  846                                                      },
  847        
  848                                            PROMPT => { NONE => 0, },
  849                                        },
  850                                        
  851                              avconv => {
  852                                          NAME => 'avconv',
  853                                          ESTR => sub {
  854                                                        $opts = '' if $defopts == 1 or $defopts == 0;
  855                                                        "-y -i %i $opts $eopts -codec:a libfaac %o",
  856                                                      },
  857                                            PROMPT => { NONE => 0, },
  858                                        },
  859                                        
  860                              dcaenc => {
  861                                          NAME => 'dcaenc',
  862                                          ESTR => sub {
  863                                                        $opts = "$bitrate" if $defopts == 0;
  864                                                        $opts = '' if $defopts == 1;
  865                                                        "%i %o $opts"
  866                                                      },
  867                                                      
  868                                          PROMPT => { NONE => 0, },
  869                                        },
  870                            },
  871                            
  872                 DECODER => {
  873                              ffmpeg => {
  874                                          NAME => 'ffmpeg',
  875                                          DSTR => "$dopts -y -i %i %o",
  876                                        },
  877                                        
  878                              avconv => {
  879                                          NAME => 'avconv',
  880                                          DSTR => "$dopts -y -i %i %o",
  881                                        },
  882                            },
  883 
  884                    TAGS => {
  885                              READ   => 0,
  886                              WRITE  => 0,
  887                              MODULE => undef,
  888                            },
  889                },              
  890                                                    
  891        flac => {
  892 
  893                 DEFAULT_ENCODER => "flac",
  894                 DEFAULT_DECODER => "flac",
  895                 
  896                 ENCODER => {
  897                               flac => {
  898                                         NAME => "flac",
  899                                         ESTR => sub { 
  900                                                       $opts = "-$fcomp" if $defopts == 1;
  901                                                       $opts = '' if $defopts == 0;
  902                                                       "$eopts -f $opts %i -o %o" 
  903                                                     },
  904                                         PROMPT => { FCOMP => 1 },
  905                                       },
  906 
  907                              flake => {
  908                                         NAME => "flake",
  909                                         ESTR => sub {
  910                                                       $opts = "-$fcomp" if $defopts == 1;
  911                                                       $opts = '' if $defopts == 0;
  912                                                       "$eopts $opts %i -o %o"
  913                                                      },
  914                                         PROMPT => { FCOMP => 1 },
  915                                       },
  916                                     
  917                             ffmpeg => {
  918                                         NAME => "ffmpeg",
  919                                         ESTR => sub { 
  920                                                       $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
  921                                                       $opts = '' if $defopts == 0;
  922                                                       "-y -i %i $eopts $opts %o" 
  923                                                     },
  924                                         
  925                                       PROMPT => {
  926                                                     BITRATE  => 1,
  927                                                     FREQ     => 1,
  928                                                     CHANNELS => 1,
  929                                                  },
  930                                       },
  931                                       
  932                             avconv => {
  933                                         NAME => 'avconv',
  934                                         ESTR => sub {
  935                                                       $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
  936                                                       $opts = '' if $defopts == 1;
  937                                                       "-y -i %i $eopts $opts %o"
  938                                                     },
  939                                         PROMPT => {
  940                                                     BITRATE  => 1,
  941                                                     FREQ     => 1,
  942                                                     CHANNELS => 1,
  943                                                   },
  944                                       },
  945                            },
  946 
  947                 DECODER => {
  948                               flac => {
  949                                         NAME => "flac",
  950                                         DSTR => sub { "$dopts -f -d %i -o %o" },
  951                                       },
  952                                     
  953                             ffmpeg => {
  954                                         NAME => "ffmpeg",
  955                                         DSTR => sub { "$dopts -y -i %i %o" },
  956                                       },
  957                                     
  958                             avconv => {
  959                                         NAME => 'avconv',
  960                                         DSTR => sub { "$dopts -y -i %i %o" },
  961                                       },
  962 
  963                            mplayer => {
  964                                         NAME => "mplayer",
  965                                         DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
  966                                       },
  967                            },
  968 
  969                 TAGS    => {
  970                              READ   => 1,
  971                              WRITE  => 1,
  972                              MODULE => "Audio::FLAC::Header",
  973                            },
  974                },
  975 
  976        fla  => {
  977 
  978                 DEFAULT_ENCODER => "flac",
  979                 DEFAULT_DECODER => "flac",
  980                 
  981                 ENCODER => {
  982                               flac => {
  983                                         NAME => "flac",
  984                                         ESTR => sub { 
  985                                                       $opts = "-$fcomp" if $defopts == 1;
  986                                                       $opts = '' if $defopts == 0;
  987                                                       "$eopts -f $opts %i -o %o" 
  988                                                     },
  989                                         PROMPT => { FCOMP => 1 },
  990                                       },
  991                            },
  992                            
  993                 DECODER => {
  994                               flac => {
  995                                         NAME => "flac",
  996                                         DSTR => sub { "$dopts -f -d %i -o %o" },
  997                                       },
  998 
  999                            mplayer => {
 1000                                         NAME => "mplayer",
 1001                                         DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 1002                                       },
 1003                            },
 1004 
 1005                 TAGS    => {
 1006                              READ   => 1,
 1007                              WRITE  => 1,
 1008                              MODULE => "Audio::FLAC::Header",
 1009                            },
 1010                },
 1011                
 1012        la   => {
 1013 
 1014                 DEFAULT_ENCODER => "la",
 1015                 DEFAULT_DECODER => "la",
 1016                 
 1017                 ENCODER => {
 1018                               la => {
 1019                                       NAME => "la",
 1020                                       ESTR => sub { "-overwrite $eopts %i %o" },
 1021                                       PROMPT => { NONE => 0, },
 1022                                     },
 1023                            },
 1024                 
 1025                 DECODER => {
 1026                               la => {
 1027                                       NAME => "la",
 1028                                       ESTR => sub { "-console $dopts %i > %o" },
 1029                                     },
 1030                            },
 1031 
 1032                    TAGS => {
 1033                              READ   => 0,
 1034                              WRITE  => 0,
 1035                              MODULE => undef,
 1036                            },
 1037                },
 1038                        
 1039         mp2 => {
 1040 
 1041                 DEFAULT_ENCODER => "ffmpeg",
 1042                 DEFAULT_DECODER => "ffmpeg",
 1043                 
 1044                 ENCODER => {
 1045                               ffmpeg => {
 1046                                           NAME => 'ffmpeg',
 1047                                           ESTR => sub {
 1048                                                         $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
 1049                                                         $opts = '' if $defopts == 0;
 1050                                                         "-y -i %i $eopts $opts %o"
 1051                                                       },
 1052                                           
 1053                                           PROMPT => {
 1054                                                       BITRATE  => 1,
 1055                                                       FREQ     => 1,
 1056                                                       CHANNELS => 1,
 1057                                                     },
 1058                                         },
 1059                                         
 1060                               avconv => {
 1061                                           NAME => 'avconv',
 1062                                           ESTR => sub {
 1063                                                         $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
 1064                                                         $opts = '' if $defopts == 0;
 1065                                                         "-y -i %i $eopts $opts %o"
 1066                                                       },
 1067                                           PROMPT => {
 1068                                                       BITRATE  => 1,
 1069                                                       FREQ     => 1,
 1070                                                       CHANNELS => 1,
 1071                                                     },
 1072                                         },
 1073                                         
 1074                              toolame => {
 1075                                           NAME => 'toolame',
 1076                                           ESTR => sub {
 1077                                                         $opts = "-b $bitrate" if $defopts == 1;
 1078                                                         $opts = '' if $defopts == 0;
 1079                                                         "$eopts $opts %i %o"
 1080                                                       },
 1081                                                       
 1082                                           PROMPT => {
 1083                                                       BITRATE => 1,
 1084                                                     },
 1085                                         },
 1086                           
 1087                              twolame => {
 1088                                           NAME => 'twolame',
 1089                                           ESTR => sub {
 1090                                                         $opts = "-b $bitrate -s $freq" if $defopts == 1;
 1091                                                         $opts = '' if $defopts == 0;
 1092                                                         "$eopts $opts %i %o"
 1093                                                       },
 1094                                           
 1095                                           PROMPT => {
 1096                                                       BITRATE => 1,
 1097                                                       FREQ    => 1,
 1098                                                     },
 1099                                         },
 1100                                         
 1101                                  sox => {
 1102                                           NAME => 'sox',
 1103                                           ESTR => sub {
 1104                                                         $opts = "-c $channels -r $bitrate" if $defopts == 1;
 1105                                                         $opts = '' if $defopts == 0;
 1106                                                         "%i $eopts $opts %o"
 1107                                                       },
 1108 
 1109                                           PROMPT => {
 1110                                                       BITRATE  => 1,
 1111                                                       CHANNELS => 1,
 1112                                                     },
 1113                                         },
 1114                            },
 1115                            
 1116                 DECODER => {
 1117                               
 1118                               ffmpeg => {
 1119                                           NAME => 'ffmpeg',
 1120                                           DSTR => "$dopts -y -i %i %o",
 1121                                         },
 1122                                         
 1123                               avconv => {
 1124                                           NAME => 'avconv',
 1125                                           DSTR => "%dopts -y -i %i %o",
 1126                                         },
 1127                                         
 1128                              mplayer => {
 1129                                           NAME => 'mplayer',
 1130                                           DSTR => "-vc null -vo null -ao pcm:file=%o %i",
 1131                                         },
 1132                            },
 1133   
 1134                    TAGS => {
 1135                              READ   => 0,
 1136                              WRITE  => 0,
 1137                              MODULE => undef,
 1138                            },
 1139                },                                        
 1140                
 1141         mp3 => {
 1142 
 1143                 DEFAULT_ENCODER => "lame",
 1144                 DEFAULT_DECODER => "lame",
 1145                 
 1146                 ENCODER => {
 1147                               lame => {
 1148                                         NAME => "lame",
 1149                                         ESTR => sub { 
 1150                                                       $opts = "--resample $freq -b $bitrate -h" if $defopts == 1;
 1151                                                       $opts = '' if $defopts == 0;
 1152                                                       "$eopts $opts %i %o" 
 1153                                                     },
 1154                                       
 1155                                         PROMPT => {
 1156                                                     BITRATE => 1,
 1157                                                     FREQ    => 1,
 1158                                                   },
 1159                                       },
 1160 
 1161                           bladeenc => {
 1162                                         NAME => "bladeenc",
 1163                                         ESTR => sub { 
 1164                                                       $opts = "-br $bitrate" if $defopts == 1;
 1165                                                       $opts = '' if $defopts == 0;
 1166                                                       "$eopts $opts %i %o" 
 1167                                                     },                                                    
 1168                                         PROMPT => { BITRATE => 1 },
 1169                                       },
 1170 
 1171                             ffmpeg => {
 1172                                         NAME => "ffmpeg",
 1173                                         ESTR => sub { 
 1174                                                       $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
 1175                                                       $opts = '' if $defopts == 0;
 1176                                                       "$eopts -y -i %i $opts %o" 
 1177                                                     },
 1178                                         
 1179                                         PROMPT => {
 1180                                                     BITRATE  => 1,
 1181                                                     FREQ     => 1,
 1182                                                     CHANNELS => 1,
 1183                                                   },
 1184                                       },
 1185                                       
 1186                             avconv => {
 1187                                         NAME => 'avconv',
 1188                                         ESTR => sub {
 1189                                                       $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
 1190                                                       $opts = '' if $defopts == 0;
 1191                                                       "-y -i %i $eopts $opts %o"
 1192                                                     },
 1193                                         PROMPT => {
 1194                                                     BITRATE  => 1,
 1195                                                     FREQ     => 1,
 1196                                                     CHANNELS => 1,
 1197                                                   },
 1198                                       },
 1199  
 1200                                sox => {
 1201                                         NAME => "sox",
 1202                                         ESTR => sub { 
 1203                                                       $opts = "-r $freq -c $channels" if $defopts == 1;
 1204                                                       $opts = '' if $defopts == 0;
 1205                                                       "%i $eopts $opts %o" 
 1206                                                     },
 1207                                         
 1208                                         PROMPT => {
 1209                                                     FREQ     => 1,
 1210                                                     CHANNELS => 1,
 1211                                                   },
 1212                                       },
 1213                            },
 1214                             
 1215                 DECODER => {
 1216                               lame => { 
 1217                                         NAME => "lame",
 1218                                         DSTR => sub { "$dopts --decode %i %o" },
 1219                                       },
 1220                              
 1221                             ffmpeg => {
 1222                                         NAME => "ffmpeg",
 1223                                         DSTR => sub { "$dopts -y -i %i %o" },
 1224                                       },
 1225                                       
 1226                             avconv => {
 1227                                         NAME => 'avconv',
 1228                                         DSTR => sub { "$dopts -y -i %i %O" },
 1229                                       },
 1230 
 1231                            mplayer => {
 1232                                         NAME => "mplayer",
 1233                                         DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 1234                                       },
 1235 
 1236                                sox => {
 1237                                         NAME => "sox",
 1238                                         DSTR => sub { "%i $dopts %o" },
 1239                                       },
 1240                            },
 1241 
 1242                 TAGS    => {
 1243                              READ   => 1,
 1244                              WRITE  => 1,
 1245                              MODULE => "MP3::Tag",
 1246                            },
 1247                },
 1248 
 1249       mp3hd => {
 1250                 
 1251                 DEFAULT_ENCODER => "mp3hdEncoder",
 1252                 DEFAULT_DECODER => "mp3hdDecoder",
 1253                 
 1254                 ENCODER => {
 1255                               mp3hdEncoder => {
 1256                                                 NAME => "mp3hdEncoder",
 1257                                                 ESTR => sub {
 1258                                                               $opts = "-br $bitrate" if $defopts == 1;
 1259                                                               $opts = '' if $defopts == 0;
 1260                                                               "$eopts $opts -if %i -of %o"
 1261                                                             },
 1262                                                 PROMPT => { BITRATE => 1 },
 1263                                               },
 1264                            },
 1265 
 1266                 DECODER => {
 1267                               mp3hdDecoder => {
 1268                                                 NAME => "mp3hdDecoder",
 1269                                                 DSTR => sub { "$dopts -if %i -of %o" },
 1270                                               },
 1271                            },
 1272 
 1273                    TAGS => {
 1274                              WRITE  => 1,
 1275                              READ   => 1,
 1276                              MODULE => "MP3::Tag",
 1277                            },
 1278                },
 1279 
 1280        mp4  => {
 1281 
 1282                 DEFAULT_ENCODER => "faac",
 1283                 DEFAULT_DECODER => "faad",
 1284                 
 1285                 ENCODER => {
 1286                 
 1287                             faac => {
 1288                                       NAME => "faac",
 1289                                       ESTR => sub { 
 1290                                                     $opts = "-q $aacqual" if $defopts == 1;
 1291                                                     $opts = '' if $defopts == 0;
 1292                                                     "$eopts -w $opts %i -o %o" 
 1293                                                   },
 1294                                       PROMPT => { AACQUAL => 1 },
 1295                                     },
 1296 
 1297                           ffmpeg => {
 1298                                       NAME => "ffmpeg",
 1299                                       ESTR => sub {
 1300                                                     $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
 1301                                                     $opts = '' if $defopts == 0;
 1302                                                     "-y -i %i $eopts $opts %o"
 1303                                                   },
 1304                                                   
 1305                                       PRIMPT => {
 1306                                                   BITRATE  => 1,
 1307                                                   FREQ     => 1,
 1308                                                   CHANNELS => 1,
 1309                                                 },
 1310                                     },
 1311                                     
 1312                           avconv => {
 1313                                       NAME => 'avconv',
 1314                                       ESTR => sub {
 1315                                                     $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
 1316                                                     $opts = '' if $defopts == 0;
 1317                                                     "-y -i %i $eopts $opts %o"
 1318                                                   },
 1319                                                   
 1320                                       PROMPT => {
 1321                                                   BITRATE  => 1,
 1322                                                   FREQ     => 1,
 1323                                                   CHANNELS => 1,
 1324                                                 },
 1325                                     },
 1326                            },
 1327                              
 1328                 DECODER => {
 1329 
 1330                             faad => {
 1331                                       NAME => "faad",
 1332                                       DSTR => sub { "$dopts -o %o %i" },
 1333                                     },
 1334 
 1335                           ffmpeg => { 
 1336                                       NAME => "ffmpeg",
 1337                                       DSTR => sub { "$dopts -y -i %i %o" },
 1338                                     },
 1339                                     
 1340                           avconv => {
 1341                                       NAME => 'avconv',
 1342                                       DSTR => sub { "$dopts -y -i %i %o" },
 1343                                     },
 1344 
 1345                          mplayer => {
 1346                                       NAME => "mplayer",
 1347                                       DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 1348                                     },
 1349                            },
 1350 
 1351                 TAGS    => {
 1352                              READ   => 1,
 1353                              WRITE  => 1,
 1354                              MODULE => "Audio::Scan",
 1355                            },
 1356                },
 1357 
 1358        # m4a container with AAC codec
 1359        mp4a  => {
 1360 
 1361                 DEFAULT_ENCODER => "faac",
 1362                 DEFAULT_DECODER => "faad",
 1363                 
 1364                 ENCODER => {
 1365                   
 1366                             faac => {
 1367                                       NAME => "faac",
 1368                                       ESTR => sub { 
 1369                                                     $opts = "-q $aacqual" if $defopts == 1;
 1370                                                     $opts = '' if $defopts == 0;
 1371                                                     "$eopts -w $opts %i -o %o" 
 1372                                                   },
 1373                                       PROMPT => { AACQUAL => 1 },
 1374                                     },
 1375                                     
 1376                           ffmpeg => {
 1377                                       NAME => "ffmpeg",
 1378                                       ESTR => sub {
 1379                                                     $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
 1380                                                     $opts = '' if $defopts == 0;
 1381                                                     "$eopts -y -i %i $opts %o"
 1382                                                   },
 1383                                               
 1384                                      PROMPT => {
 1385                                                 BITRATE  => 1,
 1386                                                 FREQ     => 1,
 1387                                                 CHANNELS => 1,
 1388                                                },
 1389                                      },
 1390                                      
 1391                            avconv => {
 1392                                        NAME => 'avconv',
 1393                                        ESTR => sub {
 1394                                                      $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1;
 1395                                                      $opts = '' if $defopts == 0;
 1396                                                      "-y -i %i $eopts $opts %o"
 1397                                                    },
 1398                                                    
 1399                                        PROMPT => {
 1400                                                    BITRATE  => 1,
 1401                                                    FREQ     => 1,
 1402                                                    CHANNELS => 1,
 1403                                                  },
 1404                                      },
 1405                            },
 1406                 
 1407                 DECODER => {
 1408 
 1409                              faad => {
 1410                                        NAME => "faad",
 1411                                        DSTR => sub { "$dopts -o %o %i" },
 1412                                      },
 1413                                        
 1414                            ffmpeg => {
 1415                                        NAME => "ffmpeg", 
 1416                                        DSTR => sub { "$dopts -y -i %i %o" },
 1417                                      },
 1418                                      
 1419                            avconv => {
 1420                                        NAME => 'avconv',
 1421                                        DSTR => sub { "$dopts -y -i %i %o" },
 1422                                      },
 1423 
 1424                           mplayer => {
 1425                                        NAME => "mplayer",
 1426                                        DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 1427                                      },
 1428                                       
 1429                            },
 1430 
 1431                 ESTR    => sub { "$eopts -w -q $aacqual %i -o %o" },
 1432 
 1433                 TAGS    => {
 1434                              READ   => 1,
 1435                              WRITE  => 1,
 1436                              MODULE => "Audio::Scan",
 1437                            },
 1438                },
 1439 
 1440        # m4a container with ALAC codec
 1441        alac  => {
 1442 
 1443                 DEFAULT_ENCODER => undef,
 1444                 DEFAULT_DECODER => "alac-decoder",
 1445                 
 1446                 DECODER => {
 1447                                       
 1448            'alac-decoder' => {
 1449                                        NAME => "alac-decoder",
 1450                                        DSTR => sub { "$dopts -f %o %i" },
 1451                                      },
 1452                                        
 1453                            ffmpeg => {
 1454                                        NAME => "ffmpeg", 
 1455                                        DSTR => sub { "$dopts -y -i %i %o" },
 1456                                      },
 1457                                      
 1458                            avconv => {
 1459                                        NAME => 'avconv',
 1460                                        DSTR => sub { "$dopts -y -i %i %o" },
 1461                                      },
 1462 
 1463                           mplayer => {
 1464                                        NAME => "mplayer",
 1465                                        DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 1466                                      },
 1467                                       
 1468                            },
 1469 
 1470                 TAGS    => {
 1471                              READ   => 1,
 1472                              WRITE  => 0,
 1473                              MODULE => "Audio::Scan",
 1474                            },
 1475                },
 1476 
 1477        m4b  => {
 1478        
 1479                 DEFAULT_ENCODER => undef,
 1480                 DEFAULT_DECODER => "faad",
 1481                 
 1482                 DECODER => {
 1483                              faad => {
 1484                                        NAME => "faad",
 1485                                        DSTR => sub { "$dopts -o %o %i" },
 1486                                      },
 1487 
 1488                           mplayer => {
 1489                                        NAME => "mplayer",
 1490                                        DSTR => sub { "$dopts -vc null -vo null -ao pcm:file=%o %i" },
 1491                                      },
 1492                                      
 1493                            ffmpeg => {
 1494                                        NAME => 'ffmpeg',
 1495                                        DSTR => sub { "$dopts -y -i %i %o" },
 1496                                      },
 1497                                      
 1498                            avconv => {
 1499                                        NAME => 'avconv',
 1500                                        DSTR => sub { "$dopts -y -i %i %o" },
 1501                                      },
 1502                            },
 1503 
 1504                 TAGS    => {
 1505                              READ   => 0,
 1506                              WRITE  => 1,
 1507                              MODULE => undef,
 1508                            },
 1509                },
 1510                              
 1511        mpc  => {
 1512 
 1513                 DEFAULT_ENCODER => "mpcenc",
 1514                 DEFAULT_DECODER => "mpcdec",
 1515                 
 1516                 ENCODER => {
 1517 
 1518                             mpcenc => {
 1519                                         NAME => "mpcenc",
 1520                                         ESTR => sub { 
 1521                                                       $opts = "--$mpcqual" if $defopts == 1;
 1522                                                       $opts = '' if $defopts == 0;
 1523                                                       "$eopts --overwrite $opts %i %o" 
 1524                                                     },
 1525                                         PROMPT => { MPCQUAL => 1 },
 1526                                       },
 1527                            },
 1528                 
 1529                 DECODER => {
 1530 
 1531                             mpcdec => {
 1532                                         NAME => "mpcdec",
 1533                                         DSTR => sub { "$dopts %i %o" },
 1534                                       },
 1535                                       
 1536                             ffmpeg => {
 1537                                         NAME => 'ffmpeg',
 1538                                         DSTR => sub { "$dopts -y -i %i %o" },
 1539                                       },
 1540                                       
 1541                             avconv => {
 1542                                         NAME => 'avconv',
 1543                                         DSTR => sub { "$dopts -y -i %i %o" },
 1544                                       },
 1545 
 1546                            mplayer => {
 1547                                         NAME => "mplayer",
 1548                                         DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 1549                                       },
 1550                            },
 1551 
 1552                 TAGS    => {
 1553                              READ   => 1,
 1554                              WRITE  => 1,
 1555                              MODULE => "Audio::Scan",
 1556                            },
 1557 
 1558                 PROMPT  => {
 1559                              MPCQUAL => 1,
 1560                            },
 1561                },
 1562 
 1563        mpp  => {
 1564 
 1565                 DEFAULT_ENCODER => "mpcenc",
 1566                 DEFAULT_DECODER => "mpcdec",
 1567                 
 1568                 ENCODER => {
 1569 
 1570                             mpcenc => {
 1571                                         NAME => "mpcenc",
 1572                                         ESTR => sub { 
 1573                                                       $opts = "--$mpcqual" if $defopts == 1;
 1574                                                       $opts = '' if $defopts == 0;
 1575                                                       "$eopts --overwrite $opts %i %o" 
 1576                                                     },
 1577                                         PROMPT => { MPCQUAL => 1 },
 1578                                       },
 1579                            },
 1580                 
 1581                 DECODER => {
 1582 
 1583                             mpcdec => {
 1584                                         NAME => "mpcdec",
 1585                                         DSTR => sub { "$dopts %i %o" },
 1586                                       },
 1587                                       
 1588                             ffmpeg => {
 1589                                         NAME => 'ffmpeg',
 1590                                         DSTR => sub { "$dopts -y -i %i %o" },
 1591                                       },
 1592                             
 1593                             avconv => {
 1594                                         NAME => 'avconv',
 1595                                         DSTR => sub { "$dopts -y -i %i %o" },
 1596                                       },
 1597 
 1598                            mplayer => {
 1599                                         NAME => "mplayer",
 1600                                         DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 1601                                       },
 1602                            },
 1603 
 1604                 TAGS    => {
 1605                              READ   => 1,
 1606                              WRITE  => 1,
 1607                              MODULE => "Audio::Scan",
 1608                            },
 1609                },
 1610 
 1611        off => {
 1612                 DEFAULT_ENCODER => 'off',
 1613                 DEFAULT_DECODER => 'off',
 1614                 
 1615                 ENCODER => {
 1616                              off => {
 1617                                       NAME => 'off',
 1618                                       ESTR => sub {
 1619                                                     $opts = "--mode $ofmode --optimize $ofopt" if $defopts == 1;
 1620                                                     $opts = '' if $defopts == 0;
 1621                                                     "$eopts --overwrite $opts %i --output %o"
 1622                                                   },
 1623                                       
 1624                                       PROMPT => {
 1625                                                   OFMODE => 1,
 1626                                                   OFOPT  => 1,
 1627                                                 },
 1628                                     },
 1629                            },
 1630                            
 1631                 DECODER => {
 1632                              off => {
 1633                                       NAME => 'off',
 1634                                       DSTR => sub { "$dopts --overwrite --decode %i --output %o" },
 1635                                     },
 1636                            },
 1637 
 1638                  TAGS   => {
 1639                              READ   => 0,
 1640                              WRITE  => 0,
 1641                              MODULE => undef,
 1642                            },
 1643                },
 1644 
 1645        ofr  => {
 1646 
 1647                 DEFAULT_ENCODER => "ofr",
 1648                 DEFAULT_DECODER => "ofr",
 1649                 
 1650                 ENCODER => {
 1651                               ofr => {
 1652                                         NAME => "ofr",
 1653                                         ESTR => sub { 
 1654                                                       $opts = "--mode $ofmode --optimize $ofopt" if $defopts == 1;
 1655                                                       $opts = '' if $defopts == 0;
 1656                                                       "$eopts --overwrite $opts %i --output %o" 
 1657                                                     },
 1658                                         
 1659                                         PROMPT => {
 1660                                                     OFMODE => 1,
 1661                                                     OFOPT  => 1,
 1662                                                   },
 1663                                      },
 1664                            },
 1665                            
 1666                 DECODER => {
 1667                               ofr => {
 1668                                         NAME => "ofr",
 1669                                         DSTR => sub { "$dopts --overwrite --decode %i --output %o" },
 1670                                      },
 1671                            },
 1672 
 1673                    TAGS => {
 1674                              READ   => 0,
 1675                              WRITE  => 0,
 1676                              MODULE => undef,
 1677                            },
 1678                },
 1679 
 1680        ofs  => {
 1681 
 1682                 DEFAULT_ENCODER => "ofs",
 1683                 DEFAULT_DECODER => "ofs",
 1684                 
 1685                 ENCODER => {
 1686                               ofs => {
 1687                                         NAME => "ofs",
 1688                                         ESTR => sub { 
 1689                                                       $opts = "--mode $ofmode --optimize $ofopt" if $defopts == 1;
 1690                                                       $opts = '' if $defopts == 0;
 1691                                                       "$eopts --overwrite $opts %i --output %o" 
 1692                                                     },
 1693                                     
 1694                                         PROMPT => {
 1695                                                     OFMODE => 1,
 1696                                                     OFOPT  => 1,
 1697                                                   },
 1698                                      },
 1699                            },
 1700                 
 1701                 DECODER => {
 1702                               ofs => {
 1703                                         NAME => "ofs",
 1704                                         DSTR => sub { "$dopts --overwrite --decode %i --output %o" },
 1705                                      },
 1706                            },
 1707 
 1708                    TAGS => {
 1709                              READ   => 0,
 1710                              WRITE  => 0,
 1711                              MODULE => undef,
 1712                            },
 1713                },
 1714 
 1715                
 1716         oga => {
 1717                 DEFAULT_ENCODER => 'oggenc',
 1718                 DEFAULT_DECODER => 'oggdec',
 1719                 
 1720                 ENCODER => {
 1721                               oggenc => {
 1722                                           NAME => 'oggenc',
 1723                                           ESTR => sub {
 1724                                                         $opts = "--resample $freq -q $oggqual" if $defopts == 1;
 1725                                                         $opts = '' if $defopts == 0;
 1726                                                         "$eopts $opts %i %o"
 1727                                                       },
 1728                                                                         PROMPT => {
 1729                                                       FREQ    => 1,
 1730                                                       OGGQUAL => 1,
 1731                                                     },
 1732                                         },
 1733 
 1734                               ffmpeg => {
 1735                                           NAME => "ffmpeg",
 1736                                           ESTR => sub { 
 1737                                                         $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1;
 1738                                                         $opts = '' if $defopts == 0;
 1739                                                         "-y -i %i $eopts $opts %o" 
 1740                                                       },
 1741                                           
 1742                                           PROMPT => {
 1743                                                       BITRATE  => 1,
 1744                                                       FREQ     => 1,
 1745                                                       CHANNELS => 1,
 1746                                                     },
 1747                                         },
 1748                               
 1749                               avconv => {
 1750                                           NAME => 'avconv',
 1751                                           ESTR => sub {
 1752                                                         $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1;
 1753                                                         $opts = '' if $defopts == 0;
 1754                                                         "-y -i %i $eopts $opts %o"
 1755                                                       },
 1756                                                       
 1757                                           PROMPT => {
 1758                                                       BITRATE  => 1,
 1759                                                       FREQ     => 1,
 1760                                                       CHANNELS => 1,
 1761                                                     },
 1762                                         },
 1763 
 1764                                  sox => {
 1765                                           NAME => "sox",
 1766                                           ESTR => sub { 
 1767                                                         $opts = "-r $freq -c $channels" if $defopts == 1;
 1768                                                         $opts = '' if $defopts == 0;
 1769                                                         "%i $eopts $opts %o" 
 1770                                                       },
 1771                                           
 1772                                           PROMPT => {
 1773                                                       FREQ     => 1,
 1774                                                       CHANNELS => 1,
 1775                                                     },
 1776                                         },
 1777                            },
 1778                            
 1779                 DECODER => {
 1780                               oggdec => {
 1781                                           NAME => "oggdec",
 1782                                           DSTR => sub { "$dopts %i --output %o" },
 1783                                         },
 1784 
 1785                               ffmpeg => {
 1786                                           NAME => "ffmpeg",
 1787                                           DSTR => sub { "$dopts -y -i %i %o" },
 1788                                         },
 1789                                         
 1790                               avconv => {
 1791                                           NAME => 'avconv',
 1792                                           DSTR => sub { "$dopts -y -i %i %o" },
 1793                                         },
 1794 
 1795                              mplayer => {
 1796                                           NAME => "mplayer",
 1797                                           DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 1798                                         },
 1799 
 1800                                  sox => {
 1801                                           NAME => "sox",
 1802                                           DSTR => sub { "%i $dopts %o" },
 1803                                         },
 1804                            },
 1805 
 1806                 TAGS    => {
 1807                              READ   => 1,
 1808                              WRITE  => 1,
 1809                              MODULE => "vorbiscomment",
 1810                            },
 1811                },               
 1812                               
 1813         ogg => {
 1814 
 1815                 DEFAULT_ENCODER => "oggenc",
 1816                 DEFAULT_DECODER => "oggdec",
 1817                 
 1818                 ENCODER => {
 1819                               oggenc => {
 1820                                           NAME => "oggenc",
 1821                                           ESTR => sub { 
 1822                                                         $opts = "--resample $freq -q $oggqual" if $defopts == 1;
 1823                                                         $opts = '' if $defopts == 0;
 1824                                                         "$eopts $opts %i -o %o" 
 1825                                                       },
 1826                                         
 1827                                           PROMPT => {
 1828                                                       FREQ    => 1,
 1829                                                       OGGQUAL => 1,
 1830                                                     },
 1831                                         },
 1832 
 1833                               ffmpeg => {
 1834                                           NAME => "ffmpeg",
 1835                                           ESTR => sub { 
 1836                                                         $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1;
 1837                                                         $opts = '' if $defopts == 0;
 1838                                                         "-y -i %i $eopts $opts %o" 
 1839                                                       },
 1840                                           
 1841                                           PROMPT => {
 1842                                                       BITRATE  => 1,
 1843                                                       FREQ     => 1,
 1844                                                       CHANNELS => 1,
 1845                                                     },
 1846                                         },
 1847                               
 1848                               avconv => {
 1849                                           NAME => 'avconv',
 1850                                           ESTR => sub {
 1851                                                         $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1;
 1852                                                         $opts = '' if $defopts == 0;
 1853                                                         "-y -i %i $eopts $opts %o"
 1854                                                       },
 1855                                                       
 1856                                           PROMPT => {
 1857                                                       BITRATE  => 1,
 1858                                                       FREQ     => 1,
 1859                                                       CHANNELS => 1,
 1860                                                     },
 1861                                         },
 1862 
 1863                                  sox => {
 1864                                           NAME => "sox",
 1865                                           ESTR => sub { 
 1866                                                         $opts = "-r $freq -c $channels" if $defopts == 1;
 1867                                                         $opts = '' if $defopts == 0;
 1868                                                         "%i $eopts $opts %o" 
 1869                                                       },
 1870                                           
 1871                                           PROMPT => {
 1872                                                       FREQ     => 1,
 1873                                                       CHANNELS => 1,
 1874                                                     },
 1875                                         },
 1876                            },
 1877                            
 1878                 DECODER => {
 1879                               oggdec => {
 1880                                           NAME => "oggdec",
 1881                                           DSTR => sub { "$dopts %i --output %o" },
 1882                                         },
 1883 
 1884                               ffmpeg => {
 1885                                           NAME => "ffmpeg",
 1886                                           DSTR => sub { "$dopts -y -i %i %o" },
 1887                                         },
 1888                                         
 1889                               avconv => {
 1890                                           NAME => 'avconv',
 1891                                           DSTR => sub { "$dopts -y -i %i %o" },
 1892                                         },
 1893 
 1894                              mplayer => {
 1895                                           NAME => "mplayer",
 1896                                           DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 1897                                         },
 1898 
 1899                                  sox => {
 1900                                           NAME => "sox",
 1901                                           DSTR => sub { "%i $dopts %o" },
 1902                                         },
 1903                            },
 1904 
 1905                 TAGS    => {
 1906                              READ   => 1,
 1907                              WRITE  => 1,
 1908                              MODULE => "vorbiscomment",
 1909                            },
 1910                },
 1911                 
 1912        opus => {
 1913                 
 1914                 DEFAULT_ENCODER => "opusenc",
 1915                 DEFAULT_DECODER => "opusdec",
 1916                 
 1917                 ENCODER => {
 1918                              opusenc => {
 1919                                           NAME => 'opusenc',
 1920                                           ESTR => sub {
 1921                                                         $opts = "--bitrate $bitrate" if $defopts == 1;
 1922                                                         $opts = '' if $defopts == 0;
 1923                                                         "$eopts $opts %i %o"
 1924                                                       },
 1925                                          PROMTP => {
 1926                                                      BITRATE => 1,
 1927                                                    },
 1928                                         },
 1929                            },
 1930 
 1931                 DECODER => {
 1932                               opusdec => {
 1933                                            NAME => 'opusdec',
 1934                                            DSTR => sub { "--force-wav %i %o" },
 1935                                            PROMPT => { NONE => 0 },
 1936                                          },
 1937                            },
 1938    
 1939                    TAGS => {
 1940                              READ   => 0,
 1941                              WRITE  => 0,
 1942                              MODULE => undef,
 1943                            },
 1944                },
 1945 
 1946     raw => {
 1947 
 1948                 DEFAULT_ENCODER => "sox",
 1949                 DEFAULT_DECODER => "sox",
 1950                 
 1951                 ENCODER => {
 1952                               sox => {
 1953                                       NAME => 'sox',
 1954                                       ESTR => sub { 
 1955                                                     $opts = "-r $freq -c $channels" if $defopts == 1;
 1956                                                     $opts = '' if $defopts == 0;
 1957                                                     "%i $opts $eopts %o $effect" 
 1958                                                   },
 1959                                     
 1960                                       PROMPT => {
 1961                                                   FREQ     => 1,
 1962                                                   CHANNELS => 1,
 1963                                                 },
 1964                                      },
 1965                            },
 1966                            
 1967                 DECODER => {
 1968                               sox => {
 1969                                         NAME => 'sox',
 1970                                         DSTR => sub { "-w -s -r $freq -c $channels $dopts %i %o" },
 1971                                      },
 1972                            },
 1973 
 1974                 TAGS    => {
 1975                              READ   => 0,
 1976                              WRITE  => 0,
 1977                              MODULE => undef,
 1978                            },
 1979                },              
 1980                
 1981      rm => {
 1982         
 1983                  DEFAULT_ENCODER => 'ffmpeg',
 1984                  DEFAULT_DECODER => 'ffmpeg',
 1985                  
 1986                  ENCODER => {
 1987                               ffmpeg => {
 1988                                           NAME => 'ffmpeg',
 1989                                           ESTR => sub { 
 1990                                                         $opts = "-ar $freq -ac $channels" if $defopts == 1;
 1991                                                         $opts = '' if $defopts == 0;
 1992                                                         "-y -i %i $eopts $opts %o" 
 1993                                                       },
 1994                                           
 1995                                           PROMPT => {
 1996                                                       FREQ     => 1,
 1997                                                       CHANNELS => 1,
 1998                                                     },
 1999                                         },
 2000                                         
 2001                               avconv => {
 2002                                           NAME => 'avconv',
 2003                                           ESTR => sub {
 2004                                                         $opts = "-ar $freq -ac $channels" if $defopts == 1;
 2005                                                         $opts = '' if $defopts == 0;
 2006                                                         "-y -i %i $eopts $opts %o"
 2007                                                       },
 2008                                           
 2009                                           PROMPT => {
 2010                                                       FREQ     => 1,
 2011                                                       CHANNELS => 1,
 2012                                                     },
 2013                                         },
 2014                            },
 2015                            
 2016                 DECODER => {
 2017                              mplayer => {
 2018                                           NAME => 'mplayer',
 2019                                           DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 2020                                         },
 2021                                         
 2022                               ffmpeg => {
 2023                                           NAME => 'ffmpeg',
 2024                                           DSTR => sub { "$dopts -y -i %i %o" },
 2025                                         },
 2026                                         
 2027                               avconv => {
 2028                                           NAME => 'avconv',
 2029                                           DSTR => sub { "$dopts -y -i %i %o" },
 2030                                         },
 2031                            },
 2032  
 2033                    TAGS => {
 2034                              READ   => 0,
 2035                              WRITE  => 0,
 2036                              MODULE => undef,
 2037                            },
 2038                },
 2039                            
 2040        shn  => {
 2041 
 2042                 DEFAULT_ENCODER => "shorten",
 2043                 DEFAULT_DECODER => "shorten",
 2044                 
 2045                 ENCODER => {
 2046                               shorten => {
 2047                                             NAME => "shorten",
 2048                                             ESTR => sub { 
 2049                                                           $opts = "-c $channels" if $defopts == 1;
 2050                                                           $opts = '' if $defopts == 0;
 2051                                                           "$eopts $opts %i %o" 
 2052                                                         },
 2053                                             PROMPT => { CHANNELS => 1 },
 2054                                          },
 2055                            },
 2056                 
 2057                 DECODER => {
 2058                               shorten => {
 2059                                             NAME => "shorten",
 2060                                             DSTR => sub { "-x %i %o" },
 2061                                          },
 2062                            },
 2063 
 2064                 TAGS    => {
 2065                              READ   => 0,
 2066                              WRITE  => 0,
 2067                              MODULE => undef,
 2068                            },
 2069                },
 2070 
 2071        spx  => {
 2072        
 2073                 DEFAULT_ENCODER => "speexenc",
 2074                 DEFAULT_DECODER => "speexdec",
 2075                 
 2076                 ENCODER => {
 2077                               speexenc => {
 2078                                             NAME => "speexenc",
 2079                                             ESTR => sub { 
 2080                                                           $opts = "--quality $spxqual" if $defopts == 1;
 2081                                                           $opts = '' if $defopts == 0;
 2082                                                           "$eopts $opts %i %o" 
 2083                                                         },
 2084                                             PROMPT => { SPXQUAL => 1 },
 2085                                           },
 2086                                           
 2087                                 ffmpeg => {
 2088                                             NAME => 'ffmpeg',
 2089                                             ESTR => sub {
 2090                                                           $opts = "--bitrate $bitrate.k" if $defopts == 1;
 2091                                                           $opts = '' if $defopts == 0;
 2092                                                           "-y -i %i $eopts $opts %o"
 2093                                                         },
 2094                                                         
 2095                                             PROMPT => {
 2096                                                         BITRATE => 1,
 2097                                                       },
 2098                                           },
 2099                                           
 2100                                 avconv => {
 2101                                             NAME => 'avconv',
 2102                                             ESTR => sub {
 2103                                                           $opts = "--bitrate $bitrate.k" if $defopts == 1;
 2104                                                           $opts = '' if $defopts == 0;
 2105                                                           "-y -i $eopts $opts %o"
 2106                                                         },
 2107                                             PROMPT => {
 2108                                                         BITRATE => 1,
 2109                                                       },
 2110                                           },
 2111                            },
 2112                            
 2113                 DECODER => {
 2114                               speexdec => {
 2115                                             NAME => "speexdec",
 2116                                             DSTR => sub { "$dopts %i %o" },
 2117                                           },
 2118                                           
 2119                                 ffmpeg => {
 2120                                             NAME => 'ffmpeg',
 2121                                             DSTR => sub { "$dopts -y -i %i %o" },
 2122                                           },
 2123                                           
 2124                                 avconv => {
 2125                                             NAME => 'avconv',
 2126                                             DSTR => sub { "$dopts -y -i %i %o" },
 2127                                           },
 2128                            },
 2129                 
 2130                 TAGS    => {
 2131                              READ   => 1,
 2132                              WRITE  => 1,
 2133                              MODULE => undef,
 2134                            },
 2135                },                          
 2136 
 2137        tta  => {
 2138 
 2139                 DEFAULT_ENCODER => "ttaenc",
 2140                 DEFAULT_DECODER => "ttaenc",
 2141                 
 2142                 ENCODER => {
 2143                               ttaenc => {
 2144                                           NAME => "ttaenc",
 2145                                           ESTR => sub { "$eopts -e %i -o %o" },
 2146                                           PROMPT => { NONE => 0, },
 2147                                         },                                                          
 2148                            },
 2149                 
 2150                 DECODER => {
 2151                               ttaenc => {
 2152                                           NAME => "ttaenc",
 2153                                           DSTR => sub { "$dopts -d %i -o %o" },
 2154                                         },
 2155 
 2156                               ffmpeg => {
 2157                                           NAME => "ffmpeg",
 2158                                           DSTR => sub { "$dopts -y -i %i %o" },
 2159                                         },
 2160                                         
 2161                               avconv => {
 2162                                           NAME => 'avconv',
 2163                                           DSTR => sub { "$dopts -y -i %i %o" },
 2164                                         },
 2165 
 2166                              mplayer => {
 2167                                           NAME => "mplayer",
 2168                                           DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 2169                                         },
 2170                            },
 2171                                         
 2172                    TAGS => {
 2173                              READ   => 0,
 2174                              WRITE  => 0,
 2175                              MODULE => undef,
 2176                            },
 2177                },
 2178                
 2179        wav  => {
 2180 
 2181                 DEFAULT_ENCODER => "mv",
 2182                 DEFAULT_DECODER => "cp",
 2183                 
 2184                 ENCODER => {
 2185                               mv => {
 2186                                       NAME => "mv",
 2187                                       ESTR => sub { "%i %o" },
 2188                                       PROMPT => { NONE => 0, },
 2189                                     },
 2190                            },
 2191                            
 2192                 DECODER => {
 2193                               cp => {
 2194                                       NAME => "cp",
 2195                                       DSTR => sub { "%i %o" },
 2196                                     }
 2197                            },
 2198 
 2199                 TAGS    => {
 2200                              READ   => 0,
 2201                              WRITE  => 0,
 2202                              MODULE => undef,
 2203                            },
 2204                },              
 2205 
 2206        wv   => {
 2207 
 2208                 DEFAULT_ENCODER => "wavpack",
 2209                 DEFAULT_DECODER => "wvunpack",
 2210                 
 2211                 ENCODER => {
 2212                               wavpack => {
 2213                                            NAME => "wavpack",
 2214                                            ESTR => sub { "$eopts -h -y %i -o %o" },
 2215                                            PROMPT => { NONE => 0, },
 2216                                          },
 2217                                          
 2218                                ffmpeg => {
 2219                                            NAME => 'ffmpeg',
 2220                                            ESTR => sub { "-y -i %i $eopts %o" },
 2221                                            PROMPT => { NONE => 0, },
 2222                                          },
 2223                                          
 2224                                avconv => {
 2225                                            NAME => 'avconv',
 2226                                            ESTR => sub { "-y -i %i $eopts %o" },
 2227                                            PROMPT => { NONE => 0, },
 2228                                          },
 2229                            },
 2230                 
 2231                 DECODER => {
 2232                               wvunpack => {
 2233                                             NAME => "wvunpack",
 2234                                             DSTR => sub { "$dopts -y %i -o %o" },
 2235                                           },
 2236 
 2237                                 ffmpeg => {
 2238                                             NAME => "ffmpeg",
 2239                                             DSTR => sub { "$dopts -y -i %i %o" },
 2240                                           },
 2241                                 
 2242                                 avconv => {
 2243                                             NAME => 'avconv',
 2244                                             DSTR => sub { "$dopts -y -i %i %o" },
 2245                                           },
 2246 
 2247                                mplayer => {
 2248                                             NAME => "mplayer",
 2249                                             DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" },
 2250                                           },
 2251                            },
 2252 
 2253                 TAGS    => {
 2254                              READ   => 1,
 2255                              WRITE  => 1,
 2256                              MODULE => "Audio::Scan",
 2257                            },
 2258                },
 2259 );
 2260 
 2261 # supported ffmpeg/avconv formats (decode only)
 2262 my @ffmpeg_codecs = ( "mmf", "ra", "wma" );
 2263 my @ffmpeg_forks  = ( "avconv", "ffmpeg" );
 2264 
 2265 foreach my $fork (@ffmpeg_forks) {
 2266 
 2267   foreach my $codec (@ffmpeg_codecs) {
 2268   
 2269       $run{$codec}{DEFAULT_ENCODER}      = $fork;
 2270       $run{$codec}{DEFAULT_DECODER}      = $fork;
 2271       $run{$codec}{ENCODER}{$fork}{NAME} = $fork;
 2272       $run{$codec}{DECODER}{$fork}{NAME} = $fork;
 2273       $run{$codec}{DECODER}{$fork}{DSTR} = sub {"-y -i %i $dopts %o"};
 2274       $run{$codec}{ENCODER}{$fork}{ESTR} = sub {"-y -i %i $eopts -ab $bitrate.k -ar $freq -ac $channels %o"};
 2275       $run{$codec}{TAGS}{READ}           = 0;
 2276       $run{$codec}{TAGS}{WRITE}          = 0;
 2277       $run{$codec}{TAGS}{MODULE}         = undef;
 2278   }
 2279 
 2280 }
 2281 
 2282 # support reading of WMA tags via Audio::Scan
 2283 $run{wma}{TAGS}{READ}   = 1;
 2284 $run{wma}{TAGS}{MODULE} = "Audio::Scan";
 2285    
 2286 # supported video to audio types
 2287 my @movie_codecs = ( 
 2288                      "rv",    "asf",   "avi",   "divx",  
 2289                      "mkv",   "mpg",   "mpeg",  "mov",   
 2290                      "ogm",   "qt",    "vcd",   "vob",   
 2291                      "wmv",   "flv",   "svcd",  "m4v",   
 2292                      "nsv",   "nuv",   "psp",   "smk",
 2293                      "ogv",   "webm",  "vp9",   "mpeg4",
 2294                      
 2295                      # decode only audio formats
 2296                      "vqf",   "tak",
 2297                    );
 2298 
 2299 foreach (@movie_codecs) {
 2300    $run{$_}{DEFAULT_ENCODER}        = undef;
 2301    $run{$_}{DEFAULT_DECODER}        = "ffmpeg";
 2302    $run{$_}{DECODER}{mplayer}{NAME} = "mplayer";
 2303    $run{$_}{DECODER}{ffmpeg}{NAME}  = "ffmpeg";
 2304    $run{$_}{DECODER}{mplayer}{DSTR} = sub { "$dopts -vc null -vo null -ao pcm:file=%o %i" };
 2305    $run{$_}{DECODER}{ffmpeg}{DSTR}  = sub { "$dopts -i %i %o"; };
 2306    $run{$_}{TAGS}{READ}             = 0;
 2307    $run{$_}{TAGS}{WRITE}            = 0;
 2308    $run{$_}{TAGS}{MODULE}           = undef;
 2309 }
 2310 
 2311 # supported sndfile-convert formats
 2312 my @sndfile = ( 
 2313                 "pvf",  "caf",  "sf",  "paf",   "fap", "sd2", 
 2314                 "mat4", "mat5", "mat", "ircam", "w64", "nist",
 2315                 "rf64",
 2316               );
 2317 
 2318 foreach (@sndfile) {
 2319      
 2320    $run{$_}{DEFAULT_ENCODER}                  = "sndfile-convert";
 2321    $run{$_}{DEFAULT_DECODER}                  = "sndfile-convert";
 2322    $run{$_}{ENCODER}{"sndfile-convert"}{NAME} = "sndfile-convert";
 2323    $run{$_}{DECODER}{"sndfile-convert"}{NAME} = "sndfile-convert";
 2324    $run{$_}{ENCODER}{"sndfile-convert"}{ESTR} = sub { "$eopts %i %o" };
 2325    $run{$_}{DECODER}{"sndfile-convert"}{DSTR} = sub { "$dopts %i %o" };
 2326    $run{$_}{TAGS}{READ}                       = 0;
 2327    $run{$_}{TAGS}{WRITE}                      = 0;
 2328    $run{$_}{TAGS}{MODULE}                     = undef;
 2329 }
 2330               
 2331 # supported sox formats
 2332 my @sox_codecs = ( 
 2333                    "aiff", "aif",  "au",  "snd",  "voc", 
 2334                    "smp",  "avr",  "cdr", "8svx", "amb",
 2335                    "dat",  "dvms", "f32", "f64",  "fssd",
 2336                    "gsrt", "hcom", "txw", "vms",  "al",
 2337                    "sou",  "ima",  "prc", "cvu",
 2338                    "maud", 
 2339                  );
 2340 
 2341 foreach (@sox_codecs) {
 2342 
 2343    $run{$_}{DEFAULT_ENCODER}    = "sox";
 2344    $run{$_}{DEFAULT_DECODER}    = "sox";
 2345    $run{$_}{ENCODER}{sox}{NAME} = "sox";
 2346    $run{$_}{DECODER}{sox}{NAME} = "sox";
 2347    $run{$_}{ENCODER}{sox}{ESTR} = sub { "%i -r $freq -c $channels $eopts %o $effect" };
 2348    $run{$_}{DECODER}{sox}{DSTR} = sub { "%i $dopts %o" };
 2349    $run{$_}{TAGS}{READ}         = 0;
 2350    $run{$_}{TAGS}{WRITE}        = 0;
 2351    $run{$_}{TAGS}{MODULE}       = undef;
 2352 
 2353    $run{$_}{ENCODER}{sox}{PROMPT}{FREQ}     = 1;
 2354    $run{$_}{ENCODER}{sox}{PROMPT}{CHANNELS} = 1;
 2355 
 2356 }
 2357 
 2358 # load codecs.conf file
 2359 load_codecs() if -e $codecs_conf;
 2360 
 2361 my $out_name = $outfile; 
 2362 my $out_dir  = $outdir;
 2363 my $first_message    = 1;
 2364 my %files;
 2365 my $number = 0;
 2366 
 2367 # process all files and directories
 2368 sub proc_input {
 2369 
 2370    $to =~ tr/A-Z/a-z/;
 2371    
 2372    perror("bad_input","") unless(exists($run{$to}));   
 2373 
 2374    proc_preserve_dir($dir[0]) if @dir and $preserve; # process recursive directory preservation (sends to proc_files   
 2375    proc_dirs() if @dir and not $preserve;            # process directories including recursively (sends to proc_files)
 2376    proc_files() if @file;                            # process all files
 2377    fork_files();                                  # start the conversion process.
 2378 }
 2379    
 2380 # process all files (all roads lead to rome)
 2381 sub proc_files {
 2382    
 2383    if (@file) {
 2384 
 2385        foreach my $i (sort(@file)) {
 2386        
 2387                my ($file, $dir, $ext) = fileparse("$i", qr/\.[^.]*/);
 2388 
 2389                    $ext    =~ s/^\.//;
 2390                    $dir    =  rel2abs($dir);
 2391                    $outdir =  $dir if not defined($out_dir) and not $preserve;
 2392                    $outdir =  $out_dir if $preserve;
 2393 
 2394                my  $if  = $ext;
 2395                    $if  =~ tr/A-Z/a-z/;
 2396                    
 2397                    $only =~ tr/A-Z/a-z/ if $only;
 2398                    
 2399               next if $only and $if ne $only;
 2400               
 2401                    $encoder = $my_encoder if defined($my_encoder);
 2402                    $decoder = $my_decoder if defined($my_decoder);
 2403                    
 2404                    $encoder = $run{$to}{DEFAULT_ENCODER} if not $my_encoder;
 2405            my $codec = ( $if eq "m4a" ? Audio::Scan->scan_info($i)->{info}->{tracks}[0]->{encoding} : $if );
 2406                    $decoder = $run{$codec}{DEFAULT_DECODER} if not $my_decoder;
 2407               
 2408                if (-e "$dir/$file.$to" and not $overwrite) {
 2409                    pnotice("overwrite","$file.$to",1);
 2410                    $total_failed++;
 2411                    next;
 2412                }
 2413                                                                                                    
 2414                if (check_input($file,$dir,$codec) == 0) {
 2415                    
 2416                    pnotice("unk_encoder","$file.$ext",1), next unless(exists($run{$to}{ENCODER}{$encoder}));
 2417                    pnotice("unk_decoder","$file.$ext",1), next unless(exists($run{$codec}{DECODER}{$decoder}));
 2418               
 2419                    get_visual_opts($to,$outdir) if $gui and not defined($first_run);
 2420                    
 2421                    $first_run = 1;
 2422                    
 2423                    perror("multi_out","")       if (defined($out_name) and $#file gt 0 or defined($out_name) and @dir);
 2424                    perror("no_outdir","")       if (not -e $outdir and not -d $outdir);
 2425 
 2426                    $outfile = "$file" if not $out_name;
 2427 
 2428                    if ($keep and $if eq $to) {
 2429                my $source_q = shell_quote "$dir/$file.$ext";
 2430                my $dest_q = shell_quote "$outdir/$outfile.$ext";
 2431                        system("cp -v $source_q $dest_q") if $outdir ne $dir and not -e "$outdir/$outfile.$ext";
 2432                        next if $outdir eq $dir;
 2433                    } 
 2434                    
 2435                    else {
 2436                             $files{"FILE$number"}{FILE} = "$dir/$file";
 2437                             $files{"FILE$number"}{OUTF} = "$outdir/$outfile";
 2438                             $files{"FILE$number"}{EXT}  = "$ext";
 2439                             $files{"FILE$number"}{CODEC}  = "$codec";
 2440                             $files{"FILE$number"}{NAME} = "$file";
 2441                             $files{"FILE$number"}{OUTD} = "$outfile";
 2442                             $files{"FILE$number"}{DECODER} = "$decoder";
 2443 
 2444                             $number++;                  
 2445                    }
 2446                  
 2447                }                       
 2448        }
 2449    }
 2450    undef(@file);
 2451 }
 2452 
 2453 # process directories and push all to @file arrary
 2454 sub proc_dirs {
 2455 
 2456    if (@dir) {
 2457 
 2458     my @tmp_dir = @dir;
 2459        undef(@dir);
 2460        $topdir = $tmp_dir[0];
 2461 
 2462     if (not $recursive) {
 2463 
 2464         undef(@file);
 2465         
 2466         foreach my $d (@tmp_dir) {
 2467 
 2468            opendir(DIR, "$d") or perror("opening_dir","$d: $!");
 2469            my @dir_files = readdir(DIR);
 2470            closedir(DIR);                
 2471            perror("empty_dir","$d") if $#dir_files <= 1;
 2472 
 2473            foreach my $f (@dir_files) {
 2474 
 2475                 if (not -d $f and not -d "$d/$f") {
 2476                     push(@file, "$d/$f");
 2477                     undef($out_name);
 2478                 }
 2479            }
 2480     }
 2481        
 2482     proc_files();
 2483     return 0;
 2484 
 2485     } 
 2486 
 2487     elsif ($recursive) {
 2488 
 2489              if (not $preserve) {
 2490                  
 2491                  undef(@file);
 2492 
 2493                  foreach my $r (@tmp_dir) {
 2494 
 2495                          $r = rel2abs($r);
 2496 
 2497                          find ( sub {
 2498                                       my $rfile = $File::Find::name;
 2499                                          push(@file, $rfile) if not -d $rfile;
 2500                                     }, $r
 2501                               );
 2502                  }
 2503                  
 2504                  proc_files();
 2505                  return 0;
 2506 
 2507              } 
 2508       }
 2509 
 2510     }   
 2511 }
 2512 
 2513 # preserve directory structuer (revised 10-7-2013)
 2514 my $out_dir_original = rel2abs($outdir) if $outdir and -d $outdir;
 2515 
 2516 sub proc_preserve_dir {
 2517 
 2518 $topdir = rel2abs($dir[0]);
 2519 
 2520 perror("no_outdir","") if not defined($out_dir_original);
 2521 perror("no_outdir","") if not -d $out_dir_original;
 2522 
 2523 undef(@file); # clear the array before we begin.
 2524 
 2525 find ( sub {
 2526              my $val = $File::Find::name;
 2527                 $val =~ s/(\$)/\\\$/g;                
 2528                              
 2529              if ($val ne $topdir) {
 2530 
 2531                 $val =~ s/$topdir\///;
 2532 
 2533                 # create mirrored directories in output directory
 2534                 if (not -f fileparse("$topdir/$val") and not -d "$out_dir_original/$val") {
 2535                       say "creating directory $out_dir_original/$val" if not -f "$topdir/$val" and $verbose;
 2536                       mkdir("$out_dir_original/$val", 0755) if not -f "$topdir/$val";
 2537                 }                
 2538 
 2539                 # this will list all files in their original directories
 2540                 if (-f "$topdir/$val") {
 2541                      say "$lang{debug} pushing to \@file: $topdir/$val" if $debug == 1;
 2542                      push(@file, "$topdir/$val");
 2543                 }
 2544                
 2545                 # set $out_dir to the 
 2546                 $out_dir = "$out_dir_original/" . dirname($val) if -f "$topdir/$val";             
 2547                 
 2548                 # send file, and output dir to proc_files();
 2549                 proc_files();
 2550              }                
 2551                                                                 
 2552            }, $topdir
 2553      );   
 2554 }                                                                                                                                                                   
 2555 
 2556 # convert input to destination format
 2557 sub convert {
 2558 
 2559     my ($inf, $outf, $infmt, $iname, $oname, $codec, $dec) = @_;
 2560 
 2561     my $if = $infmt;
 2562        $if =~ tr/A-Z/a-z/;
 2563 
 2564        clear_tag_hash() if not $rip;
 2565        
 2566        # check to see if encoder/decoder exists.  if not, see if we have one 
 2567        # that supports the desired input/output formats.
 2568        $decoder = $dec;
 2569        check_encoder();
 2570        check_decoder($codec);
 2571                          
 2572     my $wavf = "$outf.$$.wav";
 2573     my $wavf_q = shell_quote $wavf;
 2574     my $decode_string = $run{$codec}{DECODER}{$decoder}{DSTR}->();
 2575     my $inf_q = shell_quote "$inf.$infmt";
 2576        $decode_string =~ s/%i/$inf_q/;
 2577        if ( $decode_string =~ m/%o/ )  {
 2578        $decode_string =~ s/%o/$wavf_q/;
 2579        } else  {
 2580        $wavf = "$outf.wav";
 2581        $wavf_q = shell_quote $wavf;
 2582        }
 2583 
 2584        pnotice("debug","\n$run{$codec}{DECODER}{$decoder}{NAME} $decode_string", 2) if $dryrun;
 2585 
 2586        # catch ^C.  will have to be pressed repeatedly to exit the process.
 2587        $SIG{INT} = sub {
 2588                          unlink("$wavf");
 2589                          kill 9, $$; 
 2590                        };
 2591 
 2592        # decode input file to temporary wav
 2593        system("$run{$codec}{DECODER}{$decoder}{NAME} $decode_string $silent") if not $dryrun;
 2594 
 2595        # remove temporary wav file and die if decode fails
 2596        if ($? > 0) {
 2597            unlink("$wavf") if -e "$wavf";
 2598            say "";
 2599            $banner = 0;
 2600            pnotice("decode_failed","$inf.$infmt: try with --verbose",1);
 2601            return 1;
 2602        }
 2603        
 2604        # normalize wav file before encoding to output format
 2605        perror("no_app","normalize") if $normalize and not `which normalize 2>/dev/null`;
 2606        system("normalize $nopts $wavf_q") if $normalize;
 2607 
 2608        # copy meta-data from input file to %tag_name 
 2609        read_tags("$inf.$infmt", "$codec") if $run{$codec}{TAGS}{READ} == 1 and not $dryrun;
 2610 
 2611     my $tag_opts = format_tags($to); # tag options for mp4/m4a/m4b/mpc/mpp/bonk/spx/wv
 2612     
 2613     my $outf_q = shell_quote "$outf.$to";
 2614     my $encode_string = $run{$to}{ENCODER}{$encoder}{ESTR}->();
 2615        $encode_string =~ s/%i/$tag_opts $wavf_q/  if $to =~ /mpc|mpp|mp4|m4a/ and $encoder eq "faac" or $encoder eq "mpcenc";
 2616        $encode_string =~ s/%i/$wavf_q $tag_opts/  if $to =~ /mpc|mpp|mp4|m4a/ and $encoder eq "ffmpeg" or $encoder eq "avconv";
 2617        $encode_string =~ s/%i/$wavf_q/            if $to !~ /mpc|mpp|mp4|m4a/;
 2618        $encode_string =~ s/%o/$tag_opts $outf_q/     if $tag_opts ne " " and $to !~ /mpc|mpp|mp4|m4a/;
 2619        $encode_string =~ s/%o/$outf_q/               if $tag_opts eq " " or $to =~ /mpc|mpp|mp4|m4a/;
 2620        
 2621        # read tag options from command line if present
 2622        get_user_tags();
 2623 
 2624        pnotice("debug","\n$run{$to}{ENCODER}{$encoder}{NAME} $encode_string", 2) if $dryrun;
 2625 
 2626        # encode temporary WAV to desired output format.
 2627        system("$run{$to}{ENCODER}{$encoder}{NAME} $encode_string $silent") if not $dryrun;
 2628 
 2629        # remove partially encoded output file and temporary wav if encoding fails
 2630        if ($? > 0) {
 2631            unlink("$outf.$to")          if -e "$outf.$to";
 2632            unlink("$wavf")      if -e "$wavf";
 2633            say "";
 2634            $banner = 0;
 2635            pnotice("encode_failed","$outf.$to: $?",1);        
 2636            return 1;
 2637        }
 2638 
 2639        # write meta-data to output file from %tag_name hash
 2640        write_tags("$outf.$to", "$to") if $run{$to}{TAGS}{WRITE} == 1 and $tag_opts eq " "  and not $dryrun;
 2641  
 2642        unlink("$wavf") if not $dryrun;
 2643        unlink("$inf.$infmt")  if $delete and not $dryrun;
 2644 
 2645        pnotice("removed_tmp","$wavf","2") if $verbose;
 2646        pnotice("removed_src","$inf.$infmt", "2") if $delete and $verbose;
 2647 }
 2648 
 2649 $pm->run_on_finish 
 2650 ( sub { 
 2651         my $pid = shift; 
 2652         my $exit_code = shift; 
 2653         my $ident = shift;
 2654                           
 2655         if (-e "$ident.$to") {
 2656           $total_converted++;
 2657         }                             
 2658         say "$lang{debug} PID: $pid EXIT_CODE: $exit_code IDENTITY: \"$ident.$to\"" if $debug == 1;
 2659   } 
 2660 );
 2661 
 2662 # convert all files that have been placed in the %files hash through various procs*
 2663 sub fork_files {
 2664 
 2665     say "\n$name - $version\n" if not $gui and $banner == 1;
 2666   
 2667     foreach (sort(keys(%files))) 
 2668     {    
 2669         $pm->start($files{$_}{OUTF}) and next;            
 2670         my $msg = "$lang{converting}" . " " . basename($files{$_}{FILE}) . ".$files{$_}{EXT} -> $to";     
 2671         say "$msg" if not $gui;        
 2672         system("kdialog --icon $icon_path --title \"$name\" --passivepopup \"$msg\" 10 &") if $gui and $kde;
 2673         system("notify-send \"$name\" \"$msg\" -t 35 -i $icon_path &") if $gui and $gnome;                          
 2674         convert("$files{$_}{FILE}","$files{$_}{OUTF}","$files{$_}{EXT}","$files{$_}{NAME}","$files{$_}{OUTD}","$files{$_}{CODEC}","$files{$_}{DECODER}");
 2675         $pm->finish;
 2676     }            
 2677 
 2678     $pm->wait_all_children;                      
 2679     $total_failed = $number - $total_converted if $total_converted < $number;
 2680     
 2681     my $finished_msg = "\n$lang{total_converted} $total_converted, $lang{failed} $total_failed\n";
 2682     
 2683     say "$finished_msg" if not $gui;
 2684     system("kdialog --icon $icon_path --title \"$name\" --passivepopup \"$finished_msg\" 10 &") if $gui and $kde;
 2685     system("notify-send \"$name\" \"$finished_msg\" -t 35 -i $icon_path &") if $gui and $gnome;
 2686     
 2687 }                   
 2688 
 2689 # if the default encoder does not exist, cycle through the supported
 2690 # encoders until we find one that does.
 2691 sub check_encoder {
 2692 
 2693     if (not `which $encoder 2>/dev/null`) {
 2694         my $first_encoder = $encoder;
 2695         foreach (keys %{$run{$to}{ENCODER}}) { $encoder = $_ and return if `which $_ 2>/dev/null`; } 
 2696         perror("no_encode_app","$to") if $encoder eq $first_encoder;
 2697     } 
 2698 
 2699     else { return 0; }
 2700 }
 2701 
 2702 # if the default decoder does not exist, cycle through the supported
 2703 # decoders until we find one that does.
 2704 sub check_decoder {
 2705 
 2706     my $from = shift;
 2707     
 2708     if (not `which $decoder 2>/dev/null`) {
 2709         my $first_decoder = $decoder;
 2710         foreach (keys %{$run{$from}{DECODER}}) { $decoder = $_ and return if `which $_ 2>/dev/null`; }
 2711         perror("no_decode_app","$from") if $decoder eq $first_decoder;
 2712     }
 2713    
 2714     else { return 0; }
 2715 }
 2716 
 2717 # make sure encoding/decoding is supported.
 2718 sub check_input {
 2719 
 2720      my $file = shift;
 2721      my $dir  = shift;
 2722      my $codec  = shift;
 2723 
 2724      perror("no_encoder","$to") unless(defined($run{$to}{ENCODER}));
 2725 
 2726      unless(defined($run{$codec}{DECODER})) {
 2727          pnotice("no_decoder","$codec",2) if $verbose or not $only;
 2728          $total_failed++;
 2729          return 1;
 2730      }
 2731 
 2732      return 0;
 2733 }
 2734 
 2735 ########################################
 2736 # GUI options for KDE & Gnome Plugins  #
 2737 ########################################
 2738 
 2739 my $kdialog = "kdialog --title \"$name\"";
 2740 my $zenity  = "zenity  --title \"$name\" --list --radiolist --width 100 --height 300 --column '' --column ";
 2741 
 2742 sub get_visual_opts {
 2743 
 2744     my ($to_fmt,$od) = @_;
 2745 
 2746        # escape illegal characters in output directory name
 2747        $od =~ s/( |'|\(|\)|"|\\)/\\$1/g;
 2748 
 2749        $outdir    = `kdialog --getexistingdirectory $od` if $config{KDE_DIR} == 1 and $kde;
 2750        $outdir    = `zenity --title \"$lang{gui_outdir}\" --file-selection --directory --filename=\`pwd\`` if $config{ZEN_DIR} == 1 and $gnome;
 2751 
 2752        chomp($outdir);
 2753        $out_dir = $outdir;
 2754        exit(1) if not $outdir;
 2755        
 2756        if ($config{KDE_OPTS} == 1 or $config{ZEN_OPTS} == 1) {
 2757            foreach (keys %{$run{$to_fmt}{ENCODER}{$encoder}{PROMPT}}) {
 2758                    prompt_user($_);
 2759            }
 2760        }
 2761 }
 2762 
 2763 sub prompt_user {
 2764 
 2765     my $opt = shift;
 2766 
 2767       given ($opt) {
 2768 
 2769             when (/^BITRATE/)   { 
 2770                                   $bitrate  = `$kdialog --default $bitrate --combobox \"$lang{gui_bitrate}\" 56 112 128 160 192 256 320` if $kde;
 2771                                   $bitrate  = `$zenity \"$lang{gui_bitrate}\" FALSE 56 FALSE 112 FALSE 128 FALSE 160 TRUE 192 FALSE 256 FALSE 320` if $gnome;
 2772                                   chomp($bitrate);
 2773                                   exit(1) if not $bitrate;
 2774                                 }
 2775 
 2776             when (/^FREQ/)      {
 2777                                   $freq = `$kdialog --default $freq --combobox \"$lang{gui_freq}\" 32000 44100 48000` if $kde;
 2778                                   $freq = `$zenity \"$lang{gui_freq}\" FALSE 32000 TRUE 44100 FALSE 48000` if $gnome;
 2779                                   chomp($freq);
 2780                                   exit(1) if not $freq;
 2781                                 }
 2782 
 2783             when (/^CHANNELS/)  { 
 2784                                   $channels = `$kdialog --default $channels --combobox \"$lang{gui_chans}\" 1 2` if $kde;
 2785                                   $channels = `$zenity \"$lang{gui_chans}\" FALSE 1 TRUE 2` if $gnome;
 2786                                   chomp($channels);
 2787                                   exit(1) if not $channels;
 2788                                 }
 2789 
 2790             when (/^FCOMP/)     {
 2791                                   $fcomp = `$kdialog --default $fcomp --combobox \"$lang{gui_fcomp}\" 0 1 2 3 4 5 6 7 8` if $kde;
 2792                                   $fcomp = `$zenity \"$lang{gui_fcomp}\" FALSE 0 FALSE 1 TRUE 2 FALSE 3 FALSE 4 FALSE 5 FALSE 6 FALSE 7 FALSE 8` if $gnome;
 2793                                   chomp($fcomp);
 2794                                   exit(1) if not $fcomp;
 2795                                 }
 2796 
 2797             when (/^ACOMP/)     {
 2798                                   $acomp = `$kdialog --default $acomp --combobox \"$lang{gui_acomp}\" 1000 2000 3000 4000 5000` if $kde;
 2799                                   $acomp = `$zenity \"$lang{gui_acomp}\" FALSE 1000 FALSE 2000 TRUE 3000 FALSE 4000 FALSE 5000` if $gnome;
 2800                                   chomp($acomp);
 2801                                   exit(1) if not $acomp;
 2802                                 }
 2803 
 2804             when (/^OGGQUAL/)   {
 2805                                   $oggqual = `$kdialog --default $oggqual --combobox \"$lang{gui_oggqual}\" 0 1 2 3 4 5 6 7 8 9 10` if $kde;
 2806                                   $oggqual = `$zenity \"$lang{gui_oggqual}\" FALSE 0 FALSE 1 FALSE 2 TRUE 3 FALSE 4 FALSE 5 FALSE 6 FALSE 7 FALSE 8 FALSE 9 FALSE 10` if $gnome;
 2807                                   chomp($oggqual);
 2808                                   exit(1) if not $oggqual;
 2809                                 }
 2810                              
 2811             when (/^SPXQUAL/)   {
 2812                                   $spxqual = `$kdialog --default $spxqual --combobox \"$lang{gui_spxqual}\" 0 1 2 3 4 5 6 7 8 9 10` if $kde;
 2813                                   $spxqual = `$zenity \"$lang{gui_spxqual}\" FALSE 0 FALSE 1 FALSE 2 FALSE 3 FALSE 4 FALSE 5 FALSE 6 FALSE 7 TRUE 8 FALSE 9 FALSE 10` if $gnome;
 2814                                   chomp($spxqual);
 2815                                   exit(1) if not $spxqual;
 2816                                 }
 2817 
 2818             when (/^AACQUAL/)   {
 2819                                   $aacqual = `$kdialog --default $aacqual --combobox \"$lang{gui_aacqual}\" 100 200 300 400 500` if $kde;
 2820                                   $aacqual = `$zenity \"$lang{gui_aacqual}\" TRUE 100 FALSE 200 FALSE 300 FALSE 400 FALSE 500` if $gnome;
 2821                                   chomp($aacqual);
 2822                                   exit(1) if not $aacqual;
 2823                                 }
 2824 
 2825             when (/^MPCQUAL/)   {
 2826                                   $mpcqual = `$kdialog --default $mpcqual --combobox \"$lang{gui_mpcqual}\" thumb radio standard xtreme insane braindead` if $kde;
 2827                                   $mpcqual = `$zenity \"$lang{gui_mpcqual}\" FALSE thumb TRUE radio FALSE standard FALSE xtreme FALSE insane FALSE braindead` if $gnome;
 2828                                   chomp($mpcqual);
 2829                                   exit(1) if not $mpcqual;
 2830                                 }
 2831 
 2832             when (/^OFMODE/ )   {
 2833                                    $ofmode = `$kdialog --default $ofmode --combobox \"$lang{gui_ofmode}\" fast normal high extra best highnew extranew bestnew` if $kde;
 2834                                    $ofmode = `$zenity \"$lang{gui_ofmode}\" FALSE fast TRUE normal FALSE high FALSE extra FALSE best FALSE highnew FALSE extranew FALSE bestnew` if $gnome;
 2835                                    chomp($ofmode);
 2836                                    exit(1) if not $ofmode;
 2837                                 }
 2838 
 2839             when (/^OFOPT/)     {
 2840                                    $ofopt = `$kdialog --default $ofopt --combobox \"$lang{gui_ofopt}\" none fast normal high best` if $kde;
 2841                                    $ofopt = `$zenity \"$lang{gui_ofopt}\" FALSE none TRUE fast FALSE normal FALSE high FALSE best` if $gnome;
 2842                                    chomp($ofopt);
 2843                                    exit(1) if not $ofopt;
 2844                                 }
 2845 
 2846             when (/^BRATIO/)    {
 2847                                    $bratio = `$kdialog --default $bratio --combobox \"$lang{gui_bratio}\" 1 2 3 4 5` if $kde;
 2848                                    $bratio = `$zenity \"$lang{gui_bratio}\" FALSE 1 TRUE 2 FALSE 3 FALSE 4 FALSE 5` if $gnome;
 2849                                    chomp($bratio);
 2850                                    exit(1) if not $bratio;
 2851                                 }
 2852 
 2853             when (/^BQUANL/)    {
 2854                                    $bquanl = `$kdialog --default $bquanl --combobox \"$lang{gui_bquanl}\" 1.00 1.25 1.50 1.75 2.00` if $kde;
 2855                                    $bquanl = `$zenity \"$lang{gui_bquanl}\" TRUE 1.00 FALSE 1.25 FALSE 1.50 FALSE 1.75 FALSE 2.00` if $gnome;
 2856                                    chomp($bquanl);
 2857                                    exit(1) if not $bquanl;
 2858                                 }
 2859 
 2860             when (/^BPSIZE/)    {
 2861                                    $bpsize = `$kdialog --default $bpsize --combobox \"$lang{gui_bpsize}\" 10 128` if $kde;
 2862                                    $bpsize = `$zenity \"$lang{gui_bpsize}\" FALSE 10 TRUE 128` if $gnome;
 2863                                    chomp($bpsize);
 2864                                    exit(1) if not $bpsize;
 2865                                 }
 2866 
 2867             default { return 0; }
 2868       }
 2869 
 2870 }
 2871 
 2872 # all copied tags will be stored here for furture use
 2873 my %tag_name = 
 2874 (
 2875   title    => undef,
 2876   track    => undef,
 2877   artist   => undef,
 2878   album    => undef,
 2879   comment  => undef,
 2880   year     => undef,
 2881   genre    => undef,
 2882 );
 2883 
 2884 # override tags read from input file if any of the tagging
 2885 # options are specified by the user during conversion.
 2886 sub get_user_tags 
 2887 {
 2888   $tag_name{title}   = $title   if $title;
 2889   $tag_name{track}   = $track   if $track;
 2890   $tag_name{artist}  = $artist  if $artist;
 2891   $tag_name{album}   = $album   if $album;
 2892   $tag_name{comment} = $comment if $comment;
 2893   $tag_name{year}    = $year    if $year;
 2894   $tag_name{genre}   = $genre   if $genre;    
 2895 }
 2896 
 2897 # the formats MP4/M4A/M4B/MPC/MPP/WV/BONK have no tag writing module.
 2898 # tags therefore have to be written during encode via various 
 2899 # command line args.
 2900 sub format_tags {
 2901 
 2902     my $type = shift;
 2903 
 2904     given ($type) {
 2905         
 2906         when (/^mp4$|^m4a$|^m4b$/) { 
 2907         
 2908             if ($run{$to}{ENCODER}{$encoder}{NAME} eq "ffmpeg" or $run{$to}{ENCODER}{$encoder}{NAME} eq "avconv") {
 2909      
 2910                 $tag_name{track} = 0 if not $tag_name{track};
 2911                 $tag_name{year}  = 0 if not $tag_name{year};
 2912 
 2913                 return "-metadata TITLE=\"$tag_name{title}\" -metadata TRACK=\"$tag_name{track}\" -metadata ARTIST=\"$tag_name{artist}\" -metadata ALBUM=\"$tag_name{album}\" -metadata COMMENT=\"$tag_name{comment}\" -metadata YEAR=\"$tag_name{year}\" -metadata GENRE=\"$tag_name{genre}\"";
 2914 
 2915             } else {
 2916                               
 2917                 return "--title \"$tag_name{title}\" --track \"$tag_name{track}\" --artist \"$tag_name{artist}\" --album \"$tag_name{album}\" --comment \"$tag_name{comment}\" --year \"$tag_name{year}\" --genre \"$tag_name{genre}\"";
 2918 
 2919               }
 2920         } 
 2921                 
 2922         when (/^mpc$|^mpp$/) { return "--artist \"$tag_name{artist}\" --title \"$tag_name{title}\" --album \"$tag_name{album}\" --track \"$tag_name{track}\" --genre \"$tag_name{genre}\" --year \"$tag_name{year}\" --comment \"$tag_name{comment}\""; }
 2923         when (/^wv$/)    { return "-w \"Title=$tag_name{title}\" -w \"Track=$tag_name{track}\" -w \"Artist=$tag_name{artist}\" -w \"Album=$tag_name{album}\" -w \"Comment=$tag_name{comment}\" -w \"Year=$tag_name{year}\" -w \"Genre=$tag_name{genre}\""; }
 2924         when (/^bonk$/)  { return "-t \"$tag_name{title}\" -a \"$tag_name{artist}\" -c \"$tag_name{comment}\""; }
 2925         when (/^spx$/)   { return "--author \"$tag_name{artist}\" --title \"$tag_name{title}\" --comment \"year=$tag_name{year}\" --comment \"tracknumber=$tag_name{track}\" --comment \"album=$tag_name{album}\" --comment \"genre=$tag_name{genre}\" --comment \"comment=$tag_name{comment}\""; }
 2926 
 2927         default          { return " "; }
 2928     }
 2929 }
 2930 
 2931 # meta-data is read based on input file extension.
 2932 # all tags which are present will be copied to 
 2933 # the %tag_name hash.
 2934 sub read_tags {
 2935 
 2936     my $in_file   = shift;
 2937     my $in_format = shift;
 2938 
 2939     my $tag_module = $run{$in_format}{TAGS}{MODULE};
 2940 
 2941     given ($in_format) {
 2942 
 2943         when (/^mp3$|^mp3hd$/) {
 2944                                   my $mp3tag = $tag_module->new($in_file);
 2945                                   my @tags   = $mp3tag->autoinfo();
 2946 
 2947                                    $tag_name{title}   = "$tags[0]" if $tags[0];
 2948                                    $tag_name{track}   = "$tags[1]" if $tags[1];
 2949                                    $tag_name{artist}  = "$tags[2]" if $tags[2];
 2950                                    $tag_name{album}   = "$tags[3]" if $tags[3];
 2951                                    $tag_name{comment} = "$tags[4]" if $tags[4];
 2952                                    $tag_name{year}    = "$tags[5]" if $tags[5];
 2953                                    $tag_name{genre}   = "$tags[6]" if $tags[6];
 2954                                  
 2955                                    return 0;
 2956                                 }
 2957 
 2958            when (/^ogg$|^oga$/) {
 2959                                    my $ogg_tag = Audio::Scan->scan_tags($in_file)->{tags};
 2960 
 2961                                       $tag_name{title}   = $ogg_tag->{TITLE}       if $ogg_tag->{TITLE};
 2962                                       $tag_name{track}   = $ogg_tag->{TRACKNUMBER} if $ogg_tag->{TRACKNUMBER};
 2963                                       $tag_name{artist}  = $ogg_tag->{ARTIST}      if $ogg_tag->{ARTIST};
 2964                                       $tag_name{album}   = $ogg_tag->{ALBUM}       if $ogg_tag->{ALBUM};
 2965                                       $tag_name{comment} = $ogg_tag->{COMMENT}     if $ogg_tag->{COMMENT};
 2966                                       $tag_name{year}    = $ogg_tag->{YEAR}        if $ogg_tag->{YEAR};
 2967                                       $tag_name{genre}   = $ogg_tag->{GENRE}       if $ogg_tag->{GENRE};                                    
 2968                              
 2969                                       return 0;
 2970                                 }
 2971                        
 2972                  when (/^spx$/) {
 2973                                    my $pid  = open(SPX, "speexdec \"$in_file\" tmp1-$$.wav 2>&1 |") or perror("opening_file","$in_file");
 2974                                    my @data = <SPX>;
 2975                                       @data = grep(!/^$|^#/, @data);
 2976                             
 2977                                    close(SPX);
 2978                                
 2979                                    foreach (@data) {
 2980 
 2981                                        next unless /=/; 
 2982                                        chomp;
 2983                                    
 2984                                        my ($k, $v) = split /=/;
 2985                                            $k =~ tr/A-Z/a-z/;
 2986                                            $tag_name{$k} = $v if exists($tag_name{$k});
 2987                                            $tag_name{artist} = $v if $k =~ /^author/i;
 2988                                            $tag_name{track}  = $v if $k =~ /^tracknumber/i;                               
 2989                                    }
 2990                             
 2991                                    unlink("tmp-$$.wav");
 2992                                    return 0;
 2993                                 }
 2994 
 2995           when (/^flac$|^fla$/) {
 2996                                        my $flac_file = Audio::FLAC::Header->new($in_file);
 2997                                        my $flac_tag = $flac_file->tags();
 2998 
 2999                                           $tag_name{title}   = $flac_tag->{TITLE}       if $flac_tag->{TITLE};
 3000                                           $tag_name{track}   = $flac_tag->{TRACKNUMBER} if $flac_tag->{TRACKNUMBER};
 3001                                           $tag_name{artist}  = $flac_tag->{ARTIST}      if $flac_tag->{ARTIST};
 3002                                           $tag_name{album}   = $flac_tag->{ALBUM}       if $flac_tag->{ALBUM}; 
 3003                                           $tag_name{comment} = $flac_tag->{COMMENT}     if $flac_tag->{COMMENT};
 3004                                           $tag_name{year}    = $flac_tag->{DATE}        if $flac_tag->{DATE};       
 3005                                           $tag_name{genre}   = $flac_tag->{GENRE}       if $flac_tag->{GENRE};
 3006 
 3007                                         return 0;
 3008                                 }
 3009 
 3010      when (/^(mp4|m4b|alac|mp4a)$/) {    
 3011                                         my $mp4_tag = $tag_module->scan_tags($in_file)->{tags};
 3012 
 3013                                            $tag_name{title}   = $mp4_tag->{NAM}    if $mp4_tag->{NAM};
 3014                                            $tag_name{track}   = $mp4_tag->{TRKN}   if $mp4_tag->{TRKN}; 
 3015                                            $tag_name{artist}  = $mp4_tag->{ART}    if $mp4_tag->{ART};
 3016                                            $tag_name{album}   = $mp4_tag->{ALB}    if $mp4_tag->{ALB};
 3017                                            $tag_name{comment} = $mp4_tag->{CMT}    if $mp4_tag->{CMT};
 3018                                            $tag_name{year}    = $mp4_tag->{DAY}    if $mp4_tag->{DAY};
 3019                                            $tag_name{genre}   = $mp4_tag->{GNRE}   if $mp4_tag->{GNRE};
 3020  
 3021                                         return 0;
 3022                                 }
 3023 
 3024          when (/^dsf$/) {    
 3025                                         my $dsf_tag = $tag_module->scan_tags($in_file)->{tags};
 3026 
 3027                                            $tag_name{title}   = $dsf_tag->{TIT2}    if $dsf_tag->{TIT2};
 3028                                            $tag_name{track}   = $dsf_tag->{TRCK}    if $dsf_tag->{TRCK}; 
 3029                                            $tag_name{artist}  = $dsf_tag->{TPE1}    if $dsf_tag->{TPE1};
 3030                                            $tag_name{album}   = $dsf_tag->{TALB}    if $dsf_tag->{TALB};
 3031                                            $tag_name{comment} = $dsf_tag->{COMM}    if $dsf_tag->{COMM};
 3032                                            $tag_name{year}    = $dsf_tag->{TYER}    if $dsf_tag->{TYER};
 3033                                            $tag_name{genre}   = $dsf_tag->{TCON}    if $dsf_tag->{TCON};
 3034  
 3035                                         return 0;
 3036                                 }
 3037 
 3038 when (/^ape$|^mpc$|^mpp$|^wv$/) {
 3039                                         my $audio_tag = $tag_module->scan_tags($in_file)->{tags};
 3040 
 3041                                            $tag_name{title}   = $audio_tag->{TITLE}   if $audio_tag->{TITLE};
 3042                                            $tag_name{track}   = $audio_tag->{TRACK}   if $audio_tag->{TRACK};
 3043                                            $tag_name{artist}  = $audio_tag->{ARTIST}  if $audio_tag->{ARTIST};
 3044                                            $tag_name{album}   = $audio_tag->{ALBUM}   if $audio_tag->{ALBUM};
 3045                                            $tag_name{comment} = $audio_tag->{COMMENT} if $audio_tag->{COMMENT};
 3046                                            $tag_name{year}    = $audio_tag->{YEAR}    if $audio_tag->{YEAR};
 3047                                            $tag_name{genre}   = $audio_tag->{GENRE}   if $audio_tag->{GENRE};
 3048                                
 3049                                         return 0;
 3050                                 }
 3051 
 3052                  when (/^wma$/) {
 3053                                         my $wma_tag = $tag_module->scan_tags($in_file)->{tags};
 3054 
 3055                                            $tag_name{title}   = $wma_tag->{Title}       if $wma_tag->{Title};
 3056                                            $tag_name{track}   = $wma_tag->{'WM/TrackNumber'}    if $wma_tag->{'WM/TrackNumber'};
 3057                                            $tag_name{artist}  = $wma_tag->{'WM/AlbumArtist'}    if $wma_tag->{'WM/AlbumArtist'};
 3058                                            $tag_name{album}   = $wma_tag->{'WM/AlbumTitle'} if $wma_tag->{'WM/AlbumTitle'};
 3059                                            $tag_name{comment} = $wma_tag->{'WM/Description'}    if $wma_tag->{'WM/Description'};
 3060                                            $tag_name{year}    = $wma_tag->{'WM/Year'}       if $wma_tag->{'WM/Year'};
 3061                                            $tag_name{genre}   = $wma_tag->{'WM/Genre'}      if $wma_tag->{'WM/Genre'};
 3062                             
 3063                                         return 0;
 3064                                 }
 3065                          
 3066         default { return 1; }
 3067     }
 3068 }
 3069 
 3070 # write meta-data stored in %tag_name to output file.
 3071 sub write_tags {
 3072 
 3073     my $out_file   = shift;
 3074     my $out_format = shift;
 3075 
 3076     my $tag_m;
 3077 
 3078     given ($out_format) {
 3079 
 3080        when (/^mp3$|^mp3hd$/) {
 3081                                   $tag_m = MP3::Tag->new("$out_file");
 3082                             
 3083                                   # ID3v2 Tags
 3084                                   unless(exists($tag_m->{ID3v2})) { $tag_m->new_tag("ID3v2"); }
 3085 
 3086                                   $tag_m->{ID3v2}->add_frame("TIT2", "$tag_name{title}")    if defined($tag_name{title});
 3087                                   $tag_m->{ID3v2}->add_frame("TRCK", "$tag_name{track}")    if defined($tag_name{track});
 3088                                   $tag_m->{ID3v2}->add_frame("TPE1", "$tag_name{artist}")   if defined($tag_name{artist});
 3089                                   $tag_m->{ID3v2}->add_frame("TALB", "$tag_name{album}")    if defined($tag_name{album});
 3090                                   $tag_m->{ID3v2}->comment("$tag_name{comment}")            if defined($tag_name{comment});
 3091                                   $tag_m->{ID3v2}->add_frame("TYER", "$tag_name{year}")     if defined($tag_name{year});
 3092                                   $tag_m->{ID3v2}->add_frame("TCON", "$tag_name{genre}")    if defined($tag_name{genre});
 3093 
 3094                                   $tag_m->{ID3v2}->write_tag;
 3095                             
 3096                                   # ID3v1 Tags
 3097                                   unless(exists($tag_m->{ID3v1})) { $tag_m->new_tag("ID3v1"); }
 3098                             
 3099                                   $tag_m->{ID3v1}->title("$tag_name{title}")      if defined($tag_name{title});
 3100                                   $tag_m->{ID3v1}->track("$tag_name{track}")      if defined($tag_name{track});
 3101                                   $tag_m->{ID3v1}->artist("$tag_name{artist}")    if defined($tag_name{artist});
 3102                                   $tag_m->{ID3v1}->album("$tag_name{album}")      if defined($tag_name{album});
 3103                                   $tag_m->{ID3v1}->comment("$tag_name{comment}")  if defined($tag_name{comment});
 3104                                   $tag_m->{ID3v1}->year("$tag_name{year}")        if defined($tag_name{year});
 3105                                   $tag_m->{ID3v1}->genre("$tag_name{genre}")      if defined($tag_name{genre});
 3106                             
 3107                                   $tag_m->{ID3v1}->write_tag;
 3108                             
 3109                                   return 0;
 3110 
 3111                               }
 3112 
 3113          when (/^ogg$|^oga$/) {
 3114                                   $tag_m = '';
 3115                                   
 3116                                   $tag_m = "$tag_m -t \"TITLE=$tag_name{title}\""       if $tag_name{title};
 3117                                   $tag_m = "$tag_m -t \"TRACKNUMBER=$tag_name{track}\"" if $tag_name{track};
 3118                                   $tag_m = "$tag_m -t \"ARTIST=$tag_name{artist}\""     if $tag_name{artist};
 3119                                   $tag_m = "$tag_m -t \"ALBUM=$tag_name{album}\""       if $tag_name{album};
 3120                                   $tag_m = "$tag_m -t \"COMMENT=$tag_name{comment}\""   if $tag_name{comment};
 3121                                   $tag_m = "$tag_m -t \"YEAR=$tag_name{year}\""         if $tag_name{year};
 3122                                   $tag_m = "$tag_m -t \"GENRE=$tag_name{genre}\""       if $tag_name{genre};
 3123                             
 3124                   my $out_file_q = shell_quote $out_file;
 3125                                   system("vorbiscomment -w $tag_m $out_file_q") if $tag_m ne ''; 
 3126                             
 3127                                   return 0;
 3128                               }
 3129 
 3130        when (/^fla$|^flac$/)  {
 3131                                     $tag_m = Audio::FLAC::Header->new("$out_file");
 3132                                  my $tag_i = $tag_m->tags();
 3133                                  
 3134                                     $tag_i->{TITLE}       = "$tag_name{title}"   if $tag_name{title};
 3135                                     $tag_i->{TRACKNUMBER} = "$tag_name{track}"   if $tag_name{track};
 3136                                     $tag_i->{ARTIST}      = "$tag_name{artist}"  if $tag_name{artist};
 3137                                     $tag_i->{ALBUM}       = "$tag_name{album}"   if $tag_name{album};
 3138                                     $tag_i->{COMMENT}     = "$tag_name{comment}" if $tag_name{comment};
 3139                                     $tag_i->{DATE}        = "$tag_name{year}"    if $tag_name{year};
 3140                                     $tag_i->{GENRE}       = "$tag_name{genre}"   if $tag_name{genre};
 3141 
 3142                                     $tag_m->write();
 3143                             
 3144                                  return 0;
 3145                               }
 3146 
 3147         default { perror("no_write_tag","$out_file"); }
 3148     }
 3149 
 3150 }
 3151 
 3152 # this is necessary when converting multiple files.
 3153 # it prevents old tags from the previous file being 
 3154 # copied over to the next file in line.
 3155 sub clear_tag_hash {
 3156     foreach (keys(%tag_name)) {
 3157             $tag_name{$_} = '';
 3158     }
 3159 }
 3160 
 3161 # display meta-data for selected file(s)
 3162 sub show_taginfo {
 3163 
 3164     perror("no_input","") if $#file < 0;
 3165 
 3166     foreach my $i (@file) {
 3167 
 3168      my ($file, $dir, $ext) = fileparse("$i", qr/\.[^.]*/);
 3169      
 3170          $ext  =~ s/^\.//;
 3171      
 3172      my  $from = $ext;
 3173          $from =~ tr/A-Z/a-z/;
 3174 
 3175      if ($run{$from}{TAGS}{READ} == 1) {
 3176 
 3177          clear_tag_hash();
 3178          read_tags("$dir/$file.$ext","$from");
 3179 
 3180          say '';
 3181 
 3182          pnotice("tag_info","$file.$ext",2);
 3183 
 3184          say " Artist: $tag_name{artist}";
 3185          say "  Title: $tag_name{title}";
 3186          say "  Album: $tag_name{album}";
 3187          say "  Track: $tag_name{track}";
 3188          say "Comment: $tag_name{comment}";
 3189          say "   Year: $tag_name{year}";
 3190          say "  Genre: $tag_name{genre}";
 3191 
 3192          say '';
 3193 
 3194      } else { pnotice("no_read_tag","$file.$ext",2); }
 3195    }
 3196 }
 3197 
 3198 # write tags to file supplied by the user
 3199 sub write_user_tags {
 3200 
 3201     perror("no_input","") if $#file < 0;
 3202 
 3203     say '';
 3204     say "$name - $version\n";
 3205     
 3206     foreach (@file) {
 3207 
 3208          my ($file, $dir, $ext) = fileparse("$_", qr/\.[^.]*/);
 3209 
 3210             $ext  =~ s/^\.//;
 3211          my $from = $ext;
 3212             $from =~ tr/A-Z/a-z/;
 3213 
 3214          if ($run{$from}{TAGS}{WRITE} == 1) {
 3215 
 3216              clear_tag_hash();
 3217              read_tags("$dir/$file.$ext","$from");
 3218 
 3219              $tag_name{title}   = $title   if $title;
 3220              $tag_name{track}   = $track   if $track;
 3221              $tag_name{artist}  = $artist  if $artist;
 3222              $tag_name{album}   = $album   if $album;
 3223              $tag_name{comment} = $comment if $comment;
 3224              $tag_name{year}    = $year    if $year;
 3225              $tag_name{genre}   = $genre   if $genre;
 3226 
 3227              write_tags("$dir/$file.$ext","$from");
 3228              say "$lang{write_tag_i} $file.$ext";
 3229 
 3230          } else { perror("no_write_tag","$file.$ext"); }
 3231     }
 3232     say '';
 3233 }
 3234 
 3235 # print out list of supported encode & decode formats
 3236 sub show_formats {
 3237 
 3238 say "\n$name - $version\n";
 3239 say "EXT       E   D   ENCODER         DECODER         TAG-READ   TAG-WRITE";
 3240 say "----------------------------------------------------------------------";
 3241 
 3242 my $enc_count = 0;
 3243 my $dec_count = 0;
 3244 
 3245    foreach (sort(keys(%run))) {
 3246 
 3247         my $e = "N"; $e = "Y" if defined($run{$_}{DEFAULT_ENCODER});
 3248         my $d = "N"; $d = "Y" if defined($run{$_}{DEFAULT_DECODER});
 3249         my $r = "N"; $r = "Y" if $run{$_}{TAGS}{READ}  == 1;
 3250         my $w = "N"; $w = "Y" if $run{$_}{TAGS}{WRITE} == 1;
 3251         
 3252         my $enc = ''; $enc = $run{$_}{DEFAULT_ENCODER} if defined($run{$_}{DEFAULT_ENCODER});
 3253         my $dec = ''; $dec = $run{$_}{DEFAULT_DECODER} if defined($run{$_}{DEFAULT_DECODER});
 3254 
 3255         printf("%-9s %-3s %-3s %-15s %-18s %-10s %s\n", $_, $e, $d, $enc, $dec, $r, $w);
 3256 
 3257         ++$enc_count if $enc ne '';
 3258         ++$dec_count if $dec ne '';
 3259 
 3260    }
 3261    
 3262    say "\n$lang{enc_fmts} $enc_count --- $lang{dec_fmts} $dec_count\n";
 3263    
 3264 }
 3265 
 3266 # show encoders for output format
 3267 sub show_encoders {
 3268     say "\n$name - $version\n\n$lang{show_encoders}: $my_encoder\n";
 3269     foreach (sort(keys %{$run{$my_encoder}{ENCODER}})) {        
 3270         print "$_ -> ";
 3271         print "installed" if `which $_ 2>/dev/null`;
 3272         print "not found" if not `which $_ 2>/dev/null`;
 3273         print " (default)" if $_ eq $run{$my_encoder}{DEFAULT_ENCODER};
 3274         say '';
 3275     }
 3276     say '';
 3277 }
 3278 
 3279 # show decoders for input format
 3280 sub show_decoders {
 3281     say "\n$name - $version\n\n$lang{show_decoders}: $my_decoder\n";
 3282     foreach (sort(keys %{$run{$my_decoder}{DECODER}})) {
 3283         print "$_ -> ";
 3284         print "installed" if `which $_ 2>/dev/null`;       
 3285         print " (default)" if $_ eq $run{$my_decoder}{DEFAULT_DECODER};
 3286         say '';
 3287     }
 3288     say '';
 3289 }
 3290 
 3291 #################
 3292 # cd ripping... #
 3293 #################
 3294 
 3295 # get total number of tracks from cdparanoia query
 3296 sub get_total_tracks {
 3297 
 3298     open(CDINFO, "cdparanoia -Q 2>&1 |") or die "can't fork: $!\n";
 3299     my @cdquery = <CDINFO>;
 3300     close(CDINFO);
 3301 
 3302     my $fmt_tracks = $cdquery[-3];
 3303        $fmt_tracks =~ s/\s//g;
 3304 
 3305     my @ttracks = split(/\./, $fmt_tracks);
 3306 
 3307     return "$ttracks[0]";
 3308 
 3309 }
 3310 
 3311 my (%cd, %ripconfig, @cdtrack, $track_total);
 3312 
 3313 # setup the cddb config
 3314 sub get_cddb_config {
 3315 
 3316       $config{USE_CDDB}      = 0 && return if $nocddb;
 3317 
 3318       $config{CDDB_INPUT}    = 0 if $noinput;
 3319 
 3320       $ripconfig{CDDB_HOST}  = $config{CDDB_HOST};
 3321       $ripconfig{CDDB_PORT}  = $config{CDDB_PORT};
 3322       $ripconfig{CDDB_MODE}  = $config{CDDB_MODE};
 3323       $ripconfig{DEVICE}     = $device;
 3324       $ripconfig{CDDB_INPUT} = $config{CDDB_INPUT};
 3325       
 3326       print $ripconfig{CDDB_HOST};
 3327 
 3328       %cd = get_cddb(\%ripconfig);
 3329 
 3330       if (not $cd{title}) {
 3331           pnotice("no_cddb","",2);
 3332           $config{USE_CDDB} = 0;
 3333       }
 3334       else {
 3335           @cdtrack     = @{$cd{track}};
 3336           $track_total = $cd{tno};
 3337       }
 3338 
 3339 }
 3340 
 3341 # check to see if a disc is present
 3342 sub query_disc {
 3343     system("cdparanoia -q -d $device -Q > /dev/null 2>&1");
 3344     perror("no_disc","$device") if $? > 0;
 3345 }
 3346 
 3347 # set tag info from cddb
 3348 sub tag_track {
 3349 
 3350     my $tno = shift;
 3351 
 3352        $tag_name{artist}  = $cd{artist} if $cd{artist};
 3353        $tag_name{title}   = $cdtrack[$tno-1] if $cdtrack[$tno-1];
 3354        $tag_name{genre}   = $cd{cat} if $cd{cat};
 3355        $tag_name{track}   = $tno;
 3356        $tag_name{album}   = $cd{title} if $cd{title};
 3357        $tag_name{year}    = $cd{year} if $cd{year};
 3358        $tag_name{comment} = '';
 3359 
 3360 }
 3361 
 3362 # process and convert ripped track
 3363 sub rip_cd {
 3364 
 3365     my ($on,$tno) = @_;
 3366 
 3367         $outdir = $ENV{HOME};
 3368         $to =~ tr/A-Z/a-z/;
 3369         
 3370         get_visual_opts($to,$out_dir) if $gui and not defined($first_run);
 3371         $first_run = 1;        
 3372         pnotice("ripping_track","$tno",2);    
 3373  
 3374         $on =~ s/\//_/g;
 3375 
 3376         say "\ncdparanoia -d $device $tno $on.wav\n"  if $dryrun;
 3377     my $on_q = shell_quote "$on.wav";
 3378         system("cdparanoia -d $device $tno $on_q >/dev/null 2>&1")  if not $dryrun;
 3379 
 3380     if ($to !~ /wav/i) {
 3381 
 3382         push(@file, "$on.wav");
 3383         tag_track($tno);
 3384         proc_input();
 3385         clear_tag_hash();
 3386         undef(@file);
 3387         unlink("$on.wav") if not $dryrun;
 3388         pnotice("removed_tmp","$on.wav",2) if $verbose;
 3389 
 3390     }
 3391 }
 3392 
 3393 # rip selected tracks or all from disc
 3394 sub proc_cd {
 3395 
 3396  perror("no_app","cdparanoia") if not `which cdparanoia 2>/dev/null`;
 3397  
 3398  query_disc();
 3399  get_cddb_config();
 3400 
 3401  my $total_tracks = get_total_tracks();
 3402 
 3403     if ($rip eq "all") { 
 3404 
 3405         if ($config{USE_CDDB} ne 1) {
 3406 
 3407             for(my $i=1;$i<=$total_tracks;$i++) {
 3408                 rip_cd($i, $i);
 3409             }
 3410 
 3411         } elsif ($config{USE_CDDB} eq 1) {
 3412 
 3413               my $n = 1;
 3414 
 3415               foreach my $i (@cdtrack) {
 3416 
 3417                       my $out_string = $nscheme;
 3418                       
 3419                          chomp($cdtrack[$n-1]);
 3420 
 3421                          $out_string =~ s/%ar/$cd{artist}/;
 3422                          $out_string =~ s/%ti/$cdtrack[$n-1]/;
 3423                          $out_string =~ s/%tr/$n/;
 3424                          $out_string =~ s/%ab/$cd{title}/;
 3425                          $out_string =~ s/%yr/$cd{year}/;
 3426 
 3427                          rip_cd($out_string, $n);
 3428 
 3429                          ++$n;
 3430               }
 3431           }
 3432 
 3433    } else {
 3434 
 3435             my @tracks = split(/,/, $rip);
 3436 
 3437                foreach my $i (@tracks) {
 3438 
 3439                        next if $i > $total_tracks or $i < 1;
 3440 
 3441                        my $out_string = $nscheme;
 3442 
 3443                           $out_string =~ s/%ar/$cd{artist}/;
 3444                           $out_string =~ s/%ti/$cdtrack[$i-1]/;
 3445                           $out_string =~ s/%tr/$i/;
 3446                           $out_string =~ s/%ab/$cd{title}/;
 3447                           $out_string =~ s/%yr/$cd{year}/;
 3448 
 3449                           rip_cd($out_string, $i) if $config{USE_CDDB} == 1;
 3450                           rip_cd($i, $i)          if $config{USE_CDDB} == 0;
 3451                }
 3452       }
 3453 }
 3454 
 3455 # get/print cddb information from disc
 3456 sub cdinfo {
 3457 
 3458     query_disc();
 3459     get_cddb_config();
 3460 
 3461     say "$name - $version\n";
 3462 
 3463     say "Artist = $cd{artist}";
 3464     say "Album  = $cd{title}";
 3465     say "Genre  = $cd{genre}";
 3466     say "Tracks = $cd{tno}";
 3467     say "Year   = $cd{year}\n";
 3468 
 3469     my $n = 1;
 3470 
 3471     foreach (@cdtrack) {
 3472          say "Track $n: $_";
 3473          ++$n;
 3474     }
 3475 
 3476     exit(0);
 3477 }
 3478 
 3479 # version / license information
 3480 sub version {
 3481 
 3482 say "
 3483 $name - $version
 3484 
 3485 Copyright (C) 2005-2021 Philip Lyons
 3486 
 3487 This is free software.  You may redistribute copies of it under the terms of
 3488 the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
 3489 There is NO WARRANTY, to the extent permitted by law.
 3490 ";
 3491 
 3492 }
 3493 
 3494 # help & longhelp menu
 3495 sub help_menu {
 3496 
 3497 say "\n$name - $version";
 3498 
 3499 say "
 3500 -t, --to             $lang{to}
 3501 -r, --recursive      $lang{recursive}
 3502 -p, --preserve       $lang{preserve}
 3503 -f, --formats        $lang{formats}
 3504 -o, --only           $lang{only}
 3505 -k, --keep           $lang{keep}
 3506 -j, --jobs           $lang{jobs}
 3507 -h, --help           $lang{help}
 3508 -l, --longhelp       $lang{longhelp}
 3509 -v, --verbose        $lang{verbose}
 3510 ";
 3511 
 3512 say "$lang{user_opts}
 3513 
 3514 --defopts            $lang{defopts}
 3515 --eopts              $lang{eopts}
 3516 --dopts              $lang{dopts}
 3517 --nopts              $lang{nopts}
 3518 --outfile            $lang{outfile}
 3519 --outdir             $lang{outdir}
 3520 --dryrun             $lang{dryrun}
 3521 --overwrite          $lang{overwrited}
 3522 --normalize          $lang{normalize}
 3523 --delete             $lang{delete}
 3524 --encoder            $lang{encoder}
 3525 --decoder            $lang{decoder}
 3526 --version            $lang{version}
 3527 
 3528 $lang{enc_opts}
 3529 
 3530 --bitrate            $lang{bitrate}
 3531 --freq               $lang{freq}
 3532 --channels           $lang{channels}
 3533 --effect             $lang{effect}
 3534 --fcomp              $lang{fcomp}
 3535 --acomp              $lang{acomp}
 3536 --oggqual            $lang{oggqual}
 3537 --spxqual            $lang{spxqual}
 3538 --aacqual            $lang{aacqual}
 3539 --mpcqual            $lang{mpcqual}
 3540 --ofmode             $lang{ofmode}
 3541 --ofopt              $lang{ofopt}
 3542 --bratio             $lang{bratio}
 3543 --bquanl             $lang{bquanl}
 3544 --bpsize             $lang{bpsize}
 3545 
 3546 $lang{tag_opts}
 3547 
 3548 --artist             $lang{artist}
 3549 --title              $lang{title}
 3550 --track              $lang{track}
 3551 --year               $lang{year}
 3552 --album              $lang{album}
 3553 --genre              $lang{genre}
 3554 --comment            $lang{comment}
 3555 --taginfo            $lang{taginfo}
 3556 
 3557 $lang{tag_usage}
 3558 
 3559 $lang{rip_opts}
 3560 
 3561 --rip                $lang{rip}
 3562 --nocddb             $lang{nocddb}
 3563 --noinput            $lang{noinput}
 3564 --nscheme            $lang{nscheme}
 3565 --cdinfo             $lang{cdinfo}
 3566 --device             $lang{device}
 3567 
 3568 $lang{rip_usage}" if $longhelp;
 3569 
 3570 say "\n$lang{usage}\n";
 3571 
 3572 }
 3573 
 3574 sub load_module {
 3575     my ($file) = @_;
 3576     my $return;
 3577     unless($return = do $file) {
 3578         perror("opening_file","$file: $@ $!") if $@ or !defined($return) or not !$return;
 3579     }
 3580 }
 3581                                                  
 3582 sub import_module {
 3583     my ($format_ref) = @_;
 3584     my $format_name=$format_ref->{NAME};
 3585        $run{$format_name} = $format_ref;
 3586 }
 3587                
 3588 # load all user modules
 3589 sub load_user_modules {
 3590    my @imported_mods;
 3591    opendir(DIR, "$mod_dir") or perror("opening_dir","$mod_dir: $!");
 3592    foreach (readdir(DIR)) {
 3593         load_module("$mod_dir/$_") if $_ !~ /^\./;
 3594         push(@imported_mods, $_)   if $_ !~ /^\./;
 3595    }
 3596    closedir(DIR);
 3597    say "$lang{imported} @imported_mods";
 3598 }
 3599 
 3600 # place files/directories in their respective arrays
 3601 if (@ARGV) {
 3602   foreach (@ARGV) {
 3603        if    (-f $_) { push(@file,$_); print "$lang{debug} adding $_ to \@file\n" if $debug == 1; }
 3604        elsif (-d $_) { push(@dir, $_); print "$lang{debug} adding $_ to \@dir\n"  if $debug == 1; }
 3605        else { perror("no_infile","$_"); } 
 3606   }
 3607 }
 3608 
 3609 load_user_modules() if $config{IMPORTM} == 1;
 3610 
 3611 if ($to and @ARGV and not $rip) { proc_input(); exit $total_failed; } 
 3612 
 3613 elsif ($to and $rip) { proc_cd(); }
 3614 elsif ($my_encoder and not $to) { show_encoders(); }
 3615 elsif ($my_decoder and not $to) { show_decoders(); }
 3616 elsif ($verinfo)  { version(); }
 3617 elsif ($longhelp) { help_menu(); }
 3618 elsif ($formats)  { show_formats(); }
 3619 elsif ($cdinfo)   { cdinfo(); }
 3620 elsif ($taginfo and not $to) { show_taginfo(); }
 3621 elsif ($title or $track or $artist or $album or $comment or $year or $genre) { write_user_tags(); }
 3622 
 3623 else { help_menu(); }
 3624 
 3625 __END__
 3626 
 3627 =head1 NAME
 3628 
 3629 pacpl - Perl Audio Converter, a multi purpose converter/ripper/tagger
 3630 
 3631 =head1 SYNOPSIS
 3632 
 3633 pacpl --to <format> <options> [file(s)/directory(s)]
 3634 
 3635 =head1 DESCRIPTION
 3636 
 3637 Perl Audio Converter
 3638 
 3639 A Linux CLI tool for converting multiple audio types from one format to another.
 3640 
 3641 It supports the following audio formats:
 3642 
 3643 ========================================
 3644 
 3645 3G2, 3GP, 8SVX, AAC, AC3, ADTS, AIFF, AL, AMB, AMR, APE, AU, 
 3646 AVR, BONK, CAF, CDR, CVU, DAT, DSF, DTS, DVMS, F32, F64, FAP, FLA, 
 3647 FLAC, FSSD, GSRT, HCOM, IMA, IRCAM, LA, MAT, MAUD, MAT4, MAT5, 
 3648 M4A, MP2, MP3, MP4, MPC, MPP, NIST, OFF, OFR, OFS, OPUS, OGA, 
 3649 OGG, PAF, PRC, PVF, RA, RAM, RAW, RF64, SD2, SF, SHN, SMP, SND, 
 3650 SOU, SPX, SRN, TAK, TTA, TXW, VOC, VMS, VQF, W64, WAV, WMA, 
 3651 and WV.
 3652 
 3653 It can also extract audio from the following video extensions:
 3654 
 3655 ==============================================================
 3656 
 3657 RM, RV, ASF, DivX, MPG, MKV, MPEG, AVI, MOV, OGM, OGV, QT, VCD, 
 3658 SVCD, M4V, NSV, NUV, PSP, SMK, VOB, FLV, WEBM and WMV.
 3659 
 3660 Parallel Processing, a CD ripping function with CDDB support, batch conversion, 
 3661 tag preservation for most supported formats, independent tag reading & writing, 
 3662 service menus for KDE Dolphin/Konqueror, GNOME Nautilus script, and action 
 3663 scripts for Nemo/Thunar are also provided.
 3664 
 3665 =head1 OPTIONS
 3666 
 3667 B<-t, --to> I<format>
 3668 
 3669 set encode format for the input file(s) or directory(ies).  you can see a
 3670 complete list of supported encode formats by using the B<--formats> option.
 3671 
 3672 B<-r, --recursive>
 3673 
 3674 recursively scan and convert input folder(s) to destination format.
 3675 
 3676 B<-p, --preserve>
 3677 
 3678 when recursively converting a directory, preserve the input folders directory 
 3679 structure in the specified output directory.  such as:
 3680 
 3681 pacpl --to ogg -r -p /home/mp3s --outdir /home/oggs
 3682 
 3683 in the example above, let's assume the directory structure was:
 3684 
 3685 =over 21
 3686 
 3687 =item /home/mp3s/Alternative
 3688 
 3689 =item /home/mp3s/Alternative/New
 3690 
 3691 =item /home/mp3s/Rap
 3692 
 3693 =item /home/mp3s/Country
 3694 
 3695 =item /home/mp3s/Techno/
 3696 
 3697 =back
 3698 
 3699 the output directory will now contain:
 3700 
 3701 =over 4
 3702 
 3703 =item /home/oggs/Alternative
 3704 
 3705 =item /home/oggs/Alternative/New
 3706 
 3707 =item /home/oggs/Rap
 3708 
 3709 =item /home/oggs/Country
 3710 
 3711 =item /home/oggs/Techno
 3712 
 3713 =back
 3714 
 3715 with all files in each sub-folder converted to ogg.
 3716 
 3717 B<-o, --only> I<format>
 3718 
 3719 only convert files matching extension.  this option is useful when you have
 3720 a directory or batch of files with mixed audio types and only need to
 3721 convert one specific type.
 3722 
 3723 B<-k, --keep>
 3724 
 3725 do not re-encode files with extensions matching the destination extension.  
 3726 instead...copy them to the output folder, or skip to the next file.
 3727 
 3728 B<-j, --jobs>
 3729 
 3730 number of simultanious jobs to run at once.  the default limit
 3731 is set to 4 in pacpl.conf.  You can modify this value on the fly 
 3732 using --jobs=<num> or set it perminately in the configuration file
 3733 
 3734 =over 4
 3735 
 3736 =item B<-f, --formats>    show a list of supported encode/decode formats.
 3737 
 3738 =item B<-h, --help>       show the short help menu.
 3739 
 3740 =item B<-l, --longhelp>   display the complete list of options.
 3741 
 3742 =item B<--version>        show version and licensing information.
 3743 
 3744 =back
 3745 
 3746 =head1 USER OPTIONS
 3747 
 3748 B<--defopts> I<1/0>
 3749 
 3750 to turn off default encoder options use --defopts 0. this option gives you 
 3751 more control when using the --eopts command.
 3752 
 3753 defopts is set to 1 by default.  you can also toggle this option in
 3754 /etc/pacpl/pacpl.conf.
 3755 
 3756 B<--eopts> I<options>
 3757 
 3758 this option allows you to use encoder options not implemented by pacpl.
 3759 an example would be:
 3760 
 3761 pacpl --to mp4 --eopts="-c 44100 -I 1,2" YourFile.mp3
 3762 
 3763 B<--dopts> I<options>
 3764 
 3765 this option allows you to use decoder options not implemented by pacpl.
 3766 an example would be:
 3767 
 3768 pacpl --to mpc --dopts="--start 60" YourFile.ogg
 3769 
 3770 B<--outfile> I<name>
 3771 
 3772 set the output file name to I<name>.
 3773 
 3774 B<--outdir> I<directory>
 3775 
 3776 place all encoded files in I<directory>.
 3777 
 3778 B<--dryrun>
 3779 
 3780 show what would be done without actually converting anything.  this is a
 3781 good way to trouble shoot, or to see what would be done without actually
 3782 touching your files.
 3783 
 3784 B<--overwrite>
 3785 
 3786 replace the output file if it already exists.
 3787 
 3788 B<--normalize>
 3789 
 3790 adjusts volume levels of audio files.
 3791 
 3792 B<--nopts> I<options>
 3793 
 3794 this allows you to specify normalize options not implemented by pacpl
 3795 
 3796 B<--delete>
 3797 
 3798 remove source/input file after the conversion process has finished.
 3799 
 3800 B<--encoder> I<encoder>
 3801 
 3802 specify an alternate encoder for the selected output file(s)
 3803 
 3804 you can see a list of supported encoders by using the following:
 3805 
 3806 pacpl --encoder I<format>
 3807 
 3808 B<--decoder> I<decoder>
 3809 
 3810 specify an alternate decoder for the selected input file(s)
 3811 
 3812 you can see a list of supported decoders by using the following:
 3813 
 3814 pacpl --decoder I<format>
 3815 
 3816 B<-v, --verbose>
 3817 
 3818 show detailed information about the encoding process and what's actually
 3819 being done.
 3820 
 3821 =head1 ENCODER OPTIONS
 3822 
 3823 B<--bitrate> I<num>
 3824 
 3825 set the bitrate to I<num>.  default is 128.  this option does not apply 
 3826 to all formats.
 3827 
 3828 B<--freq> I<num>
 3829 
 3830 set the frequency to I<num>.  default is 44100.  this option does not apply
 3831 to all formats.
 3832 
 3833 B<--channels> I<num>
 3834 
 3835 set the number of audio channels in the output file to I<num>.  this option
 3836 does not apply to all formats.
 3837 
 3838 B<--effect> I<str>
 3839 
 3840 see B<sox>(1).  this option only applies to the following:
 3841 
 3842 AIFF, AU, SND, RAW, VOC, SMP, AVR, and CDR
 3843 
 3844 B<--fcomp> I<num>
 3845 
 3846 set flac compression level to I<num>. fastest -0, highest -8, default -2
 3847 
 3848 =over 4
 3849 
 3850 =item 1 = fast
 3851 
 3852 =item 2 = simple
 3853 
 3854 =item 3 = medium (default)
 3855 
 3856 =item 4 = high
 3857 
 3858 =item 5 = extra high,
 3859 
 3860 =back
 3861 
 3862 B<--acomp> I<num>
 3863 
 3864 set ape compression level to I<num>.
 3865 
 3866 =over 4
 3867 
 3868 =item 1000 = fast
 3869 
 3870 =item 2000 = normal
 3871 
 3872 =item 3000 = high (default)
 3873 
 3874 =item 4000 = extra high
 3875 
 3876 =item 5000 = insane
 3877 
 3878 =back
 3879 
 3880 B<--oggqual> I<num>
 3881 
 3882 set ogg quality level to I<num>. -1, very low and 10 very high, default 3
 3883 
 3884 B<--spxqual> I<num>
 3885 
 3886 set speex quality level to I<num>. 0-10, default 8 (use --bitrate <num> when using ffmpeg/avconv as encoder)
 3887 
 3888 B<--aacqual> I<num>
 3889 
 3890 set aac, mp4, m4a, or m4b quality level to I<num>. default 300
 3891 
 3892 B<--mpcqual> I<str>
 3893 
 3894 set mpc/mpp quality level to I<str>.
 3895 
 3896 =over 4
 3897 
 3898 =item thumb        low quality/internet, (typ.  58... 86 kbps)
 3899 
 3900 =item radio        medium (MP3) quality, (typ. 112...152 kbps - default)
 3901 
 3902 =item standard     high quality (dflt),  (typ. 142...184 kbps)
 3903 
 3904 =item xtreme       extreme high quality, (typ. 168...212 kbps)
 3905 
 3906 =back
 3907 
 3908 B<--ofmode> I<str>
 3909 
 3910 set off/ofr/ofs compression mode to I<str>.  normal, extra, and extranew modes
 3911 are recommended for general use.  available options are:
 3912 
 3913 =over 4
 3914 
 3915 =item fast
 3916 
 3917 =item normal (default)
 3918 
 3919 =item high
 3920 
 3921 =item extra
 3922 
 3923 =item best
 3924 
 3925 =item highnew
 3926 
 3927 =item extranew
 3928 
 3929 =item bestnew
 3930 
 3931 =back
 3932 
 3933 B<--ofopt> I<str>
 3934 
 3935 set off/ofr/ofs optimization level to I<str>.
 3936 
 3937 specify the optimization level in the engine. In order to achieve
 3938 optimal compression at all sample types, sample rates, and audio
 3939 content, the core compression engine has the possibility to find the
 3940 optimal values for its parameters, at the cost of slightly increased
 3941 compression time only. The default recommended value is fast.
 3942 do not use normal (or even high or best) for this parameter unless
 3943 encoding time does not matter and you want to obtain the smallest
 3944 possible file for a given compression mode. The difference between
 3945 the optimize levels fast and best (which is up to three times slower
 3946 than fast) is very small, generally under 0.05%, but may be also
 3947 larger in some rare cases. Note that the none optimize level is
 3948 forced by the encoder to fast optimize level for the extra, best,
 3949 highnew, extranew, and bestnew modes.
 3950 
 3951 available options are:
 3952 
 3953 =over 4
 3954 
 3955 =item none
 3956 
 3957 =item fast (default)
 3958 
 3959 =item normal
 3960 
 3961 =item high
 3962 
 3963 =item best
 3964 
 3965 =back             
 3966 
 3967 B<--bratio> I<num>
 3968 
 3969 set bonk down sampling ratio.  default 2
 3970 
 3971 B<--bquanl> I<num>
 3972 
 3973 set bonk quantanization level.  default 1.0
 3974 
 3975 B<--bpsize> I<num>
 3976 
 3977 set bonk predictor size.  default 128
 3978 
 3979 =head1 TAGGING OPTIONS
 3980 
 3981 B<note:>
 3982 
 3983 tagging outside of the encoding process can only be performed on the
 3984 following audio types:
 3985 
 3986 =over 4
 3987 
 3988 =item MP3
 3989 
 3990 =item OGG
 3991 
 3992 =item FLA
 3993 
 3994 =item FLAC
 3995 
 3996 =back
 3997 
 3998 B<--artist> I<str>
 3999 
 4000 set artist information to I<str>.
 4001 
 4002 B<--title> I<str>
 4003 
 4004 set title information to I<str>.
 4005 
 4006 B<--track> I<num>
 4007 
 4008 set track information to I<num>.
 4009 
 4010 B<--year> I<num>
 4011 
 4012 set year/date information to I<num>.
 4013 
 4014 B<--album> I<str>
 4015 
 4016 set album information to I<str>.
 4017 
 4018 B<--genre> I<str>
 4019 
 4020 set genre information to I<str>.
 4021 
 4022 B<--comment> I<str>
 4023 
 4024 set comment information to I<str>.
 4025 
 4026 B<--taginfo> I<file>
 4027 
 4028 show tagging information for I<file>.  multiple files can be specified
 4029 at once.
 4030 
 4031 =head1 RIPPING OPTIONS
 4032 
 4033 B<--rip> I<num/all>
 4034 
 4035 rip selected tracks separated by comma or all from current disc.
 4036 
 4037 =over 4
 4038 
 4039 =item pacpl --rip all --to flac
 4040 
 4041 =item pacpl --rip 1,3,9,15 --to flac 
 4042 
 4043 =back
 4044 
 4045 B<--nocddb>
 4046 
 4047 disable cddb.  use this option if you do not want tagging based on cddb.
 4048 
 4049 B<--noinput>
 4050 
 4051 disable cddb interactivity.  this is enabled by default.
 4052 
 4053 B<--nscheme> I<str>
 4054 
 4055 set naming scheme to I<str>.  default is %ar - %ti
 4056 
 4057 available options are:
 4058 
 4059 =over 4
 4060 
 4061 =item %ar = artist
 4062 
 4063 =item %ti = song title
 4064 
 4065 =item %tr = track
 4066 
 4067 =item %yr = year
 4068 
 4069 =item %ab = album
 4070 
 4071 =back
 4072 
 4073 B<eg:> --nscheme="(%tr)-%ti"
 4074 
 4075 B<--device> I<device>
 4076 
 4077 set device to I<device>.  default is /dev/dvd
 4078 
 4079 B<--cdinfo> 
 4080 
 4081 show cddb information for current disc.
 4082 
 4083 =head1 SEE ALSO
 4084 
 4085 =over 4
 4086 
 4087 =item B<sox>(1) B<ffmpeg>(1) B<lame>(1) B<oggenc>(1) B<oggdec>(1)
 4088 
 4089 =item B<flac>(1) B<shorten>(1) B<faac>(1) B<faad>(1) B<mpcenc>(1)
 4090 
 4091 =item B<mpcdec>(1) B<mplayer>(1) B<speexenc>(1) B<speexdec>(1)
 4092 
 4093 =item B<sndfile-convert>(1) B<normalize>(1) B<cdparanoia>(1)
 4094 
 4095 =item B<opusenc>(1) B<opusdec>(1) B<wavpack>(1) B<ffmpeg>(1)
 4096 
 4097 =item B<mplayer>(1) B<avconv>(1)
 4098 
 4099 =back
 4100 
 4101 =head1 BUGS
 4102 
 4103 Report all bugs to Philip Lyons (vorzox@gmail.com)
 4104 
 4105 =head1 LICENSING
 4106 
 4107 This program is free software; you can redistribute it and/or modify
 4108 it under the terms of the GNU General Public License as published by
 4109 the Free Software Foundation; either version 3 of the License, or
 4110 (at your option) any later version.
 4111 
 4112 This program is distributed in the hope that it will be useful,
 4113 but WITHOUT ANY WARRANTY; without even the implied warranty of
 4114 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 4115 GNU General Public License for more details.
 4116 
 4117 You should have received a copy of the GNU General Public License
 4118 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 4119 
 4120 =head1 AUTHOR
 4121 
 4122 <<<<<<< HEAD
 4123 Copyright (C) 2005-2021 Philip Lyons (vorzox@gmail.com)
 4124 =======
 4125 Copyright (C) 2005-2019 Philip Lyons (vorzox@gmail.com)
 4126 >>>>>>> cc4eb189828ef15228da02c14a39e484294126ec