summaryrefslogtreecommitdiff
path: root/rhimport
diff options
context:
space:
mode:
Diffstat (limited to 'rhimport')
-rw-r--r--rhimport/normalizer.go74
1 files changed, 71 insertions, 3 deletions
diff --git a/rhimport/normalizer.go b/rhimport/normalizer.go
index 15f71ed..d99984c 100644
--- a/rhimport/normalizer.go
+++ b/rhimport/normalizer.go
@@ -25,12 +25,72 @@
package rhimport
import (
+ "fmt"
+ "io"
"os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "strings"
)
+type ffmpegResult struct {
+ output string
+ err error
+}
+
+func runNormalizer(ctx *Context, src *os.File, size int64) (err error) {
+ if ctx.DeleteSourceFile {
+ defer os.Remove(src.Name())
+ }
+
+ basepath, filename := filepath.Split(src.Name())
+ ext := filepath.Ext(filename)
+ destName := strings.TrimSuffix(filename, ext) + "_normalized.flac"
+ rhl.Printf("NormalizeFile: '%s' -> '%s', using gain = %.2f dB", filename, destName, ctx.LoudnessCorr)
+
+ ctx.SourceFile = basepath + destName
+
+ ffmpeg := exec.Command("ffmpeg", "-loglevel", "warning", "-i", "-", "-filter:a", fmt.Sprintf("volume=%fdB", ctx.LoudnessCorr), "-map_metadata", "0", "-f", "flac", ctx.SourceFile)
+ var ffstdin io.WriteCloser
+ if ffstdin, err = ffmpeg.StdinPipe(); err != nil {
+ return
+ }
+
+ ffresult := make(chan ffmpegResult)
+ go func() {
+ output, err := ffmpeg.CombinedOutput()
+ ffresult <- ffmpegResult{strings.TrimSpace(string(output)), err}
+ }()
+
+ var written int64
+ for {
+ var w int64
+ w, err = io.CopyN(ffstdin, src, 512*1024)
+ if err != nil {
+ break
+ }
+ written += w
+ if ctx.ProgressCallBack != nil {
+ if keep := ctx.ProgressCallBack(2, "normalizing", float64(written), float64(size), ctx.ProgressCallBackData); !keep {
+ ctx.ProgressCallBack = nil
+ }
+ }
+ }
+ ffstdin.Close()
+ res := <-ffresult
+ if res.err != nil {
+ return fmt.Errorf("normalizer exited with error: %q, ffmpeg output: %s", res.err, res.output)
+ }
+ if err != nil && err != io.EOF {
+ return
+ }
+ return nil
+}
+
func NormalizeFile(ctx *Context) (err error) {
if ctx.LoudnessCorr == 0.0 {
- rhdl.Println("NormalizeFile: skipping normalization since the gain = 0.0dB")
+ rhl.Println("NormalizeFile: skipping normalization since the gain = 0.0dB")
if ctx.ProgressCallBack != nil {
if keep := ctx.ProgressCallBack(2, "normalizing", 1.0, 1.0, ctx.ProgressCallBackData); !keep {
ctx.ProgressCallBack = nil
@@ -39,7 +99,6 @@ func NormalizeFile(ctx *Context) (err error) {
return
}
- rhl.Printf("NormalizeFile: using gain = %.2f dB", ctx.LoudnessCorr)
ctx.NormalizationLevel = 0 // don't do double normalization
var src *os.File
@@ -61,7 +120,16 @@ func NormalizeFile(ctx *Context) (err error) {
}
}
- // TODO: call ffmpeg
+ if err = runNormalizer(ctx, src, size); err != nil {
+ rhl.Println("NormalizeFile error:", err)
+ if ctx.DeleteSourceFile {
+ os.Remove(ctx.SourceFile)
+ if ctx.DeleteSourceDir {
+ os.Remove(path.Dir(ctx.SourceFile))
+ }
+ }
+ return
+ }
if ctx.ProgressCallBack != nil {
if keep := ctx.ProgressCallBack(2, "normalizing", float64(size), float64(size), ctx.ProgressCallBackData); !keep {