Fix some assert error in EQ curves
Selected EQ curves in Draw mode should now retain their name when they are selected.
This commit is contained in:
parent
a856d1e3b0
commit
7d5e54e364
|
@ -517,6 +517,14 @@ bool EffectEqualization::Init()
|
|||
}
|
||||
|
||||
mHiFreq = rate / 2.0;
|
||||
// Unlikely, but better than crashing.
|
||||
if (mHiFreq <= loFreqI) {
|
||||
wxMessageBox( _("Track sample rate is too low for this effect."),
|
||||
_("Effect Unavailable"),
|
||||
wxOK | wxCENTRE);
|
||||
return(false);
|
||||
}
|
||||
|
||||
mLoFreq = loFreqI;
|
||||
|
||||
mBandsInUse = 0;
|
||||
|
@ -1654,84 +1662,146 @@ void EffectEqualization::SaveCurves(const wxString &fileName)
|
|||
void EffectEqualization::setCurve(int currentCurve)
|
||||
{
|
||||
// Set current choice
|
||||
Select( currentCurve );
|
||||
|
||||
Select(currentCurve);
|
||||
wxASSERT( currentCurve < (int) mCurves.GetCount() );
|
||||
bool changed = false;
|
||||
|
||||
if( mLin ) // linear freq mode?
|
||||
{
|
||||
Envelope *env = mLinEnvelope;
|
||||
env->Flatten(0.);
|
||||
env->SetTrackLen(1.0);
|
||||
Envelope *env;
|
||||
int numPoints = (int) mCurves[currentCurve].points.GetCount();
|
||||
|
||||
if( mCurves[currentCurve].points.GetCount() )
|
||||
{
|
||||
double when, value;
|
||||
int i;
|
||||
int nCurvePoints = mCurves[currentCurve].points.GetCount();
|
||||
for(i=0;i<nCurvePoints;i++)
|
||||
{
|
||||
when = mCurves[currentCurve].points[i].Freq / mHiFreq;
|
||||
value = mCurves[currentCurve].points[i].dB;
|
||||
if(when <= 1)
|
||||
env->Insert(when, value);
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ( i != nCurvePoints) // there are more points at higher freqs
|
||||
{
|
||||
when = 1.; // set the RH end to the next highest point
|
||||
value = mCurves[currentCurve].points[nCurvePoints-1].dB;
|
||||
env->Insert(when, value);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (mLin) { // linear freq mode
|
||||
env = mLinEnvelope;
|
||||
}
|
||||
else
|
||||
{
|
||||
Envelope *env = mLogEnvelope;
|
||||
env->Flatten(0.);
|
||||
env->SetTrackLen(1.0);
|
||||
else { // log freq mode
|
||||
env = mLogEnvelope;
|
||||
}
|
||||
env->Flatten(0.);
|
||||
env->SetTrackLen(1.0);
|
||||
|
||||
if( mCurves[currentCurve].points.GetCount() )
|
||||
{
|
||||
double when, value;
|
||||
double loLog = log10(20.);
|
||||
// Handle special case of no points.
|
||||
if (numPoints == 0) {
|
||||
ForceRecalc();
|
||||
return;
|
||||
}
|
||||
|
||||
double when, value;
|
||||
|
||||
// Handle special case 1 point.
|
||||
if (numPoints == 1) {
|
||||
// only one point, so ensure it is in range then return.
|
||||
when = mCurves[currentCurve].points[0].Freq;
|
||||
if (mLin) {
|
||||
when = when / mHiFreq;
|
||||
}
|
||||
else { // log scale
|
||||
// We don't go below loFreqI (20 Hz) in log view.
|
||||
double loLog = log10((double)loFreqI);
|
||||
double hiLog = log10(mHiFreq);
|
||||
double denom = hiLog - loLog;
|
||||
int i;
|
||||
int nCurvePoints = mCurves[currentCurve].points.GetCount();
|
||||
when = (log10(std::max((double) loFreqI, when)) - loLog)/denom;
|
||||
}
|
||||
value = mCurves[currentCurve].points[0].dB;
|
||||
env->Insert(std::min(1.0, std::max(0.0, when)), value);
|
||||
ForceRecalc();
|
||||
return;
|
||||
}
|
||||
|
||||
for(i=0;i<nCurvePoints;i++)
|
||||
{
|
||||
double flog = log10(mCurves[currentCurve].points[i].Freq);
|
||||
if( flog >= loLog )
|
||||
{
|
||||
when = (flog - loLog)/denom;
|
||||
value = mCurves[currentCurve].points[i].dB;
|
||||
if(when <= 1.)
|
||||
env->Insert(when, value);
|
||||
else
|
||||
{ // we have a point beyond fs/2. Insert it so that env code can use it.
|
||||
// but just this one, we have no use for the rest
|
||||
env->SetTrackLen(when); // can't Insert if the envelope isn't long enough
|
||||
env->Insert(when, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //get the first point as close as we can to the last point requested
|
||||
changed = true;
|
||||
//double f = mCurves[currentCurve].points[i].Freq;
|
||||
//double v = mCurves[currentCurve].points[i].dB;
|
||||
mLogEnvelope->Insert(0., mCurves[currentCurve].points[i].dB);
|
||||
}
|
||||
// We have at least two points, so ensure they are in frequency order.
|
||||
mCurves[currentCurve].points.Sort(SortCurvePoints);
|
||||
|
||||
if (mCurves[currentCurve].points[0].Freq < 0) {
|
||||
// Corrupt or invalid curve, so bail.
|
||||
ForceRecalc();
|
||||
return;
|
||||
}
|
||||
|
||||
if(mLin) { // linear Hz scale
|
||||
for(int pointCount = 0; pointCount < numPoints; pointCount++) {
|
||||
when = mCurves[currentCurve].points[pointCount].Freq / mHiFreq;
|
||||
value = mCurves[currentCurve].points[pointCount].dB;
|
||||
if(when <= 1) {
|
||||
env->Insert(when, value);
|
||||
}
|
||||
else {
|
||||
// There are more points at higher freqs, so interpolate next one then stop.
|
||||
when = 1.0;
|
||||
double lastF = mCurves[currentCurve].points[pointCount-1].Freq;
|
||||
double nextF = mCurves[currentCurve].points[pointCount].Freq;
|
||||
double lastDB = mCurves[currentCurve].points[pointCount-1].dB;
|
||||
double nextDB = mCurves[currentCurve].points[pointCount].dB;
|
||||
value = lastDB + ((nextDB - lastDB) * ((mHiFreq - lastF) / (nextF - lastF)));
|
||||
env->Insert(when, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // log Hz scale
|
||||
double loLog = log10((double) loFreqI);
|
||||
double hiLog = log10(mHiFreq);
|
||||
double denom = hiLog - loLog;
|
||||
int firstAbove20Hz;
|
||||
|
||||
// log scale EQ starts at 20 Hz (threshold of hearing).
|
||||
// so find the first point (if any) above 20 Hz.
|
||||
for (firstAbove20Hz = 0; firstAbove20Hz < numPoints; firstAbove20Hz++) {
|
||||
if (mCurves[currentCurve].points[firstAbove20Hz].Freq > loFreqI)
|
||||
break;
|
||||
}
|
||||
|
||||
if (firstAbove20Hz == numPoints) {
|
||||
// All points below 20 Hz, so just use final point.
|
||||
when = 0.0;
|
||||
value = mCurves[currentCurve].points[numPoints-1].dB;
|
||||
env->Insert(when, value);
|
||||
ForceRecalc();
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstAbove20Hz > 0) {
|
||||
// At least one point is before 20 Hz and there are more
|
||||
// beyond 20 Hz, so interpolate the first
|
||||
double prevF = mCurves[currentCurve].points[firstAbove20Hz-1].Freq;
|
||||
prevF = log10(std::max(1.0, prevF)); // log zero is bad.
|
||||
double prevDB = mCurves[currentCurve].points[firstAbove20Hz-1].dB;
|
||||
double nextF = log10(mCurves[currentCurve].points[firstAbove20Hz].Freq);
|
||||
double nextDB = mCurves[currentCurve].points[firstAbove20Hz].dB;
|
||||
when = 0.0;
|
||||
value = nextDB - ((nextDB - prevDB) * ((nextF - loLog) / (nextF - prevF)));
|
||||
env->Insert(when, value);
|
||||
}
|
||||
|
||||
// Now get the rest.
|
||||
for(int pointCount = firstAbove20Hz; pointCount < numPoints; pointCount++)
|
||||
{
|
||||
double flog = log10(mCurves[currentCurve].points[pointCount].Freq);
|
||||
wxASSERT(mCurves[currentCurve].points[pointCount].Freq >= loFreqI);
|
||||
|
||||
when = (flog - loLog)/denom;
|
||||
value = mCurves[currentCurve].points[pointCount].dB;
|
||||
if(when <= 1.0) {
|
||||
env->Insert(when, value);
|
||||
}
|
||||
else {
|
||||
// This looks weird when adjusting curve in Draw mode if
|
||||
// there is a point off-screen.
|
||||
|
||||
/*
|
||||
// we have a point beyond fs/2. Insert it so that env code can use it.
|
||||
// but just this one, we have no use for the rest
|
||||
env->SetTrackLen(when); // can't Insert if the envelope isn't long enough
|
||||
env->Insert(when, value);
|
||||
break;
|
||||
*/
|
||||
|
||||
// interpolate the final point instead
|
||||
when = 1.0;
|
||||
double logLastF = log10(mCurves[currentCurve].points[pointCount-1].Freq);
|
||||
double lastDB = mCurves[currentCurve].points[pointCount-1].dB;
|
||||
value = lastDB + ((value - lastDB) * ((log10(mHiFreq) - logLastF) / (flog - logLastF)));
|
||||
env->Insert(when, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(changed) // not all points were loaded so switch to unnamed
|
||||
EnvelopeUpdated();
|
||||
ForceRecalc();
|
||||
}
|
||||
|
||||
|
@ -2272,7 +2342,10 @@ void EffectEqualization::EnvLinToLog(void)
|
|||
{
|
||||
if( when[i]*mHiFreq >= 20 )
|
||||
{
|
||||
mLogEnvelope->Insert((log10(when[i]*mHiFreq)-loLog)/denom , value[i]);
|
||||
// Caution: on Linux, when when == 20, the log calulation rounds
|
||||
// to just under zero, which causes an assert error.
|
||||
double flog = (log10(when[i]*mHiFreq)-loLog)/denom;
|
||||
mLogEnvelope->Insert(std::max(0.0, flog) , value[i]);
|
||||
}
|
||||
else
|
||||
{ //get the first point as close as we can to the last point requested
|
||||
|
|
|
@ -266,6 +266,11 @@ private:
|
|||
return (*first)->Name.CmpNoCase((*second)->Name);
|
||||
}
|
||||
|
||||
static int wxCMPFUNC_CONV SortCurvePoints (EQPoint **p0, EQPoint **p1)
|
||||
{
|
||||
return (*p0)->Freq > (*p1)->Freq;
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_EQ_SSE_THREADED
|
||||
wxRadioButton *mMathProcessingType[5]; // default, sse, sse threaded, AVX, AVX threaded (note AVX is not implemented yet
|
||||
wxBoxSizer *szrM;
|
||||
|
|
Loading…
Reference in New Issue