diff --git a/bin/album_convert b/bin/album_convert
index a75db2f..d3381e8 100755
--- a/bin/album_convert
+++ b/bin/album_convert
@@ -113,7 +113,7 @@ ac_args_parse()
#
--) shift; break;;
- *) echo "args_parse internal error [$1] !"; exit 1;;
+ *) echo "args_parse internal error [$1] !"; exit 1;;
esac
done
diff --git a/bin/album_metadata_load b/bin/album_metadata_load
index 71b8365..adaa789 100755
--- a/bin/album_metadata_load
+++ b/bin/album_metadata_load
@@ -1,103 +1,138 @@
#!/bin/bash
+#-----------------------------------------------------------------------------------------------------------------------------------
+#
+# Album MetaData Load
+#
+# Copyright (C) 2016-2026 Arnaud G. GIBERT
+# mailto:arnaud@rx3.net
+#
+# This is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; If not, see
+# .
+#
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
# Includes
#-----------------------------------------------------------------------------------------------------------------------------------
-. /usr/global/lib/music.bash
+: "${RX3_LIB_DIR:=/usr/lib/rx3}"
+. "${RX3_LIB_DIR}/music_tools.bash"
-# System Constants
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Global Variables
#-----------------------------------------------------------------------------------------------------------------------------------
- AML_NAME="album_metadata_load"
-AML_VERSION="$Name: album_metadata_load-1_0_0-1 $"
+declare -g VERSION="1.0.0"
+declare -g NAME="album_metadata_load"
+declare -g HELP="usage: [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] [-c | --clean] "
+
+declare -g CLEAN="FALSE"
+declare -g SOURCE_DIR=""
+declare -g TARGET_DIR=""
+declare -g METADATA_FILE=""
+
+declare -g MODE="DEFAULT"
+declare -g VERBOSE="FALSE"
+declare -g DRY_RUN="FALSE"
-# Print Version
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Version Print
#-----------------------------------------------------------------------------------------------------------------------------------
-function version_print()
+aml_version_print()
{
- echo ${AML_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//'
+ version_print
}
-# Prin Help
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Help Print
#-----------------------------------------------------------------------------------------------------------------------------------
-function help_print()
+aml_help_print()
{
- echo "${AML_NAME} [-h | --help] | [-V | --version] | [-T | --test] [-v | --verbose] [-c | --clean] "
+ aml_version_print
+ help_print
}
+#-----------------------------------------------------------------------------------------------------------------------------------
# Arg Parse
#-----------------------------------------------------------------------------------------------------------------------------------
-function args_parse()
+aml_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}" -- "$@")
+ tmp_args=$(getopt -o ThVvc --long test,help,version,verbose,clean -n "${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
+ 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;;
+ -T|--test) MODE="TEST"; shift;;
+ -h|--help) MODE="EXIT"; aml_help_print; shift;;
+ -V|--version) MODE="EXIT"; aml_version_print; shift;;
# Global options
- -v|--verbose) verbose="true"; shift;;
- -c|--clean) clean="true"; shift;;
+ -v|--verbose) VERBOSE="TRUE"; shift;;
+ -c|--clean) CLEAN="TRUE"; shift;;
- #
- --) shift; break;;
- *) echo "args_parse internal error [$1] !"; exit 1;;
+ #
+ --) shift; break;;
+ *) echo "args_parse internal error [$1] !"; exit 1;;
esac
done
- if [[ "${mode}" != "exit" ]]
+ if [[ "${MODE}" != "EXIT" ]]
then
- if [[ "${#}" != "3" ]]
+ if [[ "${#}" != "3" ]]
then
if [[ "${#}" -lt "3" ]]
then
- echo "Not enough args!"
+ echo_error "Not enough args!"
else
- echo "Too many args!"
+ echo_error "Too many args!"
fi
- mode="exit"
- help_print
+ MODE="EXIT"
+ aml_help_print
else
- source_dir="$1"
- target_dir="$2"
- metadata_file="$3"
+ SOURCE_DIR="$1"
+ TARGET_DIR="$2"
+ METADATA_FILE="$3"
fi
fi
}
@@ -106,63 +141,59 @@ function args_parse()
+#-----------------------------------------------------------------------------------------------------------------------------------
# Main
#-----------------------------------------------------------------------------------------------------------------------------------
-args_parse "$@"
+aml_args_parse "$@"
-if [[ ${mode} == "exit" ]]
+
+
+if [[ "${MODE}" == "EXIT" ]]
then
exit 0
else
- if [[ ${mode} == "test" ]]
+ if [[ "${MODE}" == "TEST" ]]
then
- dry_run=true
- else
- dry_run=false
+ DRY_RUN="TRUE"
fi
fi
+echo_error "${NAME}: Mode: [${MODE}] Verbose: [${VERBOSE}] Clean: [${CLEAN}] Source_Dir: [${SOURCE_DIR}] Target_Dir: [${TARGET_DIR}] MetaData_File: [${METADATA_FILE}]"
-echo "mode: [${mode}] verbose: [${verbose}] clean: [${clean}] source_dir: [${source_dir}] target_dir: [${target_dir}] metadata_file: [${metadata_file}]" 1>&2
+mt_tagtab_alloc
-tagtab_alloc
+echo_error "Reading MetaData..."
-echo "Reading MetaData..."
-
-tagtab_load "${metadata_file}" "DEFAULT"
+mt_tagtab_load "${METADATA_FILE}" "DEFAULT"
nb_track=${track_id}
-echo "Nb track found: ${nb_track}"
-
-
+echo_error "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}"
+find "${SOURCE_DIR}" -maxdepth 1 -name '*.flac' -o -name '*.mp3' | sort |
+ (
+ while read track_file
+ do
+ mt_tag_get title "${track_id}" "TITLE"
+ suffix="${track_file##*.}"
+ target_file="$(printf "%02d" ${track_id})-${title}.${suffix}"
+ target_file="$(mt_fix_file_name "${target_file}" "")"
+ target_file="${TARGET_DIR}/$(mt_fix_file_name "${target_file}" "")"
- if [[ "${clean}" == "true" ]]
- then
- tag_save "${target_file}" "${track_id}" "CLEAN"
- else
- tag_save "${target_file}" "${track_id}" "NOCLEAN"
- fi
+ echo_error "Copying ${track_file} into ${target_file}"
+ cmd_exec cp "${track_file}" "${target_file}"
- track_id=$((${track_id} + 1))
- done
-)
+ if [[ "${CLEAN}" == "TRUE" ]]
+ then
+ mt_tag_save "${target_file}" "${track_id}" "CLEAN"
+ else
+ mt_tag_save "${target_file}" "${track_id}" "NOCLEAN"
+ fi
+
+ track_id=$((${track_id} + 1))
+ done
+ )
diff --git a/etc/bash_completion.d/album_convert b/etc/bash_completion.d/album_convert
index 245fab0..60e6b14 100644
--- a/etc/bash_completion.d/album_convert
+++ b/etc/bash_completion.d/album_convert
@@ -1,7 +1,7 @@
#!/bin/bash
#-----------------------------------------------------------------------------------------------------------------------------------
#
-# Album Convert
+# Album Convert Bash Completion
#
# Copyright (C) 2016-2026 Arnaud G. GIBERT
# mailto:arnaud@rx3.net
@@ -25,7 +25,8 @@
-_album_convert_completion() {
+_album_convert_completion()
+{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
diff --git a/etc/bash_completion.d/album_merge b/etc/bash_completion.d/album_merge
index 461ee5d..4253103 100644
--- a/etc/bash_completion.d/album_merge
+++ b/etc/bash_completion.d/album_merge
@@ -1,7 +1,7 @@
#!/bin/bash
#-----------------------------------------------------------------------------------------------------------------------------------
#
-# Album Merge
+# Album Merge Bash Completion
#
# Copyright (C) 2016-2026 Arnaud G. GIBERT
# mailto:arnaud@rx3.net
@@ -25,7 +25,8 @@
-_album_merge_completion() {
+_album_merge_completion()
+{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
@@ -41,10 +42,11 @@ _album_merge_completion() {
case ${COMP_CWORD} in
1|2)
COMPREPLY=( $(compgen -d -- "${cur}") )
- ;;
+ ;;
+
3|4)
COMPREPLY=()
- ;;
+ ;;
esac
}
diff --git a/etc/bash_completion.d/album_metadata_load b/etc/bash_completion.d/album_metadata_load
new file mode 100644
index 0000000..d79bf1d
--- /dev/null
+++ b/etc/bash_completion.d/album_metadata_load
@@ -0,0 +1,76 @@
+#!/bin/bash
+#-----------------------------------------------------------------------------------------------------------------------------------
+#
+# Album MetaData Load Bash Completion
+#
+# Copyright (C) 2016-2026 Arnaud G. GIBERT
+# mailto:arnaud@rx3.net
+#
+# This is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; If not, see
+# .
+#
+#-----------------------------------------------------------------------------------------------------------------------------------
+# -*- mode: shell; sh-basic-offset: 4; indent-tabs-mode: nil; -*-
+
+
+
+_album_metadata_load()
+{
+ local cur prev words cword
+ _init_completion || return
+
+ local options="
+ -h --help
+ -V --version
+ -T --test
+ -v --verbose
+ -c --clean
+ "
+
+ if (( cword == 1 )) && [[ "${cur}" == -* ]]; then
+ COMPREPLY=( $(compgen -W "${options}" -- "${cur}") )
+ return
+ fi
+
+ case "${prev}" in
+ --help|-h|--version|-V|--test|-T|--verbose|-v|--clean|-c)
+ COMPREPLY=()
+ ;;
+
+ *)
+ if (( cword >= 1 )) && (( cword <= 3 )); then
+ case "${cword}" in
+ 1)
+ # source_dir
+ _filedir -d
+ ;;
+
+ 2)
+ # target_dir
+ _filedir -d
+ ;;
+
+ 3)
+ # metadata_file
+ _filedir
+ ;;
+ esac
+ fi
+ ;;
+ esac
+}
+
+
+
+complete -F _album_metadata_load album_metadata_load
diff --git a/etc/bash_completion.d/album_name_fix b/etc/bash_completion.d/album_name_fix
index 47c6eab..9b64361 100644
--- a/etc/bash_completion.d/album_name_fix
+++ b/etc/bash_completion.d/album_name_fix
@@ -1,7 +1,7 @@
#!/bin/bash
#-----------------------------------------------------------------------------------------------------------------------------------
#
-# Album Name Fix
+# Album Name Fix Bash Completion
#
# Copyright (C) 2016-2026 Arnaud G. GIBERT
# mailto:arnaud@rx3.net
@@ -41,13 +41,15 @@ _album_name_fix_completion() {
case "${prev}" in
-a|--album_dir)
COMPREPLY=( $(compgen -d -- "${cur}") )
- ;;
+ ;;
+
-p|--music_pattern)
COMPREPLY=()
- ;;
+ ;;
+
-s|--sed_substitute_pattern)
COMPREPLY=()
- ;;
+ ;;
esac
}
diff --git a/usr/lib/rx3/music_tools.bash b/usr/lib/rx3/music_tools.bash
new file mode 100644
index 0000000..d8f0242
--- /dev/null
+++ b/usr/lib/rx3/music_tools.bash
@@ -0,0 +1,636 @@
+#!/bin/bash
+#-----------------------------------------------------------------------------------------------------------------------------------
+#
+# Music Tools Library
+#
+# Copyright (C) 2016-2026 Arnaud G. GIBERT
+# mailto:arnaud@rx3.net
+#
+# This is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; If not, see
+# .
+#
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+if [[ "${MUSIC_TOOLS_LIB}" != "" ]]
+then
+ return
+else
+ declare -g MUSIC_TOOLS_LIB=1
+fi
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Includes
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+: "${RX3_LIB_DIR:=/usr/lib/rx3}"
+. "${RX3_LIB_DIR}/base.bash"
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Global Variable
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+declare -Ag MT_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 MT_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 MT_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 MT_FLAC_TAG_COND=$(echo '('${MT_FLAC_TAG_LIST}')' | sed -e 's/ /|/g')
+
+declare -g MT_NODEF_TAG_LIST="TRACKNUMBER TITLE ISRC LYRICS"
+declare -g MT_NODEF_TAG_COND=$(echo '('${MT_NODEF_TAG_LIST}')' | sed -e 's/ /|/g')
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Fix Name
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Standardise Name
+#-----------------------------------------------------------------------------------------------------------------------------------
+# $1: Input Name
+# $2: SED Substitute Patern
+# Out: Output Name
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_fix_name()
+{
+ local input_name="$1"
+ local 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
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_fix_file_name()
+{
+ local input_file_name="$1"
+ local ssp="$2"
+
+
+ mt_fix_name "${input_file_name}" "${ssp}" |
+ sed -e 's/\(^[0-9]*\)./\1-/'
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# TagTab Alloc
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tagtab_alloc()
+{
+ unset tagtab
+ declare -Ag tagtab
+
+ declare -g taglist
+ taglist=":"
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Tag Exist
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tag_exist()
+{
+ local tag="$1"
+
+
+ echo ${taglist} | grep -e ":${tag}:"
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# TagTab Read
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tagtab_read()
+{
+ local track_id="$1"
+ local track_file="$2"
+ local 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="$(mt_tag_read "${track_file}" "${tag}")"
+
+ if [[ "$(mt_tag_exist ${tag})" == "" ]]
+ then
+ taglist="${taglist}${tag}:"
+ fi
+
+ if [[ ( "${mode}" != "FACTORING" ) || ( "${tag}" =~ ^${MT_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="$(mt_tag_read "${track_file}" "${mp3tag}")"
+
+ if [[ "${line/*=*/=}" == "=" ]] && [[ "${mp3tag}" != "" ]] && [[ "${MT_MP3_2_FLAC_TAB["${mp3tag}"]}" != "" ]]
+ then
+ tag="${MT_MP3_2_FLAC_TAB["${mp3tag}"]}"
+
+ if [[ "$(mt_tag_exist ${tag})" == "" ]]
+ then
+ taglist="${taglist}${tag}:"
+ fi
+
+ if [[ ( "${mode}" != "FACTORING" ) || ( "${tag}" =~ ^${MT_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}
+ ;;
+
+ *)
+ echo_error "mt_tagtab_read: Unknown file format: ${track_file}"
+ ;;
+ esac
+
+ if [[ ${taglist} == ":" ]]
+ then
+ taglist=""
+ fi
+
+ \rm -f ${tmp_file}
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# TagTab Load
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tagtab_load()
+{
+ local metadata_file="$1"
+ local mode="$2"
+
+
+ track_id=0
+ eoa="false"
+
+ while read -r line && [[ "${eoa}" != "true" ]]
+ do
+ tag="${line/=*}"
+ value="${line/${tag}=}"
+
+ case "${tag}"
+ in
+ @${MT_FLAC_TAG_COND})
+ tagtab["${track_id},${tag}"]="$value"
+ ;;
+
+ DEF)
+ ;;
+
+ SOT)
+ track_id=$((${track_id} + 1))
+ ;;
+
+ EOT)
+ ;;
+
+ EOA)
+ eoa="true"
+ ;;
+
+ *)
+ echo_error "mt_tagtab_load: Unkwown tag: '${tag}'"
+ ;;
+ esac
+ done < "${metadata_file}"
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# TagTab Dump
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tagtab_dump()
+{
+ local track_id="$1"
+ local dump_mode="$2"
+
+
+ case "${dump_mode}" in
+ "STANDARD")
+ dump_list="${MT_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
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tag_get()
+{
+ local declare -n return=$1
+ local track_id=$2
+ local 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
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tag_save()
+{
+ local target_file=$1
+ local track_id=$2
+ local mode=$3
+
+
+ if [[ "${mode}" == "CLEAN" ]]
+ then
+ mt_tag_all_delete "${target_file}" ""
+ fi
+
+ for tag in ${MT_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
+
+ mt_tag_get value "${track_id}" "${tag}"
+
+ mt_tag_delete "${target_file}" "${tag}"
+
+ if [[ "${value}" != "" ]]
+ then
+ mt_tag_write "${target_file}" "${tag}" "${value}"
+ fi
+ done
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Tag Read
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tag_read()
+{
+ local track_file="$1"
+ local tag="$2"
+
+
+ case "${track_file}"
+ in
+ *.flac)
+ sh_exec "metaflac --show-tag=\"${tag}\" \"${track_file}\" | sed -e 's/^[^=]*=//' -e ':a' -e 'N' -e '"'$!'"ba' -e 's/\n/\\n/g'"
+ ;;
+
+ *.mp3)
+# sh_exec "mid3v2 --list \"${track_file}\" | tail -n +2 | sed -e 's/^[^=]*=/\U&\E/' | grep -e \"^${MT_FLAC_2_MP3_TAB[\"${tag}\"]}\" | sed -e 's/^[^=]*=//' -e ':a' -e 'N' -e '"'$!'"ba' -e 's/\n/\\n/g'"
+ sh_exec "mid3v2 --list \"${track_file}\" | tail -n +2 | grep -e \"^${tag}\" | sed -e 's/^[^=]*=//' -e ':a' -e 'N' -e '"'$!'"ba' -e 's/\n/\\n/g'"
+ ;;
+
+ *)
+ echo_error "mt_tag_read: Unknown file format: ${track_file}"
+ ;;
+ esac
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Tag Write
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tag_write()
+{
+ local track_file="$1"
+ local tag="$2"
+ local value="$3"
+
+
+ value="$(echo -e "$(str_escape "${value}")")"
+
+ case "${track_file}"
+ in
+ *.flac)
+ cmd_exec metaflac --set-tag="${tag}=${value}" "${track_file}"
+ ;;
+
+ *.mp3)
+ cmd_exec mid3v2 --"${MT_FLAC_2_MP3_TAB["${tag}"]}" "${value}" "${track_file}"
+ ;;
+
+ *)
+ echo_error "mt_tag_write: Unknown file format: ${track_file}"
+ ;;
+ esac
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Tag Delete
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tag_delete()
+{
+ local track_file="$1"
+ local tag="$2"
+
+
+ case "${track_file}"
+ in
+ *.flac)
+ cmd_exec metaflac --remove-tag="${tag}" "${track_file}"
+ ;;
+
+ *.mp3)
+ cmd_exec mid3v2 --delete-frames="${MT_FLAC_2_MP3_TAB["${tag}"]}" "${track_file}"
+ ;;
+
+ *)
+ echo_error "mt_tag_delete: Unknown file format: ${track_file}"
+ ;;
+ esac
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Tag All Delete
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_tag_all_delete()
+{
+ local track_file="$1"
+ local 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
+ echo_error "mt_tag_all_delete: Can't remove ogg tags from mp3 file!"
+ else
+ case "${header_type}"
+ in
+ ogg)
+ cmd_exec metaflac --remove-all-tags "${track_file}"
+ ;;
+
+ id3)
+ cmd_exec mid3v2 --delete-all "${track_file}"
+ ;;
+
+ *)
+ echo_error "mt_tag_all_delete: Unknown header type: ${header_type}"
+ ;;
+ esac
+ fi
+
+}
+
+
+
+
+
+#-----------------------------------------------------------------------------------------------------------------------------------
+# Album Type Get
+#-----------------------------------------------------------------------------------------------------------------------------------
+
+mt_album_type_get()
+{
+ local track_file="$1"
+
+
+ for type in various_artists tribute original_soundtrack child
+ do
+ if [[ ${track_file} == */${type}/* ]]
+ then
+ echo "${type}"
+ fi
+ done
+}