diff --git a/src/Audacity.h b/src/Audacity.h index c5ea7591d..c5ff40e1e 100644 --- a/src/Audacity.h +++ b/src/Audacity.h @@ -175,7 +175,7 @@ void QuitAudacity(); #define LINEAR_TO_DB(x) (20.0 * log10(x)) #define MAX_AUDIO (1. - 1./(1<<15)) -#define JUST_BELOW_MAX_AUDIO (1. - 1./(1<<14)) +#define JUST_BELOW_MAX_AUDIO (1.f - 1.f/(1<<14)) // Marks strings for extraction only...must use wxGetTranslation() to translate. #define XO(s) wxT(s) diff --git a/src/BlockFile.cpp b/src/BlockFile.cpp index db43cfc26..01c9d9f8b 100644 --- a/src/BlockFile.cpp +++ b/src/BlockFile.cpp @@ -371,14 +371,8 @@ void BlockFile::FixSummary(void *data) /// /// @param start The offset in this block where the region should begin /// @param len The number of samples to include in the region -/// @param *outMin A pointer to where the minimum value for this region -/// should be stored -/// @param *outMax A pointer to where the maximum value for this region -/// should be stored -/// @param *outRMS A pointer to where the maximum RMS value for this -/// region should be stored. -void BlockFile::GetMinMax(size_t start, size_t len, - float *outMin, float *outMax, float *outRMS) const +auto BlockFile::GetMinMaxRMS(size_t start, size_t len, bool mayThrow) + const -> MinMaxRMS { // TODO: actually use summaries SampleBuffer blockData(len, floatSample); @@ -399,26 +393,16 @@ void BlockFile::GetMinMax(size_t start, size_t len, sumsq += (sample*sample); } - *outMin = min; - *outMax = max; - *outRMS = sqrt(sumsq/len); + return { min, max, (float)sqrt(sumsq/len) }; } /// Retrieves the minimum, maximum, and maximum RMS of this entire /// block. This is faster than the other GetMinMax function since /// these values are already computed. -/// -/// @param *outMin A pointer to where the minimum value for this block -/// should be stored -/// @param *outMax A pointer to where the maximum value for this block -/// should be stored -/// @param *outRMS A pointer to where the maximum RMS value for this -/// block should be stored. -void BlockFile::GetMinMax(float *outMin, float *outMax, float *outRMS) const +auto BlockFile::GetMinMaxRMS(bool) + const -> MinMaxRMS { - *outMin = mMin; - *outMax = mMax; - *outRMS = mRMS; + return { mMin, mMax, mRMS }; } /// Retrieves a portion of the 256-byte summary buffer from this BlockFile. This diff --git a/src/BlockFile.h b/src/BlockFile.h index 8e9813a62..56a6cf123 100644 --- a/src/BlockFile.h +++ b/src/BlockFile.h @@ -117,11 +117,13 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ { /// Returns TRUE if this BlockFile is locked virtual bool IsLocked(); + struct MinMaxRMS { float min, max, RMS; }; + /// Gets extreme values for the specified region - virtual void GetMinMax(size_t start, size_t len, - float *outMin, float *outMax, float *outRMS) const; + virtual MinMaxRMS GetMinMaxRMS(size_t start, size_t len, + bool mayThrow = true) const; /// Gets extreme values for the entire block - virtual void GetMinMax(float *outMin, float *outMax, float *outRMS) const; + virtual MinMaxRMS GetMinMaxRMS(bool mayThrow = true) const; /// Returns the 256 byte summary data block virtual bool Read256(float *buffer, size_t start, size_t len); /// Returns the 64K summary data block diff --git a/src/Sequence.cpp b/src/Sequence.cpp index 465edb0be..ce5641a38 100644 --- a/src/Sequence.cpp +++ b/src/Sequence.cpp @@ -225,13 +225,17 @@ bool Sequence::ConvertToSampleFormat(sampleFormat format, bool* pbChanged) return bSuccess; } -bool Sequence::GetMinMax(sampleCount start, sampleCount len, - float * outMin, float * outMax) const +std::pair<float, float> Sequence::GetMinMax( + sampleCount start, sampleCount len, bool mayThrow) const { if (len == 0 || mBlock.size() == 0) { - *outMin = float(0.0); // FLT_MAX? So it doesn't look like a spurious '0' to a caller? - *outMax = float(0.0); // -FLT_MAX? So it doesn't look like a spurious '0' to a caller? - return true; + return { + 0.f, + // FLT_MAX? So it doesn't look like a spurious '0' to a caller? + + 0.f + // -FLT_MAX? So it doesn't look like a spurious '0' to a caller? + }; } float min = FLT_MAX; @@ -245,13 +249,12 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len, // already in memory. for (unsigned b = block0 + 1; b < block1; ++b) { - float blockMin, blockMax, blockRMS; - mBlock[b].f->GetMinMax(&blockMin, &blockMax, &blockRMS); + auto results = mBlock[b].f->GetMinMaxRMS(mayThrow); - if (blockMin < min) - min = blockMin; - if (blockMax > max) - max = blockMax; + if (results.min < min) + min = results.min; + if (results.max > max) + max = results.max; } // Now we take the first and last blocks into account, noting that the @@ -259,12 +262,11 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len, // of either of these blocks is within min...max, then we can ignore them. // If not, we need read some samples and summaries from disk. { - float block0Min, block0Max, block0RMS; const SeqBlock &theBlock = mBlock[block0]; const auto &theFile = theBlock.f; - theFile->GetMinMax(&block0Min, &block0Max, &block0RMS); + auto results = theFile->GetMinMaxRMS(mayThrow); - if (block0Min < min || block0Max > max) { + if (results.min < min || results.max > max) { // start lies within theBlock: auto s0 = ( start - theBlock.start ).as_size_t(); const auto maxl0 = ( @@ -274,54 +276,43 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len, wxASSERT(maxl0 <= mMaxSamples); // Vaughan, 2011-10-19 const auto l0 = limitSampleBufferSize ( maxl0, len ); - float partialMin, partialMax, partialRMS; - theFile->GetMinMax(s0, l0, - &partialMin, &partialMax, &partialRMS); - if (partialMin < min) - min = partialMin; - if (partialMax > max) - max = partialMax; + results = theFile->GetMinMaxRMS(s0, l0, mayThrow); + if (results.min < min) + min = results.min; + if (results.max > max) + max = results.max; } } if (block1 > block0) { - float block1Min, block1Max, block1RMS; const SeqBlock &theBlock = mBlock[block1]; const auto &theFile = theBlock.f; - theFile->GetMinMax(&block1Min, &block1Max, &block1RMS); + auto results = theFile->GetMinMaxRMS(mayThrow); - if (block1Min < min || block1Max > max) { + if (results.min < min || results.max > max) { // start + len - 1 lies in theBlock: const auto l0 = ( start + len - theBlock.start ).as_size_t(); wxASSERT(l0 <= mMaxSamples); // Vaughan, 2011-10-19 - float partialMin, partialMax, partialRMS; - theFile->GetMinMax(0, l0, - &partialMin, &partialMax, &partialRMS); - if (partialMin < min) - min = partialMin; - if (partialMax > max) - max = partialMax; + results = theFile->GetMinMaxRMS(0, l0, mayThrow); + if (results.min < min) + min = results.min; + if (results.max > max) + max = results.max; } } - *outMin = min; - *outMax = max; - - return true; + return { min, max }; } -bool Sequence::GetRMS(sampleCount start, sampleCount len, - float * outRMS) const +float Sequence::GetRMS(sampleCount start, sampleCount len, bool mayThrow) const { // len is the number of samples that we want the rms of. // it may be longer than a block, and the code is carefully set up to handle that. - if (len == 0 || mBlock.size() == 0) { - *outRMS = float(0.0); - return true; - } + if (len == 0 || mBlock.size() == 0) + return 0.f; double sumsq = 0.0; sampleCount length = 0; // this is the cumulative length of the bits we have the ms of so far, and should end up == len @@ -333,12 +324,12 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len, // this is very fast because we have the rms of every entire block // already in memory. for (unsigned b = block0 + 1; b < block1; b++) { - float blockMin, blockMax, blockRMS; const SeqBlock &theBlock = mBlock[b]; const auto &theFile = theBlock.f; - theFile->GetMinMax(&blockMin, &blockMax, &blockRMS); + auto results = theFile->GetMinMaxRMS(mayThrow); const auto fileLen = theFile->GetLength(); + const auto blockRMS = results.RMS; sumsq += blockRMS * blockRMS * fileLen; length += fileLen; } @@ -357,9 +348,8 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len, wxASSERT(maxl0 <= mMaxSamples); // Vaughan, 2011-10-19 const auto l0 = limitSampleBufferSize( maxl0, len ); - float partialMin, partialMax, partialRMS; - theFile->GetMinMax(s0, l0, &partialMin, &partialMax, &partialRMS); - + auto results = theFile->GetMinMaxRMS(s0, l0, mayThrow); + const auto partialRMS = results.RMS; sumsq += partialRMS * partialRMS * l0; length += l0; } @@ -372,8 +362,8 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len, const auto l0 = ( start + len - theBlock.start ).as_size_t(); wxASSERT(l0 <= mMaxSamples); // PRL: I think Vaughan missed this - float partialMin, partialMax, partialRMS; - theFile->GetMinMax(0, l0, &partialMin, &partialMax, &partialRMS); + auto results = theFile->GetMinMaxRMS(0, l0, mayThrow); + const auto partialRMS = results.RMS; sumsq += partialRMS * partialRMS * l0; length += l0; } @@ -381,9 +371,7 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len, // PRL: catch bugs like 1320: wxASSERT(length == len); - *outRMS = sqrt(sumsq / length.as_double() ); - - return true; + return sqrt(sumsq / length.as_double() ); } std::unique_ptr<Sequence> Sequence::Copy(sampleCount s0, sampleCount s1) const diff --git a/src/Sequence.h b/src/Sequence.h index 278a1082b..3095e2c67 100644 --- a/src/Sequence.h +++ b/src/Sequence.h @@ -169,10 +169,9 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{ // Retrieving summary info // - bool GetMinMax(sampleCount start, sampleCount len, - float * min, float * max) const; - bool GetRMS(sampleCount start, sampleCount len, - float * outRMS) const; + std::pair<float, float> GetMinMax( + sampleCount start, sampleCount len, bool mayThrow) const; + float GetRMS(sampleCount start, sampleCount len, bool mayThrow) const; // // Getting block size and alignment information diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index ecad3e6d7..33779c360 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -36,6 +36,8 @@ #include "WaveTrack.h" #include "FFT.h" #include "Profiler.h" +#include "InconsistencyException.h" +#include "UserException.h" #include "prefs/SpectrogramSettings.h" @@ -1284,43 +1286,48 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache, return true; } -bool WaveClip::GetMinMax(float *min, float *max, - double t0, double t1) const +std::pair<float, float> WaveClip::GetMinMax( + double t0, double t1, bool mayThrow) const { - *min = float(0.0); // harmless, but unused since Sequence::GetMinMax does not use these values - *max = float(0.0); // harmless, but unused since Sequence::GetMinMax does not use these values - - if (t0 > t1) - return false; + if (t0 > t1) { + if (mayThrow) + //THROW_INCONSISTENCY_EXCEPTION + ; + return { + 0.f, // harmless, but unused since Sequence::GetMinMax does not use these values + 0.f // harmless, but unused since Sequence::GetMinMax does not use these values + }; + } if (t0 == t1) - return true; + return{ 0.f, 0.f }; sampleCount s0, s1; TimeToSamplesClip(t0, &s0); TimeToSamplesClip(t1, &s1); - return mSequence->GetMinMax(s0, s1-s0, min, max); + return mSequence->GetMinMax(s0, s1-s0, mayThrow); } -bool WaveClip::GetRMS(float *rms, double t0, - double t1) +float WaveClip::GetRMS(double t0, double t1, bool mayThrow) const { - *rms = float(0.0); - - if (t0 > t1) - return false; + if (t0 > t1) { + if (mayThrow) + //THROW_INCONSISTENCY_EXCEPTION + ; + return 0.f; + } if (t0 == t1) - return true; + return 0.f; sampleCount s0, s1; TimeToSamplesClip(t0, &s0); TimeToSamplesClip(t1, &s1); - return mSequence->GetRMS(s0, s1-s0, rms); + return mSequence->GetRMS(s0, s1-s0, mayThrow); } void WaveClip::ConvertToSampleFormat(sampleFormat format) diff --git a/src/WaveClip.h b/src/WaveClip.h index 7800dd27b..ed0727d1e 100644 --- a/src/WaveClip.h +++ b/src/WaveClip.h @@ -278,8 +278,9 @@ public: const sampleCount *& where, size_t numPixels, double t0, double pixelsPerSecond) const; - bool GetMinMax(float *min, float *max, double t0, double t1) const; - bool GetRMS(float *rms, double t0, double t1); + std::pair<float, float> GetMinMax( + double t0, double t1, bool mayThrow = true) const; + float GetRMS(double t0, double t1, bool mayThrow = true) const; // Set/clear/get rectangle that this WaveClip fills on screen. This is // called by TrackArtist while actually drawing the tracks and clips. diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index 01ae05eab..9523dbc83 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -55,6 +55,8 @@ Track classes. #include "prefs/SpectrumPrefs.h" #include "prefs/WaveformPrefs.h" +#include "InconsistencyException.h" + #include "Experimental.h" using std::max; @@ -1902,61 +1904,58 @@ double WaveTrack::GetEndTime() const // expressed relative to t=0.0 at the track's sample rate. // -bool WaveTrack::GetMinMax(float *min, float *max, - double t0, double t1) const +std::pair<float, float> WaveTrack::GetMinMax( + double t0, double t1, bool mayThrow) const { + std::pair<float, float> results { + // we need these at extremes to make sure we find true min and max + FLT_MAX, -FLT_MAX + }; bool clipFound = false; - *min = FLT_MAX; // we need these at extremes to make sure we find true min and max - *max = -FLT_MAX; - - if (t0 > t1) - return false; + if (t0 > t1) { + if (mayThrow) + //THROW_INCONSISTENCY_EXCEPTION + ; + return results; + } if (t0 == t1) - return true; - - bool result = true; + return results; for (const auto &clip: mClips) { if (t1 >= clip->GetStartTime() && t0 <= clip->GetEndTime()) { clipFound = true; - float clipmin, clipmax; - if (clip->GetMinMax(&clipmin, &clipmax, t0, t1)) - { - if (clipmin < *min) - *min = clipmin; - if (clipmax > *max) - *max = clipmax; - } else - { - result = false; - } + auto clipResults = clip->GetMinMax(t0, t1, mayThrow); + if (clipResults.first < results.first) + results.first = clipResults.first; + if (clipResults.second > results.second) + results.second = clipResults.second; } } if(!clipFound) { - *min = float(0.0); // sensible defaults if no clips found - *max = float(0.0); + results = { 0.f, 0.f }; // sensible defaults if no clips found } - return result; + return results; } -bool WaveTrack::GetRMS(float *rms, double t0, double t1) const +float WaveTrack::GetRMS(double t0, double t1, bool mayThrow) const { - *rms = float(0.0); - - if (t0 > t1) - return false; + if (t0 > t1) { + if (mayThrow) + //THROW_INCONSISTENCY_EXCEPTION + ; + return 0.f; + } if (t0 == t1) - return true; + return 0.f; - bool result = true; double sumsq = 0.0; sampleCount length = 0; @@ -1967,25 +1966,17 @@ bool WaveTrack::GetRMS(float *rms, double t0, double t1) const // if (t1 >= clip->GetStartTime() && t0 <= clip->GetEndTime()) if (t1 >= clip->GetStartTime() && t0 <= clip->GetEndTime()) { - float cliprms; sampleCount clipStart, clipEnd; - if (clip->GetRMS(&cliprms, t0, t1)) - { - clip->TimeToSamplesClip(wxMax(t0, clip->GetStartTime()), &clipStart); - clip->TimeToSamplesClip(wxMin(t1, clip->GetEndTime()), &clipEnd); - sumsq += cliprms * cliprms * (clipEnd - clipStart).as_float(); - length += (clipEnd - clipStart); - } - else - { - result = false; - } + float cliprms = clip->GetRMS(t0, t1, mayThrow); + + clip->TimeToSamplesClip(wxMax(t0, clip->GetStartTime()), &clipStart); + clip->TimeToSamplesClip(wxMin(t1, clip->GetEndTime()), &clipEnd); + sumsq += cliprms * cliprms * (clipEnd - clipStart).as_float(); + length += (clipEnd - clipStart); } } - *rms = length > 0 ? sqrt(sumsq / length.as_double()) : 0.0; - - return result; + return length > 0 ? sqrt(sumsq / length.as_double()) : 0.0; } bool WaveTrack::Get(samplePtr buffer, sampleFormat format, diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 15daad1b1..68c2d3607 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -257,9 +257,9 @@ class AUDACITY_DLL_API WaveTrack final : public Track { sampleCount start, size_t len); void GetEnvelopeValues(double *buffer, size_t bufferLen, double t0) const; - bool GetMinMax(float *min, float *max, - double t0, double t1) const; - bool GetRMS(float *rms, double t0, double t1) const; + std::pair<float, float> GetMinMax( + double t0, double t1, bool mayThrow = true) const; + float GetRMS(double t0, double t1, bool mayThrow = true) const; // // MM: We now have more than one sequence and envelope per track, so diff --git a/src/blockfile/ODDecodeBlockFile.cpp b/src/blockfile/ODDecodeBlockFile.cpp index e5c0f3681..c6dff23dd 100644 --- a/src/blockfile/ODDecodeBlockFile.cpp +++ b/src/blockfile/ODDecodeBlockFile.cpp @@ -29,6 +29,7 @@ The summary is eventually computed and written to a file in a background thread. #include "../FileFormats.h" #include "../Internat.h" +#include "NotYetAvailableException.h" const int bheaderTagLen = 20; char bheaderTag[bheaderTagLen + 1] = "AudacityBlockFile112"; @@ -91,37 +92,45 @@ auto ODDecodeBlockFile::GetSpaceUsage() const -> DiskByteCount /// Gets extreme values for the specified region -void ODDecodeBlockFile::GetMinMax(size_t start, size_t len, - float *outMin, float *outMax, float *outRMS) const +auto ODDecodeBlockFile::GetMinMaxRMS( + size_t start, size_t len, bool mayThrow) const -> MinMaxRMS { if(IsSummaryAvailable()) { - SimpleBlockFile::GetMinMax(start,len,outMin,outMax,outRMS); + return SimpleBlockFile::GetMinMaxRMS(start, len, mayThrow); } else { + if (mayThrow) + // throw NotYetAvailableException{ mAudioFileName } + ; + //fake values. These values are used usually for normalization and amplifying, so we want //the max to be maximal and the min to be minimal - *outMin = -1.0; - *outMax = 1.0; - *outRMS = (float)0.707;//sin with amp of 1 rms + return { + -1.0f, 1.0f, 0.707f //sin with amp of 1 rms + }; } } /// Gets extreme values for the entire block -void ODDecodeBlockFile::GetMinMax(float *outMin, float *outMax, float *outRMS) const +auto ODDecodeBlockFile::GetMinMaxRMS(bool mayThrow) const -> MinMaxRMS { if(IsSummaryAvailable()) { - SimpleBlockFile::GetMinMax(outMin,outMax,outRMS); + return SimpleBlockFile::GetMinMaxRMS(mayThrow); } else { + if (mayThrow) + // throw NotYetAvailableException{ mAudioFileName } + ; + //fake values. These values are used usually for normalization and amplifying, so we want //the max to be maximal and the min to be minimal - *outMin = -1.0; - *outMax = 1.0; - *outRMS = (float)0.707;//sin with amp of 1 rms + return { + -1.0f, 1.0f, 0.707f //sin with amp of 1 rms + }; } } diff --git a/src/blockfile/ODDecodeBlockFile.h b/src/blockfile/ODDecodeBlockFile.h index 3a743ffd9..0a98df679 100644 --- a/src/blockfile/ODDecodeBlockFile.h +++ b/src/blockfile/ODDecodeBlockFile.h @@ -63,10 +63,10 @@ class ODDecodeBlockFile final : public SimpleBlockFile //Calls that rely on summary files need to be overidden DiskByteCount GetSpaceUsage() const override; /// Gets extreme values for the specified region - void GetMinMax(size_t start, size_t len, - float *outMin, float *outMax, float *outRMS) const override; + MinMaxRMS GetMinMaxRMS( + size_t start, size_t len, bool mayThrow) const override; /// Gets extreme values for the entire block - void GetMinMax(float *outMin, float *outMax, float *outRMS) const override; + MinMaxRMS GetMinMaxRMS(bool mayThrow) const override; /// Returns the 256 byte summary data block bool Read256(float *buffer, size_t start, size_t len) override; /// Returns the 64K summary data block diff --git a/src/blockfile/ODPCMAliasBlockFile.cpp b/src/blockfile/ODPCMAliasBlockFile.cpp index 678d74f88..4f14be7f6 100644 --- a/src/blockfile/ODPCMAliasBlockFile.cpp +++ b/src/blockfile/ODPCMAliasBlockFile.cpp @@ -36,6 +36,8 @@ The summary is eventually computed and written to a file in a background thread. #include "../ondemand/ODManager.h" #include "../AudioIO.h" +#include "NotYetAvailableException.h" + //#include <errno.h> extern AudioIO *gAudioIO; @@ -121,37 +123,49 @@ void ODPCMAliasBlockFile::Unlock() /// Gets extreme values for the specified region -void ODPCMAliasBlockFile::GetMinMax(size_t start, size_t len, - float *outMin, float *outMax, float *outRMS) const +auto ODPCMAliasBlockFile::GetMinMaxRMS( + size_t start, size_t len, bool mayThrow) const -> MinMaxRMS { if(IsSummaryAvailable()) { - PCMAliasBlockFile::GetMinMax(start,len,outMin,outMax,outRMS); + return PCMAliasBlockFile::GetMinMaxRMS(start, len, mayThrow); } else { + if (mayThrow) + //throw NotYetAvailableException{ GetAliasedFileName() } + ; + //fake values. These values are used usually for normalization and amplifying, so we want //the max to be maximal and the min to be minimal - *outMin = -1.0*JUST_BELOW_MAX_AUDIO; - *outMax = 1.0*JUST_BELOW_MAX_AUDIO; - *outRMS = (float)0.707;//sin with amp of 1 rms + return { + -JUST_BELOW_MAX_AUDIO, + JUST_BELOW_MAX_AUDIO, + 0.707f //sin with amp of 1 rms + }; } } /// Gets extreme values for the entire block -void ODPCMAliasBlockFile::GetMinMax(float *outMin, float *outMax, float *outRMS) const +auto ODPCMAliasBlockFile::GetMinMaxRMS(bool mayThrow) const -> MinMaxRMS { if(IsSummaryAvailable()) { - PCMAliasBlockFile::GetMinMax(outMin,outMax,outRMS); + return PCMAliasBlockFile::GetMinMaxRMS(mayThrow); } else { + if (mayThrow) + //throw NotYetAvailableException{ GetAliasedFileName() } + ; + //fake values. These values are used usually for normalization and amplifying, so we want //the max to be maximal and the min to be minimal - *outMin = -1.0*JUST_BELOW_MAX_AUDIO; - *outMax = 1.0*JUST_BELOW_MAX_AUDIO; - *outRMS = (float)0.707;//sin with amp of 1 rms + return { + -JUST_BELOW_MAX_AUDIO, + JUST_BELOW_MAX_AUDIO, + 0.707f //sin with amp of 1 rms + }; } } diff --git a/src/blockfile/ODPCMAliasBlockFile.h b/src/blockfile/ODPCMAliasBlockFile.h index 1653b1e65..421eadad3 100644 --- a/src/blockfile/ODPCMAliasBlockFile.h +++ b/src/blockfile/ODPCMAliasBlockFile.h @@ -65,10 +65,10 @@ class ODPCMAliasBlockFile final : public PCMAliasBlockFile //Calls that rely on summary files need to be overidden DiskByteCount GetSpaceUsage() const override; /// Gets extreme values for the specified region - void GetMinMax(size_t start, size_t len, - float *outMin, float *outMax, float *outRMS) const override; + MinMaxRMS GetMinMaxRMS( + size_t start, size_t len, bool mayThrow) const override; /// Gets extreme values for the entire block - void GetMinMax(float *outMin, float *outMax, float *outRMS) const override; + MinMaxRMS GetMinMaxRMS(bool mayThrow) const override; /// Returns the 256 byte summary data block bool Read256(float *buffer, size_t start, size_t len) override; /// Returns the 64K summary data block diff --git a/src/effects/Amplify.cpp b/src/effects/Amplify.cpp index 82437e11f..995b29c2a 100644 --- a/src/effects/Amplify.cpp +++ b/src/effects/Amplify.cpp @@ -164,8 +164,8 @@ bool EffectAmplify::Init() for (Track *t = iter.First(); t; t = iter.Next()) { - float min, max; - ((WaveTrack *)t)->GetMinMax(&min, &max, mT0, mT1); + auto pair = ((WaveTrack *)t)->GetMinMax(mT0, mT1); // may throw + const float min = pair.first, max = pair.second; float newpeak = (fabs(min) > fabs(max) ? fabs(min) : fabs(max)); if (newpeak > mPeak) diff --git a/src/effects/Contrast.cpp b/src/effects/Contrast.cpp index c5cc25bfd..55ffd0bb9 100644 --- a/src/effects/Contrast.cpp +++ b/src/effects/Contrast.cpp @@ -84,7 +84,8 @@ bool ContrastDialog::GetDB(float &dB) return false; } - ((WaveTrack *)t)->GetRMS(&rms, mT0, mT1); + // Don't throw in this analysis dialog + rms = ((WaveTrack *)t)->GetRMS(mT0, mT1, false); meanSq += rms * rms; t = (WaveTrack *) iter.Next(); } diff --git a/src/effects/Normalize.cpp b/src/effects/Normalize.cpp index db3626144..838f6d4dd 100644 --- a/src/effects/Normalize.cpp +++ b/src/effects/Normalize.cpp @@ -344,7 +344,10 @@ bool EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg, wxMilliSleep(100); } - track->GetMinMax(&min, &max, mCurT0, mCurT1); + // set mMin, mMax. No progress bar here as it's fast. + auto pair = track->GetMinMax(mCurT0, mCurT1); // may throw + min = pair.first, max = pair.second; + } else { min = -1.0, max = 1.0; // sensible defaults? } diff --git a/src/effects/nyquist/Nyquist.cpp b/src/effects/nyquist/Nyquist.cpp index 6d4736bb8..ff3607504 100644 --- a/src/effects/nyquist/Nyquist.cpp +++ b/src/effects/nyquist/Nyquist.cpp @@ -968,7 +968,8 @@ bool NyquistEffect::ProcessOne() if (mCurNumChannels > 1) clips += wxT(" )"); float min, max; - mCurTrack[i]->GetMinMax(&min, &max, mT0, mT1); + auto pair = mCurTrack[i]->GetMinMax(mT0, mT1); // may throw + min = pair.first, max = pair.second; maxPeak = wxMax(wxMax(fabs(min), fabs(max)), maxPeak); maxPeakLevel = wxMax(maxPeakLevel, maxPeak); @@ -980,8 +981,7 @@ bool NyquistEffect::ProcessOne() peakString += wxT("nil"); } - float rms = 0.0; - mCurTrack[i]->GetRMS(&rms, mT0, mT1); + float rms = mCurTrack[i]->GetRMS(mT0, mT1); // may throw if (!std::isinf(rms) && !std::isnan(rms)) { rmsString += wxString::Format(wxT("(float %s) "), Internat::ToString(rms).c_str()); } else {