220 lines
7.1 KiB
C++
220 lines
7.1 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Project : VST SDK
|
|
//
|
|
// Category : Examples
|
|
// Filename : public.sdk/samples/vst/common/logscale.h
|
|
// Created by : Steinberg, 10/2010
|
|
// Description :
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// This file is part of a Steinberg SDK. It is subject to the license terms
|
|
// in the LICENSE file found in the top-level directory of this distribution
|
|
// and at www.steinberg.net/sdklicenses.
|
|
// No part of the SDK, including this file, may be copied, modified, propagated,
|
|
// or distributed except according to the terms contained in the LICENSE file.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include "pluginterfaces/base/ftypes.h"
|
|
#include "pluginterfaces/base/ustring.h"
|
|
#include "public.sdk/source/vst/vstparameters.h"
|
|
#include <cmath>
|
|
|
|
namespace Steinberg {
|
|
namespace Vst {
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/** LogScale class.
|
|
Scales [srcMin srcMax] to [destMin destMax]
|
|
|
|
Scaling curve is defined by given outValue for given inValue
|
|
|
|
\section example1 Example for stretched lower range
|
|
LogScale myLogScale (0, 1, 0, 1, 0.5, 0.1); \n
|
|
means: input and output ranges are the same, but myLogScale.scale (0.5) is 0.1 ([0, 0.5, 1] => [0, 0.1, 1])
|
|
|
|
\section example2 Example for compressed lower range
|
|
LogScale myLogScale (0, 1, 0, 1, 0.5, 0.9); \n
|
|
means: input and output ranges are the same, but myLogScale.scale (0.5) is 0.9 ([0, 0.5, 1] => [0, 0.9, 1])
|
|
|
|
\section example3 Example for filter frequency range
|
|
LogScale myLogScale (0, 1, 80, 22000, 0.5, 2000); \n
|
|
means: input range is between 0 and 1 and output range is between 80 and 22000 and myLogScale.scale (0.5) is 2000
|
|
([0, 0.5, 1] => [80, 2000, 22000])
|
|
*/
|
|
template <class T>
|
|
class LogScale
|
|
{
|
|
public:
|
|
/** Constructor. */
|
|
LogScale (T srcMin, T srcMax, T destMin, T destMax, T inValue=0.5, T outValue=0.1);
|
|
/** Default Constructor with [0, 0.5, 1] => [0, 0.1, 1]. */
|
|
LogScale ();
|
|
|
|
/** Applies a new scale setting. Note that destMin should be different than destMax! The same for srcMin and srcMax. */
|
|
void changeScaling (T srcMin, T srcMax, T destMin, T destMax, T inValue, T outValue);
|
|
|
|
/** Computes the scale from pIn input buffer to pOut output buffer (pIn and POut could be the same buffer). */
|
|
void scale (T* pIn, T* pOut, int32 nSamples);
|
|
/** Computes for one given value the scale. */
|
|
T scale (T input) const;
|
|
|
|
/** Computes the inverse scale from pIn input buffer to pOut output buffer (pIn and POut could be the same buffer). */
|
|
void invscale (T* pIn, T* pOut, int32 nSamples);
|
|
/** Computes for one given value the inverse scale. */
|
|
T invscale (T input) const;
|
|
/** Same than invscale with a check of the input. */
|
|
T invscaleCheck (T in) const;
|
|
|
|
protected:
|
|
|
|
void setScaling (T srcMin, T srcMax, T destMin, T destMax, T inValue, T outValue);
|
|
T scaleFactor;
|
|
T scaleFactorInv;
|
|
T srcScale;
|
|
T srcScaleInv;
|
|
T srcMin;
|
|
T expo;
|
|
T expoInv;
|
|
T destMin;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
template <class T>
|
|
LogScale<T>::LogScale (T srcMin, T srcMax, T destMin, T destMax, T inValue, T outValue)
|
|
{
|
|
setScaling (srcMin, srcMax, destMin, destMax, inValue, outValue);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
template <class T>
|
|
LogScale<T>::LogScale ()
|
|
{
|
|
setScaling (0.f, 1.f, 0.f, 1.f, 0.5f, 0.1f);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
template <class T>
|
|
void LogScale<T>::changeScaling (T srcMin, T srcMax, T destMin, T destMax, T inValue, T outValue)
|
|
{
|
|
setScaling (srcMin, srcMax, destMin, destMax, inValue, outValue);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
template <class T>
|
|
void LogScale<T>::setScaling (T _srcMin, T _srcMax, T _destMin, T _destMax, T inValue, T outValue)
|
|
{
|
|
srcMin = _srcMin;
|
|
destMin = _destMin;
|
|
|
|
scaleFactor = (_destMax - _destMin);
|
|
scaleFactorInv = 1.f / scaleFactor;
|
|
|
|
inValue = (inValue - _srcMin) / (_srcMax - _srcMin);
|
|
|
|
SMTG_ASSERT (inValue > 0.);
|
|
|
|
expo = ::log ((outValue - _destMin) / scaleFactor) / ::log (inValue);
|
|
expoInv = 1.f / expo;
|
|
|
|
srcScale = (_srcMax - _srcMin);
|
|
srcScaleInv = 1.f / srcScale;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
template <class T>
|
|
void LogScale<T>::scale (T* pIn, T* pOut, int32 nSamples)
|
|
{
|
|
for (int32 i = 0; i < nSamples; i++)
|
|
pOut[i] = ::powf ((float)((pIn[i] - srcMin) * srcScaleInv), (float)expo) * scaleFactor + destMin;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
template <class T>
|
|
T LogScale<T>::scale (T input) const
|
|
{
|
|
return ::powf ((float)((input - srcMin) * srcScaleInv), (float)expo) * scaleFactor + destMin;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
template <class T>
|
|
void LogScale<T>::invscale (T* pIn, T* pOut, int32 nSamples)
|
|
{
|
|
for (int32 i = 0; i < nSamples; i++)
|
|
pOut[i] = ::powf ((float)((pIn[i] - destMin) * scaleFactorInv), (float)expoInv) * srcScale + srcMin;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
template <class T>
|
|
T LogScale<T>::invscale (T input) const
|
|
{
|
|
return ::powf ((float)((input - destMin) * scaleFactorInv), (float)expoInv) * srcScale + srcMin;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
template <class T>
|
|
T LogScale<T>::invscaleCheck (T input) const
|
|
{
|
|
T basis = (float)((input - destMin) * scaleFactorInv);
|
|
|
|
if (basis < 0.)
|
|
basis = 0.;
|
|
|
|
return ::powf ((float)basis, (float)expoInv) * srcScale + srcMin;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/** Parameter class with a LogScale.
|
|
Define a parameter using the LogScale.
|
|
|
|
\sa Steinberg::Vst::LogScale
|
|
*/
|
|
template <class T>
|
|
class LogScaleParameter : public Parameter
|
|
{
|
|
public:
|
|
LogScaleParameter (const TChar* title, ParamID tag, LogScale<T>& logScale,
|
|
const TChar* units = nullptr, int32 flags = ParameterInfo::kCanAutomate,
|
|
UnitID unitID = kRootUnitId)
|
|
: Parameter (title, tag, units, 0., 0, flags, unitID), logScale (logScale)
|
|
{
|
|
}
|
|
|
|
void toString (ParamValue _valueNormalized, String128 string) const SMTG_OVERRIDE
|
|
{
|
|
UString128 wrapper;
|
|
wrapper.printFloat (toPlain (_valueNormalized), precision);
|
|
wrapper.copyTo (string, 128);
|
|
}
|
|
|
|
bool fromString (const TChar* string, ParamValue& _valueNormalized) const SMTG_OVERRIDE
|
|
{
|
|
UString wrapper ((TChar*)string, strlen16 (string));
|
|
if (wrapper.scanFloat (_valueNormalized))
|
|
{
|
|
_valueNormalized = toNormalized (_valueNormalized);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ParamValue toPlain (ParamValue _valueNormalized) const SMTG_OVERRIDE
|
|
{
|
|
return logScale.scale (_valueNormalized);
|
|
}
|
|
|
|
ParamValue toNormalized (ParamValue plainValue) const SMTG_OVERRIDE
|
|
{
|
|
return logScale.invscale (plainValue);
|
|
}
|
|
|
|
OBJ_METHODS (LogScaleParameter<T>, Parameter)
|
|
protected:
|
|
LogScale<T>& logScale;
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
} // namespace Vst
|
|
} // namespace Steinberg
|