diff --git a/bin/album_convert b/bin/album_convert new file mode 100755 index 0000000..a19d5b7 --- /dev/null +++ b/bin/album_convert @@ -0,0 +1,185 @@ +#!/bin/bash + +# Includes +#----------------------------------------------------------------------------------------------------------------------------------- + +. /usr/global/lib/music.bash + + + + + +# System Constants +#----------------------------------------------------------------------------------------------------------------------------------- + + AC_NAME="album_convert" +AC_VERSION="$Name: album_convert-1_0_0-1 $" + + + + + +# Print Version +#----------------------------------------------------------------------------------------------------------------------------------- + +function version_print() +{ + echo ${AC_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//' +} + + + + + +# Prin Help +#----------------------------------------------------------------------------------------------------------------------------------- + +function help_print() +{ + echo "${AC_NAME} [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] [-r | --resample] [-d | --downsampled_tag] []" +} + + + + + +# Arg Parse +#----------------------------------------------------------------------------------------------------------------------------------- + +function args_parse() +{ + mode="default" + verbose="false" + resample="false" + dstag="flase" + source_dir="" + target_dir="" + + tmp_args=$(getopt -o ThVvrd --long test,help,version,verbose,resample,downsampled_tag -n "${AC_NAME}" -- "$@") + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "${tmp_args}" + + while true ; do + case "$1" in + # Options + + # Mode switches + -T|--test) mode="test"; shift;; + -h|--help) mode="exit"; help_print; shift;; + -V|--version) mode="exit"; version_print; shift;; + + # Global options + -v|--verbose) verbose="true"; shift;; + -r|--resample) resample="true"; shift;; + -d|--downsampled_tag) dstag="true"; shift;; + + # + --) shift; break;; + *) echo "args_parse internal error [$1] !"; exit 1;; + esac + done + + if [[ "${mode}" != "exit" ]] + then + if [[ "${#}" != "2" ]] + then + if [[ "${#}" -lt "2" ]] + then + echo "Not enough args!" + else + echo "Too many args!" + fi + + mode="exit" + help_print + else + source_dir="$1" + target_dir="$2" + fi + fi +} + + + + + +# Main +#----------------------------------------------------------------------------------------------------------------------------------- + +args_parse "$@" + +if [[ "${mode}" == "exit" ]] +then + exit 0 +else + if [[ "${mode}" == "test" ]] + then + dry_run=true + else + dry_run=false + fi +fi + +if [[ "${resample}" == "true" ]] +then + resample_flags="-af \"aresample=out_sample_fmt=s16:out_sample_rate=44100\"" +else + resample_flags="" +fi + + + +echo "mode: [${mode}] verbose: [${verbose}] resample : [${resample}] downsampled_tag : [${dstag}] source_dir: [${source_dir}] target_dir: [${target_dir}]" 1>&2 + +if [[ ! -d "${target_dir}" ]] +then + echo "Target directory doesn't exit !" + exit -1 +fi + +for file in "${source_dir}"/*@(.flac|.ogg|.mp3|.m4a|.ape|.wav) +do + id="$(basename "${file}" | sed -e "s/-.*//")" + target_file="${target_dir}/${prefix}$(basename "${file}" | sed -e 's/\.[^.]*$//').flac" + + cmd="ffmpeg -i \"${file}\" -compression_level 12 ${resample_flags} \"${target_file}\"" + exec_cmd "${cmd}" +done + +if [[ ${resample} == "true" ]] +then + for file in "${target_dir}"/*.flac + do + if [[ "${dstag}" == "true" ]] + then + tag="DESCRIPTION" + + value="$(tag_read "${file}" "${tag}")" + + if [[ "$( echo "${value}" | grep "Downsampled")" == "" ]] + then + value="${value}\nDownsampled" + tag_delete "${file}" "${tag}" + tag_write "${file}" "${tag}" "${value}" + fi + fi + + for tag in "ALBUM" "TITLE" + do + value="$(tag_read "${file}" "${tag}")" + new_value="$(echo ${value} | sed -e 's/ - HD$//')" + + if [[ "${value}" != "${new_value}" ]] + then + tag_delete "${file}" "${tag}" + tag_write "${file}" "${tag}" "${new_value}" + fi + done + + cmd="mv \"${file}\" \"${file/-hd.flac/.flac}\"" + exec_cmd "${cmd}" + done +fi diff --git a/bin/album_merge b/bin/album_merge new file mode 100755 index 0000000..69945bd --- /dev/null +++ b/bin/album_merge @@ -0,0 +1,145 @@ +#!/bin/bash + +# Includes +#----------------------------------------------------------------------------------------------------------------------------------- + +. /usr/global/lib/music.bash + + + + + +# System Constants +#----------------------------------------------------------------------------------------------------------------------------------- + + AM_NAME="album_merge" +AM_VERSION="$Name: album_merge-1_0_0-1 $" + + + + + +# Print Version +#----------------------------------------------------------------------------------------------------------------------------------- + +function version_print() +{ + echo ${AM_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//' +} + + + + + +# Prin Help +#----------------------------------------------------------------------------------------------------------------------------------- + +function help_print() +{ + echo "${AM_NAME} [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] " + +} + + + + + +# Arg Parse +#----------------------------------------------------------------------------------------------------------------------------------- + +function args_parse() +{ + mode="default" + verbose="false" + source_dir="" + target_dir="" + album_name="" + prefix="" + + tmp_args=$(getopt -o ThVv --long test,help,version,verbose -n "${AM_NAME}" -- "$@") + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "${tmp_args}" + + while true ; do + case "$1" in + # Options + + # Mode switches + -T|--test) mode="test"; shift;; + -h|--help) mode="exit"; help_print; shift;; + -V|--version) mode="exit"; version_print; shift;; + + # Global options + -v|--verbose) verbose="true"; shift;; + + # + --) shift; break;; + *) echo "args_parse internal error [$1] !"; exit 1;; + esac + done + + if [[ "${mode}" != "exit" ]] + then + if [[ "${#}" != "4" ]] + then + if [[ "${#}" -lt "4" ]] + then + echo "Not enough args!" + else + echo "Too many args!" + fi + + mode="exit" + help_print + else + source_dir="$1" + target_dir="$2" + album_name="$3" + prefix="$4" + fi + fi +} + + + + + +# Main +#----------------------------------------------------------------------------------------------------------------------------------- + +shopt -s extglob + +args_parse "$@" + +if [[ ${mode} == "exit" ]] +then + exit 0 +else + if [[ ${mode} == "test" ]] + then + dry_run=true + else + dry_run=false + fi +fi + + + +echo "mode: [${mode}] verbose: [${verbose}] source_dir: [${source_dir}] target_dir: [${target_dir}] album_name: [${album_name}] prefix: [${prefix}]" 1>&2 + +for file in "${source_dir}"/*@(.flac|.mp3) +do + id="$(basename $file | sed -e "s/-.*//")" + target_file="${target_dir}/${prefix}$(basename $file)" + + cmd="cp \"${file}\" \"${target_file}\"" + exec_cmd "${cmd}" + + tag_delete "${target_file}" "ALBUM" + tag_write "${target_file}" "ALBUM" "${album_name}" + tag_delete "${target_file}" "TRACKNUMBER" + tag_write "${target_file}" "TRACKNUMBER" "${prefix}${id}" +done diff --git a/bin/album_metadata_load b/bin/album_metadata_load new file mode 100755 index 0000000..71b8365 --- /dev/null +++ b/bin/album_metadata_load @@ -0,0 +1,168 @@ +#!/bin/bash + +# Includes +#----------------------------------------------------------------------------------------------------------------------------------- + +. /usr/global/lib/music.bash + + + + + +# System Constants +#----------------------------------------------------------------------------------------------------------------------------------- + + AML_NAME="album_metadata_load" +AML_VERSION="$Name: album_metadata_load-1_0_0-1 $" + + + + + +# Print Version +#----------------------------------------------------------------------------------------------------------------------------------- + +function version_print() +{ + echo ${AML_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//' +} + + + + + +# Prin Help +#----------------------------------------------------------------------------------------------------------------------------------- + +function help_print() +{ + echo "${AML_NAME} [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] [-c | --clean] " +} + + + + + +# Arg Parse +#----------------------------------------------------------------------------------------------------------------------------------- + +function args_parse() +{ + mode="default" + verbose="false" + clean="false" + source_dir="" + target_dir="" + metadata_file="" + + tmp_args=$(getopt -o ThVvc --long test,help,version,verbose,clean -n "${AML_NAME}" -- "$@") + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "${tmp_args}" + + while true ; do + case "$1" in + # Options + + # Mode switches + -T|--test) mode="test"; shift;; + -h|--help) mode="exit"; help_print; shift;; + -V|--version) mode="exit"; version_print; shift;; + + # Global options + -v|--verbose) verbose="true"; shift;; + -c|--clean) clean="true"; shift;; + + # + --) shift; break;; + *) echo "args_parse internal error [$1] !"; exit 1;; + esac + done + + if [[ "${mode}" != "exit" ]] + then + if [[ "${#}" != "3" ]] + then + if [[ "${#}" -lt "3" ]] + then + echo "Not enough args!" + else + echo "Too many args!" + fi + + mode="exit" + help_print + else + source_dir="$1" + target_dir="$2" + metadata_file="$3" + fi + fi +} + + + + + +# Main +#----------------------------------------------------------------------------------------------------------------------------------- + +args_parse "$@" + +if [[ ${mode} == "exit" ]] +then + exit 0 +else + if [[ ${mode} == "test" ]] + then + dry_run=true + else + dry_run=false + fi +fi + + + +echo "mode: [${mode}] verbose: [${verbose}] clean: [${clean}] source_dir: [${source_dir}] target_dir: [${target_dir}] metadata_file: [${metadata_file}]" 1>&2 + +tagtab_alloc + +echo "Reading MetaData..." + +tagtab_load "${metadata_file}" "DEFAULT" + +nb_track=${track_id} +echo "Nb track found: ${nb_track}" + + + +track_id=1 + +find "${source_dir}" -maxdepth 1 -name '*.flac' -o -name '*.mp3' | sort | ( + while read track_file + do +# title="${tagtab["${track_id},TITLE"]}" + tag_get title "${track_id}" "TITLE" + + suffix="${track_file##*.}" + target_file="$(printf "%02d" ${track_id})-${title}.${suffix}" + target_file="$(fix_file_name "${target_file}" "")" + target_file="${target_dir}/$(fix_file_name "${target_file}" "")" + + echo "Copying ${track_file} into ${target_file}" + cmd="cp \"${track_file}\" \"${target_file}\"" + exec_cmd "${cmd}" + + + if [[ "${clean}" == "true" ]] + then + tag_save "${target_file}" "${track_id}" "CLEAN" + else + tag_save "${target_file}" "${track_id}" "NOCLEAN" + fi + + track_id=$((${track_id} + 1)) + done +) diff --git a/bin/album_metadata_save b/bin/album_metadata_save new file mode 100755 index 0000000..292a7b4 --- /dev/null +++ b/bin/album_metadata_save @@ -0,0 +1,193 @@ +#!/bin/bash + +# Includes +#----------------------------------------------------------------------------------------------------------------------------------- + +. /usr/global/lib/music.bash + + + + + +# System Constants +#----------------------------------------------------------------------------------------------------------------------------------- + + AMS_NAME="album_metadata_save" +AMS_VERSION="$Name: album_metadata_save-1_0_0-1 $" + + + + + +# Print Version +#----------------------------------------------------------------------------------------------------------------------------------- + +function version_print() +{ + echo ${AMS_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//' +} + + + + + +# Prin Help +#----------------------------------------------------------------------------------------------------------------------------------- + +function help_print() +{ + echo "${AMS_NAME} [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] [-f | --factoring] [-s | standardising] " +} + + + + + +# Arg Parse +#----------------------------------------------------------------------------------------------------------------------------------- + +function args_parse() +{ + mode="default" + verbose="false" + factoring="false" + standardising="false" + source_dir="" + metadata_file="" + + tmp_args=$(getopt -o ThVvfs --long test,help,version,verbose,factoring,standardising -n "${AMS_NAME}" -- "$@") + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "${tmp_args}" + + while true ; do + case "$1" in + # Options + + # Mode switches + -T|--test) mode="test"; shift;; + -h|--help) mode="exit"; help_print; shift;; + -V|--version) mode="exit"; version_print; shift;; + + # Global options + -v|--verbose) verbose="true"; shift;; + -f|--factoring) factoring="true"; shift;; + -s|--standardising) standardising="true"; shift;; + + # + --) shift; break;; + *) echo "args_parse internal error [$1] !"; exit 1;; + esac + done + + if [[ "${mode}" != "exit" ]] + then + if [[ "${#}" != "2" ]] + then + if [[ "${#}" -lt "2" ]] + then + echo "Not enough args!" + else + echo "Too many args!" + fi + + mode="exit" + help_print + else + source_dir="$1" + metadata_file="$2" + fi + fi +} + + + + + +# Main +#----------------------------------------------------------------------------------------------------------------------------------- + +args_parse "$@" + +if [[ ${mode} == "exit" ]] +then + exit 0 +else + if [[ ${mode} == "test" ]] + then + dry_run=true + else + dry_run=false + fi +fi + + + +echo "mode: [${mode}] verbose: [${verbose}] factoring: [${factoring}] standardising: [${standardising}] source_dir: [${source_dir}] metadata_file: [${metadata_file}]" 1>&2 + +declare -g nb_track + + + +find "${source_dir}" -maxdepth 1 -name '*.flac' -o -name '*.mp3' | sort | ( + + tagtab_alloc + + while read track_file + do + nb_track=$((${nb_track} + 1)) + + if [[ "${factoring}" == "true" ]] + then + tagtab_read "${nb_track}" "${track_file}" "FACTORING" + else + tagtab_read "${nb_track}" "${track_file}" "NOFACTORING" + fi + done + + track_id=0 + + while [[ "${track_id}" -le "${nb_track}" ]] + do + if [[ "${track_id}" == 0 ]] + then + echo "DEF" + else + echo "SOT" + fi + + if [[ "${standardising}" == "true" ]] + then + tagtab_dump "${track_id}" "STANDARD" + else + tagtab_dump "${track_id}" "PASSTHROUGH" + fi + + echo "EOT" + + track_id=$((${track_id} + 1)) + done + + echo "EOA" + + echo 1>&2 "NB Track dumped: [${nb_track}]" +#) +#) >"${metadata_file}" +) | ( + if [[ "${dry_run}" == "true" ]] + then + cat + else + tee "${metadata_file}" + fi +) | ( + if [[ "${verbose}" == "true" ]] + then + cat + else + cat >/dev/null + fi +) + diff --git a/bin/album_name_fix b/bin/album_name_fix new file mode 100755 index 0000000..a126806 --- /dev/null +++ b/bin/album_name_fix @@ -0,0 +1,138 @@ +#!/bin/bash + +. /usr/global/lib/music.bash + + + + + +# System Constants +#----------------------------------------------------------------------------------------------------------------------------------- + +ANF_VERSION="$Name: album_name_fix-1_0_0-1 $" + + + + + +# Print Version +#----------------------------------------------------------------------------------------------------------------------------------- + +function version_print() +{ + echo ${ANF_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//' +} + + + + + +# Prin Help +#----------------------------------------------------------------------------------------------------------------------------------- + +function help_print() +{ + echo "album_name_fix [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] [-a ] [-p|--music_pattern ] [-s|--sed_substitute_pattern ]" +} + + + + + +# Arg Parse +#----------------------------------------------------------------------------------------------------------------------------------- + +function args_parse() +{ + mode="default" + verbose="false" + album_dir="." + music_pattern="." + + tmp_args=$(getopt -o a:p:s:ThVv --long album_dir:,music_pattern:,sed_substitute_pattern:,test,help,version,verbose -n 'album_name_fix' -- "$@") + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "${tmp_args}" + + while true ; do + case "$1" in + # Path options + -a|--album_dir) shift; album_dir="$1"; shift;; + + # Options + -p|--music_pattern) shift; music_pattern="$1"; shift;; + -s|--sed_substitute_pattern) shift; ssp="$1"; shift;; + + # Mode switches + -T|--test) mode="test"; shift;; + -h|--help) mode="exit"; help_print; shift;; + -V|--version) mode="exit"; version_print; shift;; + + # Global options + -v|--verbose) verbose="true"; shift;; + + # + --) shift; break;; + *) echo "args_parse internal error [$1] !"; exit 1;; + esac + done +} + + + + + +# Main +#----------------------------------------------------------------------------------------------------------------------------------- + +shopt -s extglob + +args_parse "$@" + + + +if [[ ${mode} == "exit" ]] +then + exit 0 +else + if [[ ${mode} == "test" ]] + then + dry_run=true + else + dry_run=false + fi +fi + + + +echo "mode: [${mode}] verbose: [${verbose}] album_dir: [${album_dir}] music_pattern: [${music_pattern}] sed_substitue_pattern: [${ssp}]" 1>&2 + +cd "${album_dir}" + +IFS="\n" +find . -maxdepth 1 -name '*.flac' -o -name '*.FLAC' -o -name '*.ogg' -o -name '*.OGG' -o -name '*.mp3' -o -name '*.MP3' -o -name '*.m4a' -o -name '*.M4A' -o -name '*.ape' -o -name '*.APE' -o -name '*.wav' -o -name '*.WAV' -o -name '*.mp4' -o -name '*.MP4' -o -name '*.mkv' -o -name '*.MKV' | sed -e 's/^.\///' | grep -e "${music_pattern}" | sort | + while read track_file + do + IFS=" " + new_track_file="$(fix_file_name "${track_file}" "${ssp}")" + + if [[ "${new_track_file}" != "${track_file}" ]] + then + echo "Moving '${track_file}' into '${new_track_file}'..." + if [[ "${dry_run}" != "true" ]] + then + mv -- "${track_file}" "${new_track_file}" + else + if [[ "${verbose}" == "true" ]] + then + echo mv -- "${track_file}" "${new_track_file}" + fi + fi + else + echo "Skiping '${track_file}'..." + fi + + IFS="\n" + done diff --git a/bin/album_rename b/bin/album_rename new file mode 100755 index 0000000..d16ea04 --- /dev/null +++ b/bin/album_rename @@ -0,0 +1,21 @@ +#!/bin/bash + +if [[ "$1" == "-h" ]] +then + echo "album_rename [-h] | " + exit +fi + +source_dir="$1" +target_dir="$2" +album_name="$3" + +for file in ${source_dir}/*.flac +do + target_file="${target_dir}/$(basename $file)" + + cp "${file}" "${target_file}" + metaflac --remove-tag=ALBUM --set-tag="ALBUM=${album_name}" "${target_file}" + + i=$(($i+1)) +done diff --git a/bin/album_renum b/bin/album_renum new file mode 100755 index 0000000..da88c70 --- /dev/null +++ b/bin/album_renum @@ -0,0 +1,146 @@ +#!/bin/bash + +# Includes +#----------------------------------------------------------------------------------------------------------------------------------- + +. /usr/global/lib/music.bash + + + + + +# System Constants +#----------------------------------------------------------------------------------------------------------------------------------- + + AR_NAME="album_renum" +AR_VERSION="$Name: album_renum-1_0_0-1 $" + + + + + +# Print Version +#----------------------------------------------------------------------------------------------------------------------------------- + +function version_print() +{ + echo ${AR_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//' +} + + + + + +# Prin Help +#----------------------------------------------------------------------------------------------------------------------------------- + +function help_print() +{ + echo "${AR_NAME} [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] [ -f | --first_number ] [ -d | --number_of_digit ] " +} + + + + + +# Arg Parse +#----------------------------------------------------------------------------------------------------------------------------------- + +function args_parse() +{ + mode="default" + verbose="false" + source_dir="" + target_dir="" + first_number="1" + number_of_digit="2" + + tmp_args=$(getopt -o f:d:ThVv --long first_number:,number_of_digit:,test,help,version,verbose -n "${AR_NAME}" -- "$@") + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "${tmp_args}" + + while true ; do + case "$1" in + # Options + -f|--first_number) shift; first_number="$1"; shift;; + -d|--number_of_digit) shift; number_of_digit="$1"; shift;; + + # Mode switches + -T|--test) mode="test"; shift;; + -h|--help) mode="exit"; help_print; shift;; + -V|--version) mode="exit"; version_print; shift;; + + # Global options + -v|--verbose) verbose="true"; shift;; + + # + --) shift; break;; + *) echo "args_parse internal error [$1] !"; exit 1;; + esac + done + + if [[ "${#}" != "2" ]] + then + if [[ "${#}" -lt "2" ]] + then + echo "Not enough args!" + else + echo "Too many args!" + fi + + mode="exit" + help_print + else + source_dir="$1" + target_dir="$2" + fi +} + + + + + +# Main +#----------------------------------------------------------------------------------------------------------------------------------- + +shopt -s extglob + +args_parse "$@" + +if [[ ${mode} == "exit" ]] +then + exit 0 +else + if [[ ${mode} == "test" ]] + then + dry_run=true + else + dry_run=flase + fi +fi + + + +echo "mode: [${mode}] verbose: [${verbose}] source_dir: [${source_dir}] target_dir: [${target_dir}] first_number: [${first_number}] number_of_digit: [${number_of_digit}]" 1>&2 + +i="${first_number}" + +for file in "${source_dir}"/*@(.flac|.mp3) +do + + j=$(printf "%0${number_of_digit}d" $i) + target_file="${target_dir}/$(echo $(basename ${file}) | sed -e "s/^[0-9]*-/$j-/")"; + + cmd="cp \"${file}\" \"${target_file}\"" + exec_cmd "${cmd}" + + tag_delete "${target_file}" "TRACKNUMBER" + tag_delete "${target_file}" "DISCNUMBER" + tag_delete "${target_file}" "DISCTOTAL" + tag_write "${target_file}" "TRACKNUMBER" "$j" + + i=$(($i+1)) +done diff --git a/bin/album_retitle b/bin/album_retitle new file mode 100755 index 0000000..8e51a34 --- /dev/null +++ b/bin/album_retitle @@ -0,0 +1,48 @@ +#!/bin/bash + +function fix_file_name +{ + input="$1" + +# echo ${input} | sed -e 's/ /_/g' -e "s/'/_/g" -e 's/_(/-/g' -e 's/)//g' -e 's/_-_/-/g' -e 's/\//_/g' | tr '[:upper:]' '[:lower:]' + echo ${input} | sed -e 's/\(^[0-9]*\)./\1-/' -e 's/[ ,!/?]/_/g' -e 's/\[/-/g' -e 's/\]//g' -e "s/'/_/g" -e 's/(/-/g' -e 's/)//g' -e 's/__/_/g' -e 's/_\././' -e 's/_-/-/g' -e 's/--/-/g' -e 's/-_/-/g' -e 's/é/e/g' -e 's/è/e/g' -e 's/ê/e/g' -e 's/ë/e/g' -e 's/à/a/g' -e 's/[+&]/and/' -e 's/^-//' -e 's/"/_inch/' | tr '[:upper:]' '[:lower:]' +} + + + +shopt -s extglob + +if [[ "$1" == "-h" ]] +then + echo "album_retitle [-h] | " + exit +fi + +source_dir="$1" +target_dir="$2" +title_file="$3" + +i=1 + +while read title +do + file=(${source_dir}/$(printf %02d $i)-*.@(flac|mp3)) + suffix=${file##*.} + target_file="${target_dir}/$( fix_file_name $( fix_file_name $( fix_file_name $(printf "%02d" $i)-"${title}.${file##*.}")))" + + echo "${target_file}: '"${title}"'" + cp "${file}" "${target_file}" + + case "${suffix}" + in + flac) + metaflac --remove-tag=TRACKNUMBER --set-tag=TRACKNUMBER=$i --remove-tag=TITLE --set-tag=TITLE="${title}" "${target_file}" + ;; + + mp3) + mid3v2 -T $i -t "${title}" "${target_file}" + ;; + esac + + i=$(($i + 1)) +done < ${title_file} diff --git a/bin/album_seekpoint b/bin/album_seekpoint new file mode 100755 index 0000000..850eceb --- /dev/null +++ b/bin/album_seekpoint @@ -0,0 +1,24 @@ +#!/bin/bash + +if [[ "$1" == "-h" ]] +then + echo "album_seekpoint [-h] | " + exit +fi + + source_dir="$1" + target_dir="$2" +seek_point_delay="$3" + +for file in ${source_dir}/*.flac +do + target_file="${target_dir}/$(basename $file)" + + if [[ "${file}" != "${target_file}" ]] + then + cp "${file}" "${target_file}" + fi + + metaflac --remove --block-type=SEEKTABLE "${target_file}" + metaflac --add-seekpoint "${seek_point_delay}"s "${target_file}" +done diff --git a/bin/music-info b/bin/music-info new file mode 100755 index 0000000..d9ba7c1 --- /dev/null +++ b/bin/music-info @@ -0,0 +1,182 @@ +#!/bin/bash + +default_top=/opt/music/src + +function list +{ + type="$1" + suffix="$2" + + case $type in + "track") + find $top -type f | grep "\.${suffix}$" + ;; + + "lp"|"ep"|"single"|"live"|"compilation"|"tribute") + find $top -type f | grep -v -e "/child/" -e "/original_soundtrack/" -e "/various_artists/" | grep -e "/${type}/" | grep "\.${suffix}$" | sed -e 's/\/[^/]*$//' | sort -u + ;; + + "child") + find $top -type f | grep -e "/child/" | grep "\.${suffix}$" | sed -e 's/\/[^/]*$//' | sort -u + ;; + + "ost") + find $top -type f | grep -e "/original_soundtrack/" | grep "\.${suffix}$" | sed -e 's/\/[^/]*$//' | sort -u + ;; + + "va") + find $top -type f | grep -e "/various_artists/" | grep "\.${suffix}$" | sed -e 's/\/[^/]*$//' | sort -u + ;; + + "us") + find $top -type f | grep -v -e "/various_artists/" -e "/original_soundtrack/" -e "/lp/" -e "/ep/" -e "/single/" -e "/live/" -e "/compilation/" -e '/misc/' -e "/tribute/" | grep "\.${suffix}$" | sed -e 's/\/[^/]*$//' | sort -u + ;; + + esac +} + +function count +{ + type="$1" + suffix="$2" + + echo "$( list ${type} ${suffix} | wc -l)" +} + + + +if [[ "$1" == "-l" ]] +then + mode="list" + shift +else + mode="stats" +fi + +arg_top="$1" + +if [[ "${arg_top}" != "" ]] +then + top="$(realpath ${arg_top})" +else + top="${default_top}" +fi + + + +if [[ "${mode}" == "stats" ]] +then + + track_flac="$(count track flac)" + track_ogg="$(count track ogg)" + track_mp3="$(count track mp3)" + track_music=$((${track_flac} + ${track_ogg} + ${track_mp3})) + + track_avi="$(count track avi)" + track_mp4="$(count track mp4)" + track_mkv="$(count track mkv)" + track_video=$((${track_avi} + ${track_mp4} + ${track_mkv})) + + track_jpg="$(count track jpg)" + track_png="$(count track png)" +track_picture=$((${track_jpg} + ${track_png})) + + track_total=$((${track_music} + ${track_video} + ${track_picture})) + + lp_flac="$(count lp flac)" + lp_ogg="$(count lp ogg)" + lp_mp3="$(count lp mp3)" + lp_music=$((${lp_flac} + ${lp_ogg} + ${lp_mp3})) + + ep_flac="$(count ep flac)" + ep_ogg="$(count ep ogg)" + ep_mp3="$(count ep mp3)" + ep_music=$((${ep_flac} + ${ep_ogg} + ${ep_mp3})) + + single_flac="$(count single flac)" + single_ogg="$(count single ogg)" + single_mp3="$(count single mp3)" + single_music=$((${single_flac} + ${single_ogg} + ${single_mp3})) + + live_flac="$(count live flac)" + live_ogg="$(count live ogg)" + live_mp3="$(count live mp3)" + live_music=$((${live_flac} + ${live_ogg} + ${live_mp3})) + + compilation_flac="$(count compilation flac)" + compilation_ogg="$(count compilation ogg)" + compilation_mp3="$(count compilation mp3)" +compilation_music=$((${compilation_flac} + ${compilation_ogg} + ${compilation_mp3})) + + tribute_flac="$(count tribute flac)" + tribute_ogg="$(count tribute ogg)" + tribute_mp3="$(count tribute mp3)" +tribute_music=$((${tribute_flac} + ${tribute_ogg} + ${tribute_mp3})) + + child_flac="$(count child flac)" + child_ogg="$(count child ogg)" + child_mp3="$(count child mp3)" + child_music=$((${child_flac} + ${child_ogg} + ${child_mp3})) + + ost_flac="$(count ost flac)" + ost_ogg="$(count ost ogg)" + ost_mp3="$(count ost mp3)" + ost_music=$((${ost_flac} + ${ost_ogg} + ${ost_mp3})) + + va_flac="$(count va flac)" + va_ogg="$(count va ogg)" + va_mp3="$(count va mp3)" + va_music=$((${va_flac} + ${va_ogg} + ${va_mp3})) + + us_flac="$(count us flac)" + us_ogg="$(count us ogg)" + us_mp3="$(count us mp3)" + us_music=$((${us_flac} + ${us_ogg} + ${us_mp3})) + +set_flac_total=$((${lp_flac} + ${ep_flac} + ${single_flac} + ${live_flac} + ${compilation_flac} + ${tribute_flac} + ${child_flac} + ${ost_flac} + ${va_flac} + ${us_flac})) + set_ogg_total=$((${lp_ogg} + ${ep_ogg} + ${single_ogg} + ${live_ogg} + ${compilation_ogg} + ${tribute_ogg} + ${child_ogg} + ${ost_ogg} + ${va_ogg} + ${us_ogg})) + set_mp3_total=$((${lp_mp3} + ${ep_mp3} + ${single_mp3} + ${live_mp3} + ${compilation_mp3} + ${tribute_mp3} + ${child_mp3} + ${ost_mp3} + ${va_mp3} + ${us_mp3})) + set_total=$((${lp_music} + ${ep_music} + ${single_music} + ${live_music} + ${compilation_music} + ${tribute_music} + ${child_music} + ${ost_music} + ${va_music} + ${us_music})) + + echo "Music Statistics from ${top}:" + echo "Tracks:" + printf "Music: Flac: %5s OGG: %5s MP3: %5s Total: %6s\n" ${track_flac} ${track_ogg} ${track_mp3} ${track_music} + printf "Video: AVI: %5s mp4: %5s MKV: %5s Total: %6s\n" ${track_avi} ${track_mp4} ${track_mkv} ${track_video} + printf "Picture: JPG: %5s PNG: %5s %5s Total: %6s\n" ${track_jpg} ${track_png} "" ${track_picture} + printf " %5s %5s %5s Total: %6s\n" "" "" "" ${track_total} + + echo "" + echo "Album | Flac | OGG | MP3 || Total" + echo "---------+-------+-------+-------++------" + printf "LP | %5s | %5s | %5s || %5s\n" ${lp_flac} ${lp_ogg} ${lp_mp3} ${lp_music} + printf "EP | %5s | %5s | %5s || %5s\n" ${ep_flac} ${ep_ogg} ${ep_mp3} ${ep_music} + printf "Single | %5s | %5s | %5s || %5s\n" ${single_flac} ${single_ogg} ${single_mp3} ${single_music} + printf "Live | %5s | %5s | %5s || %5s\n" ${live_flac} ${live_ogg} ${live_mp3} ${live_music} + printf "Compil | %5s | %5s | %5s || %5s\n" ${compilation_flac} ${compilation_ogg} ${compilation_mp3} ${compilation_music} + printf "Tribute | %5s | %5s | %5s || %5s\n" ${tribute_flac} ${tribute_ogg} ${tribute_mp3} ${tribute_music} + printf "Child | %5s | %5s | %5s || %5s\n" ${child_flac} ${child_ogg} ${child_mp3} ${child_music} + printf "OST | %5s | %5s | %5s || %5s\n" ${ost_flac} ${ost_ogg} ${ost_mp3} ${ost_music} + printf "VA | %5s | %5s | %5s || %5s\n" ${va_flac} ${va_ogg} ${va_mp3} ${va_music} + printf "UnSorted | %5s | %5s | %5s || %5s\n" ${us_flac} ${us_ogg} ${us_mp3} ${us_music} + echo "---------+-------+-------+-------++------" + printf "Total | %5s | %5s | %5s || %5s\n" ${set_flac_total} ${set_ogg_total} ${set_mp3_total} ${set_total} + +else + + for suffix in flac ogg mp3 avi mp4 mkv jpg png + do + echo "Track ${suffix}:" + list track ${suffix} | sed -e "s/^/track /" + echo + done + + for type in lp ep single live compilation tribute va ost us + do + for suffix in flac ogg mp3 + do + echo "Set ${type} ${suffix}:" + list ${type} ${suffix} | sed -e "s/^/${type} /" + echo + done + done +fi diff --git a/bin/music_check b/bin/music_check new file mode 100755 index 0000000..d9d26fc --- /dev/null +++ b/bin/music_check @@ -0,0 +1,19 @@ +#!/bin/bash + +i=1 + +for file in $(find /opt/music/src -name '*.flac' | sort) +do + echo -ne "\r \r" + + printf "%05d: " $i; echo -n "${file}: " + flac --test "${file}" >/dev/null 2>&1 + + if [[ "$?" == "0" ]] + then + echo -n "OK" + else echo "KO" + fi + + i=$(($i+1)) +done \ No newline at end of file diff --git a/bin/music_folder_make b/bin/music_folder_make new file mode 100755 index 0000000..37dabb1 --- /dev/null +++ b/bin/music_folder_make @@ -0,0 +1,158 @@ +#!/bin/bash + +# Includes +#----------------------------------------------------------------------------------------------------------------------------------- + +. /usr/global/lib/music.bash + + + + + +# System Constants +#----------------------------------------------------------------------------------------------------------------------------------- + + MFM_NAME="music_folder_make" +MFM_VERSION="$Name: music_mk_folder-1_0_0-1 $" + + + + + +# Print Version +#----------------------------------------------------------------------------------------------------------------------------------- + +function version_print() +{ + echo ${MFM_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//' +} + + + + + +# Prin Help +#----------------------------------------------------------------------------------------------------------------------------------- + +function help_print() +{ + echo "${MFM_NAME} [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] [-p | --music_pattern ] [-r | --root_dir ]" +} + + + + + +# Arg Parse +#----------------------------------------------------------------------------------------------------------------------------------- + +function args_parse() +{ + mode="default" + verbose="false" + root_dir="/opt/music/src" + music_pattern="/" + + tmp_args=$(getopt -o r:p:ThVv --long root_dir:,music_pattern:,test,help,version,verbose -n "${MFM_NAME}" -- "$@") + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "${tmp_args}" + + while true ; do + case "$1" in + # Path options + -r|--root_dir) shift; root_dir="$1"; shift;; + + # Options + -p|--music_pattern) shift; music_pattern="$1"; shift;; + + # Mode switches + -T|--test) mode="test"; shift;; + -h|--help) mode="exit"; help_print; shift;; + -V|--version) mode="exit"; version_print; shift;; + + # Global options + -v|--verbose) verbose="true"; shift;; + + # + --) shift; break;; + *) echo "args_parse internal error [$1] !"; exit 1;; + esac + done +} + + + + + +# Main +#----------------------------------------------------------------------------------------------------------------------------------- + +shopt -s extglob + +args_parse "$@" + +if [[ ${mode} == "exit" ]] +then + exit 0 +else + if [[ ${mode} == "test" ]] + then + dry_run=true + else + dry_run=false + fi +fi + + + +echo "mode: [${mode}] verbose: [${verbose}] root_dir: [${root_dir}] music_pattern: [${music_pattern}]" 1>&2 + +find ${root_dir} -type d -links 2 | grep -e "${music_pattern}" | grep -v -e "/video" -e "/photo" | sort | ( + while read dir + do + if [[ $(basename ${dir}) == "misc" ]] + then + line_echo "${dir}: Misc\r" "${i}" + else + + src="" + dst="${dir}/folder.jpg" + + for file in ${dir}/cover-front ${dir}/slipcase-front ${dir}/box-front + do + for suffix in png jpg + do + if [[ "${src}" == "" ]] + then + if [[ -f "${file}.${suffix}" ]] + then + src="${file}.${suffix}" + fi + fi + done + done + + if [[ "${src}" == "" ]] + then + line_echo "${dir}: BAD!\n" "${i}" + else + if [[ ( -f "${dst}") && ( -s "${dst}") && ( "${dst}" -nt "${src}") ]] + then + line_echo "${dir}: Skipping\r" "${i}" + else + line_echo "${dir}: Processing...\n" "${i}" + + cmd="anytopnm \"${src}\" | pamscale -xyfit 1024 1024 | pnmtojpeg -quality=95 -optimize >\"${dst}\"" + exec_cmd "${cmd}" + fi + fi + fi + + i=$(($i + 1)) + done + + line_echo "" +) diff --git a/bin/music_tag_cleanner b/bin/music_tag_cleanner new file mode 100755 index 0000000..9da830e --- /dev/null +++ b/bin/music_tag_cleanner @@ -0,0 +1,195 @@ +#!/bin/bash + +# Includes +#----------------------------------------------------------------------------------------------------------------------------------- + +. /usr/global/lib/music.bash + + + + + +# System Constants +#----------------------------------------------------------------------------------------------------------------------------------- + + MTC_NAME="music_tag_cleaner" +MTC_VERSION="$Name: music_tag_cleaner-1_0_0-1 $" + + + + + +# Print Version +#----------------------------------------------------------------------------------------------------------------------------------- + +function version_print() +{ + echo ${MTC_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//' +} + + + + + +# Prin Help +#----------------------------------------------------------------------------------------------------------------------------------- + +function help_print() +{ + echo "${MTC_NAME} [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] [-f | --fix_missing_album_artist] [-a | --default_artist ] [-p | --music_pattern ] [-r | --root_dir ]" +} + + + + + +# Arg Parse +#----------------------------------------------------------------------------------------------------------------------------------- + +function args_parse() +{ + mode="default" + verbose="false" + fix_maa="false" + default_artist="" + root_dir="/opt/music/src" + music_pattern="/" + + tmp_args=$(getopt -o r:p:a:ThVvf --long root_dir:,music_pattern:,default_artist,test,help,version,verbose,fix_missing_album_artist -n "${MTC_NAME}" -- "$@") + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "${tmp_args}" + + while true ; do + case "$1" in + # Path options + -r|--root_dir) shift; root_dir="$1"; shift;; + + # Options + -a|--default_artist) shift; default_artist="$1"; shift;; + -p|--music_pattern) shift; music_pattern="$1"; shift;; + + # Mode switches + -T|--test) mode="test"; shift;; + -h|--help) mode="exit"; help_print; shift;; + -V|--version) mode="exit"; version_print; shift;; + + # Global options + -f|--fix_missing_album_artist) fix_maa="true"; shift;; + -v|--verbose) verbose="true"; shift;; + + # + --) shift; break;; + *) echo "args_parse internal error [$1] !"; exit 1;; + esac + done +} + + + + + +# Main +#----------------------------------------------------------------------------------------------------------------------------------- + +shopt -s extglob + +args_parse "$@" + +if [[ ${mode} == "exit" ]] +then + exit 0 +else + if [[ ${mode} == "test" ]] + then + dry_run=true + else + dry_run=false + fi +fi + + + +echo "mode: [${mode}] verbose: [${verbose}] root_dir: [${root_dir}] music_pattern: [${music_pattern}] fix_maa: [${fix_maa}] default_artist: [${default_artist}]" 1>&2 + +i=1 + +find "${root_dir}" -name '*.flac' -o -name '*.mp3' | grep -e "${music_pattern}" | sort | + while read track_file + do + tagtab_alloc + + tagtab_read "0" "${track_file}" "DEFAULT" + + for tag in DISCTOTAL DISCNUMBER + do + if [[ "$(echo ${taglist} | grep -e ":${tag}:")" != "" ]] + then + line_echo "${track_file}: Cleaning '${tag}' Tag...\n" "${i}" + tag_delete "${track_file}" "${tag}" + fi + done + + if [[ "$(tag_exist "ALBUM ARTIST")" != "" ]] + then + if [[ "$(tag_exist "ALBUMARTIST")" == "" ]] + then + line_echo "${track_file}: Copying 'ALBUM ARTIST' into 'ALBUMARTIST' Tag...\n" "${i}" + tag_write "${track_file}" "ALBUMARTIST" "${tagtab["0,ALBUM ARTIST"]}" + fi + + line_echo "${track_file}: Cleaning 'ALBUM ARTIST' Tag...\n" "${i}" + tag_delete "${track_file}" "ALBUM ARTIST" + else + if [[ "$(tag_exist "ALBUMARTIST")" == "" ]] + then + line_echo "${track_file}: Missing 'ALBUMARTIST' and 'ALBUM ARTIST' Tag...\n" "${i}" + + if [[ ( "${fix_maa}" == "true") ]] + then + if [[ "${default_artist}" != "" ]] + then + artist=${default_artist} + else + album_type=$(album_type_get "${track_file}") + + if [[ "/various_artists/tribute/original_soundtrack/child/" == */${album_type}/* ]] + then + artist="Various Artists" + else + if [[ "$(tag_exist "ARTIST")" == "" ]] + then + line_echo "${track_file}: Warning: Missing 'ARTIST' Tag...\n" "${i}" + else + artist="${tagtab["0,ARTIST"]}" + fi + fi + fi + + if [[ "${artist}" != "" ]] + then + line_echo "${track_file}: Copying '${artist}' into 'ALBUMARTIST' Tag...\n" "${i}" + tag_write "${track_file}" "ALBUMARTIST" "${artist}" + fi + fi + fi + fi + + if [[ "${track_file##*.}" == "flac" ]] + then + if [[ "$(file ${track_file} | grep ID3 )" != "" ]] + then + line_echo "${track_file}: Cleaning Flac ID3 Tags...\n" "${i}" + tag_all_delete ${track_file} "id3" + fi + fi + + line_echo "${track_file}: OK\r" "${i}" + + i=$(($i + 1)) + done + +line_echo "" + diff --git a/usr/lib/rx3/music.bash b/usr/lib/rx3/music.bash new file mode 100644 index 0000000..875ce7b --- /dev/null +++ b/usr/lib/rx3/music.bash @@ -0,0 +1,597 @@ +#!/bin/bash + +if [[ "${MUSIC_BASH}" != "" ]] +then + return +fi + + + +# Includes +#----------------------------------------------------------------------------------------------------------------------------------- + +. /usr/global/lib/default.bash + + + + + +# Global Variable +#----------------------------------------------------------------------------------------------------------------------------------- + +declare -g MUSIC_BASH=1 + +declare -Ag FLAC_2_MP3_TAB=( + [TRACKNUMBER]=TRCK + [TRACKTOTAL]=TRCK + [TITLE]=TIT2 + [ALBUM]=TALB + [ARTIST]=TPE1 + [COMPOSER]=TCOM + [ARRANGER]=IPLS + [CONDUCTOR]=TPE3 + [REMIXER]=TPE4 + [AUTHOR]=TEXT + [WRITER]=TEXT + [LYRICIST]=TEXT + [ALBUMARTIST]=TPE2 + [DATE]=TDRC + [GENRE]=TCON + [COMPILATION]=TCMP + [DISCTOTAL]=TPOS + [DISCNUMBER]=TPOS + [LABEL]=XXXX + [PUBLISHER]=TPUB + [ISRC]=TSRC + [BARCODE]=TXXX + [CATALOGNUMBER]=TXXX + [COPYRIGHT]=TCOP + [LICENSE]=USER + [COMMENT]=COMM + [DESCRIPTION]=TIT3 + [ENCODER]=TSSE + [MEDIA]=TMED + [LANGUAGE]=TLAN + [LYRICS]=USLT +) + +declare -Ag MP3_2_FLAC_TAB=( + [TRCK]=TRACKNUMBER:TRACKTOTAL + [TIT2]=TITLE + [TALB]=ALBUM + [TPE1]=ARTIST + [TCOM]=COMPOSER + [IPLS]=ARRANGER + [TPE3]=CONDUCTOR + [TPE4]=REMIXER + [TEXT]=AUTHOR:WRITER:LYRICIST + [TPE2]=ALBUMARTIST + [TDRC]=DATE + [TCON]=GENRE + [TCMP]=COMPILATION + [TPOS]=DISCNUMBER:DISCTOTAL + [TPUB]=PUBLISHER + [TSRC]=ISRC + [TXXX]=BARCODE:CATALOGNUMBER + [TCOP]=COPYRIGHT + [USER]=LICENSE + [COMM]=COMMENT + [TIT3]=DESCRIPTION + [TSSE]=ENCODER + [TMED]=MEDIA + [TLAN]=LANGUAGE + [USLT]=LYRICS +) + +declare -g FLAC_TAG_LIST="TRACKNUMBER TRACKTOTAL TITLE ALBUM ARTIST COMPOSER ARRANGER CONDUCTOR REMIXER AUTHOR WRITER LYRICIST ALBUMARTIST DATE GENRE COMPILATION LABEL PUBLISHER ISRC BARCODE UPC COPYRIGHT LICENSE COMMENT DESCRIPTION ENCODER MEDIA LANGUAGE LYRICS" +declare -g FLAC_TAG_COND=$(echo '('${FLAC_TAG_LIST}')' | sed -e 's/ /|/g') + +declare -g NODEF_TAG_LIST="TRACKNUMBER TITLE ISRC LYRICS" +declare -g NODEF_TAG_COND=$(echo '('${NODEF_TAG_LIST}')' | sed -e 's/ /|/g') + + + + + +#----------------------------------------------------------------------------------------------------------------------------------- +# Fix Name +#----------------------------------------------------------------------------------------------------------------------------------- +# Standardise Name +#----------------------------------------------------------------------------------------------------------------------------------- +# $1: Input Name +# $2: SED Substitute Patern +# Out: Output Name +#----------------------------------------------------------------------------------------------------------------------------------- + +function fix_name +{ + input_name="$1" + ssp="$2" + + if [[ "${ssp}" != "" ]] + then + sse="s/${ssp}" + else + sse="s/^//" + fi + + echo ${input_name} | + sed -e 's/[ ,!/?:]/_/g' \ + -e "s/['’´]/_/g" \ + -e 's/\[/-/g' -e 's/\]//g' \ + -e 's/(/-/g' -e 's/)//g' \ + -e 's/__/_/g' -e 's/_\././g' -e 's/_-/-/g' -e 's/--/-/g' -e 's/-_/-/g' \ + -e 's/à/a/g' -e 's/á/a/g' -e 's/ä/a/g' -e 's/â/a/g' -e 's/ã/a/g' -e 's/é/e/g' -e 's/è/e/g' -e 's/ê/e/g' -e 's/ë/e/g' -e 's/ï/i/g' -e 's/î/i/g' -e 's/í/i/g' -e 's/ô/o/g' -e 's/ö/o/g' -e 's/ó/o/g' -e 's/ù/u/g' -e 's/ü/u/g' -e 's/û/u/g' -e 's/ú/u/g' -e 's/ç/c/g' -e 's/ñ/n/g' \ + -e 's/À/a/g' -e 's/Á/a/g' -e 's/Ä/a/g' -e 's/Â/a/g' -e 's/Ã/a/g' -e 's/É/e/g' -e 's/È/e/g' -e 's/Ê/e/g' -e 's/Ë/e/g' -e 's/Ï/i/g' -e 's/Î/i/g' -e 's/Í/i/g' -e 's/Ô/o/g' -e 's/Ö/o/g' -e 's/Ó/o/g' -e 's/Ù/u/g' -e 's/Ü/u/g' -e 's/Û/u/g' -e 's/Ú/u/g' -e 's/Ç/c/g' -e 's/Ñ/n/g' \ + -e 's/¿//g' \ + -e 's/[+&]/and/g' -e 's/"/_inch/g' \ + -e 's/#//g' \ + -e 's/^[_-]*//' \ + -e 's/[_-]*$//' \ + -e "${sse}" | + tr '[:upper:]' '[:lower:]' +} + + + + + +#----------------------------------------------------------------------------------------------------------------------------------- +# Fix File Name +#----------------------------------------------------------------------------------------------------------------------------------- +# Standardise File Name +#----------------------------------------------------------------------------------------------------------------------------------- +# $1: Input File Name +# $2: SED Substitute Patern +# Out: Output File Name +#----------------------------------------------------------------------------------------------------------------------------------- + +function fix_file_name +{ + input_file_name="$1" + ssp="$2" + + fix_name "${input_file_name}" "${ssp}" | + sed -e 's/\(^[0-9]*\)./\1-/' +} + + + + + +# TagTab Alloc +#----------------------------------------------------------------------------------------------------------------------------------- + +function tagtab_alloc +{ + unset tagtab + declare -Ag tagtab + + declare -g taglist + taglist=":" +} + + + + + +# Tag Exist +#----------------------------------------------------------------------------------------------------------------------------------- + +function tag_exist +{ + tag="$1" + + echo ${taglist} | grep -e ":${tag}:" +} + + + + + +# TagTab Read +#----------------------------------------------------------------------------------------------------------------------------------- + +function tagtab_read +{ + track_id="$1" + track_file="$2" + mode="$3" + + tmp_file=$(mktemp) + + case "${track_file}" + in + *.flac) + metaflac --export-tags-to=- "${track_file}" | sed -e 's/^[^=]*=/\U&\E/' > ${tmp_file} + + while read line + do + tag="${line/=*}" + + if [[ ${line/*=*/=} == "=" ]] && [[ "${tag}" != "" ]] + then + value="$(tag_read "${track_file}" "${tag}")" + + if [[ "$(tag_exist ${tag})" == "" ]] + then + taglist="${taglist}${tag}:" + fi + + if [[ ( "${mode}" != "FACTORING" ) || ( "${tag}" =~ ^${NODEF_TAG_COND}$ ) || ( "${tagtab["0,${tag}"]}" != "" ) ]] + then + if [[ "${tagtab["0,${tag}"]}" != "${value}" ]] + then + tagtab["${track_id},${tag}"]="$value" + fi + else + tagtab["0,${tag}"]="${value}" + fi + fi + done < ${tmp_file} + ;; + + *.mp3) + mid3v2 --list "${track_file}" | tail -n +2 | sed -e 's/^[^=]*=/\U&\E/' > ${tmp_file} + + while read line + do + mp3tag="${line/=*}" + + value="$(tag_read "${track_file}" "${mp3tag}")" + + if [[ "${line/*=*/=}" == "=" ]] && [[ "${mp3tag}" != "" ]] && [[ "${MP3_2_FLAC_TAB["${mp3tag}"]}" != "" ]] + then + tag="${MP3_2_FLAC_TAB["${mp3tag}"]}" + + if [[ "$(tag_exist ${tag})" == "" ]] + then + taglist="${taglist}${tag}:" + fi + + if [[ ( "${mode}" != "FACTORING" ) || ( "${tag}" =~ ^${NODEF_TAG_COND}$ ) || ( "${tagtab["0,${tag}"]}" != "" ) ]] + then + if [[ "${tagtab["0,${tag}"]}" != "${value}" ]] + then + tagtab["${track_id},${tag}"]="$value" + fi + else + tagtab["0,${tag}"]="${value}" + fi + fi + done < ${tmp_file} + ;; + + *) + err_echo "tagtab_read: Unknown file format: ${track_file}" + ;; + esac + + if [[ ${taglist} == ":" ]] + then + taglist="" + fi + + \rm -f ${tmp_file} +} + + + + + +# TagTab Load +#----------------------------------------------------------------------------------------------------------------------------------- + +function tagtab_load +{ + metadata_file="$1" + mode="$2" + + track_id=0 + eoa="false" + + while read -r line && [[ "${eoa}" != "true" ]] + do + tag="${line/=*}" + value="${line/${tag}=}" + + case "${tag}" + in + @${FLAC_TAG_COND}) + tagtab["${track_id},${tag}"]="$value" + ;; + + DEF) + ;; + + SOT) + track_id=$((${track_id} + 1)) + ;; + + EOT) + ;; + + EOA) + eoa="true" + ;; + + *) + err_echo "tagtab_load: Unkwown tag: '${tag}'" + ;; + esac + done < "${metadata_file}" +} + + + + + +# TagTab Dump +#----------------------------------------------------------------------------------------------------------------------------------- + +function tagtab_dump +{ + track_id="$1" + dump_mode="$2" + + case "${dump_mode}" in + "STANDARD") + dump_list="${FLAC_TAG_LIST}" + ;; + + "PASSTHROUGH") + dump_list="${taglist//:/ }" + ;; + + "CUSTOM") + dump_list="$3" + ;; + + esac + + + + for tag in ${dump_list} + do + if [[ "${tagtab["${track_id},${tag}"]}" != "" ]] + then + echo "${tag}=${tagtab["${track_id},${tag}"]}" + fi + done +} + + + + + +# Tag Get +#----------------------------------------------------------------------------------------------------------------------------------- + +function tag_get +{ + declare -n return=$1 + track_id=$2 + tag=$3 + + + return="${tagtab["${track_id},${tag}"]}" + + if [[ "${return}" == "" ]] + then + return="${tagtab["0,${tag}"]}" + + if [[ "${return}" == "" ]] && [[ "${tag}" == "TRACKNUMBER" ]] + then + return="$(printf "%02d" ${track_id})" + fi + fi +} + + + + + +# Tag Save +#----------------------------------------------------------------------------------------------------------------------------------- + +function tag_save +{ + target_file=$1 + track_id=$2 + mode=$3 + + + + if [[ "${mode}" == "CLEAN" ]] + then + tag_all_delete "${target_file}" "" + fi + + for tag in ${FLAC_TAG_LIST} + do +# if [[ "${tagtab["${track_id},${tag}"]}" == "" ]] +# then +# value="${tagtab["0,${tag}"]}" +# +# if [[ "${value}" == "" ]] && [[ "${tag}" == "TRACKNUMBER" ]] +# then +# value="$(printf "%02d" ${track_id})" +# fi +# else +# value="${tagtab["${track_id},${tag}"]}" +# fi + + tag_get value "${track_id}" "${tag}" + + tag_delete "${target_file}" "${tag}" + + if [[ "${value}" != "" ]] + then + tag_write "${target_file}" "${tag}" "${value}" + fi + done +} + + + + + +# Tag Read +#----------------------------------------------------------------------------------------------------------------------------------- + +function tag_read +{ + track_file="$1" + tag="$2" + + case "${track_file}" + in + *.flac) + metaflac --show-tag="${tag}" "${track_file}" | sed -e 's/^[^=]*=//' -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g' + ;; + + *.mp3) +# mid3v2 --list "${track_file}" | tail -n +2 | sed -e 's/^[^=]*=/\U&\E/' | grep -e "^${FLAC_2_MP3_TAB["${tag}"]}" | sed -e 's/^[^=]*=//' -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g' + mid3v2 --list "${track_file}" | tail -n +2 | grep -e "^${tag}" | sed -e 's/^[^=]*=//' -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g' + ;; + + *) + err_echo "tag_read: Unknown file format: ${track_file}" + ;; + esac +} + + + + + +# Tag Write +#----------------------------------------------------------------------------------------------------------------------------------- + +function tag_write +{ + track_file="$1" + tag="$2" + value="$3" + + + + value="$(echo -e "$(escape_str "${value}")")" + + case "${track_file}" + in + *.flac) + cmd="metaflac --set-tag=\"${tag}=${value}\" \"${track_file}\"" + exec_cmd "${cmd}" + ;; + + *.mp3) + cmd="mid3v2 --\"${FLAC_2_MP3_TAB["${tag}"]}\" \"${value}\" \"${track_file}\"" + exec_cmd "${cmd}" + ;; + + *) + err_echo "tag_write: Unknown file format: ${track_file}" + ;; + esac +} + + + + + +# Tag Delete +#----------------------------------------------------------------------------------------------------------------------------------- + +function tag_delete +{ + track_file="$1" + tag="$2" + + case "${track_file}" + in + *.flac) + cmd="metaflac --remove-tag=\"${tag}\" \"${track_file}\"" + exec_cmd "${cmd}" + ;; + + *.mp3) + cmd="mid3v2 --delete-frames=\"${FLAC_2_MP3_TAB["${tag}"]}\" \"${track_file}\"" + exec_cmd "${cmd}" + ;; + + *) + err_echo "tag_delete: Unknown file format: ${track_file}" + ;; + esac +} + + + + + +# Tag All Delete +#----------------------------------------------------------------------------------------------------------------------------------- + +function tag_all_delete +{ + track_file="$1" + header_type="$2" + + if [[ "${header_type}" == "" ]] + then + case "${track_file##*.}" + in + flac) + header_type="ogg" + ;; + + mp3) + header_type="id3" + ;; + esac + fi + + if [[ ( "${header_type}" == "ogg") && ( "${track_file##*.}" == "mp3") ]] + then + err_echo "tag_all_delete: Can't remove ogg tags from mp3 file!" + else + case "${header_type}" + in + ogg) + cmd="metaflac --remove-all-tags \"${track_file}\"" + exec_cmd "${cmd}" + ;; + + id3) + cmd="mid3v2 --delete-all \"${track_file}\"" + exec_cmd "${cmd}" + ;; + + *) + err_echo "tag_all_delete: Unknown header type: ${header_type}" + ;; + esac + fi + +} + + + + + +# Album Type Get +#----------------------------------------------------------------------------------------------------------------------------------- + +function album_type_get +{ + track_file="$1" + + for type in various_artists tribute original_soundtrack child + do + if [[ ${track_file} == */${type}/* ]] + then + echo "${type}" + fi + done +}