Normalize audio when archiving to fixed-point format.

This commit is contained in:
Robin Gareus 2016-12-27 18:33:41 +01:00
parent 54a79639df
commit fe01666475
2 changed files with 34 additions and 2 deletions

View File

@ -5075,6 +5075,7 @@ Session::archive_session (const std::string& dest,
blacklist_dirs.push_back (string (plugins_dir_name) + G_DIR_SEPARATOR);
std::map<boost::shared_ptr<AudioFileSource>, std::string> orig_sources;
std::map<boost::shared_ptr<AudioFileSource>, float> orig_gain;
set<boost::shared_ptr<Source> > sources_used_by_this_snapshot;
if (only_used_sources) {
@ -5141,6 +5142,7 @@ Session::archive_session (const std::string& dest,
}
orig_sources[afs] = afs->path();
orig_gain[afs] = afs->gain();
std::string new_path = make_new_media_path (afs->path (), to_dir, name);
new_path = Glib::build_filename (Glib::path_get_dirname (new_path), PBD::basename_nosuffix (new_path) + ".flac");
@ -5153,6 +5155,7 @@ Session::archive_session (const std::string& dest,
try {
SndFileSource* ns = new SndFileSource (*this, *(afs.get()), new_path, compress_audio == FLAC_16BIT, progress);
afs->replace_file (new_path);
afs->set_gain (ns->gain(), true);
delete ns;
} catch (...) {
cerr << "failed to encode " << afs->path() << " to " << new_path << "\n";
@ -5279,6 +5282,9 @@ Session::archive_session (const std::string& dest,
for (std::map<boost::shared_ptr<AudioFileSource>, std::string>::iterator i = orig_sources.begin (); i != orig_sources.end (); ++i) {
i->first->replace_file (i->second);
}
for (std::map<boost::shared_ptr<AudioFileSource>, float>::iterator i = orig_gain.begin (); i != orig_gain.end (); ++i) {
i->first->set_gain (i->second, true);
}
int rv = ar.create (filemap);
remove_directory (to_dir);

View File

@ -36,6 +36,7 @@
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
#include "ardour/runtime_functions.h"
#include "ardour/sndfilesource.h"
#include "ardour/sndfile_helpers.h"
#include "ardour/utils.h"
@ -275,16 +276,41 @@ SndFileSource::SndFileSource (Session& s, const AudioFileSource& other, const st
throw failed_constructor();
}
/* copy file */
Sample buf[8192];
framecnt_t off = 0;
float peak = 0;
float norm = 1.f;
/* normalize before converting to fixed point, calc gain factor */
framecnt_t len = other.read (buf, off, 8192, /*channel*/0);
while (len > 0) {
peak = compute_peak (buf, len, peak);
off += len;
len = other.read (buf, off, 8192, /*channel*/0);
if (progress) {
progress->set_progress (0.5f * (float) off / other.readable_length ());
}
}
if (peak > 0) {
_gain *= peak;
norm = 1.f / peak;
}
/* copy file */
off = 0;
len = other.read (buf, off, 8192, /*channel*/0);
while (len > 0) {
if (norm != 1.f) {
for (framecnt_t i = 0; i < len; ++i) {
buf[i] *= norm;
}
}
write (buf, len);
off += len;
len = other.read (buf, off, 8192, /*channel*/0);
if (progress) {
progress->set_progress ((float) off / other.readable_length ());
progress->set_progress (0.5f + 0.5f * (float) off / other.readable_length ());
}
}
}