summaryrefslogtreecommitdiff
path: root/commands
diff options
context:
space:
mode:
authorroot <root@noname.(none)>2012-09-16 20:25:54 +0200
committerroot <root@noname.(none)>2012-09-16 20:25:54 +0200
commitd74decea551c5535f75dda64f271bf7f80b2adc1 (patch)
treeaf11877dfb200991bd44467f235e4763dc3d1fde /commands
downloadvdr-plugin-ripit-d74decea551c5535f75dda64f271bf7f80b2adc1.tar.gz
vdr-plugin-ripit-d74decea551c5535f75dda64f271bf7f80b2adc1.tar.bz2
Initial import of version 0.0.2
Diffstat (limited to 'commands')
-rwxr-xr-xcommands/mp3ng_audiocdripper.sh33
-rwxr-xr-xcommands/ripit.pl3567
2 files changed, 3600 insertions, 0 deletions
diff --git a/commands/mp3ng_audiocdripper.sh b/commands/mp3ng_audiocdripper.sh
new file mode 100755
index 0000000..e76d1fc
--- /dev/null
+++ b/commands/mp3ng_audiocdripper.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# 2006/11/14 by Morone
+#
+# mp3ng_audiocdripper.sh - v.0.1
+#
+# A script to start vdrplugin-ripit over SVDRP
+#$1 songname
+#$2 copydir
+#$3 artist
+#$4 album
+#$5 artistcoverdir
+#
+#
+#
+##
+### Usage:
+### ======
+### CHANGE below the path to svdrpsend.pl
+### Place an entry in mp3ngcmds.dat like this:
+### **********************************************************************************
+### Start AudioCD-Ripper? : echo "/PATH_TO_SCRIPT/mp3ng_audiocdripper.sh" | at now;
+### **********************************************************************************
+### thats all and lets hope you get good results ;)
+##
+#
+#
+#
+#
+/VDR/bin/svdrpsend.pl PLUG ripit START
+#
+#
+#######################################EOF
diff --git a/commands/ripit.pl b/commands/ripit.pl
new file mode 100755
index 0000000..6bb20cc
--- /dev/null
+++ b/commands/ripit.pl
@@ -0,0 +1,3567 @@
+#!/usr/bin/perl
+########################################################################
+#
+# LICENSE
+#
+# Copyright (C) 2005 Felix Suwald
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+# USA.
+#
+########################################################################
+#
+# CODE
+#
+# ripit.pl - Rips CD Audio and encodes files in the following steps:
+# 1) Query CDDB data for Album/Artist/Track info
+# 2) Rip the audio files from the CD
+# 3) Encode the wav files
+# 4) ID3 tag the encoded files
+# 5) Optional: Create a playlist (M3U) file.
+# 6) Optional: Prepares and sends a CDDB submission.
+#
+# Version 3.4 - August 5th 2005 - Felix Suwald and Max Kaesbauer
+# Version 2.5 - November 13th 2004 - Felix Suwald
+# Version 2.2 - October 18th 2003 - Mads Martin Joergensen
+# Version 1.0 - February 16th 1999 - Simon Quinn
+#
+#
+########################################################################
+#
+# User configurable variables:
+# Keep these values and save your own settings
+# in the config file with option --save!
+#
+
+$ENV{PATH}="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/opt/bin:/usr/i686-pc-linux-gnu/gcc-bin/3.3:/usr/X11R6/bin";
+
+# !! CHANGE THIS TO YOUR ENV !!
+$svdrpcmd = "/VDR/bin/svdrpsend.pl"; # Full path of svdrpsend.pl command.
+$cddevice = "/dev/cdrom"; # Path of audio CD device.
+
+$output = ""; # Where the sound should go to.
+$ripopt = ""; # Options for audio CD ripper.
+$ripper = 1; # 0 - dagrab, 1 - cdparanoia,
+ # 2 - cdda2wav, 3 - tosha, 4 - cdd.
+@coder = (0); # 0 - Lame, 1 - OggVorbis, 2 - Flac,
+ # comma seperated list.
+$bitrate = 128; # Bitrate for lame, if --vbrmode used,
+ # bitrate is equal to the -b option.
+$maxrate = 320; # Bitrate for lame using --vbrmode,
+ # maxrate is equal to the -B option.
+@quality = (2,3,5,100);# Quality for lame in vbr mode (0-9),
+ # best quality = 0, quality for ogg
+ # (1-10) best = 10; or compression
+ # level for Flac (0-8), lowest = 0.
+$qualame = 2; #
+$qualogg = 3; #
+$quaflac = 5; #
+$quafaac = 100; #
+$lameopt = "--vbr-new -V 2 -q 2 -b 128 -B 320 -p -preset insane"; #
+$oggopt = ""; #
+$flacopt = ""; #
+$faacopt = ""; #
+$lcd = 0; # Use lcdproc (1 yes, 0 no).
+$chars = 0; # Use special chars in files (1 yes, 0 no).
+$quiet = 1; # Be quiet (no output) (1 yes, 0 no).
+$commentag = ""; # Comment ID3 tag.
+$genre = ""; # Genre of Audio CD for ID3 tag.
+$year = ""; # Year of Audio CD for ID3 tag.
+$utftag = 1; # If zero decode utf tags to ISO8895-1.
+$eject = 0; # Eject the CD when done (1 yes, 0 no).
+$halt = 0; # Shutdown machine when finished
+ # (1 yes, 0 no).
+$nice = 5; # Set nice.
+$savenew = 0; # Saved passed parameters to new config
+ # file (1 yes, 0 no).
+$savepara = 0; # Save parameters passed in config file
+ # (1 yes, 0 no).
+$config = 0; # Use config file to read paramaters
+ # (1 yes, 0 no).
+$submission = 1; # Send CDDB submission
+ # (1 yes, 0 no).
+$parano = 0; # Disable paranoia mode in cdparanoia
+ # (1 yes, 0 no).
+$playlist = 0; # Do create the m3u playlist file
+ # (1 yes, 0 no).
+$interaction = 1; # If 0 do not ask anything, take the 1st
+ # CDDB entry found or use default names!
+ # (1 yes, 0 no).
+$underscore = 0; # Use _ instead of spaces in filenames
+ # (1 yes, 0 no).
+$lowercase = 0; # Lowercase filenames
+ # (1 yes, 0 no).
+$archive = 0; # Save CDDB files in ~/.cddb dir
+ # (1 yes, 0 no).
+$mirror = "freedb"; # The host (a freedb mirror) that
+ # shall be used instead of freedb.
+$transfer = "cddb"; # Transfer mode, cddb or http, will set
+ # default port to 8880 or 80 (for http).
+$vbrmode = "new"; # Variable bitrate, only used with lame,
+ # (new or old), see lame-manpage.
+$proto = 6; # CDDB protocol level for CDDB query.
+$proxy = ""; # Set proxy.
+$CDDB_HOST = "freedb.org"; # Set cddb host
+$mailad = ""; # Users return e-mail address.
+@sshlist = (); # List of remote machines.
+$scp = 0; # Use scp to access files (1 yes, 0 no).
+$local = 1; # Encode on locale machine (1 yes, 0 no).
+$wav = 0; # Keep the wav files (1 yes, 0 no).
+$encode = 1; # Encode the wav files (1 yes, 0 no).
+$rip = 1; # Rip the CD files (1 yes, 0 no).
+$multi = 0; # Not yet official. Do NOT use!
+$field = 0; # Not yet supported by CDDB_get.pm.
+#
+#
+# Directory and track template variables:
+# Contains the format the track names will be written as.
+# The '" and "' are important and must surround the template.
+# Example variables to use are: $tracknum, $album, $artist, $genre,
+# $trackname or $year.
+# E.g. example setting of $tracktemplate produces a trackname of
+# "07 The Game - Swandive" .
+# $tracktemplate = '"$tracknum $trackname - $artist"';
+#
+$dirtemplate = '"$artist - $album"';
+$tracktemplate = '"$tracknum $trackname"';
+#
+#
+# lcdproc settings:
+#
+$lcdhost = "localhost";
+$lcdport = "13666";
+$lcdline1 = " [initializing] ";
+$lcdline2 = " ripit-lcd-module ";
+$lcdline3 = " 2005 ";
+$lcdoline1 = "";
+$lcdoline2 = "";
+$lcdoline3 = "";
+$lcdproc;
+$lcdtrackno = 0;
+#
+$showosdinfo = 0;
+$ejectcmd = "eject";
+#
+#
+########################################################################
+#
+# No User configurable parameters below here
+#
+########################################################################
+#
+require "flush.pl";
+use Getopt::Long qw(:config no_ignore_case);
+use CDDB_get qw(get_cddb get_discids);
+use IO::Socket;
+use Fcntl;
+#
+# Initialize paths.
+#
+$homedir = "$ENV{HOME}";
+$workdir = "$ENV{PWD}";
+$usename = "$ENV{USER}";
+$hostnam = "$ENV{HOST}";
+#print ($_,$ENV{$_},"\n") foreach (keys %ENV);
+#
+# Initialise global variables
+#
+$artist = "";
+$artistag = "";
+$artislametag = "";
+$album = "";
+$albumtag = "";
+$albumlametag = "";
+$categ = ""; # CDDB category
+$genreno = ""; # ID3 genre number
+$lameindex = 0; # Index of encoder array entry.
+$lameflag = 0; # Flag to check if lame is used.
+$nocddbinfo = 1; # Assume no CDDB info exists
+$totals = 0; # Total length of CD in seconds.
+$trackselection = "";# Passed from command line
+$sufix = ""; # Needed in several subroutines
+$cddbid = 0; # Needed in several subroutines
+$cddbgenre = 0; # Needed in several subroutines
+$tracks = 0; # Needed in several subroutines
+$tracktag = ""; # Needed in several subroutines
+$tracklametag = ""; # Needed in several subroutines
+@comment = (); # Needed in several subroutines
+@commentblock = (); # Needed in several subroutines
+@framelist = (); # Needed in several subroutines
+@secondlist = (); # Needed in several subroutines
+@tracklist = (); # Needed in several subroutines
+@tracktags = (); # Needed in several subroutines
+$ripcomplete = 0; # Needed in several subroutines
+$dtitle = 0; # Disktitle needed for CDDB submission
+%cd = 0; # All CDDB entries needed in several subroutines
+$cddbsubmission = 2; # If zero then data for CDDB submission is incorrect
+ # if 1: submission OK, if 2: CDDB entry not changed
+$revision = ""; # If >= zero: CDDB entry present, edit file before submission
+$wpreset = ""; # Preset written into config file.
+$wcoder = 0; # Use a comma seperated string to write the
+ # coder-array into the config file.
+$wsshlist = ""; # As above for the list of remote machines.
+$sshflag = 0; # Ssh encoding OK if sshflag == 1.
+%sshlist = (); # Hash of remote machines.
+$version = "3.4";
+$encstart = 0;
+$ripstart = 0;
+$encend = 0;
+$ripend = 0;
+$riptime = 0;
+$enctime = 0;
+#
+# Get the parameters from the command line.
+# available: A E F G IjJkK N O R Yz
+# already used: a bBcCdDe f g hi lLmMn o pPqQr sStTuUvVwWy Z
+#
+if(! &GetOptions("archive|a!" => \$parchive,
+ "bitrate|b=s" => \$pbitrate,
+ "maxrate|B=i" => \$pmaxrate,
+ "chars|W!" => \$pchars,
+ "cddbserver|C=s" => \$PCDDB_HOST,
+ "config!" => \$pconfig,
+ "coder|c=s" => \@pcoder,
+ "comment=s" => \$pcommentag,
+ "device|d=s" => \$pcddev,
+ "dirtemplate|D=s" => \$pdirtemplate,
+ "eject|e!" => \$peject,
+ "encode!" => \$pencode,
+ "faacopt=s" => \$pfaacopt,
+ "flacopt=s" => \$pflacopt,
+ "lameopt=s" => \$plameopt,
+ "oggopt=s" => \$poggopt,
+ "field|f=i" => \$pfield,
+ "genre|g=s" => \$pgenre,
+ "halt" => \$phalt,
+ "help|h" => \$help,
+ "interaction|i!" => \$pinteraction,
+ "lcd!" => \$plcd,
+ "lcdhost=s" => \$plcdhost,
+ "lcdport=s" => \$plcdport,
+ "lowercase|l!" => \$plowercase,
+ "local!" => \$plocal,
+ "mirror|m=s" => \$pmirror,
+ "mail|M=s" => \$pmailad,
+ "multi" => \$pmulti,
+ "nice|n=s" => \$pnice,
+ "outputdir|o=s" => \$poutputdir,
+ "playlist|p!" => \$pplaylist,
+ "preset|S=s" => \$ppreset,
+ "proxy|P=s" => \$pproxy,
+ "protocol|L=i" => \$pproto,
+ "quality|q=s" => \@pquality,
+ "quiet|Q!" => \$pquiet,
+ "rip!" => \$prip,
+ "ripper|r=s" => \$pripper,
+ "ripopt=s" => \$pripopt,
+ "savenew" => \$savenew,
+ "save" => \$savepara,
+ "scp" => \$pscp,
+ "sshlist=s" => \@psshlist,
+ "submission|s!" => \$psubmission,
+ "tracktemplate|T=s" => \$ptracktemplate,
+ "transfer|t=s" => \$ptransfer,
+ "underscore|u!" => \$punderscore,
+ "utftag|U!" => \$putftag,
+ "vbrmode|v=s" => \$pvbrmode,
+ "version|V" => \$printver,
+ "year|y=i" => \$pyear,
+ "wav|w!" => \$pwav,
+ "disable-paranoia|Z" => \$pparano ) ) {
+ print "\nUsage: ripit [--device|d cd-device] [--outputdir|o path] [--ripper|r cdripper]
+ [--ripopt options] [--wav|w] [--disable-paranoia|Z] [--encode]
+ [--coder|c encoders-list] [--faacopt options] [--flacopt options]
+ [--oggopt options] [--lameopt options] [--quality qualities-list]
+ [--bitrate|b rate] [--maxrate|B maxrate] [--vbr-mode|v old / new]
+ [--preset|S mode] [--comment id3-comment] [--genre|g genre-tag]
+ [--lowercase|l] [--underscore|u] [--utftag|U] [--year|y year-tag]
+ [--dirtemplate '\"\$parameters\"'] [--tracktemplate '\"\$parameters\"']
+ [--cddbserver|C server] [--mirror|m mirror] [--protocol|L level]
+ [--proxy|P path] [--transfer|t cddb or http] [--mail|M address]
+ [--submission|s] [--interaction|i] [--nice|n adjustment] [--halt]
+ [--eject|e] [--help|h] [--lcd] [--lcdhost host] [--lcdport port]
+ [--sshlist remote machines] [--local] [--scp] [--config] [--save]
+ [--savenew] [--archive|a] [--playlist|p] [--quiet|Q] [--chars|W]
+ [--version|V] [--rip] [track_selection]
+\n
+For general usage information type:\n
+ ripit --help | less\n
+or try to run\n
+ ripit\n
+without any options.
+\n";
+ exit 1;
+}
+#
+# Evaluate the command line parameters if passed. We need to do it this
+# way, because passed options have to be saved (in case if user wants to
+# save them) before config file is read to prevent overriding passed
+# options with options from config file. And the passed options shall be
+# stronger than the config file options!
+# Problems arrise wiht options that can be zero, because zero is equal
+# to undef! As one can not distinguish between zero or undef, test it
+# if option has a digit in!
+#
+# First for the normal options.
+$bitrate = $pbitrate if($pbitrate);
+$maxrate = $pmaxrate if($pmaxrate);
+# @coder will be done in the subroutine!
+$faacopt = $pfaacopt if($pfaacopt);
+$flacopt = $pflacopt if($pflacopt);
+$lameopt = $plameopt if($plameopt);
+$oggopt = $poggopt if($poggopt);
+#
+# Because we change $CDDB_HOST save default in $DCDDB_HOST
+$CDDB_HOST = $PCDDB_HOST if($PCDDB_HOST);
+$DCDDB_HOST = $CDDB_HOST;
+$cddev = $pcddev if($pcddev);
+$commentag = $pcommentag if($pcommentag);
+$dirtemplate = $pdirtemplate if($pdirtemplate);
+$field = $pfield if($pfield =~ /^\d/);
+$genre = $pgenre if($pgenre);
+$halt = $phalt if($phalt);
+$lcdhost = $plcdhost if($plcdhost);
+$lcdport = $plcdport if($plcdport);
+$mirror = $pmirror if($pmirror);
+$mailad = $pmailad if($pmailad);
+$nice = $pnice if($pnice =~ /^\d/);
+$outputdir = $poutputdir if($poutputdir);
+$parano = $pparano if($pparano =~ /^\d/);
+$preset = $ppreset if($ppreset);
+$proto = $pproto if($pproto);
+$proxy = $pproxy if($pproxy);
+$ripper = $pripper if($pripper =~ /^\d/);
+$ripopt = $pripopt if($pripopt);
+$scp = $pscp if($pscp =~ /^\d/);
+# $psshlist will be done in the subroutine!
+$transfer = $ptransfer if($ptransfer);
+$tracktemplate = $ptracktemplate if($ptracktemplate);
+$vbrmode = $pvbrmode if($pvbrmode);
+$year = $pyear if($pyear);
+# And for the negatable options.
+$archive = $parchive if($parchive =~ /^\d/);
+$chars = $pchars if($pchars =~ /^\d/);
+$config = $pconfig if($pconfig =~ /^\d/);
+$encode = $pencode if($pencode =~ /^\d/);
+$eject = $peject if($peject =~ /^\d/);
+$interaction = $pinteraction if($pinteraction =~ /^\d/);
+$lcd = $plcd if($plcd =~ /^\d/);
+$local = $plocal if($plocal =~ /^\d/);
+$lowercase = $plowercase if($plowercase =~ /^\d/);
+$multi = $pmulti if($pmulti =~ /^\d/);
+$playlist = $pplaylist if($pplaylist =~ /^\d/);
+$quiet = $pquiet if($pquiet =~ /^\d/);
+$rip = $prip if($prip =~ /^\d/);
+$submission = $psubmission if($psubmission =~ /^\d/);
+$underscore = $punderscore if($punderscore =~ /^\d/);
+$utftag = $putftag if($putftag =~ /^\d/);
+$wav = $pwav if($pwav =~ /^\d/);
+#
+# Do some checks before writing the config file.
+#
+if($help != 1 && $printver != 1) {
+ &check_coder(); # Check encoder array.
+ &check_quality(); # Check if quality is valid.
+ &check_host(); # Check if host is valid.
+ &check_proto(); # Check if protocol level is valid.
+ &check_sshlist(); # Check list of remote machines.
+ &check_preset() if($preset);# Check preset settings.
+#
+# To be able to overwrite the config file we have to write it before...
+#
+ &save_config() if($savenew == 1);
+#
+# ...reading the parameters not yet passed from the config file.
+#
+ &read_config() if($config == 1);
+ &save_config() if($savepara == 1);
+ &check_host(); # Do it again to concatenate mirror.host.
+ &check_coder(); # Check it again for lame cbr vs vbr.
+ &check_sshlist(); # Check it again to create the hash.
+}
+#
+#
+########################################################################
+#
+# MAIN ROUTINE
+#
+########################################################################
+#
+
+$logger = "/tmp/ripit.log";
+system("echo 'AudioCD rip process started....' > $logger");
+
+#system("touch /tmp/ripit.process >/dev/null 2>&1");
+
+if ( length($ejectcmd) > 0) {
+ system("$ejectcmd $cddev");
+ sleep 10;
+ system("$ejectcmd -t $cddev");
+ sleep 20;
+}
+
+print "\nRipIT Version $version beta 20050805\n" if($quiet == 0);
+if($printver) {
+ print "\n";
+ exit 2;
+}
+
+if($help == 1) {
+ &print_help();
+ exit 3;
+}
+
+if($lcd == 1) { # lcdproc
+ &init_lcd();
+}
+
+if(($outputdir eq "") && ($output eq "")) {
+ $outputdir = $homedir;
+ chomp $outputdir;
+}
+
+if(($outputdir eq "") && !($output eq "")) {
+ $outputdir = $output;
+ chomp $outputdir;
+}
+
+if($outputdir =~ /^\.\//){ # Change relative paths to full paths
+ $outputdir =~ s/^\./$workdir/;
+}
+
+system("echo 'Ausgabeverzeichnis : $outputdir' >>$logger");
+system("echo 'Auslesegeraet : $cddev' >>$logger");
+system("echo '' >>$logger");
+
+if($cddev eq "") { # Check CD dev if none defined.
+ &check_cddev;
+}
+
+
+
+if(length($year) > 0 && length($year) != 4 ) {
+ print STDERR "Warning: year is not Y2K compliant - $year\n" if($quiet == 0);
+ system("echo 'Warnung: Jahr ist nicht Y2K sicher - $year' >>$logger");
+
+}
+
+if($halt == 1 && $quiet == 0) {
+ print "Will halt machine when finished.\n";
+ system("echo 'Computer wird nach Vorgang heruntergefahren' >>$logger");
+}
+
+if($eject == 1 && $quiet == 0) {
+ print "Will eject CD when finished.\n";
+ system("echo 'CD wird nach Rippen ausgeworfen' >>$logger");
+
+}
+
+if($playlist == 0 && $quiet == 0) {
+ print "Won't create a m3u file.\n";
+ system("echo 'Playliste wird nicht erstellt' >>$logger");
+
+}
+
+if($utftag == 0 && $quiet == 0) {
+ print "Will change encoding of Lame-tags to ISO8859-1.\n";
+}
+
+if($wav == 1 && $quiet == 0) {
+ print "Will keep the wav files.\n";
+ system("echo 'Wav Dateien werden nicht automatisch geloescht' >>$logger");
+
+}
+
+if($ARGV[0] ne '') { # Get track parameter if given.
+ $trackselection = $ARGV[0];
+}
+
+if($bitrate != 0 && $lameflag == 1) { # Check bitrate for Lame.
+ &check_bitrate;
+}
+
+if($vbrmode ne "" && $lameflag == 1) { # Check for vbr in Lame.
+ &check_vbrmode;
+}
+
+if($preset) {
+ &lame_preset;
+}
+
+&get_cdinfo(); # Extract CD info from CDDB toc.
+&create_seltrack($trackselection); # Create track selection.
+&create_dirs(); # Create directories MP3 files.
+&rip_cd(); # Rip, Encode & Tag.
+
+if($eject == 1) {
+ system "eject $cddev";
+}
+
+if($quiet == 0) {
+ print "Waiting for Encoder to finish...\n";
+ system("echo 'Warte auf Ende von Encoder...' >>$logger");
+
+}
+
+if($sshflag == 1) {
+ &del_wav();
+}
+else {
+ wait;
+}
+
+if($playlist == 1) { # Create m3u file if specified.
+ &create_m3u();
+}
+
+&del_erlog();
+&cal_times();
+
+if(-r "$mp3dir/error.log") {
+ print "\nCD may NOT be complete! Check the error.log in $mp3dir!\n\n" if($quiet == 0);
+ system("echo ' ' >>$logger");
+ system("echo 'Vorgang abgebrochen -> error.log in $mp3dir' >>$logger");
+ system("$svdrpcmd MESG 'RIPIT: VORGANG ABGEBROCHEN !'");
+}
+else {
+ print "\nAll complete!\nRipping needed $riptime min and encoding needed $enctime min.\n\n" if($quiet == 0);
+ system("echo ' ' >>$logger");
+ system("echo '!! DONE... !! VORGANG BEENDET.' >>$logger");
+ system("echo ' ' >>$logger");
+ system("echo 'Rippen : $riptime min' >>$logger");
+ system("echo 'Encoding: $enctime min' >>$logger");
+ system("$svdrpcmd MESG 'RIPIT: VORGANG FERTIG !'");
+
+}
+
+if($lcd == 1) { # lcdproc
+ $lcdline1 = " ";
+ $lcdline2 = " RipIT finished ";
+ $lcdline3 = " ";
+ &ulcd();
+ close($lcdproc) || die "close: $!";
+}
+
+system("/bin/rm -f /tmp/ripit.process");
+
+if($halt == 1 && $quiet == 0) { # Halt when finished.
+ print "\nShutdown PC...\n";
+ system("echo '\n\n!! COMPUTER WIRD HERUNTERGEFAHREN !!' >>$logger");
+ system("shutdown -h now");
+}
+
+if($multi == 1) {
+ open(SRXY,">>$logfile") or print "Can not append to file \"$logfile\"!";
+ print SRXY "\nEncoding ended: $encend";
+ close(SRXY);
+ open(SUCC,">>$logpath/success.log") or print "Can not append to file \"$logpath/succes.log\"!";
+ print "All Complete in $cddev with $artist: $album.\n";
+ print SUCC "$artist;$album;$cddbid;$logfile;$hostnam;$riptime;$enctime\n";
+ close(SUCC);
+}
+
+exit;
+
+
+########################################################################
+#
+# SUBROUTINES
+#
+########################################################################
+
+########################################################################
+#
+# Read the Album, Artist, DiscID and Track Titles from the get_CDDB()
+# generated TOC file.
+#
+sub get_cdinfo {
+ my %config;
+
+ # Get number of ID and number of tracks of CD.
+ my $cd = get_discids($cddev);
+ my ($id,$toc) = ($cd->[0], $cd->[2]);
+ $tracks = $cd->[1];
+ $cddbid = sprintf("%08x", $id);
+
+ my $count = 1;
+ my $usearch = "x";
+ if($archive == 1 && $multi == 0) {
+ print "\nChecking for a CDDB entry \@ local machine, please wait a second...\n\n" if($quiet == 0);
+ system("echo 'Suche CDDB Eintrag..., bitte warten...' >>$logger");
+ system("mkdir -m 0777 -p $homedir/.cddb") && \
+ die "Cannot create directory $homedir/.cddb: $!"||system("echo 'Kann Verzeichnis $homedir/.cddb nicht erstellen...' >>$logger");
+ opendir(CDDB, "$homedir/.cddb/") || print "Can not read in $homedir/.cddb: $!";
+ my @categs = grep {/\w/i} readdir(CDDB);
+ close CDDB;
+ my @cddbid = ();
+ foreach (@categs) {
+ if(-d "$homedir/.cddb/$_") {
+ opendir(CATEG, "$homedir/.cddb/$_") || print "Can not read in $homedir/.cddb: $!";
+ my @entries = grep {/$cddbid/} readdir(CATEG);
+ close CATEG;
+ push @cddbid, $_ if($entries[0]);
+ }
+ elsif(-f "$homedir/.cddb/$_") {
+ push @cddbid, $_ if($_ =~ /$cddbid/);
+ }
+ }
+ if($cddbid[0]) {
+ print "Found entry $cddbid in $homedir/.cddb on this machine!\n" if($interaction == 1);
+ print "This CD could be:\n\n" if($interaction == 1);
+ system("echo 'CDDB Eintrag gefunden : $cddbid' >>$logger");
+ foreach (@cddbid) {
+ my $openflag="no";
+ if(-r "$homedir/.cddb/$_/$cddbid") {
+ open(LOG, "$homedir/.cddb/$_/$cddbid");
+ $openflag = "ok";
+ }
+ elsif(-r "$homedir/.cddb/$cddbid") {
+ open(LOG, "$homedir/.cddb/$cddbid");
+ $_ = "none";
+ $openflag = "ok";
+ }
+ if($openflag == "ok") {
+ my @loglines = <LOG>;
+ close(LOG);
+ my @artist = grep(s/^DTITLE=//, @loglines);
+ $artist = @artist[0];
+ $artist =~ s/[\015]//g;
+ chomp $artist;
+ my @genre = grep(s/^DGENRE=//, @loglines);
+ my $agenre = @genre[0];
+ $agenre =~ s/[\015]//g;
+ chomp $agenre;
+ print "$count: $artist ($agenre) in category: $_\n" if($interaction == 1);
+ $count++;
+ $agenre = "";
+ }
+ }
+ print "\n0: Use online CDDB instead!\n" if($interaction == 1);
+ if($interaction == 0) {
+ $usearch = 1;
+ }
+ else {
+ while($usearch !~ /\d/ || $usearch >= $count) {
+ print "\nChoose: (1) ";
+ $usearch = <STDIN>;
+ chomp $usearch;
+ $usearch = 1 if($usearch eq "");
+ }
+ }
+ }
+ else {
+ $usearch = 0;
+ }
+ if($usearch != 0) {
+ &read_entry("$homedir/.cddb/$cddbid[$usearch-1]/$cddbid",$cddbid[$usearch-1],$tracks);
+ }
+ }
+ else {
+ $usearch = 0;
+ }
+
+ if($usearch == 0) {
+ print "\nChecking for a CDDB entry \@ $CDDB_HOST, please wait a second...\n" if($quiet == 0);
+ system("echo 'Suche CDDB Eintrag \@ $CDDB_HOST' >>$logger");
+ #Configure CDDB_get parameters
+ $config{CDDB_HOST} = $CDDB_HOST;
+ while($transfer !~ /^cddb$|^http$/) {
+ print "Transfer mode not valid!\n";
+ system("echo 'Transfermodus nicht gestattet' >>$logger");
+ print "Enter cddb or http : ";
+ $transfer = <STDIN>;
+ chomp $transfer;
+ }
+ if($transfer eq "cddb") {
+ $CDDB_PORT = 8880;
+ $CDDB_MODE = "cddb";
+ }
+ elsif($transfer eq "http") {
+ $CDDB_PORT = 80;
+ $CDDB_MODE = "http";
+ }
+ $config{CDDB_MODE} = $CDDB_MODE;
+ $config{CDDB_PORT} = $CDDB_PORT;
+ $config{CD_DEVICE} = $cddev;
+ $config{HTTP_PROXY}= $proxy if($proxy);
+ if($multi == 1) {
+ unless($field) {
+ $field = 1;
+ }
+ if($field == 0) {
+ $field = 1;
+ }
+ $config{entry} = $field;
+ }
+ if($interaction == 0) {
+ $CDDB_INPUT = 0;
+ }
+ else {
+ $CDDB_INPUT = 1;
+ }
+ $config{input} = $CDDB_INPUT;
+ $config{PROTO_VERSION} = $proto;
+ #Change to whatever, but be aware to enter exactly 4 words!
+ #E.g. username hostname clientname version
+ $config{HELLO_ID} = "RipIT www.suwald.com/ripit/ripit.html RipIT $version";
+
+ eval {%cd = get_cddb(\%config);};
+ if($@) {
+ print "No connection to internet?\n" if($quiet == 0);
+ system("echo 'Keine Verbindung zum Internet' >>$logger");
+ $submission = 0;
+ }
+ }
+
+ # Write CDDB entry to ~/.cddb/category if there is not already
+ # an entry present (then $usearch != 0).
+ if($archive == 1 && $usearch == 0) {
+ $categ = $cd{cat};
+ chomp $categ;
+ system("mkdir -m 0777 -p $homedir/.cddb/$categ/") && die "Cannot create directory $homedir/.cddb/$categ: $!\n";
+ open(TOC, "> $homedir/.cddb/$categ/$cddbid") || print "Can not write to $homedir/.cddb/$categ/$cddbid: $!";
+ foreach (@{$cd{raw}}) {
+ print TOC $_;
+ }
+ close TOC;
+ }
+
+ if($multi == 1) {
+ my @devnameblock = split(/\//, $cddev);
+ $logfile = $devnameblock[$#devnameblock];
+ &read_entry($logfile);
+ }
+# $artist =~ s/[:*#?$\!]//g if($chars == 0);# Strip dodgey chars
+
+ if(defined $cd{title}) {
+ $artistag = $cd{artist};
+ $albumtag = $cd{title};
+ $artistag =~ s/[;|><"\015]//g; # Strip dodgey chars
+ $albumtag =~ s/[;|><"\015]//g; # Strip dodgey chars
+ $artistag =~ s/`/'/g;
+ $albumtag =~ s/`/'/g;
+ $artist = $artistag;
+ $artist = lc($artist) if($lowercase == 1);
+ $artist =~ s/ /_/g if($underscore == 1);
+ $album = $albumtag;
+ $album = lc($album) if($lowercase == 1);
+ $album =~ s/ /_/g if($underscore == 1);
+ $artist =~ s/[:*#?$\!]//g if($chars == 0); # Strip dodgey chars
+ $album =~ s/[:*#?$\!]//g if($chars == 0); # Strip dodgey chars
+ $artist =~ s/[*]//g; # Strip dodgey chars
+ $album =~ s/[*]//g; # Strip dodgey chars
+ $artist =~ s/\// - /g;
+ $album =~ s/\// - /g;
+ $dtitle = $artistag . " / " . $albumtag;
+ $categ = $cd{cat};
+ # Set the year if it wasn't passed on command line.
+ if($year eq "") {
+ $year = $cd{year};
+ $year =~ s/[\015]//g;
+ }
+ # Set the genre if it wasn't passed on command line.
+ # Change the $cddbgenre flag to 1: genre is from CDDB.
+ if($genre eq "" && defined $cd{genre} && $multi == 0) {
+ $genre = $cd{genre};
+ $genre =~ s/[\015]//g;
+ $cddbgenre = 1;
+ }
+ my @revision = grep(/^\#\sRevision:\s/, @{$cd{raw}});
+ @revision = grep(s/^\#\sRevision:\s//, @revision);
+ $revision = @revision[0];
+ chomp $revision;
+ # Now extract the disk comment lines EXTD
+ # NOTE: Each EXTD line my have \n's, but two EXTD lines do
+ # NOT mean that there's a linebreak in between! So, what we
+ # have to do is, put all comment lines into a string and
+ # split the string according to the \n's. But because I don't
+ # like the \n in lines, RipIT will break them and add a \n at
+ # the end of each line!
+ @comment = grep(/^EXTD=/, @{$cd{raw}});
+ @comment = grep(s/^EXTD=//, @comment);
+ # clean the comments
+ foreach (@comment) {
+ chomp $_;
+ $_ =~ s/[\015]//g;
+ }
+ my $line = "@comment";
+ $line =~ s/[\015]//g;
+ @commentblock = split(/\\n/, $line);
+ foreach (@commentblock) {
+ chomp $_;
+ $_ =~ s/^\s//g;
+ }
+ # Now extract the track comment lines EXTT
+ @trackcom = grep(/^EXTT\d+=/, @{$cd{raw}});
+ @trackcom = grep(s/^EXTT\d+=//, @trackcom);
+ foreach (@trackcom) {
+ chomp $_;
+ $_ =~ s/[\015]//g;
+ }
+ # and extract the playorder line.
+ my @playorder = grep(/^PLAYORDER=/, @{$cd{raw}});
+ @playorder = grep(s/^PLAYORDER=//, @playorder);
+ $playorder = @playorder[0];
+ chomp $playorder;
+ $nocddbinfo = 0; # Got CDDB info OK
+ }
+ else {
+ if($submission == 0) {
+ print "\nNo CDDB info choosen or found for this CD\n" if($quiet == 0);
+ system("echo 'Keinen CDDB Eintrag gefunden' >>$logger");
+
+ }
+ # Set submission OK, will be set to zero if default
+ # names are used.
+ $cddbsubmission = 1;
+ # Don't ask for default settings, use them! ...
+ if($interaction == 0) {
+ &create_deftrack(1);
+ }
+ # ... or ask whether 1) default or 2) manual entries
+ # shall be used or entered.
+ else {
+ &create_deftrack(2);
+ }
+ }
+ if($genre ne "" && $multi == 0) {
+ &check_genre();
+ }
+ # What if someone wants underscore and/or lowercase in filenames
+ # and has genre in the dir or tracktemplate? So we have to
+ # lowercase genre and underscore it if it is a 2 word expression.
+ if(($dirtemplate =~ /\$genre/ or $tracktemplate =~ /\$genre/) && $genre ne "") {
+ my $tempgenre = $genre;
+ $tempgenre = lc($tempgenre) if($lowercase == 1);
+ if($genre =~ /\w\s\w/ && $underscore == 1) {
+ $tempgenre =~ s/ /_/g;
+ # Do it the hard way: assume we have the definitive
+ # genre, so replace the string "$genre" with the
+ # value of $tempgenre!
+ $dirtemplate =~ s/\$genre/$tempgenre/g;
+ $tracktemplate =~ s/\$genre/$tempgenre/g;
+ }
+ }
+
+ if($multi == 1) {
+ `sed "2 a Artist - Album:$artist - $album" $logfile > $logfile.new `;
+ rename("$logfile.new","$logfile");
+ unlink("$logfile.new");
+ }
+
+ if($quiet == 0) {
+ print "\n-----------------";
+ system("echo '--------------------' >>$logger");
+ print "\nCDDB and ID3 Info";
+ system("echo 'CDDB und ID3 Info' >>$logger");
+ print "\n-----------------\n";
+ system("echo '--------------------' >>$logger");
+ print "Artist: $artistag\n";
+ system("echo 'Artist: $artistag' >>$logger");
+ print "Album: $albumtag\n";
+ system("echo 'Album: $albumtag' >>$logger");
+ print "Category: $categ\n";
+ system("echo 'Kategorie: $categ' >>$logger");
+ print "ID3-Genre: $genre ($genreno)\n";
+ system("echo 'Genre: $genre' >>$logger");
+ if(lc($genre) ne lc($cd{'genre'})) {
+ print "CDDB-Genre: $cd{'genre'}\n";
+ }
+ print "Year: $year\n";
+ system("echo 'Jahr: $year' >>$logger");
+ print "Revision: $revision\n";
+ # It happens, that the ID from CDDB is NOT
+ # identical to the ID calculated from the
+ # frames of your CD...
+ if($cddbid ne $cd{id} && defined $cd{id} ) {
+ print "CDDB id: $cd{id}\n";
+ }
+ print "CD id: $cddbid\n";
+ system("echo 'CD id: $cddbid' >>$logger");
+ if(defined @commentblock) {
+ foreach (@commentblock) {
+ print "Comment: $_\n";
+ system("echo 'Kommentar: $_\n' >>$logger");
+ }
+ }
+ print "\n";
+
+ }
+ # Read out pregap before calculating track lengths.
+ my $frames = $toc->[0]->{'frames'};
+ push @framelist, "$frames";
+ my $n = 1;
+ # Now print track infos.
+ foreach (@{$cd{track}}) {
+ $_ =~ s/`/'/g; # Change ` to ' to avoid problems later
+ $_ =~ s/[;|><"\015]//g;
+ push @tracktags, $_;
+ # Get frames and total time.
+ my $frames = $toc->[$n]->{'frames'};
+ push @framelist, "$frames";
+ $frames = $frames - $framelist[$n-1];
+ my $second = int($frames/75);
+ push @secondlist, "$second";
+ my $frame = $frames - $second * 75;
+ my $minute = int($second/60);
+ $second = $second - $minute * 60;
+ printf("%02d: [%02d:%02d.%02d] %s\n", $n, $minute, $second, $frame, $_) if($quiet == 0);
+ $_ =~ s/[:*#?$\!]//g if($chars == 0);
+ $_ =~ s/[*]//g;
+ $_ =~ s/\//-/g; # Change / to - to avoid problems later
+ $_ = lc($_) if($lowercase == 1);
+ $_ =~ s/ /_/g if($underscore == 1);
+ push @tracklist, $_;
+ $n++;
+ }
+ # Get total length from last entry.
+ $min = $toc->[$n-1]->{min};
+ $sec = $toc->[$n-1]->{sec};
+ $totals = $sec + 60 * $min;
+ print "\n\n" if($quiet == 0);
+
+ # Some more error checking.
+ if(($seltrack[0] - 1) > $#tracklist) {
+ die "Starting track is higher than number of tracks on CD!";
+ }
+ if($artist eq "") {
+ die "TOC ERROR: No Artist Found";
+ }
+
+ # lcdproc
+ if($lcd == 1){
+ $lcdline1 = $artist."-".$album;
+ $lcdline2 = "R00|00.0%|----------";
+ $lcdline3 = "E00|00.0%|----------";
+ &ulcd();
+ }
+}
+########################################################################
+#
+# Create the track selection from the parameters passed on the command-
+# line.
+#
+sub create_seltrack {
+ my($i,$tempstr,$intrack);
+ ($tempstr) = @_;
+ if(($tempstr =~ /,/) || ($tempstr =~ /\-/)) {
+ @intrack = split(/,/ , $tempstr);
+# If last character is a , add an other item with a -
+ if($tempstr =~ /,$/) {
+ push @intrack,($intrack[$#intack]+1) . "-";
+ }
+ foreach $intrack (@intrack) {
+ if($intrack =~ /\-/) {
+ @outrack = split(/-/ , $intrack);
+# If last character is a -, add last track to $outrack
+ if($#outrack == 0) {
+ $outrack[1] = $#tracklist + 1;
+ }
+ for($i = $outrack[0]; $i <= $outrack[1]; $i++) {
+ push @seltrack,$i;
+ }
+ }
+ else {
+ push @seltrack,$intrack;
+ }
+ }
+ }
+ elsif($tempstr eq '') {
+ for($i = 1; $i <= ($#tracklist + 1); $i++) {
+ $seltrack[$i - 1] = $i;
+ }
+ }
+ elsif($tempstr =~ /^[0-9]*[0-9]$/) {
+ $seltrack[0] = $tempstr;
+ }
+ else {
+ die "Track selection invalid";
+ }
+
+ # Sort the tracks in order, perl is so cool :-)
+ @seltrack = sort {$a <=> $b} @seltrack;
+
+ # Check the validaty of the track selection.
+ foreach (@seltrack) {
+ if($_ > ($#tracklist + 1)) {
+ die "Track selection higher than no of tracks";
+ }
+ }
+}
+########################################################################
+#
+# Ask if CDDB submission shall be done because one might change some
+# settings a last time before writing to directories and files! Then
+# create the directory where the flac, mp3 or ogg files will go.
+# Fail if directory exists or can't be created.
+#
+sub create_dirs {
+ # Directory created will be: /outputdir/$dirtemplate
+
+ my $index = 2;
+ unless($cddbsubmission == 0 || $interaction == 0) {
+ while($index !~ /^[0-1]$/) {
+ if(defined $cd{title}) {
+ print "\nDo you want to edit the CDDB entry? Try it, it's easy!\n\n";
+ }
+ else {
+ print "\nDo you want to submit your entries to the CDDB?";
+ print "\nYou're almost there, just type Enter at each question!\n\n";
+ }
+ print "1: Yes, and I know about the naming-rules of freedb.org \n\n";
+ print "0: No\n\nChoose [0-1]: (0) ";
+ $index = <STDIN>;
+ chomp $index;
+ if($index eq "") {
+ $index = 0;
+ }
+ print "\n";
+ }
+ if($index == 1) {
+ if($revision ne "") {
+ print "\nPlease change some settings!";
+ print "\nYou may confirm all CDDB settings with Enter!\n";
+ $revision++;
+ &create_deftrack(0);
+ }
+ else{
+ $revision = 0;
+ }
+ }
+ elsif($index != 0) {
+ print "You should choose 0 or 1!\n";
+ }
+ }
+ if($index == 1) {
+ &pre_subm();
+ }
+
+ # Now check and create the full path "mp3dir" where the files
+ # will go. First Check the dirtemplate and use the actual year
+ # as default if none is given!
+ if(($dirtemplate =~ /\$year/ || $tracktemplate =~ /\$year/) && $year eq "") {
+ $year = `date \'+%Y\'`;
+ chomp $year;
+ }
+ if(($dirtemplate =~ /\$genre/ || $tracktemplate =~ /\$genre/) && $genre eq "") {
+ $genre = Unknown;
+ chomp $genre;
+ }
+ if(!eval("\$dir = $dirtemplate")) {
+ die "Directory Template incorrect, caused eval to fail: $!";
+ }
+
+ $dir = lc $dir if($lowercase == 1);
+ $dir =~ s/ /_/g if($underscore == 1);
+
+ $mp3dir = $outputdir."/".$dir;
+ # Delete ending . in directory name if no special characters
+ # wanted!
+ $mp3dir =~ s/[.]+$// if($chars == 0);
+ # Now check if the outputdir alread exists, if it does, try
+ # "outputdir i" with i an integer until it works.
+ my $i=1;
+ my $nmp3dir = $mp3dir;
+ if($multi == 0) {
+ while(defined(opendir(TESTDIR, $nmp3dir)) && $rip == 1) {
+ $nmp3dir = $mp3dir." ".$i if($underscore == 0);
+ $nmp3dir = $mp3dir."_".$i if($underscore == 1);
+ $i++;
+ }
+ }
+ else {
+ if(defined(opendir(TESTDIR, $mp3dir))) {
+ # Delete error.log now, else the next device will
+ # start to encode!
+ if(-r "$mp3dir/error.log") {
+ print "Found an orfand error.log in $mp3dir.\n";
+ unlink("$mp3dir/error.log");
+ }
+ `echo " " >> $logfile`;
+ `echo "The directory $mp3dir is already present!" >> $logfile`;
+ # We supposed it would be better to write into the same
+ # directory, if identical CDDB entry for another CD found.
+ # But there are plenty of Compilations with more than one
+ # disc which have all the same title...
+ while(defined(opendir(TESTDIR, $nmp3dir))) {
+ $nmp3dir = $mp3dir." ".$i if($underscore == 0);
+ $nmp3dir = $mp3dir."_".$i if($underscore == 1);
+ $i++;
+ }
+ if(-r "$nmp3dir/error.log") {
+ print "Found an orfand error.log in $nmp3dir.\n";
+ unlink("$nmp3dir/error.log");
+ }
+ $i--;
+ `sed '3 s/\$/ $i/' $logfile > $logfile.new ` if($underscore == 0);
+ `sed '3 s/\$/_$i/' $logfile > $logfile.new ` if($underscore == 1);
+ rename("$logfile.new","$logfile");
+ unlink("$logfile.new");
+ }
+ my @logpath = split(/\//, $mp3dir);
+ pop(@logpath);
+ pop(@logpath);
+ $logpath = join('/',@logpath);
+ }
+ $mp3dir = $nmp3dir."/";
+
+ if(!opendir(TESTDIR, $mp3dir)) {
+ system("mkdir -m 0777 -p \"$mp3dir\"") && \
+ die "Cannot create directory $mp3dir: $!";
+ }
+ else {
+ closedir(TESTDIR);
+ }
+}
+########################################################################
+#
+# Create the track file name from the tracktemplate variable.
+#
+sub get_trackname {
+ my($trnum,$trname,$riptrname);
+
+ ($trnum,$trname) = @_;
+
+ # Create the full file name from the track template, unless
+ # the disk is unknown.
+ if($nocddbinfo == 0) {
+ # We do not need to lowercase the tracktemplate, because
+ # all variables in are already lowercased!
+ $tracktemplate =~ s/ /\\_/g if($underscore == 1);
+ # We have to update tracknum and trackname because they
+ # are evalueted by the tracktemplate!
+ $tracknum = sprintf("%02d",$trnum);
+ $trackname = $trname;
+ $trackname =~ s/[:*#?$\!\"\']//g if($chars == 0); # Strip dodgey chars
+ if(!eval("\$riptrname = \$mp3dir.$tracktemplate")) {
+ die "Track Template incorrect, caused eval to fail: $!";
+ }
+ }
+ else {
+ $trname = lc $trname if($lowercase == 1);
+ $trname =~ s/ /_/g if($underscore == 1);
+ $riptrname = $mp3dir.$trname;
+ }
+
+ return $riptrname;
+}
+########################################################################
+#
+# Rip the CD.
+#
+sub rip_cd {
+ my($shortname,@shortname,$startenc,$trackcn);
+
+ if($#seltrack == 0) {
+ print "Track @seltrack will be ripped!\n\n" if($quiet == 0);
+ system("echo 'Track @seltrack wird ausgelesen\n\n' >>$logger");
+
+ }
+ else {
+ print "Tracks @seltrack will be ripped!\n\n" if($quiet == 0);
+ system("echo 'Tracks @seltrack werden ausgelesen\n\n' >>$logger");
+
+ }
+ $trackcn = 0;
+
+ $ripstart = `date \'+%R\'`;
+ chomp $ripstart;
+
+ if($multi == 1) {
+ open(SRXY,">>$logfile") or print "Can not append to file \"$logfile\"!";
+ print SRXY "\nRipping started: $ripstart";
+ close(SRXY);
+ }
+
+ system("echo 'Rippen gestartet' >>$logger");
+
+ foreach (@seltrack) {
+ $trackcn++;
+ $riptrackname = &get_trackname($_, $tracklist[$_ - 1]);
+ $riptrackno = $_;
+ @shortname = split(/\// , $riptrackname);
+ $shortname = $shortname[$#shortname];
+ print "Ripping \"$shortname\"...\n" if($quiet == 0);
+ $shortname =~ s/[:*#?$\!\"\']//g if($chars == 0); # Strip dodgey chars
+ system("echo 'Ripper : \"$shortname\".....' >>$logger");
+ # lcdproc
+ if($lcd == 1){
+ $_lcdtracks = scalar @seltrack;
+ $lcdtrackno++;
+ if($_lcdtracks eq $lcdtrackno) {
+ $lcdperc = "*100";
+ }
+ else {
+ $lcdperc = sprintf("%04.1f",$lcdtrackno/$_lcdtracks*100);
+ }
+ $lcdline2=~ s/\|\d\d.\d/\|$lcdperc/;
+ $lcdtracknoF = sprintf("%02d",$lcdtrackno);
+ $lcdline2=~ s/\R\d\d/\R$lcdtracknoF/;
+ substr($lcdline2,10,10) = substr($shortname,3,13);
+ &ulcd();
+ }
+ # There is a problem with too long file names,
+ # encountered e.g. with some classical CDs.
+ # Cdparanoia cuts the length, cdda2wav too...
+ # but how should RipIT know?
+ # Use a shorter track name if total length (incl.
+ # path) > 230 characters.
+ if(length($riptrackname) > 230) {
+ $riptrackname = &get_trackname($_,$_."short");
+ }
+ # Choose the cdaudio ripper to use
+ #
+ # TODO: Check behaviour of all rippers when data track
+ # encountered. Choose to use print instead of die if
+ # ripper stops itself!
+ # dagrab fails @ data-track, so don't die! and create an error.log
+ # cdparanoia fails @ data-track, so don't die! and create an error.log
+ # cdda2wav prints errors @ data-track, therefore die!
+ if($ripper == 0 && $rip == 1) {
+ if($trackcn == 1) {
+ $ripopt = $ripopt . " -r 3" if($parano == 1);
+ $ripopt = $ripopt . " -v" if($quiet == 0);
+ }
+ if(system("(dagrab $ripopt -d $cddev -f \"$riptrackname.rip\" $riptrackno 3>&1 1>&2 2>&3 | tee -a \"$mp3dir/error.log\" ) 3>&1 1>&2 2>&3 ")) {
+ print "Dagrab detected some read errors on $tracklist[$_ - 1]\n\n";
+ # Create error message in CD-directory for encoder: don't wait.
+ open(ERO,">>$mp3dir/error.log") or print "Can not append to file \"$mp3dir/error.log\"!";
+ print ERO "\nDagrab detected some read errors at $riptrackno on CD $artist - $album, do not worry!";
+ close(ERO);
+ }
+ print "\n";
+ }
+ elsif($ripper == 1 && $rip == 1) {
+ if($trackcn == 1) {
+ $ripopt = $ripopt . " -Z" if($parano == 1);
+ $ripopt = $ripopt . " -q" if($quiet == 1);
+ }
+ if($multi == 0) {
+ if(system("cdparanoia $ripopt -d $cddev $riptrackno \"$riptrackname.rip\"")) {
+ print "cdparanoia failed on $tracklist[$_ - 1]\n\n";
+ # Create error message in CD-directory for encoder: don't wait.
+ system("echo 'cdparanoia fehlgeschlagen! Track [$_ - 1]' >>$logger");
+
+ open(ERO,">>$mp3dir/error.log") or print "Can not append to file \"$mp3dir/error.log\"!";
+ print ERO "\nTrack $riptrackno on CD $artist - $album failed!";
+ close(ERO);
+ }
+ }
+ elsif($multi == 1) {
+ $ripopt = $ripopt . " -X" if($trackcn == 1);
+ if(system("cdparanoia $ripopt -d $cddev $riptrackno \"$riptrackname.rip\" 2>> \"$logfile.$riptrackno.txt\"")) {
+ # Apend error message to file srXY for rip2m to start checktrack.
+ open(SRXY,">>$logfile") or print "Can not append to file \"$logfile\"!";
+ print SRXY "\ncdparanoia failed on $tracklist[$_ - 1] in device $cddev";
+ close(SRXY);
+ # Create error message in CD-directory for encoder: don't wait.
+ open(ERO,">>$mp3dir/error.log") or print "Can not append to file \"$mp3dir/error.log\"!";
+ print ERO "Track $riptrackno on CD $artist - $album failed!\n";
+ close(ERO);
+ # Kill failed CD only if it is not the last track. Last track may be data/video track.
+ # I.e. print error message to file srXY.Z.txt, checktrack will grep for string
+ # "cdparanoia failed" and kill the CD immediately!
+ if($riptrackno != $seltrack[$#seltrack]) {
+ open(SRTF,">>$logfile.$riptrackno.txt") or print "Can not append to file \"$logfile.$riptrackno.txt\"!";
+ print SRTF "\ncdparanoia failed on $tracklist[$_ - 1] in device $cddev, error !";
+ close(SRTF);
+ # Create on the fly error message in log-directory.
+ open(ERO,">>$logpath/failed.log") or print "Can not append to file \"$logpath/failed.log\"!";
+ print ERO "$artist;$album;$cddbid;$cddev;$hostnam\n";
+ close(ERO);
+ # Now wait to be terminated by checktrack.
+ sleep 360;
+ exit;
+ }
+ }
+ }
+ }
+ elsif($ripper == 2 && $rip == 1) {
+ if($trackcn == 1) {
+ $ripopt = $ripopt . " -q" if($quiet == 1);
+ }
+ if($multi == 0) {
+ if(system("cdda2wav -D $cddev -H $ripopt -t $riptrackno \"$riptrackname\_rip\"")) {
+ print "cdda2wav failed on $tracklist[$_ - 1]";
+ open(ERO,">>$mp3dir/error.log") or print "Can not append to file \"$mp3dir/error.log\"!";
+ print ERO "\nTrack $riptrackno on CD $artist - $album failed!";
+ close(ERO);
+ }
+ }
+ elsif($multi == 1) {
+ if(system("cdda2wav -D $cddev -H $ripopt -t $riptrackno \"$riptrackname\_rip\" 2>> \"$logfile.$riptrackno.txt\"")) {
+ # Apend error message to file srXY for rip2m to start checktrack.
+ open(SRXY,">>$logfile") or print "Can not append to file \"$logfile\"!";
+ print SRXY "\ncdda2wav failed on $tracklist[$_ - 1] in device $cddev";
+ close(SRXY);
+ # Create error message in CD-directory for encoder: don't wait.
+ open(ERO,">>$mp3dir/error.log") or print "Can not append to file \"$mp3dir/error.log\"!";
+ print ERO "Track $riptrackno on CD $artist - $album failed!\n";
+ close(ERO);
+ # Kill failed CD only if it is not the last track. Last track may be data/video track.
+ # I.e. print error message to file srXY.Z.txt, checktrack will grep for string
+ # "cdparanoia failed" and kill the CD immediately!
+ if($riptrackno != $seltrack[$#seltrack]) {
+ open(SRTF,">>$logfile.$riptrackno.txt") or print "Can not append to file \"$logfile.$riptrackno.txt\"!";
+ print SRTF "\ncdparanoia failed on $tracklist[$_ - 1] in device $cddev, error !";
+ close(SRTF);
+ # Create on the fly error message in log-directory.
+ open(ERO,">>$logpath/failed.log") or print "Can not append to file \"$logpath/failed.log\"!";
+ print ERO "$artist;$album;$cddbid;$cddev;$hostnam\n";
+ close(ERO);
+ # Now wait to be terminated by checktrack.
+ sleep 360;
+ exit;
+ }
+ }
+ }
+ }
+ elsif($ripper == 3 && $rip == 1) {
+ if(system("tosha -d $cddev -f wav -t $riptrackno -o \"$riptrackname.rip\"")) {
+ die "tosha failed on $tracklist[$_ - 1]";
+ }
+ }
+ elsif($ripper == 4 && $rip == 1) {
+ $cdd_dev = $cddev;
+ $cdd_dev =~ s/^\/dev\/r//;
+ $cdd_dev =~ s/c$//;
+ if(system("cdd -t $riptrackno -q -f $cdd_dev - 2> /dev/null | sox -t cdr -x - \"$riptrackname.rip\"")) {
+ die "cdd failed on $tracklist[$_ - 1]";
+ }
+ }
+ elsif($rip == 1) {
+ print "No CD Ripper defined";
+ }
+
+ # Rename rip file to a wav for encoder so that it will be picked
+ # up by the encoder background process.
+ # Cdda2wav output is not easy to handle.
+ # Everything beyond the last . has been erased.
+ if($ripper == 2) {
+ if($riptrackname =~ /\./) {
+ # And split is too clever! If a trackname
+ # ends with "name..." all points get lost,
+ # so we've to add a word at the end!
+ my $cddatrackname = $riptrackname . "end";
+ @riptrackname = split(/\./, $cddatrackname);
+ delete($riptrackname[$#riptrackname]);
+ $cddatrackname = join('.',@riptrackname);
+ rename("$cddatrackname.wav","$riptrackname.rip");
+ }
+ else {
+ rename("$riptrackname\_rip.wav","$riptrackname.rip");
+ }
+ }
+ rename("$riptrackname.rip","$riptrackname.wav");
+ unlink("$logfile.$riptrackno.txt") if($multi == 1);
+# print "Rip complete $tracklist[$_ - 1]\n\n";
+
+ # Start the encoder in the background, but only once.
+ if($startenc == 0 && $encode == 1) {
+ $encstart = `date \'+%R\'`;
+ chomp $encstart;
+ if($multi == 1) {
+ open(SRXY,">>$logfile") or print "Can not append to file \"$logfile\"!";
+ print SRXY "\nEncoding started: $encstart";
+ system("echo 'Encoden gestartet: $encstart' >>$logger");
+ close(SRXY);
+ }
+ $startenc = 1;
+ unless(fork) {
+ print "Start encoding now!\n";
+ system("echo 'Encoden gestartet' >>$logger");
+ &enc_cd();
+ }
+ }
+ # Make output look nice. Keep ENCODER message together!
+ if($riptrackno != $seltrack[$#seltrack]) {
+ sleep 1;
+ }
+ }
+ # Ugly hack to tell the child process that we are waiting for it
+ # to finish.
+ open(ERR, ">>$mp3dir/error.log") || print "Can not append to file error.log!\n";
+ print ERR "The audio CD ripper reports: all done!\n";
+ close(ERR);
+ $ripend = `date \'+%R\'`;
+ chomp $ripend;
+ if($multi == 1) {
+ open(SRXY,">>$logfile") or print "Can not append to file \"$logfile\"!";
+ print SRXY "\nRipping complete: $ripend";
+ system("echo 'Rippen komplett !! $ripend' >>$logger");
+ close(SRXY);
+ }
+}
+########################################################################
+#
+# Encode the wav
+# This runs as a separate process from the main program which
+# allows it to continuously encode as the ripping is being done.
+# The encoder will also wait for the ripped wav in-case the encoder
+# is faster than the CDROM.
+#
+sub enc_cd {
+ my($x,$enc,$ncount,$riptrackno,$riptrackname);
+
+ foreach (@seltrack) {
+ $riptrackname = &get_trackname($_, $tracklist[$_ - 1]);
+ $riptrackno = $_;
+ $ncount++;
+ # lcdproc
+ if($lcd == 1){
+ $_lcdtracks = scalar @seltrack;
+ $_lcdenctrack = $ncount;
+ if($_lcdtracks eq $_lcdenctrack) {
+ $lcdperc = "*100";
+ }
+ else {
+ $lcdperc = sprintf("%04.1f",$_lcdenctrack/$_lcdtracks*100);
+ }
+ $lcdline3=~ s/\|\d\d.\d/\|$lcdperc/;
+ $_lcdenctrackF = sprintf("%02d",$_lcdenctrack);
+ $lcdline3=~ s/\E\d\d/\E$_lcdenctrackF/;
+ my @shortname = split(/\// , $riptrackname);
+ my $shortname = $shortname[$#shortname];
+ substr($lcdline3,10,10) = substr($shortname,3,13);
+ &ulcd();
+ }
+
+ # Cosmetics for nice output.
+ my $lasttrack = $seltrack[$#seltrack];
+ my $lasttrackname = &get_trackname($lasttrack, $tracklist[$lasttrack - 1]);
+ my @shortname = split(/\// , $riptrackname);
+ my $shortname = $shortname[$#shortname];
+
+ $tracktag = $tracktags[$_ - 1];
+ if($utftag == 0) {
+# $tracktag = utf8::downgrade($tracktag)
+# $artistag = utf8::downgrade($artistag)
+# $albumtag = utf8::downgrade($albumtag)
+ $tracklametag = &back_encoding($tracktag);
+ $artislametag = &back_encoding($artistag);
+ $albumlametag = &back_encoding($albumtag);
+ }
+ else{
+ $tracklametag = $tracktag;
+ $artislametag = $artistag;
+ $albumlametag = $albumtag;
+ }
+
+ # Keep looping until the wav file appears, i.e. wait for
+ # ripper timeout. Timeout is 3 times the length of track
+ # to rip/encode. Then leave that one and finish the job!
+ my $slength = $secondlist[$_ - 1];
+ my $mlength = (int($slength / 60) + 1) * 3;
+ my $tlength = (int($slength / 10) + 6) * 3;
+ my $x = 0;
+ # If the file name is too long, look for special
+ # name.
+ my $wavname = $riptrackname;
+ if(length($riptrackname) > 230) {
+ $wavname = &get_trackname($_,$_."short");
+ }
+ while(! -r "$wavname.wav") {
+ $x++;
+ last if($x > $tlength);
+ # Condition 1: Too long waiting for the track!
+ if($x >= $tlength) {
+ print "Encoder waited $mlength minutes for file\n";
+ print "$shortname.wav to appear, now giving up!\n";
+ print "with $artist - $album in device $cddev\n" if($multi == 1);
+ system("echo 'Encode wartet seit $mlenght Mintuen auf Datei' >>$logger");
+ $shortname =~ s/[:*#?$\!\"\']//g if($chars == 0); # Strip dodgey chars
+ system("echo 'Encoder: Gebe auf -> \"$shortname.wav\"' >>$logger");
+ $x = $tlength + 1;
+ if($multi == 1){
+ $x = 0 if(-r "$riptrackname.rip");
+ print "Don't worry, I continue the job!\n\n";
+
+ }
+ }
+ sleep 10;
+ # Condition 2: Check the error log!
+ # If at this moment the ripper did not start with
+ # the riptrackname.rip, assume it was a data track!
+ # If cdparanoia failed on a data track, there will
+ # be an entry in the error.log.
+ # If dagrab gave error messages, but the wav file
+ # was created, we won't get to this point, so don't
+ # worry.
+ if(-r "$mp3dir/error.log") {
+ open(ERR, "$mp3dir/error.log") || print "error.log disappeared!\n";
+ my @errlines = <ERR>;
+ close ERR;
+ my @errtrack = grep(/^Track $riptrackno /, @errlines);
+ my $errtrack = "@errtrack";
+ @errtrack = split(/ /, $errtrack);
+ $errtrack = @errtrack[1];
+ if($errtrack) {
+ $x = $tlength + 1;
+ print "\nDid not detect track $errtrack ($shortname.rip), assume ripper failure!\n" if($quiet == 0);
+ print "I will finish the job! Check the error.log!\n" if($quiet == 0 && $sshflag == 0);
+ }
+ }
+ }
+ next if($x > $tlength);
+ if(length($riptrackname) > 230) {
+ rename("$wavname.wav","$riptrackname.wav");
+ }
+
+ my $delwav = 0;
+ # Set the encoder(s) we are going to use.
+ for($c=0; $c<=$#coder; $c++) {
+ # This file exists if the ripper finished. It is used to enhance
+ # the output. Don't mess up the messages!
+ if($ripcomplete == 0 ) {
+ if(-r "$mp3dir/error.log") {
+ open(ERR, "$mp3dir/error.log") || print "Can not open file error.log!\n";
+ my @errlines = <ERR>;
+ close ERR;
+ my @ripcomplete = grep(/^The audio CD ripper reports: all done!$/, @errlines);
+ $ripcomplete = 1 if(@ripcomplete);
+ }
+ }
+ if($ripcomplete == 1 && $quiet == 0) {
+ print "\n";
+ }
+ if($ncount == 1 && $ripcomplete == 0 && $c > 0 && $quiet == 0) {
+ print "\n\n";
+ }
+ if($ncount > 1 && $ripcomplete == 0 && $quiet == 0) {
+ print "\n\n";
+ }
+ my $sufix = "";
+ # Get the command for the encoder to use!
+ if($coder[$c] == 0) {
+ if($ncount == 1) {
+ if($preset) {
+ $lameopt = $lameopt . " --preset $preset";
+ }
+ else
+ {
+ $lameopt = $lameopt . " --vbr-$vbrmode" if($vbrmode);
+ $lameopt = $lameopt . " -b $bitrate" if($bitrate ne "off");
+ $lameopt = $lameopt . " -B $maxrate" if($maxrate != 0);
+ $lameopt = $lameopt . " -V $qualame" if($qualame ne "off" && $vbrmode);
+ $lameopt = $lameopt . " -q $qualame" if($qualame ne "off" && !$vbrmode);
+ }
+ }
+ $enc = "lame $lameopt -S --tt \"$tracklametag\" --ta \"$artislametag\" --tl \"$albumlametag\" --ty \"$year\" --tg \"$genre\" --tn $riptrackno --tc \"$commentag\" --add-id3v2 \"$riptrackname.wav\" \"$riptrackname.mp3\"";
+ print "Lame $lameopt encoding track ".$ncount." of ".($#seltrack + 1)."" if($quiet == 0);
+ print "\@ quality $qualame\n" if($quiet == 0 && !$preset);
+ print "\n" if($quiet == 0);
+ $sufix = "mp3";
+ }
+ elsif($coder[$c] == 1) {
+ if($ncount == 1) {
+ $oggopt = $oggopt . " -q $qualogg" if($qualogg ne "off");
+ $oggopt = $oggopt . " -M $maxrate" if($maxrate != 0);
+ }
+ $enc = "oggenc $oggopt -t \"$tracktag\" -a \"$artistag\" -l \"$albumtag\" -d \"$year\" -G \"$genre\" -N $riptrackno -c \"$commentag\" -o \"$riptrackname.ogg\" \"$riptrackname.wav\"";
+ print "Ogg $oggopt encoding track ".$ncount." of ".($#seltrack + 1)." \@ quality $qualogg\n" if($quiet == 0);
+ $sufix = "ogg";
+ }
+ elsif($coder[$c] == 2) {
+ if($ncount == 1) {
+ $flacopt = $flacopt . " -$quaflac" if($quaflac ne "off");
+ }
+ $enc = "flac $flacopt --tag=Title=\"$tracktag\" --tag=Artist=\"$artistag\" --tag=Album=\"$albumtag\" --tag=Year=\"$year\" --tag=Catagory=\"$categ\" --tag=Genre=\"$genre\" --tag=Tracknumber=\"$riptrackno\" --tag=Comment=\"$commentag\" --tag=CD_id=\"$cddbid\" \"$riptrackname.wav\"";
+ print "Flac $flacopt encoding track ".$ncount." of ".($#seltrack + 1)." \@ compression $quaflac\n" if($quiet == 0);
+ $sufix = "flac";
+ }
+ elsif($coder[$c] == 3) {
+ if($ncount == 1) {
+ $faacopt = $faacopt . " -q $quafaac" if($quafaac ne "off");
+ }
+ $enc = "faac $faacopt -w --title \"$tracktag\" --artist \"$artist\" --album \"$album\" --year \"$year\" --genre \"$genre\" --track $riptrackno --comment \"$commentag\" \"$riptrackname.wav\" ";
+ print "Faac $faacopt encoding track ".$ncount." of ".($#seltrack + 1)." \@ quality $quafaac\n" if($quiet == 0);
+ $sufix = "m4a";
+ }
+ $sufix = "mp3" if($sufix eq "");
+ # Set "last encoding of track" - flag.
+ $delwav = 1 if($wav == 0 && $c == $#coder);
+ # Set nice if wished.
+ $enc="nice -n $nice ".$enc if($nice);
+ print "Encoding \"$shortname\"...\n" if($quiet == 0);
+ $shortname =~ s/[:*#?$\!\"\']//g if($chars == 0); # Strip dodgey chars
+ system("echo 'Encoder : \"$shortname\"...' >>$logger");
+ # Make the output look nice, don't mess the messages!
+ if($ripcomplete == 0 ) {
+ if(-r "$mp3dir/error.log") {
+ open(ERR, "$mp3dir/error.log") || print "Can not open file error.log!\n";
+ my @errlines = <ERR>;
+ close ERR;
+ my @ripcomplete = grep(/^The audio CD ripper reports: all done!$/, @errlines);
+ $ripcomplete = 1 if(@ripcomplete);
+ }
+ print "\n" if($quiet == 0);
+ }
+ # Finally, do the job of encoding, and a lot of cosmetics...
+ if($sshflag == 1) {
+ &enc_ssh($delwav,$enc,$riptrackname,$shortname,$sufix);
+ }
+ else {
+ if(! system("$enc > /dev/null 2> /dev/null")) {
+ if($ripcomplete == 0) {
+ if(-r "$mp3dir/error.log") {
+ open(ERR, "$mp3dir/error.log") || print "Can open file error.log!\n";
+ my @errlines = <ERR>;
+ close ERR;
+ my @ripcomplete = grep(/^The audio CD ripper reports: all done!$/, @errlines);
+ $ripcomplete = 1 if(@ripcomplete);
+ }
+ print "\n\n" if($quiet == 0);
+ }
+ print "Encoding complete \"$shortname\"\n" if($quiet == 0);
+ $shortname =~ s/[:*#?$\!\"\']//g if($chars == 0); # Strip dodgey chars
+ system("echo 'Encoder: Fertig -> \"$shortname\"' >>$logger");
+ if($ripcomplete == 0) {
+ if(-r "$mp3dir/error.log") {
+ open(ERR, "$mp3dir/error.log") || print "Can not open file error.log!\n";
+ my @errlines = <ERR>;
+ close ERR;
+ my @ripcomplete = grep(/^The audio CD ripper reports: all done!$/, @errlines);
+ $ripcomplete = 1 if(@ripcomplete);
+ }
+ print "\n" if($quiet == 0);
+ }
+ }
+ else {
+ print "Encoder failed on $tracklist[$_ - 1] in $cddev.";
+ system("echo 'Encoder : FEHLGESCHLAGEN -> $tracklist[$_ - 1] -> $cddev' >>$logger");
+ if($multi == 1) {
+ # Print error message to file srXY.Z.txt, checktrack will grep
+ # for string "encoder failed" and kill the CD immediately!
+ open(SRTF,">>$logfile.$riptrackno.txt") or print "Can not append to file \"$logfile.$riptrackno.txt\"!";
+ print SRTF "\nencoder failed on $tracklist[$_ - 1] in device $cddev, error !";
+ close(SRTF);
+ # Create on the fly error message in log-directory.
+ open(ERO,">>$logpath/failed.log") or print "Can not append to file \"$logpath/failed.log\"!";
+ print ERO "$artist;$album;$cddbid;$cddev;$hostnam!\n";
+ close(ERO);
+ # Now wait to be terminated by checktrack.
+ sleep 360;
+ }
+ }
+ sleep 1;
+ }
+ }
+ if($delwav == 1 && $sshflag == 0) {
+ unlink("$riptrackname.wav");
+ }
+ }
+ exit ;
+}
+########################################################################
+#
+# Creates the M3U file used by players such as X11Amp.
+#
+sub create_m3u {
+ my ($file);
+ my @mp3s = ();
+
+ $file = "$artist.m3u";
+ if($underscore == 1) {
+ $file =~ s/ /_/g;
+ }
+
+ opendir(DIR, $mp3dir);
+ open(PLIST, ">$mp3dir$file");
+ @mp3s = readdir(DIR);
+
+ # TODO: it works for the moment, but one should consider that
+ # coder is an array, and for which files should a m3u file be
+ # done? only mp3, only ogg ?
+ if($coder == 1) {
+ @mp3s = grep { /\.ogg/i } @mp3s;
+ }
+ elsif($coder == 2) {
+ @mp3s = grep { /\.flac/i } @mp3s;
+ }
+ else {
+ @mp3s = grep { /\.mp3/i } @mp3s;
+ }
+
+ # Now start writing to the file:
+ print PLIST "#EXTM3U\n";
+ #
+ # Remember to write according to the trackselection, i.e.
+ # don't write the names from first track on to the m3u file!
+ my $i = 0;
+ foreach (@mp3s) {
+ my $n = $seltrack[$i] - 1;
+ # Use tags to write into m3u file, not filenames!
+ if($tracktags[$n]) {
+ print PLIST "#EXTINF:$secondlist[$n],$tracktags[$n]\n";
+ }
+ # Use filenames for m3u file only if no tags found!
+ # This should not happen!
+ else {
+ $riptrackname = &get_trackname($seltrack[$i], $tracklist[$_ - 1]);
+ my @shortname = split(/\// , $riptrackname);
+ my $shortname = $shortname[$#shortname];
+ $shortname =~ s/^\d\d[\s_]//;
+ if($underscore == 1) { $shortname =~ s/_/ /g; };
+ print PLIST "#EXTINF:$secondlist[$n],$shortname\n";
+ }
+ print PLIST $mp3dir, $_, "\n";
+ $i++;
+ }
+
+ #print PLIST "$_\n" for reverse (@mp3s);
+ close(PLIST);
+ closedir(DIR);
+}
+########################################################################
+#
+# Creates a default or manual track list.
+#
+sub create_deftrack {
+# Chose if you want to use default names or enter them manually.
+# Do not ask if we come form CDDB submission, i.e. index == 0,
+# or if $interaction == 0, then $index == 1.
+ my($i,$j,$index,$test) = (0,1,@_);
+
+ $index = 1 if($quiet == 1);
+
+ while($index !~ /^[0-1]$/ ) {
+ print "\nThis CD shall be labeled with:\n\n";
+ print "1: Default Album, Artist and Tracknames\n\n";
+ print "0: Manual input\n\nChoose [0-1]: (0) ";
+ $index = <STDIN>;
+ chomp $index;
+ if($index eq "") {
+ $index = 0;
+ }
+ print "\n";
+ }
+# Create default tracklist and cd-hash.
+ if($index == 1) {
+ $artist = "Unknown Artist";
+ $album = "Unknown Album";
+ %cd = (
+ artist => $artist,
+ title => $album,
+ cat => $cat,
+ genre => $genre,
+ year => $year,
+ );
+ while($i < $tracks) { # Treat $tracks as scalar
+ $j = $i + 1;
+ $j = "0" . $j if($j < 10);
+ $cd{track}[$i] = "Track "."$j";
+ ++$i;
+ }
+ $cddbsubmission = 0;
+ }
+# Create manual tracklist.
+ elsif($index == 0) {
+ $test="a"x257;
+ while(length($test) > 256) {
+ # In case of CDDB resubmission
+ if(defined $cd{artist}) {
+ print "\n Artist ($artist): ";
+ }
+ # In case of manual CDDB entry
+ else {
+ print "\n Artist : ";
+ }
+ $artist = <STDIN>;
+ chomp $artist;
+ $test = $artist;
+ if(length($test) > 256) {
+ print "\nComment should not be longer than 256 characters.";
+ print "\nPlease enter the artist name again! \n";
+ }
+ }
+ # If CDDB entry confirmed, take it
+ if(defined $cd{artist} && $artist eq "") {
+ $artist = $cd{artist};
+ }
+ # If CDDB entry CHANGED, submission OK
+ elsif(defined $cd{artist} && $artist ne "") {
+ $cddbsubmission = 1;
+ }
+ if($artist eq "") {
+ $artist = "Unknown Artist";
+ $cddbsubmission = 0;
+ }
+ $artist =~ s/`/'/g; # Change ` to ' to avoid problems later
+ $artist =~ s/[;|><"\015]//g;
+ $artistag = $artist;
+ $artist =~ s/[:*#?$\!]//g if($chars == 0);
+ $artist =~ s/[*]//g;
+ $artist =~ s/\//-/g; # Change / to - to avoid problems later
+ $test="a"x257;
+ while(length($test) > 256) {
+ if(defined $cd{title}) {
+ print "\n Album ($album): ";
+ }
+ else {
+ print "\n Album : ";
+ }
+ $album = <STDIN>;
+ chomp $album;
+ $album =~ s/[;:*#|><"\015]//g; # Don't count these caracters
+ $test = $album;
+ if(length($test) > 256) {
+ print "\nComment should not be longer than 256 characters.";
+ print "\nPlease enter the album name again! \n";
+ }
+ }
+ # If CDDB entry confirmed, take it
+ if(defined $cd{title} && $album eq "") {
+ $album = $cd{title};
+ }
+ # If CDDB entry CHANGED, submission OK
+ elsif(defined $cd{title} && $album ne "") {
+ $cddbsubmission = 1;
+ }
+ if($album eq "") {
+ $album = "Unknown Album";
+ $cddbsubmission = 0;
+ }
+ $album =~ s/`/'/g; # Change ` to ' to avoid problems later
+ $album =~ s/[;|><"\015]//g;
+ $albumtag = $album;
+ $album =~ s/[:*#?$\!]//g if($chars == 0);
+ $album =~ s/[*]//g;
+ $album =~ s/\//-/g; # Change / to - to avoid problems later
+ $dtitle = $artistag . " / " . $albumtag;
+ print "\n";
+ $i=1;
+ while($i <= $tracks) { # Treat $tracks as scalar
+ if(defined $cd{track}[$i-1]) {
+ printf(" Track %02d ($tracklist[$i-1]): %s", $i);
+ }
+ else {
+ printf(" Track %02d: %s", $i);
+ }
+ $track = <STDIN>;
+ chomp $track;
+ $track =~ s/`/'/g; # Change ` to ' to avoid problems later
+ $track =~ s/[;|><"\015]//g;
+ $tracktag = $track;
+ $track =~ s/[:*#?$\!]//g if($chars == 0);
+ $track =~ s/[*]//g;
+ $track =~ s/\//-/g; # Change / to - to avoid problems later
+ if(length($track) > 256) {
+ print "\nComment should not be longer than 256 characters.";
+ print "\nPlease enter the track name again! \n";
+ next;
+ }
+ # If CDDB entry confirmed, take and replace it in tracklist
+ if(defined $cd{track}[$i-1] && $track ne "") {
+ splice @tracklist, $i-1, 1, $track;
+ splice @tracktags, $i-1, 1, $tracktag;
+ $cddbsubmission = 1;
+ }
+ elsif(!$cd{track}[$i-1] && $track eq "") {
+ $track = "Track";
+ $cddbsubmission = 0;
+ }
+ # Fill the "empty" array @{$cd{track}}
+ push @{$cd{track}}, "$track";
+ $i++;
+ }
+ }
+ else {
+ die "You should choose 0 or 1";
+ }
+ $nocddbinfo = 0; # Got default/manual CDDB info OK
+}
+########################################################################
+#
+# Read the CD and generate a TOC with DiscID, track frames and total
+# length. Then prepare CDDB-submission with entries from @tracklist.
+#
+sub pre_subm {
+ my($check,$i,$ans,$date,$line,$oldcat,$subject,$test) = (0,0);
+ # Check for CDDB ID vs CD ID problems.
+ if($cddbid ne $cd{id} && defined $cd{id}) {
+ print "\nWarning: CDID ($cddbid) is not identical to CDDB entry ($cd{id})!";
+ print "\nYou might get a collision error. Try anyway!\n";
+ $revision = 0
+ }
+ # Ask if CDDB entries shall be changed and
+ # ask if missing entries shall be filled.
+ if(defined $cd{year}) {
+ $year = get_answ(year,$year);
+ }
+ if($year eq "") {
+ while($year !~ /^\d{4}$| / || !$year ) {
+ print "\nPlease enter the year (or none): ";
+ $year = <STDIN>;
+ chomp $year;
+ last if(!$year);
+ }
+ }
+ $cddbsubmission = 1 unless($year eq $cd{year});
+ # Ask if CDDB category shall be changed and check if done.
+ $oldcat = $categ;
+ if(defined $cd{cat}) {
+ $categ = get_answ('CDDB category',$categ);
+ }
+ if($categ eq "") {
+ print "\nPlease enter a valid CDDB category";
+ print "\nE.g. blues, classical, country, data, folk, jazz, ";
+ print "\n newage, reggae, rock, soundtrack, misc \n";
+ while($categ !~ /^blues$|^classical$|^country$|^data$|^folk$|^jazz$|^newage$|^reggae$|^rock$|^soundtrack$|^misc$/ ) {
+ print "\nPlease enter a valid CDDB category (rock): ";
+ $categ = <STDIN>;
+ chomp $categ;
+ if($categ eq "") {
+ $categ = rock;
+ }
+ }
+ $cddbsubmission = 1 unless($categ eq $cd{cat});
+ }
+ # If one changes catecory for a new submission, set Revision to 0.
+ if($oldcat ne $categ && defined $cd{cat}){
+ $revision = 0;
+ }
+ # Remind the user if genre is not ID3v2 compliant!
+ if($coder != 0 && $genre ne "") {
+ &check_genre();
+ $cddbsubmission = 1 unless($genre eq $cd{'genre'});
+ }
+ # It would be better not to ask if genre had been passed
+ # from command line... but then I need one more var to compare!
+ if(defined $cd{'genre'} && $genre ne "") {
+ $genre = get_answ(genre,$genre);
+ }
+ if($genre eq "") {
+ print "\nNo valid genre";
+ print "\nPlease enter a valid CDDB genre (or none): ";
+ $genre = <STDIN>;
+ chomp $genre;
+ # Allow to submit no genre! Else check it!
+ # Set cddbgenre flag to 2.
+ if($genre ne "") {
+ $genre =~ s/[\015]//g;
+ $cddbgenre = 2;
+ &check_genre();
+ }
+ }
+ $cddbsubmission = 1 unless($genre eq $cd{'genre'});
+ # Now start to write the CDDB submission
+ open(TOC, ">$homedir/cddb.toc") || die "Can not write to cddb.toc $!";
+ print TOC "# xmcd CD database generated by RipIT\n";
+ print TOC "#\n";
+ print TOC "# Track frame offsets:\n";
+ $i = 0;
+ foreach (@framelist) {
+ print TOC "# $_\n" if($i < $#framelist);
+ $i++;
+ }
+ print TOC "#\n";
+ print TOC "# Disc length: $totals seconds\n";
+ print TOC "#\n";
+ print TOC "# Revision: $revision\n";
+ $date = `date`;
+ chomp $date;
+ print TOC "# Submitted via: RipIT $version www.suwald.com/ripit/ripit.html at $date\n";
+ print TOC "#\n";
+ print TOC "DISCID=$cddbid\n";
+ print TOC "DTITLE=$dtitle\n";
+ print TOC "DYEAR=$year\n";
+ if(defined $genre){
+ print TOC "DGENRE=$genre\n";
+ }
+ elsif($genre eq "" && defined $categ) {
+ print TOC "DGENRE=$categ\n";
+ }
+ $i = 0;
+ foreach (@tracktags) {
+ print TOC "TTITLE$i=$_\n";
+ ++$i;
+ }
+ if($commentblock[0] ne "") {
+ $ans = x;
+ $check = 0;
+ print "Confirm (Enter), delete or edit each comment line (c/d/e)!\n";
+ foreach (@commentblock) {
+ while($ans !~ /^c|^d|^e/) {
+ print "$_ (c/d/e): ";
+ $ans = <STDIN>;
+ chomp $ans;
+ if($ans eq "") {
+ $ans = c;
+ }
+ }
+ if($ans =~ /^c/ || $ans eq "") {
+ print TOC "EXTD=$_\\n\n";
+ $check = 1;
+ }
+ elsif($ans =~ /^e/) {
+ $test="a"x257;
+ while(length($test) > 256) {
+ print "Enter a different line: \n";
+ my $ans = <STDIN>;
+ chomp $ans;
+ $ans =~ s/[;*#|><"\$\015]//g;
+ # TODO: split too long lines instead of
+ # reentering them!
+ $test = $ans;
+ if(length($ans) <= 256) {
+ print TOC "EXTD=$ans\n";
+ }
+ else {
+ print "\nComment should not be longer than 256 characters.";
+ print "\nPlease enter the comment again! \n";
+ }
+ }
+ $cddbsubmission = 1;
+ $ans = x;
+ $check = 1;
+ }
+ else {
+ # Don't print the line.
+ $cddbsubmission = 1;
+ }
+ $ans = x;
+ }
+ $line = "a";
+ while(defined $line ) {
+ print "Do you want to add a line? (Enter for none or type!): ";
+ $line = <STDIN>;
+ chomp $line;
+ $line =~ s/[;*#|><"\$\015]//g;
+ $cddbsubmission = 1 if($line ne "");
+ last if(!$line);
+ # TODO: split too long lines instead of
+ # reentering them!
+ if(length($line) <= 256) {
+ print TOC "EXTD=$line\\n\n";
+ }
+ else {
+ print "\nComment should not be longer than 256 characters.";
+ print "\nPlease enter the comment again! \n";
+ }
+ $check = 1;
+ }
+ # If all lines have been deleted, add an empty EXTD line!
+ if($check == 0){
+ print TOC "EXTD=\n";
+ }
+ }
+ # If there are no comments, ask to add some.
+ elsif($commentblock[0] eq "") {
+ $line = "a";
+ while(defined $line ) {
+ print "Please enter a comment line (or none): ";
+ $line = <STDIN>;
+ chomp $line;
+ $line =~ s/[;*#|><"\$\015]//g;
+ $cddbsubmission = 1 if($line ne "");
+ # TODO: split too long lines instead of
+ # reentering them!
+ if(length($line) <= 256) {
+ print TOC "EXTD=$line\n";
+ }
+ else {
+ print "\nComment should not be longer than 256 characters.";
+ print "\nPlease enter the comment again! \n";
+ }
+ # This line has to be written, so break the
+ # while loop here and not before, as above.
+ last if(!$line);
+ }
+ }
+ else {
+ print TOC "EXTD=\n";
+ }
+
+ $ans = get_answ('Track comment','existing ones');
+ if($ans eq "") {
+ $i = 0;
+ while($i < $tracks) { # Treat $tracks as scalar
+ $test="a"x257;
+ while(length($test) > 256) {
+ if($trackcom[$i] ne "") {
+ printf(" Track comment %02d ($trackcom[$i]): %s", $i+1);
+ }
+ else {
+ printf(" Track comment %02d: %s", $i+1);
+ }
+ $track = <STDIN>;
+ chomp $track;
+ $track =~ s/`/'/g; # Change ` to ' to avoid problems later
+ $track =~ s/[#|\015]//g;
+ $test = $track;
+ if(length($test) > 256) {
+ print "\nComment should not be longer than 256 characters.";
+ print "\nPlease enter the track comment again! \n";
+ }
+ }
+ # If CDDB entry confirmed, take and replace it in tracklist
+ if(defined $trackcom[$i] && $track eq "") {
+ print TOC "EXTT$i=$trackcom[$i]\n";
+ }
+ elsif(defined $trackcom[$i] && $track ne "") {
+ print TOC "EXTT$i=$track\n";
+ $cddbsubmission = 1;
+ }
+ elsif($track ne "") {
+ print TOC "EXTT$i=$track\n";
+ $cddbsubmission = 1;
+ }
+ else {
+ print TOC "EXTT$i=\n";
+ }
+ $i++;
+ }
+ }
+ elsif(defined @trackcom) {
+ $i = 0;
+ foreach (@tracklist) {
+ print TOC "EXTT$i=$trackcom[$i]\n";
+ ++$i;
+ }
+ }
+ else {
+ $i = 0;
+ foreach (@tracklist) {
+ print TOC "EXTT$i=\n";
+ ++$i;
+ }
+ }
+
+ print TOC "PLAYORDER=$playorder\n";
+ close(TOC);
+ # Copy the *edited* CDDB file if variable set to the ~/.cddb/
+ # directory.
+ if($archive == 1 && $cddbsubmission != 2) {
+ system("mkdir -m 0777 -p \"$homedir/.cddb/$categ\"") && \
+ die "Cannot create directory \"$homedir/.cddb/$categ\": $!";
+ system("cp \"$homedir/cddb.toc\" \"$homedir/.cddb/$categ/$cddbid\"") && \
+ die "Cannot copy cddb.toc to directory \"$homedir/.cddb/$categ/$cddbid\": $!";
+ print "Saved file $cddbid in \"$homedir/.cddb/$categ/\"";
+ }
+ print "\n";
+ # Don't send mail if nail command unknown or not connected to
+ # the internet.
+ unless(!system "nail -V") {
+ print "nail (mail) not installed?\n";
+ $cddbsubmission = 0;
+ }
+ # If no connection to the internet do not submit.
+ if($submission == 0) {
+ $cddbsubmission = 0;
+ }
+ if($cddbsubmission == 1) {
+ while($mailad !~ /.@.+[.]./) {
+ print "\nReady for submission, enter a valid return e-mail address: ";
+ $mailad = <STDIN>;
+ chomp $mailad;
+ }
+ $subject = "cddb " . $categ . " " . $cddbid;
+ open TOC, "cat \"$homedir/cddb.toc\" |" or die "Can not open file cddb.toc $!";
+ open MAIL, "|nail freedb-submit\@freedb.org -r $mailad -s \"$subject\" " or die "nail not installed? $!";
+ my @lines = <TOC>;
+ foreach (@lines) {
+ print MAIL "$_";
+ }
+ close MAIL;
+ die "Mail exit status not zero: $?" if $?;
+ close TOC;
+ print "CDDB entry submitted\n\n";
+ unlink("$homedir/cddb.toc");
+ }
+ elsif($cddbsubmission == 2) {
+ print "\nCDDB entry created but not send because no changes";
+ print "\nwere made! Please edit and send it manually to ";
+ print "\nfreedb-submit\@freedb.org with Subject:";
+ print "\ncddb $categ $cddbid\n\n";
+ }
+ else {
+ print "\nCDDB entry saved in your home directory, but not send,";
+ print "\nplease edit it and send it manually to:";
+ print "\nfreedb-submit\@freedb.org with Subject:";
+ print "\ncddb $categ $cddbid\n\n";
+ }
+}
+########################################################################
+#
+# Check if genre is correct
+#
+sub check_genre {
+ my ($i,$j) = (0,1);
+
+ # If Lame is not used, don't die if ID3v2-tag is not compliant.
+ if($lameflag == 0) {
+ if(system "lame --genre-list | grep -i \" $genre\" > /dev/null " ) {
+ print "Genre $genre is not ID3v2 compliant!\n" if($quiet == 0);
+ print "I continue anyway!\n\n" if($quiet == 0);
+ $genreno = "not ID3v2 compliant!\n";
+ chomp $genreno;
+ return;
+ }
+ }
+ # Now check if genre is OK... if not, delete it!
+ while(system "lame --genre-list | grep -i \"$genre\" > /dev/null " ) {
+ if($quiet == 0) {
+ print "Genre $genre is not ID3v2 compliant!\n";
+ print "\nPlease enter a valid CDDB genre (or none): ";
+ $genre = <STDIN>;
+ chomp $genre;
+ }
+ else {
+ $genre = "Other";
+ }
+ # If $genre was from CDDB set the $cddbgenre flag to 0.
+ if($cddbgenre == 1) {
+ $cddbgenre = 0;
+ }
+ }
+ # ...and if none is choosen return to "get CDDB" or "CDDB
+ # submission" ($cddbgenre is 0, 1 or 2)...
+ if($genre eq "" && $cddbgenre != 1) {
+ return;
+ }
+ # ...or if genre is OK (from above) do quick check if it came
+ # from "get CDDB" subroutine...
+ elsif($cddbgenre == 1 && $genre ne "") {
+ $genre = `lame --genre-list | grep -i \'\^... $genre\$\' `;
+ chomp $genre;
+ $cddbgenre = 0;
+ }
+ # ... or if genre was passed as number...
+ elsif($genre =~ /^\d/) {
+ if($genre < 10) {
+ $genre = `lame --genre-list | grep -i \" $genre\" `;
+ }
+ elsif($genre =~ /^\d{2}$/) {
+ $genre = `lame --genre-list | grep -i \" $genre\" `;
+ }
+ else {
+ $genre = `lame --genre-list | grep -i \"$genre\" `;
+ }
+ chomp $genre;
+ }
+ # ... or if genre was passed as word.
+ elsif($genre =~ /\w/) {
+ $genre = `lame --genre-list | grep -i \" $genre\" `;
+ chomp $genre;
+ if($genre =~ /\n/) {
+ print "More than one genre possibility found!\n";
+ my @list = split(/\n/,$genre);
+ while($i > $#list+1 || $i == 0) {
+ foreach (@list) {
+ printf(" %2d: $_ \n",$j);
+ $j++;
+ }
+ $j--;
+ print "\nChoose [1-$j]: ";
+ $i = <STDIN>;
+ chomp $i;
+ $j = 1;
+ }
+ $genre = $list[$i-1];
+ chomp $genre;
+ }
+ }
+ elsif($cddbgenre != 2) {
+ die "Genre $genre is invalid!";
+ }
+ @genre = split(/ /, $genre);
+ while($genre[0] eq "") {
+ $genreno = shift(@genre);
+ }
+ $genreno = shift(@genre);
+ $genre = "@genre";
+}
+########################################################################
+#
+# Check mirrors
+#
+sub check_host {
+ while($mirror !~ /^freedb$|^at$|^au$|^ca$|^ca2$|^de$|^es$|^fi$|^ru$|^uk$|^us$/){
+ print "host mirror ($mirror) not valid!\n";
+ print "enter freedb, at, au, ca, ca2, de, es, fi, ru, uk, or us: ";
+ $mirror = <STDIN>;
+ chomp $mirror;
+ }
+ $CDDB_HOST = $mirror.".freedb.org";
+ chomp $CDDB_HOST;
+}
+########################################################################
+#
+# Reply to question
+#
+sub get_answ {
+ my $ans = x;
+ while($ans !~ /^y|^n/) {
+ print "Do you want to enter a different ".$_[0]." than ".$_[1]."? [y/n], (n): ";
+ $ans = <STDIN>;
+ chomp $ans;
+ if($ans eq ""){
+ $ans = n;
+ }
+ }
+ if($ans =~ /^y/){
+ return "";
+ }
+ return $_[1];
+}
+########################################################################
+#
+# Check quality passed from command line for oggenc, flac and lame only
+# if vbr wanted (then it's encoder no 3).
+#
+sub check_quality {
+ my $corrflag = 0;
+ if($qualame ne "off") {
+ while($qualame > 9) {
+ print "\nThe quality $qualame is not valid for Lame!\n";
+ print "Please enter a different quality (0 = best), [0-9]: ";
+ $qualame = <STDIN>;
+ chomp $qualame;
+ $corrflag = 1;
+ }
+ }
+ if($qualogg ne "off") {
+ while($qualogg > 10 || $qualogg == 0) {
+ print "\nThe quality $qualogg is not valid for Ogg!\n";
+ print "Please enter a different quality (10 = best), [1-10]: ";
+ $qualogg = <STDIN>;
+ chomp $qualogg;
+ $corrflag = 1;
+ }
+ }
+ if($quaflac ne "off") {
+ while($quaflac > 8) {
+ print "\nThe compression level $quaflac is not valid for Flac!\n";
+ print "Please enter a different compression level (0 = lowest), [0-8]: ";
+ $quaflac = <STDIN>;
+ chomp $quaflac;
+ $corrflag = 1;
+ }
+ }
+ if($quafaac ne "off") {
+ while($quafaac > 500 || $quafaac < 10) {
+ print "\nThe quality $quaflac is not valid for Faac!\n";
+ print "Please enter a different quality (500 = max), [10-500]: ";
+ $quafaac = <STDIN>;
+ chomp $quafaac;
+ $corrflag = 1;
+ }
+ }
+ # Now save the corrected values to the pquality array! Do it in
+ # the same order the encoders had been passed! If no encoders
+ # were passed, test if there are encoders in the config file...
+ if($corrflag == 1) {
+ @pquality = split(/,/, join(',', @pquality));
+ for($index = 0; $index <= $#pquality; $index++) {
+ if($coder[$index] =~ /^\d/) {
+ $pquality[$index] = $qualame if($coder[$index] == 0);
+ $pquality[$index] = $qualogg if($coder[$index] == 1);
+ $pquality[$index] = $quaflac if($coder[$index] == 2);
+ $pquality[$index] = $quafaac if($coder[$index] == 3);
+ }
+ else {
+ $pquality[$index] = $qualame if($index == 0);
+ $pquality[$index] = $qualogg if($index == 1);
+ $pquality[$index] = $quaflac if($index == 2);
+ $pquality[$index] = $quafaac if($index == 3);
+ }
+ }
+ $pquality = join(',',@pquality);
+ @pquality = ();
+ $pquality[0] = $pquality;
+ }
+}
+########################################################################
+#
+# Check bitrate for Lame only if vbr is wanted.
+#
+sub check_vbrmode {
+ while($vbrmode ne "new" && $vbrmode ne "old") {
+ print "\nFor vbr using Lame choose *new* or *old*! (new): ";
+ $vbrmode = <STDIN>;
+ chomp $vbrmode;
+ $vbrmode = new if ($vbrmode eq "");
+ }
+}
+########################################################################
+#
+# Check preset for Lame only.
+#
+sub lame_preset {
+ if($vbrmode eq "new") {
+ $preset = "fast " . $preset;
+ }
+}
+########################################################################
+#
+# Check if there is an other than $cddevice which has a CD if no --dev
+# option was given.
+#
+sub check_cddev {
+ if(open(CD, "$cddevice")) {
+ $cddev = $cddevice;
+ close CD;
+ }
+ else {
+ # Remember: match character "ranges" in []-brackets,
+ # grep '^/dev/[^fd,^hd,^sd]' is not what we want!
+ open(DEV, "grep '^/dev/[^f,^h]' /etc/fstab | awk '{print \$1}' |");
+ @dev = <DEV>;
+ @dev = grep(!/sd/, @dev);
+ close DEV;
+ foreach (@dev) {
+ if(open(CD, "$_")) {
+ $cddev = $_;
+ chop $cddev;
+ close CD;
+ }
+ }
+ }
+}
+########################################################################
+#
+# Check bitrate if bitrate is not zero.
+#
+sub check_bitrate {
+ while($bitrate !~ /^32$|^40$|^48$|^56$|^64$|^80$|^96$|^112$|^128$|^160$|^192$|^224$|^256$|^320$|^off$/) {
+ print "\nBitrate should be one of the following numbers or \"off\"! Please Enter";
+ print "\n32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 or 320: (128) \n";
+ $bitrate = <STDIN>;
+ chomp $bitrate;
+ if($bitrate eq "") {
+ $bitrate = 128;
+ }
+ }
+}
+########################################################################
+#
+# Check protocol level for CDDB query.
+#
+sub check_proto {
+ while($proto > 6) {
+ print "Protocol level for CDDB query should be less-equal 6!\n";
+ print "Enter an other value for protocol level (6): ";
+ $proto = <STDIN>;
+ chomp $proto;
+ $proto = 6 if($proto eq "");
+ }
+}
+########################################################################
+#
+# Check, clean and sort the coder array, and then, according to, the
+# qualities.
+#
+sub check_coder {
+ # Create encoder array if passed or read from config file.
+ if($pcoder[0] =~ /^\d/) {
+ @coder = split(/,/, join(',',@pcoder));
+ }
+ else {
+ @coder = split /,/, join(',', @coder);
+ }
+ # Now check if an encoder was passed several times.
+ @scoder = sort {$a <=> $b} @coder;
+ my $index=0;
+ while($index < $#scoder) {
+ if($scoder[$index] == $scoder[$index+1]) {
+ # TODO delete entry if encoder appears more than once.
+# splice @coder,$index,1;
+ die "Found encoder $scoder[$index] twice, confused!\n";
+ }
+ $index++;
+ }
+ # Now check, that there is no entry >= 4, find the index
+ # of lame if present and calculate the number of encoders
+ # that need a quality entry.
+ my $nofcoders=0;
+ for($index = 0; $index <= $#coder; $index++) {
+ if($coder[$index] >= 4) {
+ print "Encoder number $coder[$index] does not yet exist, please enter\n";
+ die "0 for Lame, 1 for Oggenc, 2 for Flac and 3 for Faac!\n\n";
+ }
+ $nofcoders++;
+ if($coder[$index] == 0 || $coder[$index] >= 4) {
+ $lameindex = $index;
+ $nofcoders = $nofcoders - 1;
+ $lameflag = 1;
+ }
+ }
+ # Use comma separated string to write the encoder array to the
+ # config file!
+ $wcoder = join(',',@coder);
+ $nofcoders=$nofcoders-1;
+ # Now order the qualities (if passed) in the same way as coders!
+ # Note, the array of coders is NOT sorted!
+ # First, check if there is a config file with an probably unusual
+ # order of encoders. In this way, the check-quality subroutine
+ # will ask the correct questions and not mess up the encoders!
+ if($pcoder[0] !~ /^\d/ && -r "$homedir/.ripit/config") {
+ open(CONF, "$homedir/.ripit/config");
+ my @conflines = <CONF>;
+ close CONF;
+ @pcoder = grep(s/^coder=//, @conflines) if($pcoder[0] !~ /^\d/);
+ chomp @pcoder;
+ if($pcoder[0] =~ /^\d/) {
+ @coder = split(/,/, join(',',@pcoder));
+ }
+ }
+ # Second, check if quality was passed.
+ if($pquality[0] =~ /^\d/ || $pquality[0] eq "off") {
+ @quality = split(/,/, join(',', @pquality));
+ # If lame was passed, but no quality for lame (because
+ # user wants cbr), then add the default quality for lame
+ # at the right place of array @quality to ensure that the
+ # &check_quality() subroutine works! NOTE: $nofcoder is
+ # the number of non-lame encoders!
+ if($#quality == $nofcoders && $lameflag == 1) {
+ splice @quality, $lameindex, 1, (5,$quality[$lameindex]);
+ }
+ for($index = 0; $index <= $#quality; $index++) {
+ if($coder[$index] =~ /^\d/) {
+ $qualame = $quality[$index] if($coder[$index] == 0);
+ $qualogg = $quality[$index] if($coder[$index] == 1);
+ $quaflac = $quality[$index] if($coder[$index] == 2);
+ $quafaac = $quality[$index] if($coder[$index] == 3);
+ }
+ else {
+ $qualame = $quality[$index] if($index == 0);
+ $qualogg = $quality[$index] if($index == 1);
+ $quaflac = $quality[$index] if($index == 2);
+ $quafaac = $quality[$index] if($index == 3);
+ }
+ }
+ }
+}
+########################################################################
+#
+# Over or re-write the config file (depends on option savenew or save).
+#
+sub save_config {
+ system("mkdir -m 0777 -p ~/.ripit") && \
+ die "Cannot create directory ~/.ripit/config: $!";
+ my $ripdir = $homedir . "/.ripit";
+ rename("$ripdir/config","$ripdir/config.old") if(-r "$ripdir/config");
+ open(CONF, "> $ripdir/config") || die "Can not write to ~/.ripit/config: $!";
+ print CONF "archive=$archive\n";
+ print CONF "bitrate=$bitrate\n";
+ print CONF "maxrate=$maxrate\n";
+ print CONF "cddevice=$cddev\n"; # Don't use $device here!
+ print CONF "CDDBHOST=$DCDDB_HOST\n";
+ print CONF "chars=$chars\n";
+ print CONF "coder=$wcoder\n"; # $pcoder was checked!
+ print CONF "comment=$commentag\n";
+ print CONF "eject=$eject\n";
+ print CONF "encode=$encode\n";
+ print CONF "faacopt=$faacopt\n";
+ print CONF "flacopt=$flacopt\n";
+ print CONF "lameopt=$lameopt\n";
+ print CONF "oggopt=$oggopt\n";
+ print CONF "halt=$halt\n";
+ print CONF "interaction=$interaction\n";
+ print CONF "lcd=$lcd\n";
+ print CONF "lcdhost=$lcdhost\n";
+ print CONF "lcdport=$lcdport\n";
+ print CONF "local=$local\n";
+ print CONF "lowercase=$lowercase\n";
+ print CONF "mirror=$mirror\n";
+ print CONF "mailad=$mailad\n";
+ print CONF "nice=$nice\n";
+ print CONF "output=$outputdir\n";
+ print CONF "paranoia=$parano\n";
+ print CONF "playlist=$playlist\n";
+ print CONF "preset=$wpreset\n";
+ print CONF "proto=$proto\n";
+ print CONF "proxy=$proxy\n";
+ print CONF "quafaac=$quafaac\n";
+ print CONF "quaflac=$quaflac\n";
+ print CONF "qualame=$qualame\n";
+ print CONF "qualogg=$qualogg\n";
+ print CONF "quiet=$quiet\n";
+ print CONF "ripper=$ripper\n";
+ print CONF "ripopt=$ripopt\n";
+ print CONF "scp=$scp\n";
+ print CONF "sshlist=$wsshlist\n";
+ print CONF "submission=$submission\n";
+ print CONF "transfer=$transfer\n";
+ print CONF "underscore=$underscore\n";
+ print CONF "utftag=$utftag\n";
+ print CONF "vbrmode=$vbrmode\n";
+ print CONF "year=$year\n";
+ print CONF "wav=$wav\n";
+ print CONF "dirtemplate=$dirtemplate\n";
+ print CONF "tracktemplate=$tracktemplate\n";
+ close CONF;
+}
+########################################################################
+#
+# Read the config file, take the parameters only if NOT yet defined!
+#
+sub read_config {
+ my $ripdir = $homedir."/.ripit/config";
+ if(-r "$ripdir" ) {
+ open(CONF, "$ripdir") || print "Can not read config file!\n";
+ my @conflines = <CONF>;
+ close CONF;
+ my @archive = grep(s/^archive=//, @conflines);
+ $archive = @archive[0] if($parchive !~ /^\d/);
+ chomp $archive;
+ my @bitrate = grep(s/^bitrate=//, @conflines);
+ $bitrate = @bitrate[0] if(!$pbitrate);
+ chomp $bitrate;
+ my @maxrate = grep(s/^maxrate=//, @conflines);
+ $maxrate = @maxrate[0] if(!$pmaxrate);
+ chomp $maxrate;
+ my @cddev = grep(s/^cddevice=//, @conflines);
+ $cddev = @cddev[0] if(!$pcddev);
+ chomp $cddev;
+ my @chars = grep(s/^chars=//, @conflines) if($pchars !~ /^\d/);
+ $chars = @chars[0] if(@chars[0]);
+ chomp $chars;
+ my @commentag = grep(s/^comment=//, @conflines);
+ $commentag = @commentag[0] if(!$pcommentag);
+ chomp $commentag;
+ my @CDDB_HOST = grep(s/^CDDBHOST=//, @conflines);
+ $CDDB_HOST = @CDDB_HOST[0] if(!$PCDDB_HOST);
+ chomp $CDDB_HOST;
+ @pcoder = grep(s/^coder=//, @conflines) if($pcoder[0] !~ /^\d/);
+ chomp @pcoder;
+ # NOTE: all coders are in array entry $pcoder[0]!
+ my @dirtemplate = grep(s/^dirtemplate=//, @conflines);
+ $dirtemplate = @dirtemplate[0] if(!$pdirtemplate);
+ chomp $dirtemplate;
+ my @eject = grep(s/^eject=//, @conflines);
+ $eject = @eject[0] if($peject !~ /^\d/);
+ chomp $eject;
+ my @encode = grep(s/^encode=//, @conflines);
+ $encode = @encode[0] if($pencode !~ /^\d/);
+ chomp $encode;
+ my @halt = grep(s/^halt=//, @conflines);
+ $halt = @halt[0] if(!$phalt);
+ chomp $halt;
+ my @interaction = grep(s/^interaction=//, @conflines);
+ $interaction = @interaction[0] if($pinteraction !~ /^\d/);
+ chomp $interaction;
+ my @lcd = grep(s/^lcd=//, @conflines);
+ $lcd = @lcd[0] if($plcd !~ /^\d/);
+ chomp $lcd;
+ my @lcdhost = grep(s/^lcdhost=//, @conflines);
+ $lcdhost = @lcdhost[0] if(!$plcdhost);
+ chomp $lcdhost;
+ my @lcdport = grep(s/^lcdport=//, @conflines);
+ $lcdport = @lcdport[0] if(!$plcdport);
+ chomp $lcdport;
+ my @local = grep(s/^local=//, @conflines);
+ $local = @local[0] if($plocal !~ /^\d/);
+ chomp $local;
+ my @lowercase = grep(s/^lowercase=//, @conflines);
+ $lowercase = @lowercase[0] if($plowercase !~ /^\d/);
+ chomp $lowercase;
+ my @mailad = grep(s/^mailad=//, @conflines);
+ $mailad = @mailad[0] if(!$pmailad);
+ chomp $mailad;
+ my @mirror = grep(s/^mirror=//, @conflines);
+ $mirror = @mirror[0] if(!$pmirror);
+ chomp $mirror;
+ my @nice = grep(s/^nice=//, @conflines);
+ $nice = @nice[0] if($pnice !~ /^\d/);
+ chomp $nice;
+ my @outputdir = grep(s/^output=//, @conflines);
+ $outputdir = @outputdir[0] if(!$poutputdir);
+ chomp $outputdir;
+ my @parano = grep(s/^paranoia=//, @conflines);
+ $parano = @parano[0] if($pparano !~ /^\d/);
+ chomp $parano;
+ my @playlist = grep(s/^playlist=//, @conflines);
+ $playlist = @playlist[0] if($pplaylist !~ /^\d/);
+ chomp $playlist;
+ my @preset = grep(s/^preset=//, @conflines);
+ $preset = @preset[0] if(!$ppreset);
+ chomp $preset;
+ my @proto = grep(s/^proto=//, @conflines);
+ $proto = @proto[0] if(!$pproto);
+ chomp $proto;
+ my @proxy = grep(s/^proxy=//, @conflines);
+ $proxy = @proxy[0] if(!$pproxy);
+ chomp $proxy;
+ my @quafaac = grep(s/^quafaac=//, @conflines) if($pquality[0] !~ /^\d/);
+ $quafaac = @quafaac[0] if(@pquafaac[0] !~ /^\d$|^off/);
+ chomp $quafaac;
+ my @quaflac = grep(s/^quaflac=//, @conflines) if($pquality[0] !~ /^\d/);
+ $quaflac = @quaflac[0] if($pquality[0] !~ /^\d$|^off/);
+ chomp $quaflac;
+ my @qualame = grep(s/^qualame=//, @conflines) if($pquality[0] !~ /^\d/);
+ $qualame = @qualame[0] if($pquality[0] !~ /^\d$|^off/);
+ chomp $qualame;
+ my @qualogg = grep(s/^qualogg=//, @conflines) if($pquality[0] !~ /^\d/);
+ $qualogg = @qualogg[0] if($pquality[0] !~ /^\d$|^off/);
+ chomp $qualogg;
+ my @faacopt = grep(s/^faacopt=//, @conflines);
+ $faacopt = @faacopt[0] if(!$pfaacopt);
+ chomp $faacopt;
+ my @flacopt = grep(s/^flacopt=//, @conflines);
+ $flacopt = @flacopt[0] if(!$pflacopt);
+ chomp $flacopt;
+ my @lameopt = grep(s/^lameopt=//, @conflines);
+ $lameopt = @lameopt[0] if(!$plameopt);
+ chomp $lameopt;
+ my @oggopt = grep(s/^oggopt=//, @conflines);
+ $oggopt = @oggopt[0] if(!$poggopt);
+ chomp $oggopt;
+ my @quiet = grep(s/^quiet=//, @conflines);
+ $quiet = @quiet[0] if($pquiet !~ /^\d/);
+ chomp $quiet;
+ my @ripper = grep(s/^ripper=//, @conflines);
+ $ripper = @ripper[0] if($pripper !~ /^\d/);
+ chomp $ripper;
+ my @ripopt = grep(s/^ripopt=//, @conflines);
+ $ripopt = @ripopt[0] if($pripopt !~ /^\d/);
+ chomp $ripopt;
+ my @rlist = grep(s/^sshlist=//, @conflines) if(!$psshlist[0]);
+ chomp @rlist;
+ # NOTE: all machine names are in array entry $rlist[0]!
+ @sshlist = split(/,/, join(',',@rlist));
+ my @scp = grep(s/^scp=//, @conflines);
+ $scp = @scp[0] if($pscp !~ /^\d/);
+ chomp $scp;
+ my @submission = grep(s/^submission=//, @conflines);
+ $submission = @submission[0] if($psubmission !~ /^\d/);
+ chomp $submission;
+ my @transfer = grep(s/^transfer=//, @conflines);
+ $transfer = @transfer[0] if(!$ptransfer);
+ chomp $transfer;
+ my @tracktemplate = grep(s/^tracktemplate=//, @conflines);
+ $tracktemplate = @tracktemplate[0] if(!$ptracktemplate);
+ chomp $tracktemplate;
+ my @underscore = grep(s/^underscore=//, @conflines);
+ $underscore = @underscore[0] if($punderscore !~ /^\d/);
+ chomp $underscore;
+ my @utftag = grep(s/^utftag=//, @conflines);
+ $utftag = @utftag[0] if($putftag !~ /^\d/);
+ chomp $utftag;
+ my @vbrmode = grep(s/^vbrmode=//, @conflines);
+ $vbrmode = @vbrmode[0] if(!$pvbrmode);
+ chomp $vbrmode;
+ my @year = grep(s/^year=//, @conflines);
+ $year = @year[0] if(!$pyear);
+ chomp $year;
+ my @wav = grep(s/^wav=//, @conflines);
+ $wav = @wav[0] if($pwav !~ /^\d/);
+ chomp $wav;
+ }
+ else {
+ print "No config file found!\n" if($quiet == 0);
+ }
+}
+
+########################################################################
+#
+# Display a help page and exit!
+#
+sub print_help {
+ print "\n
+NAME:
+ ripit - Perl Script to Create .flac .ogg .mp3 or .m4a (aac) files
+ from an audio CD.
+\n
+SYNOPSIS:
+ ripit [options]
+\n
+DESCRIPTION:
+ This Perl script makes it a lot easier to create \"mp3\" files from
+ an audio CD. RipIT supports the formats Flac, Lame, Ogg and Faac.
+ It tries to find the artist and song titles with the CDDB_get.pm.
+ One can submit and edit CDDB entries \@ freedb.org.
+\n
+OPTIONS:
+ [track_selection]
+ Tracks to rip from. If not specified, all tracks will be
+ ripped. Specify a single track by using a single number,
+ or a selection of tracks using numbers separated by commas
+ or hyphens, i.e. 2,6,10, or 3,5,7-9 .
+ Using a number followed by a comma or hyphen will rip from
+ that track to the end of the CD i.e. 3,5- rips track 3 and
+ from track 5 to the last one.
+
+ -o dir
+ --outputdir dir
+ Where the sound should go, default: not set.
+
+ -d cddevice
+ --device cddevice
+ Path of audio CD device, default: /dev/cdrom.
+
+ -r ripper
+ --ripper ripper
+ CDripper to use, 0 - dagrab, 1 - cdparanoia, 2 - cdda2wav,
+ 3 - tosha, 4 - cdd, default cdparanoia. Because cdparanoia
+ and dagrab are the only rippers that immediately fail on
+ data tracks, RipIT can create an error.log if problems are
+ encountered and continues to ripp and code without endless
+ looping! Please use dagrab or cdparanoia except if you
+ know what you're doing (know that you will wait)! Default:
+ 1.
+
+ --ripopt
+ User definable options for CDripper.
+
+ -Z
+ --disable-paranoia
+ When using dagrab, the number of retries will be set to 3,
+ with cdparanoia this option is equal to the -Z option.
+ Default: off.
+
+ -c encoder
+ --coder encoder
+ Encoder(s) to use, 0 - Lame, 1 - Ogg, 2 - Flac, 3 - Faac,
+ a comma seperated list!
+ E.g. --coder 2,0,1,3 --quality 3,5,300 sets compression
+ level for Flac to 3, Ogg-quality to 5 and Faac quality to
+ 300. What about Lame-quality? Lame does not need quality
+ for constant-bitrate, it assumes that no quality is used,
+ but sets it to the lame-default value of 5 in the case one
+ uses vbr-mode! Default: 0.
+ Better use --coder 2,0,1,3 --quality 3,4,5,300.
+
+ --faacopt Faac-options
+ Pass other options to the encoder, quote them with double
+ quotes if needed; default: not set.
+
+ --flacopt Flac-options
+ Pass other options to the encoder, quote them with double
+ quotes if needed; default: not set.
+
+ --lameopt Lame-options
+ Pass other options to the encoder, quote them with double
+ quotes if needed; default: not set.
+
+ --oggopt Oggenc-options
+ Pass other options to the encoder, quote them with double
+ quotes if needed; default: not set.
+
+ -q quality
+ --quality quality
+ A comma seperated list of values or the word \"off\", passed
+ in the same order as the list of encoders! If no encoders
+ passed, follow the order of the config file!
+ Quality for ogg (1-10), highest = 10; or compression level
+ for Flac (0-8), lowest compression = 0; or quality for Lame
+ in vbr mode (0-9), best quality = 0; or quality for Faac
+ (10-500), highest = 500; default: 5,3,5,100.
+ The value \"off\" turns option quality off.
+
+ -v mode
+ --vbrmode mode
+ Variable bitrate, only used with Lame, mode is new or old,
+ see Lame manpage. The Lame-option quality will be changed
+ to -V instead of -q if vbr-mode is used; default: not set.
+
+ -b rate
+ --bitrate rate
+ Encode \"mp3\" at this bitrate for Lame, if option --vbrmode
+ used, bitrate is equal to the -b option, so one might want
+ set off, default: 128.
+
+ -B rate
+ --maxrate rate
+ maxrate (Bitrate) for Lame using --vbrmode is equal to the
+ -B option in Lame or the -M option in Oggenc, default: 0.
+
+ -S mode
+ --preset mode
+ Use the preset switch when encoding with Lame. With otpion
+ --vbrmode new --preset fast will be used. Mode is one of:
+ insane (320 kbps @ CBR), extreme (256 kbps), standard (192
+ kbps) or medium (160 kbps) or any other valid bitrate.
+ Default: off.
+
+ -W
+ --chars
+ Use special characters in file names; default: on.
+
+ --comment id3 comment
+ Specify a comment tag, default: not set.
+
+ -g genre
+ --genre genre
+ Overrides CDDB genre, must be a valid Lame-genre name if
+ using Lame, can (but shouldn't) be anything if using other
+ encoders, default: not set.
+
+ -y year
+ --year year
+ Tag sound files with this year, default: not set.
+
+ --sshlist list
+ Comma seperated list of remote machines where RipIT should
+ encode. The output path must be the same for all machines.
+ Specify the login (login\@machine) only if not the same for
+ the remote machine. Else just state the machine names. See
+ EXAMPLES for more informtation, default: off.
+
+ --scp If the fs can not be accessed on the remote machines, copy
+ the wavs to the remote machines, default: off.
+
+ --local
+ Only used with option --sshlist; if all encodings shall be
+ done on remote machines, use --nolocal, default: on.
+
+ -t mode
+ --transfer mode
+ Transfer mode, cddb or http, will set default port to 8880
+ or 80 (for http), default: cddb.
+
+ -C server
+ --cddbserver server
+ CDDB server, default freedb.org. Note, the full address is
+ \"mirror\".freedb.org, i. e. default is freedb.freedb.org.
+
+ -m mirror
+ --mirror mirror
+ Choose \"freedb\" or one of the possible freedb bmirrors, e.
+ g. \"at\", default: freedb. For more information check the
+ webpage www.freedb.org.
+
+ -L level
+ --protocol level
+ CDDB protocol level for CDDB query. Level 6 supports UTF-8
+ and level 5 not. Use level 5 to suppress UTF-8. Cf. option
+ --utftag below. Default: 6
+
+ -P address
+ --proxy address
+ The http proxy to use when accessing the cddb server. The
+ protocol must be http! Default: not set.
+
+ -M address
+ --mail address
+ Users return email address, needed for submitting an entry
+ to freedb.org; default: not set.
+
+ -D '\"...\$parameters...\"'
+ --dirtemplate '\"...\$parameters...\"'
+ Use single AND double quotes to pass the parameters of the
+ templates! Allowed are following parameters: \$album,
+ \$artist, \$genre, \$trackname, \$tracknum and \$year, e. g.
+ '\"\$artist - \$year\"'.
+ Default dirtemplate: '\"\$artist - \$album\"' ,
+ default tracktemplate: '\"\$tracknum \$trackname\"' .
+
+ -T '\"...\$parameters...\"'
+ --tracktemplate '\"...\$parameters...\"'
+ See above.
+
+ -n value
+ --nice value
+ Set niceness of encoding process, default 0.
+
+ -a
+ --archive
+ Read and save CDDB files in ~/.cddb/\"category\" directory,
+ where the \"category\" is one of the 11 CDDB categories.
+ Default: off.
+
+ -e
+ --eject
+ Ejects the CD when finished, if your hardware supports it;
+ default off.
+
+ --halt
+ Powers off the machine when finished if your configuration
+ supports it; default: off.
+
+ -s
+ --submission
+ Specify --nosubmission if the computer is offline and the
+ created file cddb.toc shall be saved in the home directory
+ instead of being submitted. With option --archive it will
+ also be saved in the ~/.cddb directory. Note: it is really
+ easy to resubmit incomplete CDDB entries! One can confirm
+ each existing field with Enter and add a missing genre or
+ year. The purpose of this option is to permit the user to
+ edit the CDDB data for the own tags, but not to overwrite
+ the original CDDB entry! Default: off.
+
+ -p
+ --playlist
+ Create the m3u playlist file, or use --noplaylist. Default
+ on.
+
+ -i
+ --interaction
+ Specify --nointeraction if ripit shall take the first CDDB
+ entry found and rip without any questioning. Default: on.
+
+ --lcd
+ Use lcdproc to display status, default: not set.
+
+ --lcdhost
+ Specify the lcdproc host, default: localhost.
+
+ --lcdport
+ Specify the lcdport, default: default: 13666.
+
+ -l
+ --lowercase
+ Lowercase filenames, default: off.
+
+ --quiet
+ Do not output any comments, default: off.
+
+ -u
+ --underscore
+ Use underscores _ instead of spaces in filenames, default:
+ off.
+
+ -U
+ --utftag
+ Decode tags (but not filenames) from UTF-8 to ISO8859-1 if
+ (mp3) player doesn't support them in UTF-8, default: off.
+
+ --encode
+ Do encode the wavs. Prevent encoding if only the wav-files
+ shall be created (then use option --wav, see below).
+ Default: on, else use --noencode.
+
+ -w
+ --wav
+ Keep the wav files after encoding instead of deleting them
+ default: off.
+
+ -h
+ --help Print this and exit.
+
+ -V
+ --version
+ Print version and exit.
+
+ --config
+ Read parameters from config file or specify --noconfig to
+ prevent reading it; default: on.
+
+ --save Add parameters passed on command line to config file. This
+ options does not overwrite other settings. An existing
+ config file will be saved as config.old. Default: off.
+
+ --savenew
+ Save all parameters passed on command line to a new config
+ file, backup an existing file to config.old. Default: off.
+
+
+\n
+EXAMPLES
+ To specify a CD device, type
+
+ ripit --device /dev/sr1
+
+ To specify the output directory, type
+
+ ripit --outputdir /foo/paths/
+
+ To rip'n'code a special track selection, type
+
+ ripit 1,3-6,8-11
+
+ To use several encoders in the same run, type
+
+ ripit --coder 1,0,2 --quality 3,6
+
+ Note: in this case, RipIT assumes that Lame (encoder 0) is used
+ in CBR mode wihtout quality option, so Ogg (encoder 1) will get
+ quality 3 and Flac (encoder 2) quality 6.
+
+ To use Lame with variable bitrate (VBR), type
+
+ ripit --vbrmode new --bitrate 0
+
+ Note, one should reset the --bitrate to 0 (zero) if the -b option
+ of Lame is not desired. According to VBR mode in Lame, use \"new\"
+ or \"old\". It is recommended to use the preset switches for Lame,
+ (see Lame-man-page) and specify fast encoding with --vbrmode new
+
+ ripit --preset extreme --vbrmode new
+
+ To define a directory template where the sound files should go,
+ type
+
+ ripit --dirtemplate '\"\$artist - \$year\"'
+
+ To save a config file in ~/home/.ripit/ with options: to use Lame
+ and Ogg, don't create a m3u file, archive the CDDB entry files in
+ ~/.cddb/\"category\"/ and to eject CD when done, type
+
+ ripit --coder 0,1 --noplaylist --archive --eject --save
+
+ If ripit hangs during CDDB lookup, choose an other mirror instead
+ of default freedb.freedb.org server, e. g. at.freedb.org
+
+ ripit --mirror at
+
+ To do the job without any interaction, type
+
+ ripit --nointeraction
+
+ To use a network for encoding, make sure that the paths are equal
+ on all machines!
+
+ ripit --sshlist sun,saturn,tethys
+
+ where sun, saturn and tethys are remote machines on which a user
+ can login via ssh without entering a password or passphrase! Note
+ that the paths must be equal for the user on all remote machines!
+ If the login is different on some machines, try
+
+ ripit --sshlist login1\@sun,login2\@saturn,login3\@tethys
+
+ If there is \"no\" identical path on the remote machines, then the
+ user might enter e.g. /tmp/ as output directory.
+ If the file-system is not mounted on each remote machine, one can
+ try to copy the wavs to the remote machines using option --scp.
+
+ ripit --sshlist sun,saturn,tethys --scp
+
+FILES
+ .ripit/config
+ User config file.
+
+ /usr/share/doc/packages/ripit/README
+ /usr/share/doc/packages/ripit/HISTORY
+ /usr/share/doc/packages/ripit/LICENSE
+
+BUGS
+ Probably there are more than some.
+
+SEE ALSO
+ cdparanoia(1), lame(1), oggenc(1), flac(1),
+
+AUTHORS
+ RipIT is now maintained by Felix Suwald, please send bugs, wishes
+ comments to ripit _[at]_ suwald _[dot]_ com. For bugs, wishes and
+ comments about lcdproc, contact max.kaesbauer [at] gmail[dot]com.
+ Former maintainer: Mads Martin Joergensen; RipIT was originally
+ developed by Simon Quinn.
+
+DATE
+ 28 Jun 2005
+
+
+ \n\n";
+}
+########################################################################
+#
+# Change encoding of tags back to iso-8859-1.
+#
+sub back_encoding {
+ my $temp_file = "/tmp/utf8-$$\.txt";
+ open(TMP, ">$temp_file") or print "$temp_file $!";
+ print TMP $_[0];
+ close TMP;
+ my $decoded = `/usr/bin/iconv -f UTF-8 -t ISO-8859-1 $temp_file`;
+ unlink("/tmp/utf8-$$\.txt");
+ return $decoded;
+}
+########################################################################
+#
+# Check the preset options.
+#
+sub check_preset {
+ if($preset !~ /^\d/) {
+ while($preset !~ /^insane$|^extreme$|^standard$|^medium$/) {
+ print "\nPreset should be one of the following words! Please Enter \n";
+ print "insane (320\@CBR), extreme (256), standard (192) or medium (160), (standard): ";
+ $preset = <STDIN>;
+ chomp $preset;
+ if($preset eq "") {
+ $preset = "standard";
+ }
+ }
+ }
+ else {
+ while($preset !~ /^32$|^40$|^48$|^56$|^64$|^80$|^96$|^112$|^128$|^160$|^192$|^224$|^256$|^320$/) {
+ print "\nPreset should be one of the following numbers! Please Enter \n";
+ print "32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 or 320, (128):\n";
+ $preset = <STDIN>;
+ chomp $preset;
+ if($preset eq "") {
+ $preset = 128;
+ }
+ }
+ }
+ $preset = "medium" if($preset == 160);
+ $preset = "standard" if($preset == 192);
+ $preset = "extreme" if($preset == 256);
+ $preset = "insane" if($preset == 320);
+ $wpreset = $preset;
+}
+########################################################################
+#
+# Check sshlist of remote machines and create a hash.
+#
+sub check_sshlist {
+ if(@psshlist) {
+ @sshlist = split(/,/, join(',',@psshlist));
+ }
+ if(@sshlist) {
+ $sshflag = 1;
+ $wsshlist = join(',',@sshlist);
+ # Now create a hash with all machines and a flag.
+ # We don't need the flag yet...
+ $sshlist{'local'} = '0' if($local == 1);
+ foreach (@sshlist) {
+ $sshlist{$_} = '0';
+ }
+ }
+ else {
+ $sshflag = 0;
+ }
+}
+########################################################################
+#
+# Dispatcher for encoding on remote machines. If there are no .lock
+# files, a ssh command will be passed, else the dispatcher waits until
+# an already passed ssh command terminates and removes the lock file.
+# The dispatcher checks all machines all 6 seconds until a machine is
+# available. If option -scp is used, the dispatcher will not start an
+# other job while copying. If it happens, that one machine ended, it
+# looks like nothing would happen during scp.
+#
+sub enc_ssh {
+ my $machine;
+ my @codwav = ();
+ my $delwav = $_[0];
+ my $enccom = $_[1];
+ my $ripnam = $_[2];
+ my $shortname = $_[3];
+ my $sufix = $_[4];
+ my $old_mp3dir = $mp3dir;
+ my $old_ripnam = $ripnam;
+ $sshflag = 2;
+ while ($sshflag == 2) {
+ # Start on the local machine first.
+ if(! -r "$mp3dir/local.lock") {
+ if($local == 1) {
+ $sshflag = 1;
+ $machine = "local";
+ push @codwav, "$shortname";
+ }
+ }
+ last if($sshflag == 1);
+ foreach $_ (keys %sshlist) {
+ $machine = $_;
+ if(! -r "$mp3dir/$machine.lock") {
+ $sshflag = 1;
+ }
+ # Prepare array @codwav with all tracknames in,
+ # which are still in progress.
+ else {
+ open(LOCK, "$mp3dir/$machine.lock");
+ my @locklines = <LOCK>;
+ close LOCK;
+ my $locklines = @locklines[0] if(@locklines[0]);
+ chomp $locklines;
+ # Push trackname into array only if not yet
+ # present.
+ my @presence = grep(/$locklines/, @codwav);
+ my $presence = $presence[0];
+ push @codwav, "$locklines" if(! $presence);
+ }
+ last if($sshflag == 1);
+ }
+ last if($sshflag == 1);
+ sleep 3;
+ }
+ open(LOCKF, ">$mp3dir/$machine.lock");
+ print LOCKF "$shortname.$sufix\n";
+ close (LOCKF);
+ # We need more quotes for the commands (faac,flac,lame,ogg)
+ # passed to the remote machen. NOTE: But now pay attention
+ # to single quotes in tags. Quote them outside of single quotes!
+ # TODO: Please tell me how to quote leading periods, thanks!!!
+ if($machine !~ /^local$/) {
+ $enccom =~ s/'/'\\''/g;
+ $enccom = "'".$enccom."'";
+ $enccom = "ssh $machine " . $enccom;
+ if($scp) {
+ # CREATE the directory:
+ # Please tell me why one has to quote the double quotes
+ # with a backslash when using ssh!
+ $mp3dir = esc_char($mp3dir);
+ system("ssh $machine mkdir -p \\\"$mp3dir\\\"");
+ # COPY the File:
+ # Please tell me why one should NOT quote a file name
+ # with blanks when using scp!
+ $ripnam = esc_char($ripnam);
+ system("scp $ripnam.wav $machine:\"$ripnam.wav\" > /dev/null 2> /dev/null");
+ }
+ }
+ $enccom = $enccom . " > /dev/null 2> /dev/null ";
+ if($machine !~ /^local$/ && $scp) {
+ $enccom = $enccom . " && scp $machine:\"$ripnam.$sufix\" $ripnam.$sufix > /dev/null 2> /dev/null && ssh $machine rm \"$ripnam.*\" ";
+ }
+ $enccom = $enccom . " && rm \"$old_mp3dir$machine.lock\" &";
+ system("$enccom");
+ $mp3dir = $old_mp3dir;
+ $ripnam = $old_ripnam;
+ # Delete the wav only if all encodings of this track are done!
+ # When the last encoding of a track started, its name is pushed
+ # into the array @delname. Then the first (oldest) entry is
+ # compared to the @codwav array. If still present, nothing
+ # happens, else the wav will be deleted and the trackname
+ # shifted.
+ if($delwav == 1) {
+ push @delname, "$shortname";
+ my $delflag = 0;
+ while ($delflag == 0) {
+ my $delname = $delname[0];
+ my @delwav = grep(/$delname/, @codwav);
+ if($delwav[0] eq "" && $#delname > 1) {
+ unlink("$mp3dir/$delname.wav");
+ shift(@delname);
+ # Prevent endless loop if array is empty.
+ $delflag = 1 if($delwav[0] eq "");
+ }
+ else {
+ $delflag = 1;
+ }
+ }
+ }
+}
+########################################################################
+#
+# Delete wavs if sshlist was used. TODO: Improve code for following
+# situation: if no .lock files are found, but the encoder did not yet
+# finish, don't delete the wavs. Do it only after 3*4 seconds timeout
+# with no .lock file.
+#
+sub del_wav {
+ my $waitflag = 1;
+ sleep 3;
+ while ($waitflag <= 3) {
+ sleep 3;
+ opendir(DIR, "$mp3dir");
+ my @locks = readdir(DIR);
+ closedir(DIR);
+ @locks = grep { /\.lock$/ } @locks;
+ $waitflag++ if(! @locks);
+ $waitflag = 0 if(@locks);
+ }
+ if($wav == 0) {
+ opendir(DIR, "$mp3dir");
+ my @wavs = readdir(DIR);
+ closedir(DIR);
+ @wavs = grep { /\.wav$/ } @wavs;
+ unlink("$mp3dir/$_") foreach (@wavs);
+ }
+ if($scp) {
+ my $old_mp3dir = $mp3dir;
+ $mp3dir = esc_char($mp3dir);
+ foreach $_ (keys %sshlist) {
+ $machine = $_;
+ system("ssh $machine rmdir \\\"$mp3dir\\\" > /dev/null 2> /dev/null") if($machine !~ /^local$/);
+ }
+ $mp3dir = $old_mp3dir;
+ }
+}
+########################################################################
+#
+# LCDproc subroutines, all credits to Max Kaesbauer. For comments and
+# questions contact max [dot] kaesbauer [at] gmail [dot] com.
+#
+
+# print
+
+sub plcd {
+ ($data) = @_;
+ print $lcdproc $data."\n";
+ $res = <$lcdproc>;
+}
+
+# update
+
+sub ulcd {
+ if($lcdoline1 ne $lcdline1) {
+ $lcdoline1 = $lcdline1;
+ plcd("widget_set ripitlcd line1 1 2 {$lcdline1}");
+ }
+ if($lcdoline2 ne $lcdline2) {
+ $lcdoline2 = $lcdline2;
+ plcd("widget_set ripitlcd line2 1 3 {$lcdline2}");
+ }
+ if($lcdoline3 ne $lcdline3) {
+ $lcdoline3 = $lcdline3;
+ plcd("widget_set ripitlcd line3 1 4 {$lcdline3}");
+ }
+}
+
+# init
+
+sub init_lcd {
+ $lcdproc = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => $lcdhost,
+ PeerPort => $lcdport,
+ ) || die "Cannot connect to LCDproc port\n";
+ $lcdproc->autoflush(1);
+ sleep 1;
+
+ print $lcdproc "hello\n";
+ @lcd_specs = split(/ /,<$lcdproc>);
+
+ $screen{wid} = $lcd_specs[7];
+ $screen{hgt} = $lcd_specs[9];
+ $screen{cellwid} = $lcd_specs[11];
+ $screen{cellhgt} = $lcd_specs[13];
+
+ $screen{pixwid} = $screen{wid}*$screen{cellwid};
+ $screen{pixhgt} = $screen{hgt}*$screen{cellhgt};
+
+ fcntl($lcdproc, F_SETFL, O_NONBLOCK);
+
+ plcd("client_set name {ripit.pl}");
+ plcd("screen_add ripitlcd");
+ plcd("screen_set ripitlcd name {ripitlcd}");
+
+ plcd("widget_add ripitlcd title title");
+ plcd("widget_set ripitlcd title {RipIT $version}");
+
+ plcd("widget_add ripitlcd line1 string");
+ plcd("widget_add ripitlcd line2 string");
+ plcd("widget_add ripitlcd line3 string");
+}
+########################################################################
+#
+# Read the CDDB on the local machine.
+#
+sub read_entry {
+ $logfile = $_[0];
+ open(LOG, $logfile);
+ my @cddblines = <LOG>;
+ close(LOG);
+ %cd = ();
+ # Note that long lines may be split into several lines
+ # all starting with the same keyword, e.g. DTITLE.
+ if($multi == 0) {
+ $cd{raw} = \@cddblines;
+ my @artist = grep(s/^DTITLE=//g, @cddblines);
+ $artist = join(' / ',@artist);
+ $artist =~ s/[\015]//g;
+ $artist =~ s/\n\s\/\s//g;
+ chomp $artist;
+ # Artist is just the first part before first occurrence of
+ # of /, album gets all the rest!
+ my @disctitle = split(/\s\/\s/, $artist);
+ $artist = shift(@disctitle);
+ $album = join(' / ',@disctitle);
+ chomp $artist;
+ chomp $album;
+ $cat = $_[1];
+ my @genre = grep(s/^DGENRE=//, @cddblines);
+ $genre = @genre[0] if($genre eq "");
+ $genre =~ s/[\015]//g;
+ chomp $genre;
+ my @year = grep(s/^DYEAR=//, @cddblines);
+ $year = @year[0];
+ $year =~ s/[\015]//g;
+ chomp $year;
+ $trackno = $_[2];
+ }
+ else {
+ my @artist = grep(s/^artist:\s//, @cddblines);
+ $artist = @artist[0];
+ chomp $artist;
+ my @album = grep(s/^title:\s//, @cddblines);
+ $album = @album[0];
+ chomp $album;
+ my @category = grep(s/^category:\s//, @cddblines);
+ $cat = @category[0];
+ chomp $cat;
+ my @genre = grep(s/^genre:\s//, @cddblines);
+ $genre = @genre[0];
+ chomp $genre;
+ my @year = grep(s/^year:\s//, @cddblines);
+ $year = @year[0];
+ chomp $year;
+ my @cddbid = grep(s/^cddbid:\s//, @cddblines);
+ $cddbid = @cddbid[0];
+ chomp $cddbid;
+ my @trackno = grep(s/^trackno:\s//, @cddblines);
+ $trackno = @trackno[0];
+ chomp $trackno;
+ }
+ $cd{artist} = $artist;
+ $cd{title} = $album;
+ $cd{cat} = $cat;
+ $cd{genre} = $genre;
+ $cd{year} = $year;
+ my $i=1;
+ my $j=0;
+ while($i <= $trackno){
+ my @track = ();
+ @track = grep(s/^TTITLE$j=//, @cddblines) if($multi == 0);
+ @track = grep(s/^track\s$i:\s//, @cddblines) if($multi == 1);
+ $track = join(' / ',@track);
+ $track =~ s/[\015]//g;
+ $track =~ s/\n\s\/\s//g;
+ chomp $track;
+ $cd{track}[$j]=$track;
+ $i++;
+ $j++;
+ }
+}
+########################################################################
+#
+# Delete error.log if there is no Track comment in!
+#
+sub del_erlog {
+ if(-r "$mp3dir/error.log") {
+ open(ERR, "$mp3dir/error.log") || print "error.log disappeared!\n";
+ my @errlines = <ERR>;
+ close ERR;
+ my @ulink = grep(/Track /, @errlines);
+ if(!@ulink && $multi == 0) {
+ unlink("$mp3dir/error.log");
+ }
+ }
+}
+########################################################################
+#
+# Escape special characters when using scp.
+#
+sub esc_char {
+ $_[0] =~ s/\(/\\\(/g;
+ $_[0] =~ s/\)/\\\)/g;
+ $_[0] =~ s/\[/\\\[/g;
+ $_[0] =~ s/\]/\\\]/g;
+ $_[0] =~ s/\&/\\\&/g;
+ $_[0] =~ s/\'/\\\'/g;
+ $_[0] =~ s/ /\\ /g;
+ return $_[0];
+}
+########################################################################
+#
+# Calculate how much time ripping and encoding needed.
+#
+sub cal_times{
+ $encend = `date \'+%R\'`;
+ chomp $encend;
+ my @encstart = split(/:/, $encstart);
+ my @ripstart = split(/:/, $ripstart);
+ my @encend = split(/:/, $encend);
+ my @ripend = split(/:/, $ripend);
+ $riptime = ($ripend[0]*60+$ripend[1])-($ripstart[0]*60+$ripstart[1]);
+ $enctime = ($encend[0]*60+$encend[1])-($encstart[0]*60+$encstart[1]);
+}