From d45176c24a2110a8a177ed3dcae35b15cfd78ab3 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Tue, 3 May 2016 15:59:01 +0200 Subject: manpage neu, Makefile neu, version update --- .gitignore | 2 + Makefile | 45 ++++++++ sound-cutter | 332 ----------------------------------------------------- sound-cutter.8.in | 63 +++++++++++ sound-cutter.in | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 443 insertions(+), 332 deletions(-) create mode 100644 .gitignore create mode 100644 Makefile delete mode 100755 sound-cutter create mode 100644 sound-cutter.8.in create mode 100755 sound-cutter.in diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1f96622 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +sound-cutter +sound-cutter.8 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..719e24b --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +# +# sound-cutter - Wrapper for sox for mastering stereo music (a.k.a. CDs) from multi channel records +# +# Copyright (c) 2013-2016 Erich Eckner +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. +# + +DESTDIR = +BINDIR = /usr/bin +MANDIR = /usr/share/man + +VERSION = 1.0.1 + +all: sound-cutter sound-cutter.8 + +%: %.in + sed "s/#VERSION#/$(VERSION)/; s@#BINDIR#@$(BINDIR)@" $< > $@ + +.PHONY: install dist clean + +install: all + install -D -m0755 sound-cutter $(DESTDIR)$(BINDIR)/sound-cutter + install -D -m0644 sound-cutter.8 $(DESTDIR)$(MANDIR)/man8/sound-cutter.8 + +dist: clean + (cd .. && tar czvf sound-cutter-$(VERSION).tar.gz sound-cutter-$(VERSION)) + +clean: + rm -f sound-cutter{,.8} + +# End of file diff --git a/sound-cutter b/sound-cutter deleted file mode 100755 index fe3e181..0000000 --- a/sound-cutter +++ /dev/null @@ -1,332 +0,0 @@ -#!/bin/bash - -set -e - -verwendung() { - >&2 echo '' - >&2 echo 'Verwendung:' - >&2 echo '' - >&2 echo "${me}"' [ -f | --force ] [ -a | --ausfuehrlich ] [ -1 | --noGain ] [ -n | --dummy ] { ( -i | --input ) input$i.flac } ( -o | --output ) output.flac ( -p | --points ) points' - >&2 echo '' - >&2 echo ' Mischen und Schneiden:' - >&2 echo ' -f | --force: output.flac ggf. überschreiben' - >&2 echo ' -1 | --noGain: Lautstärke nicht normalisieren' - >&2 echo ' -n | --dummy: nur auszuführenden Befehl anzeigen und nichts tun' - >&2 echo ' -s | --sampleRate: alternative Samplerate zum Abspeichern' - >&2 echo ' -i | --input: Quelle' - >&2 echo ' -o | --output: Ziel' - >&2 echo ' -p | --points: Punktedatei' - >&2 echo ' -a | --ausfuehrlich: ausführliche Zwischenausgaben machen' - >&2 echo '' - >&2 echo "$0"' [ -h | --help ]' - >&2 echo ' Hilfe anzeigen' - >&2 echo '' - [ -z "$1" ] && exit 1 || exit $1 -} - -timetosample() { - local zeit - case "$2" in - *:*:*) - zeit="$2" - ;; - *:*) - zeit="0:$2" - ;; - *) - zeit="0:0:0$2" - ;; - esac - bc <<< "( 0.5 + $1 * $(date "+%s.%N" -ud "1970-01-01 ${zeit}") ) / 1" -} - -me="$(readlink -f "$0")" - -eval set -- "$( - getopt -o 1ahfi:no:p:s: \ - --long noGain \ - --long ausfuehrlich \ - --long help \ - --long force \ - --long input: \ - --long dummy \ - --long output: \ - --long points: \ - --long sampleRate: \ - -n "$(basename "$0")" -- "$@" || \ - echo verwendung -)" - -noGain=false -ausfuehrlich=false -force=false -dummy=false - -while true; do - case "$1" in - -1|--noGain) - noGain=true - ;; - -a|--ausfuehrlich) - ausfuehrlich=true - ;; - -f|--force) - force=true - ;; - -h|--help) - verwendung 0 - ;; - -i|--input) - shift - inputs[${#inputs[@]}]="$1" - ;; - -n|--dummy) - dummy=true - ;; - -o|--output) - shift - [ -n "${output}" ] && echo 'Ich kann nur eine Output-Datei-Option verstehen.' && verwendung - output="$1" - ;; - -p|--points) - shift - [ -n "${points}" ] && echo 'Ich kann nur eine Point-Datei-Option verstehen.' && verwendung - points="$1" - ;; - -s|--sampleRate) - shift - [ -n "${outRate}" ] && echo 'Ich kann nur eine Samplerate-Option verstehen.' && verwendung - outRate="$1" - ;; - --) - shift - [ $# -gt 0 ] && echo 'Unbekannte Parameter: '"$#" && verwendung - break - ;; - *) - >&2 echo 'Hups, das sollte nicht passieren könne, '"$1"' kenne ich doch nicht ...' - exit -1 - ;; - esac - shift -done - -[ -z "${output}" ] && >&2 echo 'Output-Datei fehlt!' && verwendung -[ -z "${points}" ] && >&2 echo 'Points-Datei fehlt!' && verwendung -[ "${#inputs[@]}" -eq 0 ] && >&2 echo 'Input-Datei fehlt!' && verwendung - -[ ! -e "${points}" ] && >&2 echo "Die Schnittpunktedatei '${points}' existiert nicht!" && exit 1 -for inp in "${inputs[@]}" -do - [ ! -e "${inp}" ] && >&2 echo "Die Inputdatei '${inp}' existiert nicht!" && verwendung - [ $(echo "${inp}" | grep -c "\s") -gt 0 ] && >&2 echo "Bitte keine Leerzeichen im input-Dateinamen!" && exit 1 -done - -[ $(echo "${output}" | grep -c "\s") -gt 0 ] && >&2 echo "Bitte keine Leerzeichen im output-Dateinamen!" && exit 1 -[ $(echo "${points}" | grep -c "\s") -gt 0 ] && >&2 echo "Bitte keine Leerzeichen im points-Dateinamen!" && exit 1 - -if [ -e "${output}" ] -then - if ${force} - then - ${dummy} || rm "${output}" - else - >&2 echo "Die Ausgabedatei '${output}' existiert bereits!" && exit 1 - fi -fi -odn="$(dirname "$(readlink -f "${output}")")" -obn="$(basename "${output}")" -if [ $(ls -1 "${odn}" | grep "$(echo "${obn}" | sed "s/%[0-9]\?n/.*/g")" | wc -l) -gt 0 ] -then - if ${force} - then - ${dummy} || rm ${odn}/$(echo "${obn}" | sed "s/%[0-9]\?n/*/g") - else - >&2 echo "Die Ausgabedatei '${output}' existiert bereits!" && exit 1 - fi -fi - -inRate="$(soxi -r "${inputs[0]}")" -[ -z "${outRate}" ] && outRate="${inRate}" - -i=-1 -absInTime=0 -absOutTime=0 -while read -r in -do - line="$( - echo "${in}" | \ - sed 's|\s\+| |g' | \ - sed 's/^ *//' | \ - sed 's/ *\(\#\( .*\)\?\)\?$//' - )" - [ -z "${line}" ] && continue - teilEins="$(echo "${line}" | sed 's| *\(#.*\)\?$||')" - teilZwei="$(echo "${line}" | sed 's|^[^#]*\(# *\)\?||')" - - if [ ${i} -eq -1 ] - then - firstline="${teilEins}" - remixcmd="${teilZwei}" - if echo "${remixcmd}" | \ - grep -q "rate " - then - >&2 echo 'FEHLER: "rate" explizit gesetzt, das bringt die Zeitmessung durcheinander - verwende statt dessen die Option "-s" bzw. "--sampleRate".' - verwendung - fi - i=0 - continue - fi - if [ -z "${teilEins}" ] - then - if [ -n "${trackmods[${i}]}" ] - then - echo "Syntaxfehler in Track $[${i}+1]: habe bereits Modifikatoren gelesen ('${trackmods[${i}]}' -> '${teilZwei}')" - exit 1 - fi - trackmods[${i}]=" ${teilZwei}" - inTimecorrections[${i}]=0 - outTimecorrections[${i}]=0 - while echo "${trackmods[${i}]}" | grep -q " trimsplice" - do - rest="${trackmods[${i}]#* trimsplice}" - - end=$(timetosample ${inRate} $(echo "${rest}" | awk '{print $1}')) - if [ ! "${doverlaps[${i}]}" == "" ] - then - end=$[${end}+${doverlaps[${i}]}] - fi - inDiscard=$(timetosample ${inRate} $(echo "${rest}" | awk '{print $2}')) - outDiscard=$(timetosample ${outRate} $(echo "${rest}" | awk '{print $2}')) - inExcess=$(timetosample ${inRate} $(echo "${rest}" | awk '{print $3}')) - outExcess=$(timetosample ${outRate} $(echo "${rest}" | awk '{print $3}')) - leeway=$(timetosample ${inRate} $(echo "${rest}" | awk '{print $4}')) - - trackmods[${i}]="$( - echo "${trackmods[${i}]}" | \ - sed "s/ \+trimsplice\( \+[^ ]\+\)\{4\}/ trim 0s ${end}s ${inDiscard}s splice -t ${end}s,${inExcess}s,${leeway}s/" - )" - inTimecorrections[${i}]=$[${inTimecorrections[${i}]}+${inDiscard}+2*${inExcess}] - outTimecorrections[${i}]=$[${outTimecorrections[${i}]}+${outDiscard}+2*${outExcess}] - done - continue - fi - - i=$[${i}+1] - - tmp=$(timetosample ${inRate} "${teilEins}") - inTimes[${i}]=$[${tmp}-${absInTime}] - absInTime=${tmp} - tmp=$(timetosample ${outRate} "${teilEins}") - outTimes[${i}]=$[${tmp}-${absOutTime}] - absOutTime=${tmp} - - newFile[${i}]=true - teilZwei="${teilZwei} " - while [ -n "${teilZwei}" ] - do - case "${teilZwei}" in - "overlap "*) - teilZwei="${teilZwei#* }" - overlaps[${i}]=$[$(timetosample ${inRate} ${teilZwei%% *})/2] - doverlaps[${i}]=$[2*${overlaps[${i}]}] - teilZwei="${teilZwei#* }" - ;; - "noNewFile"*) - teilZwei="${teilZwei#* }" - newFile[${i}]=false - ;; - " ") - break - ;; - *) - >&2 echo "'${teilZwei}' ist unverständlich zwischen zwei Stücken ('${line}')" - exit 1 - ;; - esac - done -done < "${points}" - -if ${ausfuehrlich} -then - echo "trackmods:" - for (( i=0; i<=${#inTimes[@]}; i++ )) - do - echo "${i}: ${trackmods[${i}]} ; ${inTimes[${i}]} ; ${overlaps[${i}]} ; ${doverlaps[${i}]} ; ${inTimecorrections[${i}]}" - done -fi - -repcmd="" -abstime=0 -for (( i=1; i<=${#inTimes[@]}; i++ )) -do - abstime=$[${abstime}+${inTimes[${i}]}] - [ -z "${doverlaps[${i}]}" ] && continue - repcmd="${repcmd} trim 0s $[${abstime}-${doverlaps[${i}]}]s : trim 0s ${doverlaps[${i}]}s repeat :" - abstime=0 -done - -trackmodcmd="" -abstime=0 -for (( i=0; i<=${#inTimes[@]}; i++ )) -do - if [ ${i} -gt 0 ] - then - [ -n "${inTimecorrections[$[${i}-1]]}" ] && \ - inTimes[${i}]=$[${inTimes[${i}]}-${inTimecorrections[$[${i}-1]]}] - [ -n "${outTimecorrections[$[${i}-1]]}" ] && \ - outTimes[${i}]=$[${outTimes[${i}]}-${outTimecorrections[$[${i}-1]]}] - fi - - [ -n "${inTimes[$[${i}+1]]}" ] && abstime=$[${abstime}+${inTimes[$[${i}+1]]}] - [ -n "${doverlaps[${i}]}" ] && abstime=$[${abstime}+${doverlaps[${i}]}] - [ "${trackmods[${i}]}" == "${trackmods[$[${i}+1]]}" ] && continue - if [ ${i} -eq ${#inTimes[@]} ] - then - trackmodcmd="${trackmodcmd}${trackmods[${i}]} " - else - trackmodcmd="${trackmodcmd}trim 0s ${abstime}s${trackmods[${i}]} : " - fi - abstime=0 -done - -splicecmd="" -abstime=0 -for (( i=0; i<=${#inTimes[@]}; i++ )) -do - [ -n "${inTimes[${i}]}" ] && abstime=$[${abstime}+${inTimes[${i}]}] - [ -z "${overlaps[${i}]}" ] && continue - splicecmd="${splicecmd} ${abstime}s,${overlaps[${i}]}s,0s" - abstime=$[${abstime}+${doverlaps[${i}]}] -done -[ -n "${splicecmd}" ] && splicecmd="splice -t${splicecmd}" - -trimcmd="" -for (( i=1; i<=${#outTimes[@]}; i++ )) -do - trimcmd="${trimcmd}trim 0s =${outTimes[${i}]}s : " - ${newFile[${i}]} && trimcmd="${trimcmd}newfile : " -done - -[ ${outRate} -ne ${inRate} ] && remixcmd="${remixcmd} rate -v ${outRate}" - -if ! ${noGain} -then - firstline="${firstline} gain -b" - remixcmd="${remixcmd} gain -n" -fi - -echo sox -M "${inputs[@]}" -p trim ${firstline} -echo sox -t sox - -p ${repcmd} -echo sox -t sox - -p ${trackmodcmd} -echo sox -t sox - -p ${splicecmd} ${remixcmd} -echo sox -t sox - ${output} ${trimcmd} - -if ! ${dummy} -then - sox -M "${inputs[@]}" -p trim ${firstline}| \ - sox -t sox - -p ${repcmd} | \ - sox -t sox - -p ${trackmodcmd} | \ - sox -t sox - -p ${splicecmd} ${remixcmd} | \ - sox -t sox - ${output} ${trimcmd} -fi diff --git a/sound-cutter.8.in b/sound-cutter.8.in new file mode 100644 index 0000000..c5b9697 --- /dev/null +++ b/sound-cutter.8.in @@ -0,0 +1,63 @@ +.TH sound-cutter 8 "" "sound-cutter #VERSION#" "" +.SH NAME +sound-cutter \- Wrapper for sox for mastering stereo music (a.k.a. CDs) from multi channel records +.SH SYNOPSIS +\fBsound-cutter [options]\fP +.SH DESCRIPTION +\fBsound-cutter\fP mixes, processes and cuts multi channel recordings via \fBsox\fP. +.SH OPTIONS +.TP +.B "\-1, \-\-no\-gain" +Do not normalize audio (it's faster). +.TP +.B "\-f, \-\-force" +Overwrite output file(s). +.TP +.B "\-n, \-\-dummy" +Only print what would be done. +.TP +.B "\-s, \-\-sampleRate" +Explicitly set output sample rate. +.TP +.B "\-i, \-\-input" +Specify input file, one at a time (can be given multiple times). +.TP +.B "\-o, \-\-output" +Specify output file. +May be given only once. +.TP +.B "\-p, \-\-points" +Specify points file (see below for syntax). +May be given only once. +.TP +.B "\-a, \-\-ausfuehrlich" +Give verbose explanations (rudimentary). +.TP +.B "\-h, \-\-help" +Print help and exit. +.SH POINTS_FILE +Structure of file containing instructions for mixing, processing and cutting: +.TP +.B "# with trailing space" +starts comment (until end of line) +.TP +.B "# without trailing space" +divides left and right part of line +.TP +.B "first line" +left part denotes global start and stop of recording, +right part denotes final remix command +.TP +.B "other lines with non-empty left part" +denote border between tracks. Left part is time for cut, right part may be \fBoverlap $someTime\fP to denote fade betweeen tracks and/or \fBnoNewFile\fP to denote that no new +track should start here (thus it's only a border between \fBsub\fPtracks) or may be left empty. +.TP +.B "other lines with empty left part" +denote modifications of current (sub)track. +Additional to all sox effects, \fBtrimsplice $position $discard $excess $leeway\fP is also valid. +This combines splice and trim in a sensible manner. +These type of lines must not occure successively. +.SH AUTHOR +.nf +Erich Eckner +.fi diff --git a/sound-cutter.in b/sound-cutter.in new file mode 100755 index 0000000..2878350 --- /dev/null +++ b/sound-cutter.in @@ -0,0 +1,333 @@ +#!/bin/bash + +set -e + +verwendung() { + >&2 echo 'Dies ist sound-cutter Version #VERSION#' + >&2 echo '' + >&2 echo 'Verwendung:' + >&2 echo '' + >&2 echo "${me}"' [ -f | --force ] [ -a | --ausfuehrlich ] [ -1 | --noGain ] [ -n | --dummy ] { ( -i | --input ) input$i.flac } ( -o | --output ) output.flac ( -p | --points ) points' + >&2 echo '' + >&2 echo ' Mischen und Schneiden:' + >&2 echo ' -f | --force: output.flac ggf. überschreiben' + >&2 echo ' -1 | --noGain: Lautstärke nicht normalisieren' + >&2 echo ' -n | --dummy: nur auszuführenden Befehl anzeigen und nichts tun' + >&2 echo ' -s | --sampleRate: alternative Samplerate zum Abspeichern' + >&2 echo ' -i | --input: Quelle' + >&2 echo ' -o | --output: Ziel' + >&2 echo ' -p | --points: Punktedatei' + >&2 echo ' -a | --ausfuehrlich: ausführliche Zwischenausgaben machen' + >&2 echo '' + >&2 echo "$0"' [ -h | --help ]' + >&2 echo ' Hilfe anzeigen' + >&2 echo '' + [ -z "$1" ] && exit 1 || exit $1 +} + +timetosample() { + local zeit + case "$2" in + *:*:*) + zeit="$2" + ;; + *:*) + zeit="0:$2" + ;; + *) + zeit="0:0:0$2" + ;; + esac + bc <<< "( 0.5 + $1 * $(date "+%s.%N" -ud "1970-01-01 ${zeit}") ) / 1" +} + +me="$(readlink -f "$0")" + +eval set -- "$( + getopt -o 1ahfi:no:p:s: \ + --long noGain \ + --long ausfuehrlich \ + --long help \ + --long force \ + --long input: \ + --long dummy \ + --long output: \ + --long points: \ + --long sampleRate: \ + -n "$(basename "$0")" -- "$@" || \ + echo verwendung +)" + +noGain=false +ausfuehrlich=false +force=false +dummy=false + +while true; do + case "$1" in + -1|--noGain) + noGain=true + ;; + -a|--ausfuehrlich) + ausfuehrlich=true + ;; + -f|--force) + force=true + ;; + -h|--help) + verwendung 0 + ;; + -i|--input) + shift + inputs[${#inputs[@]}]="$1" + ;; + -n|--dummy) + dummy=true + ;; + -o|--output) + shift + [ -n "${output}" ] && echo 'Ich kann nur eine Output-Datei-Option verstehen.' && verwendung + output="$1" + ;; + -p|--points) + shift + [ -n "${points}" ] && echo 'Ich kann nur eine Point-Datei-Option verstehen.' && verwendung + points="$1" + ;; + -s|--sampleRate) + shift + [ -n "${outRate}" ] && echo 'Ich kann nur eine Samplerate-Option verstehen.' && verwendung + outRate="$1" + ;; + --) + shift + [ $# -gt 0 ] && echo 'Unbekannte Parameter: '"$#" && verwendung + break + ;; + *) + >&2 echo 'Hups, das sollte nicht passieren könne, '"$1"' kenne ich doch nicht ...' + exit -1 + ;; + esac + shift +done + +[ -z "${output}" ] && >&2 echo 'Output-Datei fehlt!' && verwendung +[ -z "${points}" ] && >&2 echo 'Points-Datei fehlt!' && verwendung +[ "${#inputs[@]}" -eq 0 ] && >&2 echo 'Input-Datei fehlt!' && verwendung + +[ ! -e "${points}" ] && >&2 echo "Die Schnittpunktedatei '${points}' existiert nicht!" && exit 1 +for inp in "${inputs[@]}" +do + [ ! -e "${inp}" ] && >&2 echo "Die Inputdatei '${inp}' existiert nicht!" && verwendung + [ $(echo "${inp}" | grep -c "\s") -gt 0 ] && >&2 echo "Bitte keine Leerzeichen im input-Dateinamen!" && exit 1 +done + +[ $(echo "${output}" | grep -c "\s") -gt 0 ] && >&2 echo "Bitte keine Leerzeichen im output-Dateinamen!" && exit 1 +[ $(echo "${points}" | grep -c "\s") -gt 0 ] && >&2 echo "Bitte keine Leerzeichen im points-Dateinamen!" && exit 1 + +if [ -e "${output}" ] +then + if ${force} + then + ${dummy} || rm "${output}" + else + >&2 echo "Die Ausgabedatei '${output}' existiert bereits!" && exit 1 + fi +fi +odn="$(dirname "$(readlink -f "${output}")")" +obn="$(basename "${output}")" +if [ $(ls -1 "${odn}" | grep "$(echo "${obn}" | sed "s/%[0-9]\?n/.*/g")" | wc -l) -gt 0 ] +then + if ${force} + then + ${dummy} || rm ${odn}/$(echo "${obn}" | sed "s/%[0-9]\?n/*/g") + else + >&2 echo "Die Ausgabedatei '${output}' existiert bereits!" && exit 1 + fi +fi + +inRate="$(soxi -r "${inputs[0]}")" +[ -z "${outRate}" ] && outRate="${inRate}" + +i=-1 +absInTime=0 +absOutTime=0 +while read -r in +do + line="$( + echo "${in}" | \ + sed 's|\s\+| |g' | \ + sed 's/^ *//' | \ + sed 's/ *\(\#\( .*\)\?\)\?$//' + )" + [ -z "${line}" ] && continue + teilEins="$(echo "${line}" | sed 's| *\(#.*\)\?$||')" + teilZwei="$(echo "${line}" | sed 's|^[^#]*\(# *\)\?||')" + + if [ ${i} -eq -1 ] + then + firstline="${teilEins}" + remixcmd="${teilZwei}" + if echo "${remixcmd}" | \ + grep -q "rate " + then + >&2 echo 'FEHLER: "rate" explizit gesetzt, das bringt die Zeitmessung durcheinander - verwende statt dessen die Option "-s" bzw. "--sampleRate".' + verwendung + fi + i=0 + continue + fi + if [ -z "${teilEins}" ] + then + if [ -n "${trackmods[${i}]}" ] + then + echo "Syntaxfehler in Track $[${i}+1]: habe bereits Modifikatoren gelesen ('${trackmods[${i}]}' -> '${teilZwei}')" + exit 1 + fi + trackmods[${i}]=" ${teilZwei}" + inTimecorrections[${i}]=0 + outTimecorrections[${i}]=0 + while echo "${trackmods[${i}]}" | grep -q " trimsplice" + do + rest="${trackmods[${i}]#* trimsplice}" + + end=$(timetosample ${inRate} $(echo "${rest}" | awk '{print $1}')) + if [ ! "${doverlaps[${i}]}" == "" ] + then + end=$[${end}+${doverlaps[${i}]}] + fi + inDiscard=$(timetosample ${inRate} $(echo "${rest}" | awk '{print $2}')) + outDiscard=$(timetosample ${outRate} $(echo "${rest}" | awk '{print $2}')) + inExcess=$(timetosample ${inRate} $(echo "${rest}" | awk '{print $3}')) + outExcess=$(timetosample ${outRate} $(echo "${rest}" | awk '{print $3}')) + leeway=$(timetosample ${inRate} $(echo "${rest}" | awk '{print $4}')) + + trackmods[${i}]="$( + echo "${trackmods[${i}]}" | \ + sed "s/ \+trimsplice\( \+[^ ]\+\)\{4\}/ trim 0s ${end}s ${inDiscard}s splice -t ${end}s,${inExcess}s,${leeway}s/" + )" + inTimecorrections[${i}]=$[${inTimecorrections[${i}]}+${inDiscard}+2*${inExcess}] + outTimecorrections[${i}]=$[${outTimecorrections[${i}]}+${outDiscard}+2*${outExcess}] + done + continue + fi + + i=$[${i}+1] + + tmp=$(timetosample ${inRate} "${teilEins}") + inTimes[${i}]=$[${tmp}-${absInTime}] + absInTime=${tmp} + tmp=$(timetosample ${outRate} "${teilEins}") + outTimes[${i}]=$[${tmp}-${absOutTime}] + absOutTime=${tmp} + + newFile[${i}]=true + teilZwei="${teilZwei} " + while [ -n "${teilZwei}" ] + do + case "${teilZwei}" in + "overlap "*) + teilZwei="${teilZwei#* }" + overlaps[${i}]=$[$(timetosample ${inRate} ${teilZwei%% *})/2] + doverlaps[${i}]=$[2*${overlaps[${i}]}] + teilZwei="${teilZwei#* }" + ;; + "noNewFile"*) + teilZwei="${teilZwei#* }" + newFile[${i}]=false + ;; + " ") + break + ;; + *) + >&2 echo "'${teilZwei}' ist unverständlich zwischen zwei Stücken ('${line}')" + exit 1 + ;; + esac + done +done < "${points}" + +if ${ausfuehrlich} +then + echo "trackmods:" + for (( i=0; i<=${#inTimes[@]}; i++ )) + do + echo "${i}: ${trackmods[${i}]} ; ${inTimes[${i}]} ; ${overlaps[${i}]} ; ${doverlaps[${i}]} ; ${inTimecorrections[${i}]}" + done +fi + +repcmd="" +abstime=0 +for (( i=1; i<=${#inTimes[@]}; i++ )) +do + abstime=$[${abstime}+${inTimes[${i}]}] + [ -z "${doverlaps[${i}]}" ] && continue + repcmd="${repcmd} trim 0s $[${abstime}-${doverlaps[${i}]}]s : trim 0s ${doverlaps[${i}]}s repeat :" + abstime=0 +done + +trackmodcmd="" +abstime=0 +for (( i=0; i<=${#inTimes[@]}; i++ )) +do + if [ ${i} -gt 0 ] + then + [ -n "${inTimecorrections[$[${i}-1]]}" ] && \ + inTimes[${i}]=$[${inTimes[${i}]}-${inTimecorrections[$[${i}-1]]}] + [ -n "${outTimecorrections[$[${i}-1]]}" ] && \ + outTimes[${i}]=$[${outTimes[${i}]}-${outTimecorrections[$[${i}-1]]}] + fi + + [ -n "${inTimes[$[${i}+1]]}" ] && abstime=$[${abstime}+${inTimes[$[${i}+1]]}] + [ -n "${doverlaps[${i}]}" ] && abstime=$[${abstime}+${doverlaps[${i}]}] + [ "${trackmods[${i}]}" == "${trackmods[$[${i}+1]]}" ] && continue + if [ ${i} -eq ${#inTimes[@]} ] + then + trackmodcmd="${trackmodcmd}${trackmods[${i}]} " + else + trackmodcmd="${trackmodcmd}trim 0s ${abstime}s${trackmods[${i}]} : " + fi + abstime=0 +done + +splicecmd="" +abstime=0 +for (( i=0; i<=${#inTimes[@]}; i++ )) +do + [ -n "${inTimes[${i}]}" ] && abstime=$[${abstime}+${inTimes[${i}]}] + [ -z "${overlaps[${i}]}" ] && continue + splicecmd="${splicecmd} ${abstime}s,${overlaps[${i}]}s,0s" + abstime=$[${abstime}+${doverlaps[${i}]}] +done +[ -n "${splicecmd}" ] && splicecmd="splice -t${splicecmd}" + +trimcmd="" +for (( i=1; i<=${#outTimes[@]}; i++ )) +do + trimcmd="${trimcmd}trim 0s =${outTimes[${i}]}s : " + ${newFile[${i}]} && trimcmd="${trimcmd}newfile : " +done + +[ ${outRate} -ne ${inRate} ] && remixcmd="${remixcmd} rate -v ${outRate}" + +if ! ${noGain} +then + firstline="${firstline} gain -b" + remixcmd="${remixcmd} gain -n" +fi + +echo sox -M "${inputs[@]}" -p trim ${firstline} +echo sox -t sox - -p ${repcmd} +echo sox -t sox - -p ${trackmodcmd} +echo sox -t sox - -p ${splicecmd} ${remixcmd} +echo sox -t sox - ${output} ${trimcmd} + +if ! ${dummy} +then + sox -M "${inputs[@]}" -p trim ${firstline}| \ + sox -t sox - -p ${repcmd} | \ + sox -t sox - -p ${trackmodcmd} | \ + sox -t sox - -p ${splicecmd} ${remixcmd} | \ + sox -t sox - ${output} ${trimcmd} +fi -- cgit v1.2.3-54-g00ecf