# HG changeset patch # User Chris Cannam # Date 1536333201 -3600 # Node ID 75d92155fa204a4ed6752a7db5ea58b6807a689d # Parent c9c2aa17439ae75413e6f0e54b43520414a68f90 Add normalisation option diff -r c9c2aa17439a -r 75d92155fa20 data/fileio/WavFileReader.cpp --- a/data/fileio/WavFileReader.cpp Thu Sep 06 16:26:19 2018 +0100 +++ b/data/fileio/WavFileReader.cpp Fri Sep 07 16:13:21 2018 +0100 @@ -25,13 +25,17 @@ using namespace std; -WavFileReader::WavFileReader(FileSource source, bool fileUpdating) : +WavFileReader::WavFileReader(FileSource source, + bool fileUpdating, + bool normalise) : m_file(0), m_source(source), m_path(source.getLocalFilename()), m_seekable(false), m_lastStart(0), m_lastCount(0), + m_normalise(normalise), + m_max(0.f), m_updating(fileUpdating) { m_frameCount = 0; @@ -87,9 +91,13 @@ // and mark those (basically only non-adaptive WAVs). m_seekable = true; } + + if (m_normalise && !m_updating) { + m_max = getMax(); + } } - SVDEBUG << "WavFileReader: Filename " << m_path << ", frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", format " << m_fileInfo.format << ", seekable " << m_fileInfo.seekable << " adjusted to " << m_seekable << endl; + SVDEBUG << "WavFileReader: Filename " << m_path << ", frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", format " << m_fileInfo.format << ", seekable " << m_fileInfo.seekable << " adjusted to " << m_seekable << ", normalise " << m_normalise << endl; } WavFileReader::~WavFileReader() @@ -136,11 +144,31 @@ { updateFrameCount(); m_updating = false; + if (m_normalise) { + m_max = getMax(); + } } floatvec_t WavFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count) const { + floatvec_t frames = getInterleavedFramesUnnormalised(start, count); + + if (!m_normalise || m_max == 0.f) { + return frames; + } + + for (int i = 0; in_range_for(frames, i); ++i) { + frames[i] /= m_max; + } + + return frames; +} + +floatvec_t +WavFileReader::getInterleavedFramesUnnormalised(sv_frame_t start, + sv_frame_t count) const +{ static HitCount lastRead("WavFileReader: last read"); if (count == 0) return {}; @@ -200,6 +228,43 @@ return data; } +float +WavFileReader::getMax() const +{ + if (!m_file || !m_channelCount) { + return 0.f; + } + + // First try for a PEAK chunk + + double sfpeak = 0.0; + if (sf_command(m_file, SFC_GET_SIGNAL_MAX, &sfpeak, sizeof(sfpeak)) + == SF_TRUE) { + SVDEBUG << "File has a PEAK chunk reporting max level " << sfpeak + << endl; + return float(fabs(sfpeak)); + } + + // Failing that, read all the samples + + float peak = 0.f; + sv_frame_t ix = 0, chunk = 65536; + + while (ix < m_frameCount) { + auto frames = getInterleavedFrames(ix, chunk); + for (float x: frames) { + float level = fabsf(x); + if (level > peak) { + peak = level; + } + } + ix += chunk; + } + + SVDEBUG << "Measured file peak max level as " << peak << endl; + return peak; +} + void WavFileReader::getSupportedExtensions(set &extensions) { diff -r c9c2aa17439a -r 75d92155fa20 data/fileio/WavFileReader.h --- a/data/fileio/WavFileReader.h Thu Sep 06 16:26:19 2018 +0100 +++ b/data/fileio/WavFileReader.h Fri Sep 07 16:13:21 2018 +0100 @@ -41,7 +41,9 @@ class WavFileReader : public AudioFileReader { public: - WavFileReader(FileSource source, bool fileUpdating = false); + WavFileReader(FileSource source, + bool fileUpdating = false, + bool normalise = false); virtual ~WavFileReader(); virtual QString getLocation() const { return m_source.getLocation(); } @@ -55,7 +57,8 @@ * Must be safe to call from multiple threads with different * arguments on the same object at the same time. */ - virtual floatvec_t getInterleavedFrames(sv_frame_t start, sv_frame_t count) const; + virtual floatvec_t getInterleavedFrames(sv_frame_t start, sv_frame_t count) + const; static void getSupportedExtensions(std::set &extensions); static bool supportsExtension(QString ext); @@ -84,7 +87,14 @@ mutable sv_frame_t m_lastStart; mutable sv_frame_t m_lastCount; + bool m_normalise; + float m_max; + bool m_updating; + + floatvec_t getInterleavedFramesUnnormalised(sv_frame_t start, + sv_frame_t count) const; + float getMax() const; }; #endif