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:
parent
dcac8788ff
commit
70d9e4bdc7
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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?
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user