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;
|
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;
|
mLoFreq = loFreqI;
|
||||||
|
|
||||||
mBandsInUse = 0;
|
mBandsInUse = 0;
|
||||||
|
@ -1654,84 +1662,146 @@ void EffectEqualization::SaveCurves(const wxString &fileName)
|
||||||
void EffectEqualization::setCurve(int currentCurve)
|
void EffectEqualization::setCurve(int currentCurve)
|
||||||
{
|
{
|
||||||
// Set current choice
|
// Set current choice
|
||||||
Select( currentCurve );
|
Select(currentCurve);
|
||||||
|
|
||||||
wxASSERT( currentCurve < (int) mCurves.GetCount() );
|
wxASSERT( currentCurve < (int) mCurves.GetCount() );
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
if( mLin ) // linear freq mode?
|
Envelope *env;
|
||||||
{
|
int numPoints = (int) mCurves[currentCurve].points.GetCount();
|
||||||
Envelope *env = mLinEnvelope;
|
|
||||||
env->Flatten(0.);
|
|
||||||
env->SetTrackLen(1.0);
|
|
||||||
|
|
||||||
if( mCurves[currentCurve].points.GetCount() )
|
if (mLin) { // linear freq mode
|
||||||
{
|
env = mLinEnvelope;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else { // log freq mode
|
||||||
{
|
env = mLogEnvelope;
|
||||||
Envelope *env = mLogEnvelope;
|
}
|
||||||
env->Flatten(0.);
|
env->Flatten(0.);
|
||||||
env->SetTrackLen(1.0);
|
env->SetTrackLen(1.0);
|
||||||
|
|
||||||
if( mCurves[currentCurve].points.GetCount() )
|
// Handle special case of no points.
|
||||||
{
|
if (numPoints == 0) {
|
||||||
double when, value;
|
ForceRecalc();
|
||||||
double loLog = log10(20.);
|
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 hiLog = log10(mHiFreq);
|
||||||
double denom = hiLog - loLog;
|
double denom = hiLog - loLog;
|
||||||
int i;
|
when = (log10(std::max((double) loFreqI, when)) - loLog)/denom;
|
||||||
int nCurvePoints = mCurves[currentCurve].points.GetCount();
|
}
|
||||||
|
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++)
|
// We have at least two points, so ensure they are in frequency order.
|
||||||
{
|
mCurves[currentCurve].points.Sort(SortCurvePoints);
|
||||||
double flog = log10(mCurves[currentCurve].points[i].Freq);
|
|
||||||
if( flog >= loLog )
|
if (mCurves[currentCurve].points[0].Freq < 0) {
|
||||||
{
|
// Corrupt or invalid curve, so bail.
|
||||||
when = (flog - loLog)/denom;
|
ForceRecalc();
|
||||||
value = mCurves[currentCurve].points[i].dB;
|
return;
|
||||||
if(when <= 1.)
|
}
|
||||||
env->Insert(when, value);
|
|
||||||
else
|
if(mLin) { // linear Hz scale
|
||||||
{ // we have a point beyond fs/2. Insert it so that env code can use it.
|
for(int pointCount = 0; pointCount < numPoints; pointCount++) {
|
||||||
// but just this one, we have no use for the rest
|
when = mCurves[currentCurve].points[pointCount].Freq / mHiFreq;
|
||||||
env->SetTrackLen(when); // can't Insert if the envelope isn't long enough
|
value = mCurves[currentCurve].points[pointCount].dB;
|
||||||
env->Insert(when, value);
|
if(when <= 1) {
|
||||||
break;
|
env->Insert(when, value);
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else
|
// There are more points at higher freqs, so interpolate next one then stop.
|
||||||
{ //get the first point as close as we can to the last point requested
|
when = 1.0;
|
||||||
changed = true;
|
double lastF = mCurves[currentCurve].points[pointCount-1].Freq;
|
||||||
//double f = mCurves[currentCurve].points[i].Freq;
|
double nextF = mCurves[currentCurve].points[pointCount].Freq;
|
||||||
//double v = mCurves[currentCurve].points[i].dB;
|
double lastDB = mCurves[currentCurve].points[pointCount-1].dB;
|
||||||
mLogEnvelope->Insert(0., mCurves[currentCurve].points[i].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();
|
ForceRecalc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2272,7 +2342,10 @@ void EffectEqualization::EnvLinToLog(void)
|
||||||
{
|
{
|
||||||
if( when[i]*mHiFreq >= 20 )
|
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
|
else
|
||||||
{ //get the first point as close as we can to the last point requested
|
{ //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);
|
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
|
#ifdef EXPERIMENTAL_EQ_SSE_THREADED
|
||||||
wxRadioButton *mMathProcessingType[5]; // default, sse, sse threaded, AVX, AVX threaded (note AVX is not implemented yet
|
wxRadioButton *mMathProcessingType[5]; // default, sse, sse threaded, AVX, AVX threaded (note AVX is not implemented yet
|
||||||
wxBoxSizer *szrM;
|
wxBoxSizer *szrM;
|
||||||
|
|
Loading…
Reference in New Issue