Advertisement
Guest User

braintorch

a guest
Feb 10th, 2010
678
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 41.59 KB | None | 0 0
  1. #!/bin/bash
  2. PATH=${PATH}:/bin:/usr/bin:/usr/local/bin
  3.  
  4. [ ${SHELL} = "/bin/bash" ] || exit "Bash required!"
  5.  
  6. # set CPU_NUMBER to the number of your CPUs. This variable is used by FlaCuda.
  7.  
  8. CPU_NUMBER=1
  9.  
  10. # --== ERRORS ==--
  11.  
  12. chk_error=0
  13.  
  14. NO_ERR=0
  15. E_UNK=1
  16.  
  17. E_TOOL_NOT_FOUND=2
  18. E_UNK_OUT_CODEC=3
  19. E_UNK_IN_CODEC=4
  20. E_IN_FILE_NOT_FOUND=5
  21.  
  22. E_TOOL_CBP_NOT_FOUND=6
  23. E_TOOL_CP_NOT_FOUND=7
  24. E_TOOL_ST_NOT_FOUND=8
  25. E_TOOL_F_NOT_FOUND=9
  26. E_TOOL_IC_NOT_FOUND=10
  27.  
  28. E_TAG_APE_NOT_FOUND=11
  29. E_TAG_FLAC_NOT_FOUND=12
  30. E_TAG_MP3_NOT_FOUND=13
  31. E_TAG_OGG_NOT_FOUND=14
  32.  
  33. E_CODEC_FLAC_NOT_FOUND=15
  34. E_CODEC_FLAKE_NOT_FOUND=16
  35. E_CODEC_APE_NOT_FOUND=17
  36. E_CODEC_WVp_NOT_FOUND=18
  37. E_CODEC_WVu_NOT_FOUND=19
  38. E_CODEC_OFR_NOT_FOUND=20
  39. E_CODEC_SHN_NOT_FOUND=21
  40. E_CODEC_TTA_NOT_FOUND=22
  41. E_CODEC_MP3_NOT_FOUND=23
  42. E_CODEC_OGGd_NOT_FOUND=24
  43. E_CODEC_OGGe_NOT_FOUND=25
  44. E_CODEC_FLACUDA_NOT_FOUND=66
  45.  
  46. E_UNK_CODEPAGE=26
  47. E_CODEPAGE_NOT_SET=27
  48. E_CANT_CONVERT_CUE=28
  49.  
  50. E_CANT_SPLIT=29
  51. E_CANT_READ_CUE=30
  52.  
  53. E_CANT_TAG_FLAC=31
  54. E_CANT_TAG_APE=32
  55. E_CANT_TAG_MP3=33
  56. E_CANT_TAG_OGG=34
  57.  
  58. E_CANT_MKDIR=35
  59. E_CANT_MOVE_FILE=36
  60.  
  61. E_WRONG_NUM_TRACKS=37
  62.  
  63. E_NOT_CUE_FILE=38
  64.  
  65. E_CANT_FIX_CUE=39
  66.  
  67. E_TAG_M4A_NOT_FOUND=40
  68. E_CODEC_M4Ae_NOT_FOUND=41
  69. E_CODEC_M4Ad_NOT_FOUND=42
  70. E_CANT_TAG_M4A=43
  71.  
  72. E_OPTERROR=65
  73.  
  74. # --== VARIABLES ==--
  75.  
  76. NO_ARGS=0
  77.  
  78. NAME="CUE 2 Tracks"
  79. DESC="Tool for spliting audio CD image to tracks with cue sheet info."
  80. VER="0.2.11"
  81. AUTHOR="Sergey (sergey.dryabzhinsky@gmail.com)"
  82.  
  83. # (tool|tag|codec)_* - set to <file> if its exists, "" otherwise
  84.  
  85. MIN_SHNTOOL_VERSION=300
  86.  
  87. tool_CBP=""
  88. tool_CP=""
  89. tool_ST=""
  90. tool_F=""
  91. tool_IC=""
  92.  
  93. tag_APE=""
  94. tag_FLAC=""
  95. tag_MP3=""
  96. tag_OGG=""
  97. tag_M4A=""
  98.  
  99. codec_FLAC=""
  100. codec_FLAKE=""
  101. codec_APE=""
  102. codec_WVp=""
  103. codec_WVu=""
  104. codec_OFR=""
  105. codec_SHN=""
  106. codec_TTA=""
  107. codec_FLACUDA=""
  108.  
  109. codec_MP3=""
  110. codec_OGGd=""
  111. codec_OGGe=""
  112. codec_M4Ae=""
  113. codec_M4Ad=""
  114.  
  115. codec_IN=""
  116. codec_OUT=""
  117.  
  118. # (tool|tag|codec)_*_needed - set to 1 if its needed, 0 otherwise
  119.  
  120. tool_CBP_needed=1
  121. tool_CP_needed=1
  122. tool_ST_needed=1
  123. tool_F_needed=1
  124. tool_IC_needed=0
  125.  
  126. tag_APE_needed=0
  127. tag_FLAC_needed=0
  128. tag_MP3_needed=0
  129. tag_OGG_needed=0
  130. tag_M4A_needed=0
  131.  
  132. codec_FLAC_needed=0
  133. codec_FLAKE_needed=0
  134. codec_APE_needed=0
  135. codec_WVp_needed=0
  136. codec_WVu_needed=0
  137. codec_OFR_needed=0
  138. codec_SHN_needed=0
  139. codec_TTA_needed=0
  140. codec_MP3_needed=0
  141. codec_OGGd_needed=0
  142. codec_OGGe_needed=0
  143. codec_M4Ae_needed=0
  144. codec_M4Ad_needed=0
  145. codec_FLACUDA_needed=0
  146.  
  147. cueFile=""
  148. inFile=""
  149. inFileDir=""
  150. file_splitlog=""
  151. file_splitlogwork=""
  152. outCodec="flac"
  153. toolCodec="flac"
  154. outCodecLevel=0  # best
  155. outCodecParam=""
  156. outCodecQuality="4"
  157. outCodecBitRate=128
  158. outCodecMode="V"
  159. outExt="flac"
  160. inCodec=""
  161. inCodecParam=""
  162. inFile2WAV=0
  163.  
  164. fromCP=""
  165. locCP="ASCII"
  166.  
  167. outFormatStr="%N"
  168. outFileName=""
  169. tempDirName="."
  170. scriptName=`basename "$0"`
  171.  
  172. onlyTest=1
  173. quiteMode=0
  174. splitInTest=0
  175.  
  176. niceness=0
  177.  
  178. putTags=1
  179.  
  180. useColors=0
  181. useXTitle=0
  182.  
  183. pre_ALBUM_DATE=""
  184. pre_ALBUM_GENRE=""
  185. pre_ALBUM_DISCID=""
  186. pre_ALBUM_NUMBER=""
  187.  
  188. tags_ALBUM_TITLE=""
  189. tags_ALBUM_PERFORMER=""
  190. tags_ALBUM_COMPOSER=""
  191. tags_ALBUM_GENRE=""
  192. tags_ALBUM_DATE=""
  193. tags_ALBUM_TRACKS=0
  194. tags_ALBUM_DISCID=""
  195. tags_ALBUM_NUMBER=""
  196. tags_TRACK_TITLE=""
  197. tags_TRACK_PERFORMER=""
  198. tags_TRACK_COMPOSER=""
  199. tags_TRACK_GENRE=""
  200. tags_TRACK_NUMBER=0
  201. tags_TRACK_ZNUMBER=0
  202.  
  203. # --== COLORS ==--
  204. color_default='\033[00m'
  205. color_red='\033[01;31m'
  206. color_green='\033[01;32m'
  207. color_yellow='\033[01;33m'
  208. color_magenta='\033[01;35m'
  209. color_cyan='\033[01;36m'
  210.  
  211. # --== FUNCTIONS ==--
  212. set_xterm_title() {
  213.     [ ${useXTitle} -ne 0 ] && echo -ne "\033]0;${NAME} v${VER} -= $1 =- \007"
  214. }
  215.  
  216. print_error() {
  217.     echo -e "${color_red}Error${color_default}: $1" >&2
  218. }
  219.  
  220. print_message() {
  221.     if [[ "$1" == "-n" ]]
  222.     then
  223.         [ ${quiteMode} -eq 0 ] && echo -e -n "$2"
  224.     else
  225.         [ ${quiteMode} -eq 0 ] && echo -e "$1"
  226.     fi
  227. }
  228.  
  229. # function for checking existance of tools
  230. checktool() {
  231.     tool="$1"
  232.     pk="$2"
  233.  
  234.     print_message -n "\t${color_yellow}*${color_default} Checking for '${color_cyan}${tool}${color_default}'..." >&2
  235.  
  236.     ctool=`which "${tool}" 2>/dev/null`
  237.     if [ ! -n "${ctool}" ]
  238.     then
  239.         print_message "\t[${color_red}failed${color_default}]! Install '${pk}'!\n" >&2
  240.         return ${E_TOOL_NOT_FOUND}
  241.     else
  242.         print_message "\t[${color_green}ok${color_default}]" >&2
  243.         echo "${ctool}"
  244.     fi
  245. }
  246.  
  247. # check shntool version
  248. check_shntool_version() {
  249.     print_message -n "\t${color_yellow}*${color_default} Checking '${color_cyan}shntool${color_default}' version..."
  250.     ver=`shntool -v 2>&1 | grep shntool | awk '{print $2}'`
  251.     ver_clean=`echo ${ver} | sed -e 's:\.::g'`
  252.     if ((${ver_clean}>=${MIN_SHNTOOL_VERSION}))
  253.     then
  254.         print_message "\t[${color_green}${ver}${color_default}]"
  255.         return 0
  256.     else
  257.         print_message "\t[${color_red}${ver}${color_default}]! Install version 3.0 or higher!\n"
  258.         return 1
  259.     fi
  260. }
  261.  
  262. # function for printing codecs
  263. print_codecs() {
  264.     echo -e "\tCodecs may be:\n\
  265. \t\twav     : no encode, raw sound wave,\n\
  266. \t\tflac    : (default) Free Lossless Audio Codec,\n\
  267. \t\tflake   : FLAC realisation via FFmpeg (beta),\n\
  268. \t\tape     : Monkey's Audio Codec,\n\
  269. \t\twv      : WavPack,\n\
  270. \t\tofr     : OptimFrog,\n\
  271. \t\tshn     : shorten,\n\
  272. \t\tmp3     : mpeg 1 layer 3 via lame,\n\
  273. \t\togg     : ogg vorbis\n\
  274. \t\tm4a     : aac with m4a container,\n\
  275. \t\tflacuda : cuda-accelerated flac-encoder,\n\
  276. " >&2
  277. }
  278.  
  279. # function for printing levels
  280. print_levels() {
  281.     echo -e "\tLevels may be:\n\
  282. \t\t'best' or 0 : Best for store (default),\n\
  283. \t\t'fast' or 1 : Fastest processing,\n\
  284. \t\t'mid'  or 2 : Fairly good for portable hardware\n\
  285. " >&2
  286. }
  287.  
  288. # function for printing naming scheme
  289. print_naming_scheme() {
  290.     echo -e "\tNaming scheme is:\n\
  291. \t\t%A : Album title\n\
  292. \t\t%a : Album disc number\n\
  293. \t\t%P : Album performer\n\
  294. \t\t%D : Album date\n\
  295. \t\t%G : Album genre\n\
  296. \t\t%t : Track title\n\
  297. \t\t%p : Track performer\n\
  298. \t\t%g : Track genre\n\
  299. \t\t%n : Track number\n\
  300. \t\t%N : Track number with leading zero\n\
  301. " >&2
  302. }
  303.  
  304. # function for print some program info
  305. print_info() {
  306.     echo -e "\n${color_yellow}${NAME}, ${DESC}${color_default}\n\tVersion: ${color_cyan}${VER}${color_default}\n\tAuthor : ${color_cyan}${AUTHOR}${color_default}\n" >&2
  307. }
  308.  
  309. # function for printing some help info
  310. print_help() {
  311.     print_info
  312.     echo -e "\
  313. Usage: ${scriptName} [options] <cue file>\n\
  314. Options:\n\
  315. \t-R              : Disable testing and doing nothing - starts Real work\n\
  316. \t-C              : Use colored messages\n\
  317. \t-X              : Set XTerm title\n\
  318. \t-i <image file> : Set CD image file. If not set - read from cue\n\
  319. \t-c <codec>      : Set output codec" >&2
  320.     print_codecs
  321.     echo -e "\
  322. \t-l <level> : Set level of output codec compression rate.\
  323. " >&2
  324.     print_levels
  325.     echo -e "\
  326. \t-f <codepage>      : Convert to UTF-8 from this 'codepage'\n\
  327. \t-d                 : Disable taging of output files with cue info\n\
  328. \t-A <album>         : Set album title\n\
  329. \t-P <performer>     : Set album performer\n\
  330. \t-K <composer>      : Set album composer\n\
  331. \t-D <date>          : Set album date\n\
  332. \t-G <genre>         : Set album genre\n\
  333. \t-I <id>            : Set album disk ID\n\
  334. \t-N <number>        : Set album disc number\n\
  335. \t-o <format string> : Set naming scheme for output files\
  336. " >&2
  337.     print_naming_scheme
  338.     echo -e "\
  339. \t-V         : Print version and exit\n\
  340. \t-h         : Print this help and exit\n\
  341. \t-q         : Quite mode - only errors to stderr\n\
  342. \t-s         : Start spliting even in testing mode (to /dev/null)\n\
  343. \t-n <level> : Nice level (process scheduling priority):\n\
  344. \t             From high (-19) to low (19)\n\
  345. \n\
  346. \tOptions only for mp3, ogg:\n\
  347. \t-Q <quality> : Set quality of codec compression (4 - default)\n\
  348. \tQuality may be:\n\
  349. \t\tMP3 :   0 - high,  9 - low\n\
  350. \t\tM4A : 500 - high, 10 - low\n\
  351. \t\tOGG :  10 - high, -1 - low\n\
  352. \t-B <bitrate>      : Set compression bitrate in kbps (default to 'high')\n\
  353. \t-M <bitrate mode> : C - Constant, V - Variable (default)\n\
  354. \t\tNote: If choosen V - then -B specifies maximum bitrate (only mp3)\n\
  355. \n\
  356. To get some action run:\n\
  357. \t${scriptName} -c flac -f cp1251 -o \"/path/to/music/%P/%D - %A/%N\" CDimage.cue\n\
  358. " >&2
  359. }
  360.  
  361. # function for print program version
  362. print_version() {
  363.     echo "${VER}"
  364. }
  365.  
  366. # function for checking output codecs
  367. check_outCodec() {
  368.     [ ! -n "${outCodec}" ] && outCodec="flac"
  369.  
  370.     outCodec=`echo ${outCodec} | tr [:upper:] [:lower:]`
  371.  
  372.     case "${outCodec}" in
  373.         "flac" )
  374.             codec_FLAC_needed=1
  375.             if [ ${putTags} -eq 1 ]; then tag_FLAC_needed=1; fi
  376.             outExt="flac"
  377.             toolCodec="${outCodec}"
  378.             outCodecParam=" flac -8 -o %f -"
  379.             [ ${outCodecLevel} -eq 1 ] && outCodecParam=" flac -1 -o %f -"
  380.             [ ${outCodecLevel} -eq 2 ] && outCodecParam=" flac -4 -o %f -"
  381.             codec_OUT="flac"
  382.         ;;
  383.         "flake" )
  384.             codec_FLAKE_needed=1
  385.             if [ ${putTags} -eq 1 ]; then tag_FLAC_needed=1; fi
  386.             outExt="flac"
  387.             toolCodec="${outExt}"
  388.             outCodecParam=" flake -12 - %f"
  389.             [ ${outCodecLevel} -eq 1 ] && outCodecParam=" flake -1 - %f"
  390.             [ ${outCodecLevel} -eq 2 ] && outCodecParam=" flake -4 - %f"
  391.             codec_OUT="flake"
  392.         ;;
  393.         "flacuda" )
  394.             codec_FLACUDA_needed=1
  395.             if [ ${putTags} -eq 1 ]; then tag_FLAC_needed=1; fi
  396.             outExt="flac"
  397.             toolCodec="${outExt}"
  398.             outCodecParam=" flacuda --cpu-threads ${CPU_NUMBER} -8 -o %f -"
  399.             [ ${outCodecLevel} -eq 1 ] && outCodecParam=" flacuda -1 -o %f -"
  400.             [ ${outCodecLevel} -eq 2 ] && outCodecParam=" flacuda -4 -o %f -"
  401.             codec_OUT="flacuda"
  402.         ;;
  403.         "ape" )
  404.             codec_APE_needed=1
  405.             if [ ${putTags} -eq 1 ]; then tag_APE_needed=1; fi
  406.             outExt="ape"
  407.             toolCodec="${outCodec}"
  408.             outCodecParam=" mac - %f -c5000"
  409.             [ ${outCodecLevel} -eq 1 ] && outCodecParam=" mac - %f -c1000"
  410.             [ ${outCodecLevel} -eq 2 ] && outCodecParam=" mac - %f -c3000"
  411.             codec_OUT="mac"
  412.         ;;
  413.         "wv" )
  414.             codec_WVp_needed=1
  415.             if [ ${putTags} -eq 1 ]; then tag_APE_needed=1; fi
  416.             outExt="wv"
  417.             toolCodec="${outCodec}"
  418.             outCodecParam=" wavpack -hh -x6 - -o %f"
  419.             [ ${outCodecLevel} -eq 1 ] && outCodecParam=" wavpack -f - -o %f"
  420.             [ ${outCodecLevel} -eq 2 ] && outCodecParam=" wavpack -h - -o %f"
  421.             codec_OUT="wavpack"
  422.         ;;
  423.         "ofr" )
  424.             codec_OFR_needed=1
  425.             toolCodec="${outCodec}"
  426.             outExt="ofr"
  427.             codec_OUT="optimfrog"
  428.         ;;
  429.         "shn" )
  430.             codec_SHN_needed=1
  431.             toolCodec="${outCodec}"
  432.             outExt="shn"
  433.             codec_OUT="shorten"
  434.         ;;
  435.         "mp3" )
  436.             codec_MP3_needed=1
  437.             if [ ${putTags} -eq 1 ]; then tag_MP3_needed=1; fi
  438.             outExt="mp3"
  439.             toolCodec="cust"
  440.             outCodecParam=" ext=mp3 lame -S -m j -q ${outCodecQuality}"
  441.             if [ "${outCodecMode}" = "C" ]
  442.             then
  443.                 outCodecParam=" ${outCodecParam} --cbr -b ${outCodecBitRate}"
  444.             else
  445.                 outCodecParam=" ${outCodecParam} -v --vbr-new -B ${outCodecBitRate} -V ${outCodecQuality}"
  446.             fi
  447.             outCodecParam=" ${outCodecParam} - %f"
  448.             codec_OUT="lame"
  449.         ;;
  450.         "m4a" )
  451.             codec_M4Ae_needed=1
  452.             if [ ${putTags} -eq 1 ]; then tag_M4A_needed=1; fi
  453.             outExt="m4a"
  454.             toolCodec="cust"
  455.             outCodecParam=" ext=m4a faac"
  456.             if [ "${outCodecMode}" = "C" ]
  457.             then
  458.                 outCodecParam=" ${outCodecParam} -b ${outCodecBitRate}"
  459.             else
  460.                 outCodecParam=" ${outCodecParam} -q ${outCodecQuality}"
  461.             fi
  462.             outCodecParam=" ${outCodecParam} -w - -o %f"
  463.             codec_OUT="faac"
  464.         ;;
  465.         "ogg" )
  466.             codec_OGGe_needed=1
  467.             if [ ${putTags} -eq 1 ]; then tag_OGG_needed=1; fi
  468.             outExt="ogg"
  469.             toolCodec="cust"
  470.             outCodecParam=" ext=ogg oggenc -Q"
  471.             if [ "${outCodecMode}" = "C" ]
  472.             then
  473.                 outCodecParam=" ${outCodecParam} -b ${outCodecBitRate}"
  474.             else
  475.                 outCodecParam=" ${outCodecParam} -q ${outCodecQuality}"
  476.             fi
  477.             outCodecParam=" ${outCodecParam} -o %f -"
  478.             codec_OUT="oggenc"
  479.         ;;
  480.         "wav" )
  481.             outExt="wav"
  482.             toolCodec="wav"
  483.             putTags=0
  484.         ;;
  485.         * )
  486.             print_error "Output codec '${color_cyan}${outCodec}${color_default}' not supported."
  487.             [ ${quiteMode} -eq 0 ] && print_codecs
  488.             return ${E_UNK_OUT_CODEC}
  489.         ;;
  490.     esac
  491.     print_message "\tSetting output codec to '${color_cyan}${outCodec}${color_default}'"
  492. }
  493.  
  494. check_inCodec() {
  495.     [ ! -n "${inFile}" ] && inFile=`grep -m 1 FILE "${cueFile}" | sed -r 's/(.?*)\"(.?*)\"(.?*)/\2/g'`
  496.  
  497.     print_message "\tFile to split: '${color_cyan}${inFileDir}/${inFile}${color_default}'"
  498.  
  499.     if [ ! -e "${inFileDir}/${inFile}" ]
  500.     then
  501.         print_error "File '${color_cyan}${inFileDir}/${inFile}${color_default}' not founded!"
  502.         [ ${onlyTest} -eq 0 ] && return ${E_IN_FILE_NOT_FOUND}
  503.     fi
  504.  
  505.     inCodec="${inFile##*.}"
  506.     inCodec=`echo ${inCodec} | tr [:upper:] [:lower:]`
  507.  
  508.     case "${inCodec}" in
  509.         "flac" )
  510.             codec_FLAC_needed=1
  511.             codec_IN="flac"
  512.         ;;
  513.         "ape" )
  514.             codec_APE_needed=1
  515.             codec_IN="mac"
  516.         ;;
  517.         "wv" )
  518.             codec_WVu_needed=1
  519.             codec_IN="wvunpack"
  520.         ;;
  521.         "ofr" )
  522.             codec_OFR_needed=1
  523.             codec_IN="optimfrog"
  524.         ;;
  525.         "shn" )
  526.             codec_SHN_needed=1
  527.             codec_IN="shorten"
  528.         ;;
  529.         "tta" )
  530.             codec_TTA_needed=1
  531.             codec_IN="ttaenc"
  532.         ;;
  533.         "mp3" )
  534.             codec_MP3_needed=1
  535.             codec_IN="wav"
  536.             inFile2WAV=1
  537.         ;;
  538.         "m4a" )
  539.             codec_M4Ad_needed=1
  540.             codec_IN="wav"
  541.             inFile2WAV=1
  542.         ;;
  543.         "ogg" )
  544.             codec_OGGe_needed=1
  545.             codec_IN="wav"
  546.             inFile2WAV=1
  547.         ;;
  548.         "wav" )
  549.         ;;
  550.         * )
  551.             print_error "Input codec '${color_cyan}${inCodec}${color_default}' not supported."
  552.             return ${E_UNK_IN_CODEC}
  553.         ;;
  554.     esac
  555.     print_message "\tSetting input codec to '${color_default}${inCodec}${color_default}'"
  556. }
  557.  
  558. # function for search tools
  559. search_tools() {
  560.     if [ ${tool_CBP_needed} -eq 1 ]
  561.     then
  562.         tool_CBP=`checktool cuebreakpoints cuetools`
  563.         [ -n "${tool_CBP}" ] || return ${E_TOOL_CBP_NOT_FOUND}
  564.     fi
  565.  
  566.     if [ ${tool_CP_needed} -eq 1 ]
  567.     then
  568.         tool_CP=`checktool cueprint cuetools`
  569.         [ -n "${tool_CP}" ] || return ${E_TOOL_CP_NOT_FOUND}
  570.     fi
  571.  
  572.     if [ ${tool_ST_needed} -eq 1 ]
  573.     then
  574.         tool_ST=`checktool shntool shntool`
  575.         [ -n "${tool_ST}" ] || return ${E_TOOL_ST_NOT_FOUND}
  576.         check_shntool_version || return ${E_TOOL_ST_NOT_FOUND}
  577.     fi
  578.  
  579.     if [ ${tool_F_needed} -eq 1 ]
  580.     then
  581.         tool_F=`checktool file file`
  582.         [ -n "${tool_F}" ] || return ${E_TOOL_F_NOT_FOUND}
  583.     fi
  584.  
  585.     if [ ${tool_IC_needed} -eq 1 ]
  586.     then
  587.         tool_IC=`checktool iconv glibc`
  588.         [ -n "${tool_IC}" ] || return ${E_TOOL_IC_NOT_FOUND}
  589.     fi
  590. }
  591.  
  592. # function for searching (de|en)coders
  593. search_dencoders() {
  594.     if [ ${codec_WVp_needed} -eq 1 ]
  595.     then
  596.         codec_WVp=`checktool wavpack wavpack`
  597.         [ -n "${codec_WVp}" ] || return ${E_CODEC_WVp_NOT_FOUND}
  598.     fi
  599.  
  600.     if [ ${codec_WVu_needed} -eq 1 ]
  601.     then
  602.         codec_WVu=`checktool wvunpack wavpack`
  603.         [ -n "${codec_WVu}" ] || return ${E_CODEC_WVu_NOT_FOUND}
  604.     fi
  605.  
  606.     if [ ${codec_SHN_needed} -eq 1 ]
  607.     then
  608.         codec_SHN=`checktool shorten shorten`
  609.         [ -n "${codec_SHN}" ] || return ${E_CODEC_SHN_NOT_FOUND}
  610.     fi
  611.  
  612.     if [ ${codec_APE_needed} -eq 1 ]
  613.     then
  614.         codec_APE=`checktool mac mac`
  615.         [ -n "${codec_APE}" ] || return ${E_CODEC_APE_NOT_FOUND}
  616.     fi
  617.  
  618.     if [ ${codec_FLAC_needed} -eq 1 ]
  619.     then
  620.         codec_FLAC=`checktool flac flac`
  621.         [ -n "${codec_FLAC}" ] || return ${E_CODEC_FLAC_NOT_FOUND}
  622.     fi
  623.  
  624.     if [ ${codec_FLAKE_needed} -eq 1 ]
  625.     then
  626.         codec_FLAKE=`checktool flake flake`
  627.         [ -n "${codec_FLAKE}" ] || return ${E_CODEC_FLAKE_NOT_FOUND}
  628.     fi
  629.  
  630.     if [ ${codec_OFR_needed} -eq 1 ]
  631.     then
  632.         codec_OFR=`checktool ofr optimfrog`
  633.         [ -n "${codec_OFR}" ] || return ${E_CODEC_OFR_NOT_FOUND}
  634.     fi
  635.  
  636.     if [ ${codec_TTA_needed} -eq 1 ]
  637.     then
  638.         codec_TTA=`checktool ttaenc ttaenc`
  639.         [ -n "${codec_TTA}" ] || return ${E_CODEC_TTA_NOT_FOUND}
  640.     fi
  641.  
  642.     if [ ${codec_MP3_needed} -eq 1 ]
  643.     then
  644.         codec_MP3=`checktool lame lame`
  645.         [ -n "${codec_MP3}" ] || return ${E_CODEC_MP3_NOT_FOUND}
  646.     fi
  647.  
  648.     if [ ${codec_M4Ae_needed} -eq 1 ]
  649.     then
  650.         codec_M4Ae=`checktool faac faac`
  651.         [ -n "${codec_M4Ae}" ] || return ${E_CODEC_M4Ae_NOT_FOUND}
  652.     fi
  653.  
  654.     if [ ${codec_M4Ad_needed} -eq 1 ]
  655.     then
  656.         codec_M4Ad=`checktool faad faad`
  657.         [ -n "${codec_M4Ad}" ] || return ${E_CODEC_M4Ad_NOT_FOUND}
  658.     fi
  659.  
  660.     if [ ${codec_OGGd_needed} -eq 1 ]
  661.     then
  662.         codec_OGGd=`checktool oggdec oggdec`
  663.         [ -n "${codec_OGGd}" ] || return ${E_CODEC_OGGd_NOT_FOUND}
  664.     fi
  665.  
  666.     if [ ${codec_OGGe_needed} -eq 1 ]
  667.     then
  668.         codec_OGGe=`checktool oggenc oggenc`
  669.         [ -n "${codec_OGGe}" ] || return ${E_CODEC_OGGe_NOT_FOUND}
  670.     fi
  671.  
  672.     if [ ${codec_FLACUDA_needed} -eq 1 ]
  673.     then
  674.         codec_FLACUDA=`checktool flacuda flacuda`
  675.         [ -n "${codec_FLACUDA}" ] || return ${E_CODEC_FLACUDA_NOT_FOUND}
  676.     fi
  677. }
  678.  
  679. # function for search taging tools
  680. search_tagers() {
  681.     if [ ${tag_APE_needed} -eq 1 ]
  682.     then
  683.         tag_APE=`checktool apetag apetag`
  684.         [ -n "${tag_APE}" ] || return ${E_TAG_APE_NOT_FOUND}
  685.     fi
  686.  
  687.     if [ ${tag_FLAC_needed} -eq 1 ]
  688.     then
  689.         tag_FLAC=`checktool metaflac flac`
  690.         [ -n "${tag_FLAC}" ] || return ${E_TAG_FLAC_NOT_FOUND}
  691.     fi
  692.  
  693.     if [ ${tag_MP3_needed} -eq 1 ]
  694.     then
  695.         tag_MP3=`checktool id3v2 id3v2`
  696.         [ -n "${tag_MP3}" ] || return ${E_TAG_MP3_NOT_FOUND}
  697.     fi
  698.    
  699.     if [ ${tag_M4A_needed} -eq 1 ]
  700.     then
  701.         tag_M4A=`checktool mp4tags mpeg4ip-utils`
  702.         [ -n "${tag_M4A}" ] || return ${E_TAG_M4A_NOT_FOUND}
  703.     fi
  704.    
  705.     if [ ${tag_OGG_needed} -eq 1 ]
  706.     then
  707.         tag_OGG=`checktool vorbiscomment vorbis-tools`
  708.         [ -n "${tag_OGG}" ] || return ${E_TAG_OGG_NOT_FOUND}
  709.     fi
  710. }
  711.  
  712. #function for trying codepage
  713. try_codepage() {
  714.     tcp=$1
  715.     if [ -n "${tcp}" ]
  716.     then
  717.         trycdp=`${tool_IC} -l | grep -i "${tcp}"`
  718.         if [ ! -n "$trycdp" ]
  719.         then
  720.             print_error "Unknown codepage: '${color_cyan}${tcp}${color_default}..."
  721.             return ${E_UNK_CODEPAGE}
  722.         fi
  723.     else
  724.         return ${E_CODEPAGE_NOT_SET}
  725.     fi
  726. }
  727.  
  728. # function for geting ocale codepage
  729. get_local_codepage() {
  730.     if [ -n "${LANG}" ]
  731.     then
  732.         locCP=`echo ${LANG} | sed -r 's/(.?*)\.(.?*)/\2/g'`
  733.         [ ! -n "${locCP}" ] && locCP="ASCII"
  734.     else
  735.         locCP="ASCII"
  736.     fi
  737. }
  738.  
  739. is_file_unicode() {
  740.     # Check for BOM simbol
  741.     [ ! -f "$1" ] && return -1
  742.     bom=`head -c 3 "$1"`
  743.     [ ${bom} = $'\357\273\277' ] && return 1
  744.     return 0
  745. }
  746.  
  747. prepare_and_fix_cue() {
  748.     is_file_unicode "${cueFile}"
  749.     # Remove BOM record?
  750.     if [ $? -eq 1 ]
  751.     then
  752.         print_message "\t${color_yellow}Fix${color_default}: Now we try to remove BOM record..."
  753.         bnc=`basename "${cueFile}" .cue`
  754.         ncn="${tempDirName}/${bnc}.nobom.cue"
  755.         symbols=`cat "${cueFile}" | wc -c`
  756.         ((symbols-=3))
  757.         tail -c ${symbols} "${cueFile}" > "${ncn}"
  758.         [ $? -ne 0 ] && return ${E_CANT_FIX_CUE}
  759.         cueFile="${ncn}"
  760.         print_message "\tNew cue sheet file name: '${color_cyan}${cueFile}${color_default}'"
  761.     fi
  762.     lastline=`tail -n 1 "${cueFile}" | tr -d [:blank:] | tr -d [:cntrl:]`
  763.     if [[ "${lastline}" != "" ]]
  764.     then
  765.         print_message "\t${color_yellow}Fix${color_default}: Last empty line missing..."
  766.         bnc=`basename "${cueFile}" .cue`
  767.         ncn="${tempDirName}/${bnc}.line.cue"
  768.         cp "${cueFile}" "${ncn}"
  769.         echo -e "\n" >> "${ncn}"
  770.         [ $? -ne 0 ] && return ${E_CANT_FIX_CUE}
  771.         cueFile="${ncn}"
  772.         print_message "\tNew cue sheet file name: '${color_cyan}${cueFile}${color_default}'"
  773.     fi
  774. }
  775.  
  776. # function for recode cue sheet file
  777. recode_cue() {
  778.     isutf=""
  779.     if [ -n "${tool_F}" ]
  780.     then
  781.         isutf=`${tool_F} "${cueFile}" | grep "UTF-8"`
  782.     else
  783.         isutf=""
  784.     fi
  785.  
  786.     isascii=""
  787.     if [ -n "${tool_F}" ]
  788.     then
  789.         isascii=`${tool_F} "${cueFile}" | grep "ASCII"`
  790.     else
  791.         isascii=""
  792.     fi
  793.  
  794.     if [ -n "${isutf}" ]
  795.     then
  796.         print_message "\tSeems like cue sheet already in UTF-8 encoding. ${color_green}Good${color_default}! ;)"
  797.     else
  798.         if [ -n "${isascii}" ]
  799.         then
  800.             print_message "\tSeems like cue sheet in ASCII encoding. ${color_yellow}Not bad${color_default}... :|"
  801.             [ ! -n "${fromCP}" ] && return 0
  802.         else
  803.             print_message "\tSeems like cue sheet not in UTF-8 encoding. ${color_red}Bad${color_default}! :("
  804.         fi
  805.  
  806.         if [ -n "${tool_IC}" ]
  807.         then
  808.             if [ -n "${fromCP}" ]
  809.             then
  810.                 get_local_codepage
  811.  
  812.                 chk_error=0
  813.                 try_codepage ${fromCP}
  814.                 chk_error=$?
  815.                 [ ${chk_error} -ne 0 ] && fromCP=${locCP}
  816.  
  817.                 print_message "\tNow we try to recode cue sheet to ${color_green}UTF-8${color_default} from ${color_yellow}${fromCP}${color_default}..."
  818.                 bnc=`basename "${cueFile}" .cue`
  819.                 cat "${cueFile}" | ${tool_IC} -f "${fromCP}" -t "UTF-8" > "${tempDirName}/${bnc}.utf8.cue"
  820.                 [ $? -ne 0 ] && return ${E_CANT_CONVERT_CUE}
  821.                 cueFile="${tempDirName}/${bnc}.utf8.cue"
  822.                 print_message "\tNew cue sheet file name: '${color_cyan}${cueFile}${color_default}'"
  823.             fi
  824.         fi
  825.     fi
  826. }
  827.  
  828. recode_to_wav() {
  829.     inFileWAV="${inFile}.wav"
  830.     [ ${onlyTest} -ne 0 ] && return
  831.     errors=0
  832.     FullPathIN="${inFileDir}/${inFile}"
  833.     FullPathOUT="${tempDirName}/${inFileWAV}"
  834.     print_message "\tRecoding '${color_cyan}${inFile}${color_default}' to WAV..."
  835.     case "${inCodec}" in
  836.         "flac" )
  837.             flac -d -f -o "${FullPathOUT}" "${FullPathIN}"
  838.             errors=$?
  839.         ;;
  840.         "ape" )
  841.             mac "${FullPathIN}" "${FullPathOUT}" -d
  842.             errors=$?
  843.         ;;
  844.         "wv" )
  845.             wvunpack -y -o "${FullPathOUT}" "${FullPathIN}"
  846.             errors=$?
  847.         ;;
  848.         "ofr" )
  849.         ;;
  850.         "shn" )
  851.             shorten -x "${FullPathIN}" "${FullPathOUT}"
  852.             errors=$?
  853.         ;;
  854.         "tta" )
  855.             ttaenc -d -o "${FullPathOUT}" "${FullPathIN}"
  856.             errors=$?
  857.         ;;
  858.         "mp3" )
  859.             lame -S --decode "${FullPathIN}" "${FullPathOUT}"
  860.             errors=$?
  861.         ;;
  862.         "m4a" )
  863.             faad -q -o "${FullPathOUT}" "${FullPathIN}"
  864.             errors=$?
  865.         ;;
  866.         "ogg" )
  867.             oggdec -Q --decode -o "${FullPathOUT}" "${FullPathIN}"
  868.             errors=$?
  869.         ;;
  870.         "wav" )
  871.         ;;
  872.         * )
  873.             print_error "Decode '${color_cyan}${inCodec}${color_default}' to WAV not supported."
  874.             return ${E_UNK_IN_CODEC}
  875.         ;;
  876.     esac
  877.     [ ${errors} -ne 0 ] && return -1
  878.     inFile="${inFileWAV}"
  879.     inFileDir="${tempDirName}"
  880.     inCodec="wav"
  881.     codec_IN="wav"
  882.     print_message "\tSetting new input file to '${color_cyan}${inFile}${color_default}'"
  883. }
  884.  
  885. # function for split condition
  886. split_cond() {
  887.     tlc=$1
  888.     ttl="$2"
  889.     (( tlc < tags_ALBUM_TRACKS )) && return 0
  890.     [ ! -n "${ttl}" ] && return 0
  891.     return 1
  892. }
  893.  
  894. # function for image splitting
  895. split_image() {
  896.     runopt=""
  897.     [ ${quiteMode} -ne 0 ] && runopt="-q"
  898.     file_splitlog="${tempDirName}/split.log"
  899.     file_splitlogwork="${file_splitlog}.work"
  900.     err=0
  901.     _outCodecOpts=""
  902.     if [ ${onlyTest} -eq 0 ]
  903.     then
  904.         _outCodecOpts="${toolCodec}${outCodecParam}"
  905.     else
  906.         [ ${splitInTest} -eq 0 ] && return 0
  907.         _outCodecOpts="null"
  908.     fi
  909.  
  910.     cd "${inFileDir}"
  911.     ${tool_CBP} "${cueFile}" | ${tool_ST} split ${runopt} -d "${tempDirName}" -O always -t %n ${inCodecParam} -o "${_outCodecOpts}" "./${inFile}" &> "${file_splitlog}" &
  912.     disown %1
  913.     cd "${OLDPWD}"
  914.  
  915.     lc=0
  916.     tl=""
  917.     cl=""
  918.     llc=${lc}
  919.     lw=0
  920.     split_cond ${lc} "${tl}"
  921.     sc=$?
  922.     while [ ${sc} -eq 0 ]
  923.     do
  924.         if [ -e "${file_splitlog}" ]
  925.         then
  926.             cp "${file_splitlog}" "${file_splitlogwork}"
  927.             cl=`tail -n 1 "${file_splitlogwork}" | awk 'BEGIN {FS="\b\b\b\b\b"} { if ( NF > 1 ) print $1, $NF; else print $1}' | sed -e 's/\ \ 0%\ \ //g' -e 's/Splitting\ //g'`
  928.             if [ -n "${cl}" ]
  929.             then
  930.                 llc=${lc}
  931.                 lc=`cat "${file_splitlogwork}" | wc -l`
  932.                 ((lc++))
  933.                 spl=`echo ${cl} | tr -d [:cntrl:] | awk 'BEGIN {FS=" : "} {print $1}' | sed -e "s:${tempDirName}/::g" -e "s:\./::g"`
  934.                 prc=`echo ${cl} | awk 'BEGIN {FS=" : "} {print $2}'`
  935.                 if (( lc <= tags_ALBUM_TRACKS ))
  936.                 then
  937.                     bs="\b"
  938.                     for ((i=1;i<lw;i++))
  939.                     do
  940.                         bs="${bs}\b"
  941.                     done
  942.  
  943.                     if (( llc != lc ))
  944.                     then
  945.                         if (( lc > 1 ))
  946.                         then
  947.                             print_message "${bs}${color_green}100%${color_default}"
  948.                         else
  949.                             print_message ""
  950.                         fi
  951.                         print_message -n "Track ${color_green}${lc}${color_default}: ${spl} : ${color_yellow}${prc}${color_default}"
  952.                         lw=${#prc}
  953.                     else
  954.                         print_message -n "${bs}${color_yellow}${prc}${color_default}"
  955.                         lw=${#prc}
  956.                     fi
  957.                     set_xterm_title "Splitting Track ${lc} of ${tags_ALBUM_TRACKS}, Progress: ${prc}"
  958.                 else
  959.                     print_message "${bs}${color_green}100%${color_default}"
  960.                 fi
  961.             fi
  962.             tl=`echo "${cl}" | grep "100% OK"`
  963.             split_cond ${lc} "${tl}"
  964.             sc=$?
  965.         fi
  966.         str=`ps ax | grep shntool | grep -v grep`
  967.         if [[ "${str}" == "" ]]
  968.         then
  969.             if [ ${sc} -eq 0 ]
  970.             then
  971. #               err=1
  972.                 sc=1
  973.             fi
  974.         fi
  975.         sleep 1s
  976.     done
  977.  
  978.     if [ ${err} -ne 0 ]
  979.     then
  980.         print_error "Some error occured while spliting file '${color_cyan}${inFileDir}/${inFile}${color_default}'!"
  981.         return ${E_CANT_SPLIT}
  982.     fi
  983. }
  984.  
  985. # function for reading album info
  986. read_album_info() {
  987.     test=`${tool_CP} -d %N "${cueFile}" 2>&1 | grep error`
  988.     if [ -n "${test}" ]
  989.     then
  990.         print_error "Some error occured while reading CUE sheet!"
  991.         return ${E_CANT_READ_CUE}
  992.     fi
  993.  
  994.     if [ ! -n "${pre_ALBUM_PERFORMER}" ]
  995.     then
  996.         tags_ALBUM_PERFORMER=`${tool_CP} -d %P "${cueFile}"`
  997.     else
  998.         tags_ALBUM_PERFORMER=${pre_ALBUM_PERFORMER}
  999.     fi
  1000.     print_message "\tAlbum Performer = ${color_cyan}${tags_ALBUM_PERFORMER}${color_default}"
  1001.  
  1002.     if [ ! -n "${pre_ALBUM_COMPOSER}" ]
  1003.     then
  1004.         tags_ALBUM_COMPOSER=`${tool_CP} -d %C "${cueFile}"`
  1005.     else
  1006.         tags_ALBUM_COMPOSER=${pre_ALBUM_COMPOSER}
  1007.     fi
  1008.     [ -n "${tags_ALBUM_COMPOSER}" ] && print_message "\tAlbum Performer = ${color_cyan}${tags_ALBUM_PERFORMER}${color_default}"
  1009.  
  1010.     if [ ! -n "${pre_ALBUM_TITLE}" ]
  1011.     then
  1012.         tags_ALBUM_TITLE=`${tool_CP} -d %T "${cueFile}"`
  1013.     else
  1014.         tags_ALBUM_TITLE=${pre_ALBUM_TITLE}
  1015.     fi
  1016.     print_message "\tAlbum Title = ${color_cyan}${tags_ALBUM_TITLE}${color_default}"
  1017.  
  1018.     if [ ! -n "${pre_ALBUM_GENRE}" ]
  1019.     then
  1020.         tags_ALBUM_GENRE=`${tool_CP} -d %G "${cueFile}"`
  1021.     else
  1022.         tags_ALBUM_GENRE=${pre_ALBUM_GENRE}
  1023.     fi
  1024.  
  1025.     [ -n "${tags_ALBUM_GENRE}" ] || tags_ALBUM_GENRE=`grep -m 1 GENRE "${cueFile}" | sed -r -e 's/.?*REM\ GENRE\ (.?*)/\1/g' -e 's:"::g' | tr -d [:cntrl:]`
  1026.     [ -n "${tags_ALBUM_GENRE}" ] || tags_ALBUM_GENRE="Other"
  1027.     print_message "\tAlbum Genre = ${color_cyan}${tags_ALBUM_GENRE}${color_default}"
  1028.  
  1029.     [ -n "${pre_ALBUM_NUMBER}" ] && tags_ALBUM_NUMBER=${pre_ALBUM_NUMBER}
  1030.     [ -n "${tags_ALBUM_NUMBER}" ] && print_message "\tAlbum Disc Number = ${color_cyan}${tags_ALBUM_NUMBER}${color_default}"
  1031.  
  1032.     [ -n "${pre_ALBUM_DISCID}" ] && tags_ALBUM_DISCID=${pre_ALBUM_DISCID}
  1033.     [ -n "${tags_ALBUM_DISCID}" ] || tags_ALBUM_DISCID=`grep -m 1 DISCID "${cueFile}" | sed -r -e 's/.?*REM\ DISCID\ (.?*)/\1/g' -e 's:"::g' | tr -d [:cntrl:]`
  1034.     [ -n "${tags_ALBUM_DISCID}" ] && print_message "\tAlbum Disc ID = ${color_cyan}${tags_ALBUM_DISCID}${color_default}"
  1035.  
  1036.     if [ ! -n "${pre_ALBUM_DATE}" ]
  1037.     then
  1038.         tags_ALBUM_DATE=`grep -m 1 DATE "${cueFile}" | sed -r -e 's/.?*REM\ DATE\ (\d)/\1/g' -e 's:"::g' | tr -d [:cntrl:] | tr -d " " | tr -d [:alpha:]`
  1039.     else
  1040.         tags_ALBUM_DATE=${pre_ALBUM_DATE}
  1041.     fi
  1042.     [ -n "${tags_ALBUM_DATE}" ] || tags_ALBUM_DATE=0000
  1043.     print_message "\tAlbum Date = ${color_cyan}${tags_ALBUM_DATE}${color_default}"
  1044.  
  1045.     tags_ALBUM_TRACKS=`${tool_CP} -d %N "${cueFile}"`
  1046.     print_message "\tNumber of Tracks = ${color_cyan}${tags_ALBUM_TRACKS}${color_default}"
  1047. }
  1048.  
  1049. # function for track taging
  1050. tag_track() {
  1051.     case "${outCodec}" in
  1052.         "flac" | "flake" | "flacuda" )
  1053.             if [ ${onlyTest} -eq 0 ]
  1054.             then
  1055.                 optional=""
  1056.                 [ -n "${tags_ALBUM_DISCID}" ] && optional="${optional} --set-tag=DISCID=${tags_ALBUM_DISCID}"
  1057.                 [ -n "${tags_ALBUM_NUMBER}" ] && optional="${optional} --set-tag=DISCNUMBER=${tags_ALBUM_NUMBER}"
  1058.                 [ -n "${tags_TRACK_COMPOSER}" ] && optional="${optional} --set-tag=COMPOSER=${tags_TRACK_COMPOSER}"
  1059.                 ${tag_FLAC} \
  1060.                 --set-tag="TITLE=${tags_TRACK_TITLE}" \
  1061.                 --set-tag="ALBUM=${tags_ALBUM_TITLE}" \
  1062.                 --set-tag="ARTIST=${tags_TRACK_PERFORMER}" \
  1063.                 --set-tag="DATE=${tags_ALBUM_DATE}" \
  1064.                 --set-tag="TRACKNUMBER=${tags_TRACK_ZNUMBER}" \
  1065.                 --set-tag="GENRE=${tags_TRACK_GENRE}" \
  1066.                 --set-tag="COMMENT=${NAME} v${VER}" \
  1067.                 ${optional} \
  1068.                 "${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}" &>/dev/null
  1069.                 if [ $? -ne 0 ]
  1070.                 then
  1071.                     print_error "Cant tag '${color_cyan}${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}${color_default}'"
  1072.                     return ${E_CANT_TAG_FLAC}
  1073.                 fi
  1074.             fi
  1075.         ;;
  1076.         "ape" | "wv" )
  1077.             if [ ${onlyTest} -eq 0 ]
  1078.             then
  1079.                 [ -n "${tags_ALBUM_DISCID}" ] && optional="${optional} -p DISCID=${tags_ALBUM_DISCID}"
  1080.                 [ -n "${tags_ALBUM_NUMBER}" ] && optional="${optional} -p MEDIA=${tags_ALBUM_NUMBER}"
  1081.                 [ -n "${tags_TRACK_COMPOSER}" ] && optional="${optional} -p COMPOSER=${tags_TRACK_COMPOSER}"
  1082.                 ${tag_APE} -i "${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}" -m update \
  1083.                 -p TITLE="${tags_TRACK_TITLE}" \
  1084.                 -p ALBUM="${tags_ALBUM_TITLE}" \
  1085.                 -p ARTIST="${tags_TRACK_PERFORMER}" \
  1086.                 -p YEAR="${tags_ALBUM_DATE}" \
  1087.                 -p TRACK="${tags_TRACK_ZNUMBER}" \
  1088.                 -p GENRE="${tags_TRACK_GENRE}" \
  1089.                 ${optional} \
  1090.                 -p COMMENT="${NAME} v${VER}" &>/dev/null
  1091.                 if [ $? -ne 0 ]
  1092.                 then
  1093.                     print_error "Cant tag '${color_cyan}${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}${color_default}'"
  1094.                     return ${E_CANT_TAG_APE}
  1095.                 fi
  1096.             fi
  1097.         ;;
  1098.         "mp3" )
  1099.             if [ ${onlyTest} -eq 0 ]
  1100.             then
  1101.                 gn=`${tag_MP3} -L | grep -E -e "(.?*): ${tags_TRACK_GENRE}$" | awk '{print $1}' | sed -e 's/://g' -e 's/\ //g'`
  1102.                 [ ! -n "${gn}" ] && gn=12
  1103.  
  1104.                 ${tag_MP3} -2 \
  1105.                 -t "${tags_TRACK_TITLE}" \
  1106.                 -A "${tags_ALBUM_TITLE}" \
  1107.                 -a "${tags_TRACK_PERFORMER}" \
  1108.                 -y "${tags_ALBUM_DATE}" \
  1109.                 -T "${tags_TRACK_ZNUMBER}" \
  1110.                 -g "${gn}" \
  1111.                 -c "${NAME} v${VER}" \
  1112.                  "${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}" &>/dev/null
  1113.  
  1114.                 if [ $? -ne 0 ]
  1115.                 then
  1116.                     print_error "Cant tag '${color_cyan}${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}${color_default}'"
  1117.                     return ${E_CANT_TAG_MP3}
  1118.                 fi
  1119.             fi
  1120.         ;;
  1121.         "ogg" )
  1122.             if [ ${onlyTest} -eq 0 ]
  1123.             then
  1124.                 optional=""
  1125.                 [ -n "${tags_ALBUM_DISCID}" ] && optional="${optional} -t DISCID=${tags_ALBUM_DISCID}"
  1126.                 [ -n "${tags_ALBUM_NUMBER}" ] && optional="${optional} -t DISCNUMBER=${tags_ALBUM_NUMBER}"
  1127.                 [ -n "${tags_TRACK_COMPOSER}" ] && optional="${optional} -t COMPOSER=${tags_TRACK_COMPOSER}"
  1128.                 ${tag_OGG} -w \
  1129.                 -t TITLE="${tags_TRACK_TITLE}" \
  1130.                 -t ALBUM="${tags_ALBUM_TITLE}" \
  1131.                 -t ARTIST="${tags_TRACK_PERFORMER}" \
  1132.                 -t DATE="${tags_ALBUM_DATE}" \
  1133.                 -t TRACKNUMBER="${tags_TRACK_ZNUMBER}" \
  1134.                 -t GENRE="${tags_TRACK_GENRE}" \
  1135.                 -t COMMENT="${NAME} v${VER}" \
  1136.                 ${optional} \
  1137.                  "${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}" &>/dev/null
  1138.                 if [ $? -ne 0 ]
  1139.                 then
  1140.                     print_error "Cant tag '${color_cyan}${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}${color_default}'"
  1141.                     return ${E_CANT_TAG_OGG}
  1142.                 fi
  1143.             fi
  1144.         ;;
  1145.         "m4a" )
  1146.             if [ ${onlyTest} -eq 0 ]
  1147.             then
  1148.                 optional=""
  1149.                 optionalComment=""
  1150.                 [ -n "${tags_ALBUM_DISCID}" ] && optionalComment="${optionalComment}, DISCID=${tags_ALBUM_DISCID}"
  1151.                 [ -n "${tags_ALBUM_NUMBER}" ] && optionalComment="${optional} -disk ${tags_ALBUM_NUMBER}"
  1152.                 [ -n "${tags_TRACK_COMPOSER}" ] && optional="${optional} -writer ${tags_TRACK_COMPOSER}"
  1153.                 ${tag_M4A} \
  1154.                 -song "${tags_TRACK_TITLE}" \
  1155.                 -album "${tags_ALBUM_TITLE}" \
  1156.                 -artist "${tags_TRACK_PERFORMER}" \
  1157.                 -year "${tags_ALBUM_DATE}" \
  1158.                 -track "${tags_TRACK_NUMBER}" \
  1159.                 -tracks "${tags_ALBUM_TRACKS}" \
  1160.                 -genre "${tags_TRACK_GENRE}" \
  1161.                 -comment "${NAME} v${VER}${optionalComment}" \
  1162.                 ${optional} \
  1163.                 "${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}" # &>/dev/null
  1164.                 if [ $? -ne 0 ]
  1165.                 then
  1166.                     print_error "Cant tag '${color_cyan}${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}${color_default}'"
  1167.                     return ${E_CANT_TAG_M4A}
  1168.                 fi
  1169.             fi
  1170.         ;;
  1171.     esac
  1172. }
  1173.  
  1174. # function for decode naming scheme with bash
  1175. get_out_file_name() {
  1176.     temp_AT=${tags_ALBUM_TITLE//\//\\}
  1177.     temp_AP=${tags_ALBUM_PERFORMER//\//\\}
  1178.     temp_AG=${tags_ALBUM_GENRE//\//\\}
  1179.     temp_AD=${tags_ALBUM_DATE//\//\\}
  1180.     temp_TT=${tags_TRACK_TITLE//\//\\}
  1181.     temp_TP=${tags_TRACK_PERFORMER//\//\\}
  1182.     temp_TG=${tags_TRACK_GENRE//\//\\}
  1183.  
  1184.     tstr="${outFormatStr}.${outExt}"
  1185.     tstr=${tstr//\%A/${temp_AT}}
  1186.     tstr=${tstr//\%G/${temp_AG}}
  1187.     tstr=${tstr//\%P/${temp_AP}}
  1188.     tstr=${tstr//\%D/${temp_AD}}
  1189.     tstr=${tstr//\%t/${temp_TT}}
  1190.     tstr=${tstr//\%p/${temp_TP}}
  1191.     tstr=${tstr//\%g/${temp_TG}}
  1192.     tstr=${tstr//\%n/${tags_TRACK_NUMBER}}
  1193.     tstr=${tstr//\%N/${tags_TRACK_ZNUMBER}}
  1194.     tstr=${tstr//\%a/${tags_ALBUM_NUMBER}}
  1195.     echo ${tstr}
  1196. }
  1197.  
  1198. # function for track moving
  1199. move_track() {
  1200.     outFileName=`get_out_file_name`
  1201.     outDirName=`dirname "${outFileName}"`
  1202.     print_message -n " to '${color_cyan}${outFileName}${color_default}'..."
  1203.     if [ ${onlyTest} -eq 0 ]
  1204.     then
  1205.         if [ ! -d "${outDirName}" ]
  1206.         then
  1207.             mkdir -p "${outDirName}"
  1208.             [ $? -eq 0 ] || return ${E_CANT_MKDIR}
  1209.         fi
  1210.         mv "${tempDirName}/${tags_TRACK_ZNUMBER}.${outExt}" "${outFileName}"
  1211.         [ $? -eq 0 ] || return ${E_CANT_MOVE_FILE}
  1212.     fi
  1213. }
  1214.  
  1215. # function for tracks processing
  1216. process_tracks() {
  1217.     [[ "${tags_ALBUM_TRACKS}" == "" || "${tags_ALBUM_TRACKS}" == "0" ]] && return ${E_WRONG_NUM_TRACKS}
  1218.     for (( i=1; i<=${tags_ALBUM_TRACKS}; i++ )) {
  1219.         if (( $i < 10 ))
  1220.         then
  1221.             tags_TRACK_ZNUMBER="0$i"
  1222.         else
  1223.             tags_TRACK_ZNUMBER="$i"
  1224.         fi
  1225.         tags_TRACK_NUMBER="$i"
  1226.         set_xterm_title "Processing ${tags_TRACK_NUMBER} of ${tags_ALBUM_TRACKS} [pre]"
  1227.  
  1228.         tags_TRACK_TITLE=`${tool_CP} -n $i -t %t "${cueFile}"`
  1229.         tags_TRACK_PERFORMER=`${tool_CP} -n $i -t %p "${cueFile}"`
  1230.         tags_TRACK_COMPOSER=`${tool_CP} -n $i -t %c "${cueFile}"`
  1231.         tags_TRACK_GENRE=`${tool_CP} -n $i -t %g "${cueFile}"`
  1232.  
  1233.         print_message "\tTrack ${color_green}${tags_TRACK_NUMBER}${color_default}: ${color_magenta}${tags_TRACK_TITLE}${color_default}"
  1234.         if [[ "${tags_TRACK_PERFORMER}" != "${tags_ALBUM_PERFORMER}" && "${tags_TRACK_PERFORMER}" != "" ]]
  1235.         then
  1236.             print_message "\t\tPerformer: ${tags_TRACK_PERFORMER}"
  1237.         else
  1238.             tags_TRACK_PERFORMER=${tags_ALBUM_PERFORMER}
  1239.         fi
  1240.         if [[ "${tags_TRACK_COMPOSER}" != "${tags_ALBUM_COMPOSER}" && "${tags_TRACK_COMPOSER}" != "" ]]
  1241.         then
  1242.             print_message "\t\tComposer: ${tags_TRACK_COMPOSER}"
  1243.         else
  1244.             tags_TRACK_COMPOSER=${tags_ALBUM_COMPOSER}
  1245.         fi
  1246.         if [[ "${tags_TRACK_GENRE}" != "${tags_ALBUM_GENRE}" && "${tags_TRACK_GENRE}" != "" ]]
  1247.         then
  1248.             print_message "\t\tGenre: ${tags_TRACK_GENRE}"
  1249.         else
  1250.             tags_TRACK_GENRE=${tags_ALBUM_GENRE}
  1251.         fi
  1252.  
  1253.         if [ ${putTags} -eq 1 ]
  1254.         then
  1255.             set_xterm_title "Processing ${tags_TRACK_NUMBER} of ${tags_ALBUM_TRACKS} [tag]"
  1256.             print_message -n "\t${color_green}*${color_default} Taging..."
  1257.             chk_error=0
  1258.             tag_track
  1259.             chk_error=$?
  1260.             if [ ${chk_error} -eq 0 ]
  1261.             then
  1262.                 print_message "\t[${color_green}ok${color_default}]."
  1263.             else
  1264.                 print_message "\t[${color_red}failed${color_default}]"
  1265.                 [ ${onlyTest} -eq 0 ] && return ${chk_error}
  1266.             fi
  1267.         fi
  1268.  
  1269.         print_message -n "\t${color_green}*${color_default} Moving..."
  1270.         set_xterm_title "Processing ${tags_TRACK_NUMBER} of ${tags_ALBUM_TRACKS} [move]"
  1271.         chk_error=0
  1272.         move_track
  1273.         chk_error=$?
  1274.         if [ ${chk_error} -eq 0 ]
  1275.         then
  1276.             print_message "\t[${color_green}ok${color_default}]."
  1277.         else
  1278.             print_message "\t[${color_red}failed${color_default}]"
  1279.             [ ${onlyTest} -eq 0 ] && return ${chk_error}
  1280.         fi
  1281.     }
  1282. }
  1283.  
  1284. # function called on exit
  1285. onexit() {
  1286.     echo ""
  1287.     str=`ps ax | grep shntool | grep -v grep`
  1288.     if [ -n "${str}" ]
  1289.     then
  1290.         killall -Iq ${codec_OUT}
  1291.         killall -Iq ${codec_IN}
  1292.         killall -Iq shntool
  1293.         killall -Iq cuebreackpoints
  1294.     fi
  1295.     if [[ "${tempDirName}" != "." ]]
  1296.     then
  1297.         [ -d "${tempDirName}" ] && rm -rf "${tempDirName}"
  1298.     else
  1299.         rm -f "${file_splitlog}" "${file_splitlogwork}"
  1300.     fi
  1301.     ${PROMPT_COMMAND}
  1302.     [[ "$1" == "halt" ]] && exit ${E_UNK}
  1303.     ecode=$1
  1304.     [ ! -n "${ecode}" ] && ecode=0
  1305.     exit ${ecode}
  1306. }
  1307.  
  1308. onhalt() {
  1309.     print_message "\n${color_red}Halted!${color_default}"
  1310.     onexit halt
  1311. }
  1312.  
  1313. run_section() {
  1314.     title=$1
  1315.     func=$2
  1316.     msg=$3
  1317.  
  1318.     set_xterm_title "${title}"
  1319.     print_message "${color_yellow}${title}${color_default}"
  1320.     chk_error=0
  1321.     ${func}
  1322.     chk_error=$?
  1323.     if [ ${chk_error} -ne 0 ]
  1324.     then
  1325.         [ ${onlyTest} -eq 0 ] && onexit ${chk_error}
  1326.     fi
  1327.     print_message "${msg}"
  1328. }
  1329.  
  1330. # --== MAIN PROGRAM ==--
  1331.  
  1332. while getopts ":CXRVc:f:o:dD:G:l:qsn:Q:M:B:I:i:hA:P:K:N:W" Option
  1333. do
  1334.     case ${Option} in
  1335.         W )
  1336.             inFile2WAV=1
  1337.         ;;
  1338.         C )
  1339.             useColors=1
  1340.         ;;
  1341.         X )
  1342.             useXTitle=1
  1343.         ;;
  1344.         c )
  1345.             outCodec=`echo ${OPTARG} | tr [:upper:] [:lower:]`
  1346.         ;;
  1347.         f )
  1348.             fromCP=${OPTARG}
  1349.             tool_F_needed=1
  1350.             tool_IC_needed=1
  1351.         ;;
  1352.         o )
  1353.             outFormatStr=${OPTARG}
  1354.         ;;
  1355.         d )
  1356.             putTags=0
  1357.         ;;
  1358.         R )
  1359.             onlyTest=0
  1360.         ;;
  1361.         V )
  1362.             print_version
  1363.             onexit
  1364.         ;;
  1365.         A )
  1366.             pre_ALBUM_TITLE="${OPTARG}"
  1367.         ;;
  1368.         P )
  1369.             pre_ALBUM_PERFORMER="${OPTARG}"
  1370.         ;;
  1371.         K )
  1372.             pre_ALBUM_COMPOSER="${OPTARG}"
  1373.         ;;
  1374.         D )
  1375.             pre_ALBUM_DATE="${OPTARG}"
  1376.         ;;
  1377.         G )
  1378.             pre_ALBUM_GENRE="${OPTARG}"
  1379.         ;;
  1380.         N )
  1381.             pre_ALBUM_NUMBER=${OPTARG}
  1382.         ;;
  1383.         I )
  1384.             pre_ALBUM_DISCID="${OPTARG}"
  1385.         ;;
  1386.         l )
  1387.             outCodecLevel=`echo ${OPTARG} | tr [:upper:] [:lower:]`
  1388.         ;;
  1389.         q )
  1390.             quiteMode=1
  1391.         ;;
  1392.         s )
  1393.             splitInTest=1
  1394.         ;;
  1395.         n )
  1396.             niceness=`echo ${OPTARG} | sed -r 's/[^-0-9](.?*)$//'`
  1397.             (( ${niceness} < -19 )) && niceness=-19
  1398.             (( ${niceness} > 19 )) && niceness=19
  1399.         ;;
  1400.         Q )
  1401.             outCodecQuality=`echo ${OPTARG} | sed -r 's/[^-0-9](.?*)$//'`
  1402.             (( ${outCodecQuality} < -1 )) && outCodecQuality=-1
  1403.             (( ${outCodecQuality} > 10 )) && outCodecQuality=10
  1404.             outCodecLevel=3
  1405.         ;;
  1406.         M )
  1407.             outCodecMode=`echo ${OPTARG} | tr [:lower:] [:upper:]`
  1408.             if [[ "${outCodecMode}" != "C" && "${outCodecMode}" != "V" ]]
  1409.             then
  1410.                 outCodecMode="V"
  1411.             fi
  1412.         ;;
  1413.         B )
  1414.             outCodecBitRate=`echo ${OPTARG} | sed -r 's/[^-0-9](.?*)$//'`
  1415.             (( ${outCodecBitRate} < 32 )) && outCodecBitRate=32
  1416.             (( ${outCodecBitRate} > 500 )) && outCodecBitRate=500
  1417.             outCodecLevel=3
  1418.         ;;
  1419.         i )
  1420.             inFile=${OPTARG}
  1421.         ;;
  1422.         h )
  1423.             print_help
  1424.             onexit
  1425.         ;;
  1426.         * ) print_error "Unimplemented option chosen." ;;   # DEFAULT
  1427.     esac
  1428. done
  1429.  
  1430. # Reset all colors to None
  1431. if [ ${useColors} -eq 0 ]
  1432. then
  1433.     color_default=""
  1434.     color_red=""
  1435.     color_green=""
  1436.     color_yellow=""
  1437.     color_cyan=""
  1438.     color_magenta=""
  1439. fi
  1440.  
  1441. # --== Check options ==--
  1442. if [ $# -eq "$NO_ARGS" ]  # Script invoked with no command-line args?
  1443. then
  1444.     print_help
  1445.     onexit $E_OPTERROR    # Exit and explain usage, if no argument(s) given.
  1446. fi
  1447.  
  1448. shift $(($OPTIND - 1))
  1449.  
  1450. set_xterm_title "Starting..."
  1451.  
  1452. cueFile="$1"
  1453.  
  1454. if [ ! -n "${cueFile}" ]
  1455. then
  1456.     print_help
  1457.     exit $E_OPTERROR
  1458. fi
  1459.  
  1460. print_info
  1461.  
  1462. trap onhalt SIGTERM
  1463. trap onhalt SIGKILL
  1464. trap onhalt SIGINT
  1465.  
  1466. [ ! ${niceness} -eq 0 ] && print_message "\tSetting niceness level to '${color_yellow}${niceness}${color_default}'\n"
  1467. renice ${niceness} $$ &>/dev/null
  1468.  
  1469. if [[ ! -e "${cueFile}" || ! -f "${cueFile}" ]]
  1470. then
  1471.     print_error "File '${color_cyan}${cueFile}${color_default}' dont exists or not a regular file!"
  1472.     onexit ${E_NOT_CUE_FILE}
  1473. fi
  1474.  
  1475. if [ -n "${inFile}" ]
  1476. then
  1477.     if [ -e "${inFile}" ]
  1478.     then
  1479.         inFileDir=`dirname "${inFile}"`
  1480.         inFile=`basename "${inFile}"`
  1481.     else   
  1482.         print_error "File '${inFile}' not found! Setting to default path..."
  1483.         inFile=""
  1484.     fi
  1485. else
  1486.     inFileDir=`dirname "${cueFile}"`
  1487. fi
  1488.  
  1489. [[ "${inFileDir}" == "." ]] && inFileDir=`pwd`
  1490.  
  1491. tempDirName=`mktemp -q -d /tmp/${scriptName}-XXXXXX`
  1492. [ -n "${tempDirName}" ] || tempDirName="."
  1493.  
  1494. testformat=`echo ${outFormatStr} | sed -e 's:%n::' -e 's:%N::' -e 's:%t::'`
  1495. if [[ "${outFormatStr}" == "${testformat}" ]]
  1496. then
  1497.     print_error "Put any of '%n, %N, %t' changable tag descriptors or file writing errors may be occured! Setting to default '%N'..."
  1498.     outFormatStr="%N"
  1499. fi
  1500.  
  1501. run_section "Searching for tools..." search_tools
  1502. run_section "Fixing CUE if needed..." prepare_and_fix_cue
  1503. run_section "Recode CUE if needed..." recode_cue
  1504.  
  1505. # setup quality
  1506. _echoCodecLevel=""
  1507. case ${outCodecLevel} in
  1508.     "best" | 0 )
  1509.         outCodecLevel=0
  1510.         _echoCodecLevel="best"
  1511.         case ${outCodec} in
  1512.             "mp3" )
  1513.                 outCodecMode="V"
  1514.                 outCodecQuality=0
  1515.             ;;
  1516.             "ogg" )
  1517.                 outCodecMode="V"
  1518.                 outCodecQuality=10
  1519.             ;;
  1520.             "m4a" )
  1521.                 outCodecMode="V"
  1522.                 outCodecQuality=500
  1523.             ;;
  1524.         esac
  1525.     ;;
  1526.     "fast" | 1 )
  1527.         outCodecLevel=1
  1528.         _echoCodecLevel="fast"
  1529.         case ${outCodec} in
  1530.             "mp3" )
  1531.                 outCodecMode="V"
  1532.                 outCodecQuality=7
  1533.             ;;
  1534.             "ogg" )
  1535.                 outCodecMode="V"
  1536.                 outCodecQuality=1
  1537.             ;;
  1538.             "m4a" )
  1539.                 outCodecMode="V"
  1540.                 outCodecQuality=20
  1541.             ;;
  1542.         esac
  1543.     ;;
  1544.     "mid" | 2 )
  1545.         outCodecLevel=2
  1546.         _echoCodecLevel="mid"
  1547.         case ${outCodec} in
  1548.             "mp3" )
  1549.                 outCodecMode="V"
  1550.                 outCodecQuality=2
  1551.             ;;
  1552.             "ogg" )
  1553.                 outCodecMode="V"
  1554.                 outCodecQuality=6
  1555.             ;;
  1556.             "m4a" )
  1557.                 outCodecMode="V"
  1558.                 outCodecQuality=192
  1559.             ;;
  1560.         esac
  1561.     ;;
  1562.     "custom" | 3 )
  1563.         outCodecLevel=3
  1564.         _echoCodecLevel="custom"
  1565.     ;;
  1566.     * )
  1567.         print_error "Unknown compression level '${outCodecLevel}'..."
  1568.         print_levels
  1569.         outCodecLevel=0
  1570.         _echoCodecLevel="best"
  1571.     ;;
  1572. esac
  1573.  
  1574.  
  1575. # setup codecs quality limits
  1576. case "${outCodec}" in
  1577.     "mp3")
  1578.         (( ${outCodecQuality} < 0 )) && outCodecQuality=0
  1579.         (( ${outCodecQuality} > 9 )) && outCodecQuality=9
  1580.         if (( ${outCodecBitRate} > 256 ))
  1581.         then
  1582.             outCodecBitRate=320
  1583.         elif (( ${outCodecBitRate} > 192 ))
  1584.         then
  1585.             outCodecBitRate=256
  1586.         elif (( ${outCodecBitRate} > 128 ))
  1587.         then
  1588.             outCodecBitRate=192
  1589.         elif (( ${outCodecBitRate} > 96 ))
  1590.         then
  1591.             outCodecBitRate=128
  1592.         elif (( ${outCodecBitRate} > 64 ))
  1593.         then
  1594.             outCodecBitRate=96
  1595.         elif (( ${outCodecBitRate} > 32 ))
  1596.         then
  1597.             outCodecBitRate=64
  1598.         else
  1599.             outCodecBitRate=32
  1600.         fi
  1601.     ;;
  1602.     "m4a")
  1603.         (( ${outCodecQuality} < 10 )) && outCodecQuality=10
  1604.         (( ${outCodecQuality} > 500 )) && outCodecQuality=500
  1605.         (( ${outCodecBitRate} < 10 )) && outCodecBitRate=10
  1606.         (( ${outCodecBitRate} > 500 )) && outCodecBitRate=500
  1607.     ;;
  1608.     "ogg")
  1609.         (( ${outCodecQuality} < -1 )) && outCodecQuality=-1
  1610.         (( ${outCodecQuality} > 10 )) && outCodecQuality=10
  1611.         (( ${outCodecBitRate} < 32 )) && outCodecBitRate=32
  1612.         (( ${outCodecBitRate} > 500 )) && outCodecBitRate=500
  1613.     ;;
  1614. esac
  1615.  
  1616. run_section "Check output codec..." check_outCodec "\tSetting output codec compression level to '${color_yellow}${_echoCodecLevel}${color_default}'\n"
  1617. run_section "Check input codec..." check_inCodec
  1618. run_section "Searching for encoder/decoder tools..." search_dencoders
  1619.  
  1620. if [ ${putTags} -eq 1 ]
  1621. then
  1622.     run_section "Searching for taging tools..." search_tagers
  1623. fi
  1624.  
  1625. run_section "Reading album info..." read_album_info
  1626. [ ${inFile2WAV} -ne 0 ] && run_section "Recode to WAV..." recode_to_wav
  1627. run_section "Start splitting..." split_image
  1628. run_section "Processing tracks..." process_tracks
  1629.  
  1630. if [ ${onlyTest} -eq 1 ]
  1631. then
  1632.     print_message "\n${color_magenta}${NAME} executed in testing mode! To get real work rerun it with -R option.${color_default}"
  1633. fi
  1634.  
  1635. onexit
  1636.  
  1637. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement