# split_tracks splits each track of the library. # # The library is mirrored for each type of split. # karaoke: reduces the volume of the vocals by 80% and remixes it # drum only: just the drums # no drum: everything but the drums #!/bin/bash function make_drum() { mkdir -p "${dest_dir['no drums']}" quiet_drums="${actual_work_dir}/quiet drums.wav" wav_name="$(sed 's/\.flac$/.wav/' <<< "$file_name")" mixed_wav="${dest_dir['no drums']}/${wav_name}" final_opus="$(sed 's/\.wav$/.opus/' <<< "$mixed_wav")" echo sox -v "$volume_reduction_factor" "$drum_track" "$quiet_drums" sox -v "$volume_reduction_factor" "$drum_track" "$quiet_drums" echo sox -m "${nodrums[@]}" "$quiet_drums" "$mixed_wav" sox -m "${nodrums[@]}" "$quiet_drums" "$mixed_wav" rm "$quiet_drums" echo opusenc --comp 10 --downmix-stereo \ --title "'${tags[TITLE]}'" --artist "'${tags[ARTIST]}'" \ --album "'${tags[ALBUM]}'" --tracknumber "'${tags[TRACKNUMBER]}'" \ --date "'${tags[DATE]}'" "'$mixed_wav'" "'$final_opus'" opusenc --comp 10 --downmix-stereo \ --title "${tags[TITLE]}" --artist "${tags[ARTIST]}" \ --album "${tags[ALBUM]}" --tracknumber "${tags[TRACKNUMBER]}" \ --date "${tags[DATE]}" "$mixed_wav" "$final_opus" rm "$mixed_wav" } function make_drumonly() { mkdir -p "${dest_dir['drums only']}" echo echo dest dir: ${dest_dir['drums only']} echo drum track: "$drum_track" final_opus="${dest_dir['drums only']}/$(sed 's/\.flac$/.opus/' <<< "$file_name")" echo opusenc --comp 10 --downmix-stereo \ --title "'${tags[TITLE]}'" --artist "'${tags[ARTIST]}'" \ --album "'${tags[ALBUM]}'" --tracknumber "'${tags[TRACKNUMBER]}'" \ --date "'${tags[DATE]}'" "'$drum_track'" "'$final_opus'" opusenc --comp 10 --downmix-stereo \ --title "${tags[TITLE]}" --artist "${tags[ARTIST]}" \ --album "${tags[ALBUM]}" --tracknumber "${tags[TRACKNUMBER]}" \ --date "${tags[DATE]}" "$drum_track" "$final_opus" } function make_karaoke() { mkdir -p "${dest_dir[karaoke]}" quiet_vocals="${actual_work_dir}/quiet vocals.wav" wav_name="$(sed 's/\.flac$/.wav/' <<< "$file_name")" mixed_wav="${dest_dir['karaoke']}/${wav_name}" final_opus="$(sed 's/\.wav$/.opus/' <<< "$mixed_wav")" echo sox -v "$volume_reduction_factor" "$vocal_track" "$quiet_vocals" sox -v "$volume_reduction_factor" "$vocal_track" "$quiet_vocals" echo sox -m "${karaoke[@]}" "$quiet_vocals" "$mixed_wav" sox -m "${karaoke[@]}" "$quiet_vocals" "$mixed_wav" rm "$quiet_vocals" echo opusenc --comp 10 --downmix-stereo \ --title "'${tags[TITLE]}'" --artist "'${tags[ARTIST]}'" \ --album "'${tags[ALBUM]}'" --tracknumber "'${tags[TRACKNUMBER]}'" \ --date "'${tags[DATE]}'" "'$mixed_wav'" "'$final_opus'" opusenc --comp 10 --downmix-stereo \ --title "${tags[TITLE]}" --artist "${tags[ARTIST]}" \ --album "${tags[ALBUM]}" --tracknumber "${tags[TRACKNUMBER]}" \ --date "${tags[DATE]}" "$mixed_wav" "$final_opus" rm "$mixed_wav" } volume_reduction_factor='0.2' src_library="${HOME}/flac" work_dir="${HOME}/split" actual_work_dir="${work_dir}/htdemucs_ft" type -P 'demucs' &>/dev/null || ( printf 'No demucs in path.\nInstall with `pip install demucs` or something.\n\n' >&2 exit 1 ) find "$src_library" -type f -name '*.flac' | while read file; do if find "$work_dir" -type f &>/dev/null; then rm -rf "${work_dir}"/*; fi echo "file: $file" if [[ ! -f "$file" ]]; then file="${file//ome\/luket/\/home\/luket}" echo "new file: $file" if [[ ! -f "$file" ]]; then echo 'shits broke' >&2 exit 1 fi fi # file is full original path + filename src_dir="$(dirname "$file")" file_name="$(basename "$file")" unset tags unset dest_dir declare -A tags echo tag time while read -r line; do echo line: $line tag_type="$(cut -d= -f1 <<< "$line")" tag_val="$(cut -d= -f2- <<< "$line")" [[ "$tag_type" == 'ReleaseDate' ]] && tag_type='DATE' [[ "$tag_type" == 'Year' ]] && tag_type='YEAR' [[ "$tag_type" == 'Artist' ]] && tag_type='ARTIST' [[ "$tag_type" == 'Title' ]] && tag_type='TITLE' [[ "$tag_type" == 'Tracknumber' ]] && tag_type='TRACKNUMBER' [[ "$tag_type" == 'Album' ]] && tag_type='ALBUM' tags[$tag_type]="$tag_val" done < <(metaflac --list --block-type=VORBIS_COMMENT "$file" | grep 'comment\[' | cut -d: -f2- | sed 's/^ //') declare -a ensure ensure=( TRACKNUMBER TITLE DATE ALBUM ARTIST ) for tag_type in "${ensure[@]}"; do if [[ -z "${tags[$tag_type]}" ]]; then tags[$tag_type]="missing $tag_type" fi done declare -A dest_dir dest_dir['karaoke']="${src_dir//flac/karaoke}" dest_dir['drums only']="${src_dir//flac/drums only}" dest_dir['no drums']="${src_dir//flac/no drums}" demucs -n htdemucs_ft -o "$work_dir" --filename '{track} {stem}.{ext}' -j2 -d cpu --clip-mode rescale -- "$file" < /dev/tty unset files karaoke nodrums declare -a files karaoke nodrums readarray -t files < <(find "$work_dir" -type f -name '*.wav') unset vocal_track unset drum_track for cur_file in "${files[@]}"; do echo current file: "$cur_file" if ! grep -Eq 'drums\.wav$' <<< "$cur_file"; then nodrums+=("$cur_file") else drum_track="$cur_file" fi if ! grep -Eq 'vocals\.wav$' <<< "$cur_file"; then karaoke+=("$cur_file") else vocal_track="$cur_file" fi done for i in "${nodrums[@]}"; do printf 'Drum practice: %s\n' "$i" done if [[ -z "$drum_track" ]]; then printf 'No drum track. Will not create a drum practice file.\n' else make_drum make_drumonly fi for i in "${karaoke[@]}"; do printf 'Karaoke practice: %s\n' "$i" done if [[ ! "$vocal_track" ]]; then printf 'No vocal track. Will not create a karaoke file.\n' else make_karaoke fi done