1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-21 14:02:57 +02:00

Other spectrogram scales, easily defined!! -- and include bug fixes 1038, 1039

This commit is contained in:
Paul Licameli
2015-06-16 14:10:21 -04:00
parent 9b9ceab6ab
commit 846c5d454e
5 changed files with 158 additions and 11 deletions

View File

@@ -19,6 +19,10 @@ Paul Licameli
enum NumberScaleType {
nstLinear,
nstLogarithmic,
nstMel,
nstBark,
nstErb,
nstUndertone,
nstNumScaleTypes,
};
@@ -46,6 +50,34 @@ public:
mUnit = 1.0;
}
break;
case nstMel:
{
mValue0 = hzToMel(value0);
mValue1 = hzToMel(value1);
mUnit = unit;
}
break;
case nstBark:
{
mValue0 = hzToBark(value0);
mValue1 = hzToBark(value1);
mUnit = unit;
}
break;
case nstErb:
{
mValue0 = hzToErb(value0);
mValue1 = hzToErb(value1);
mUnit = unit;
}
break;
case nstUndertone:
{
mValue0 = hzToUndertone(value0);
mValue1 = hzToUndertone(value1);
mUnit = unit;
}
break;
default:
wxASSERT(false);
}
@@ -71,6 +103,57 @@ public:
return !(*this == other);
}
static inline float hzToMel(float hz)
{
return 1127 * log(1 + hz / 700);
}
static inline float melToHz(float mel)
{
return 700 * (exp(mel / 1127) - 1);
}
static inline float hzToBark(float hz)
{
// Traunmueller's formula
const float z1 = 26.81 * hz / (1960 + hz) - 0.53;
if (z1 < 2.0)
return z1 + 0.15 * (2.0 - z1);
else if (z1 > 20.1)
return z1 + 0.22 * (z1 - 20.1);
else
return z1;
}
static inline float barkToHz(float z1)
{
if (z1 < 2.0)
z1 = 2.0 + (z1 - 2.0) / 0.85;
else if (z1 > 20.1)
z1 = 20.1 + (z1 - 20.1) / 1.22;
return 1960 * (z1 + 0.53) / (26.28 - z1);
}
static inline float hzToErb(float hz)
{
return 11.17268 * log(1 + (46.06538 * hz) / (hz + 14678.49));
}
static inline float erbToHz(float erb)
{
return 676170.4 / (47.06538 - exp(0.08950404 * erb)) - 14678.49;
}
static inline float hzToUndertone(float hz)
{
return -1.0 / std::max (1.0f, hz);
}
static inline float undertoneToHz(float u)
{
return -1.0 / u;
}
// Random access
float PositionToValue(float pp) const
{
@@ -81,6 +164,14 @@ public:
return mValue0 + pp * (mValue1 - mValue0);
case nstLogarithmic:
return exp(mValue0 + pp * (mValue1 - mValue0));
case nstMel:
return melToHz(mValue0 + pp * (mValue1 - mValue0)) / mUnit;
case nstBark:
return barkToHz(mValue0 + pp * (mValue1 - mValue0)) / mUnit;
case nstErb:
return erbToHz(mValue0 + pp * (mValue1 - mValue0)) / mUnit;
case nstUndertone:
return undertoneToHz(mValue0 + pp * (mValue1 - mValue0)) / mUnit;
}
}
@@ -102,6 +193,14 @@ public:
case nstLinear:
case nstLogarithmic:
return mValue;
case nstMel:
return melToHz(mValue) / mUnit;
case nstBark:
return barkToHz(mValue) / mUnit;
case nstErb:
return erbToHz(mValue) / mUnit;
case nstUndertone:
return undertoneToHz(mValue) / mUnit;
}
}
@@ -109,6 +208,10 @@ public:
{
switch (mType) {
case nstLinear:
case nstMel:
case nstBark:
case nstErb:
case nstUndertone:
mValue += mStep;
break;
case nstLogarithmic:
@@ -133,6 +236,10 @@ public:
default:
wxASSERT(false);
case nstLinear:
case nstMel:
case nstBark:
case nstErb:
case nstUndertone:
return Iterator
(mType, (mValue1 - mValue0) / nPositions, mValue0, mUnit);
case nstLogarithmic:
@@ -151,6 +258,14 @@ public:
return ((val - mValue0) / (mValue1 - mValue0));
case nstLogarithmic:
return ((log(val) - mValue0) / (mValue1 - mValue0));
case nstMel:
return ((hzToMel(val * mUnit) - mValue0) / (mValue1 - mValue0));
case nstBark:
return ((hzToBark(val * mUnit) - mValue0) / (mValue1 - mValue0));
case nstErb:
return ((hzToErb(val * mUnit) - mValue0) / (mValue1 - mValue0));
case nstUndertone:
return ((hzToUndertone(val * mUnit) - mValue0) / (mValue1 - mValue0));
}
}