1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-17 16:40:07 +02:00

GetMinMax, GetRMS functions take a mayThrow argument, return numbers

This commit is contained in:
Paul Licameli 2016-12-25 08:40:15 -05:00
parent dcac8788ff
commit 70d9e4bdc7
17 changed files with 183 additions and 184 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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,

View File

@ -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

View File

@ -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
};
}
}

View File

@ -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

View File

@ -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
};
}
}

View File

@ -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

View File

@ -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)

View File

@ -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();
}

View File

@ -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?
}

View File

@ -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 {