Loading...
Searching...
No Matches
juce_NormalisableRange.h
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
template <typename ValueType>
class NormalisableRange
{
public:
NormalisableRange() = default;
NormalisableRange (const NormalisableRange&) = default;
NormalisableRange& operator= (const NormalisableRange&) = default;
NormalisableRange (NormalisableRange&&) = default;
NormalisableRange& operator= (NormalisableRange&&) = default;
NormalisableRange (ValueType rangeStart,
ValueType rangeEnd,
ValueType intervalValue,
ValueType skewFactor,
bool useSymmetricSkew = false) noexcept
: start (rangeStart), end (rangeEnd), interval (intervalValue),
skew (skewFactor), symmetricSkew (useSymmetricSkew)
{
checkInvariants();
}
NormalisableRange (ValueType rangeStart,
ValueType rangeEnd) noexcept
: start (rangeStart), end (rangeEnd)
{
checkInvariants();
}
NormalisableRange (ValueType rangeStart,
ValueType rangeEnd,
ValueType intervalValue) noexcept
: start (rangeStart), end (rangeEnd), interval (intervalValue)
{
checkInvariants();
}
NormalisableRange (Range<ValueType> range) noexcept
: NormalisableRange (range.getStart(), range.getEnd())
{
}
NormalisableRange (Range<ValueType> range, ValueType intervalValue) noexcept
: NormalisableRange (range.getStart(), range.getEnd(), intervalValue)
{
}
using ValueRemapFunction = std::function<ValueType(ValueType rangeStart,
ValueType rangeEnd,
ValueType valueToRemap)>;
NormalisableRange (ValueType rangeStart,
ValueType rangeEnd,
ValueRemapFunction convertFrom0To1Func,
ValueRemapFunction convertTo0To1Func,
ValueRemapFunction snapToLegalValueFunc = {}) noexcept
: start (rangeStart),
end (rangeEnd),
convertFrom0To1Function (std::move (convertFrom0To1Func)),
convertTo0To1Function (std::move (convertTo0To1Func)),
snapToLegalValueFunction (std::move (snapToLegalValueFunc))
{
checkInvariants();
}
ValueType convertTo0to1 (ValueType v) const noexcept
{
if (convertTo0To1Function != nullptr)
return clampTo0To1 (convertTo0To1Function (start, end, v));
auto proportion = clampTo0To1 ((v - start) / (end - start));
if (exactlyEqual (skew, static_cast<ValueType> (1)))
return proportion;
if (! symmetricSkew)
return std::pow (proportion, skew);
auto distanceFromMiddle = static_cast<ValueType> (2) * proportion - static_cast<ValueType> (1);
return (static_cast<ValueType> (1) + std::pow (std::abs (distanceFromMiddle), skew)
* (distanceFromMiddle < ValueType() ? static_cast<ValueType> (-1)
: static_cast<ValueType> (1)))
/ static_cast<ValueType> (2);
}
ValueType convertFrom0to1 (ValueType proportion) const noexcept
{
proportion = clampTo0To1 (proportion);
if (convertFrom0To1Function != nullptr)
return convertFrom0To1Function (start, end, proportion);
if (! symmetricSkew)
{
if (! exactlyEqual (skew, static_cast<ValueType> (1)) && proportion > ValueType())
proportion = std::exp (std::log (proportion) / skew);
return start + (end - start) * proportion;
}
auto distanceFromMiddle = static_cast<ValueType> (2) * proportion - static_cast<ValueType> (1);
if (! exactlyEqual (skew, static_cast<ValueType> (1)) && ! exactlyEqual (distanceFromMiddle, static_cast<ValueType> (0)))
distanceFromMiddle = std::exp (std::log (std::abs (distanceFromMiddle)) / skew)
* (distanceFromMiddle < ValueType() ? static_cast<ValueType> (-1)
: static_cast<ValueType> (1));
return start + (end - start) / static_cast<ValueType> (2) * (static_cast<ValueType> (1) + distanceFromMiddle);
}
ValueType snapToLegalValue (ValueType v) const noexcept
{
if (snapToLegalValueFunction != nullptr)
return snapToLegalValueFunction (start, end, v);
if (interval > ValueType())
v = start + interval * std::floor ((v - start) / interval + static_cast<ValueType> (0.5));
return (v <= start || end <= start) ? start : (v >= end ? end : v);
}
Range<ValueType> getRange() const noexcept { return { start, end }; }
void setSkewForCentre (ValueType centrePointValue) noexcept
{
jassert (centrePointValue > start);
jassert (centrePointValue < end);
symmetricSkew = false;
skew = std::log (static_cast<ValueType> (0.5)) / std::log ((centrePointValue - start) / (end - start));
checkInvariants();
}
ValueType start = 0;
ValueType end = 1;
ValueType interval = 0;
ValueType skew = 1;
bool symmetricSkew = false;
private:
void checkInvariants() const
{
jassert (end > start);
jassert (interval >= ValueType());
jassert (skew > ValueType());
}
static ValueType clampTo0To1 (ValueType value)
{
auto clampedValue = jlimit (static_cast<ValueType> (0), static_cast<ValueType> (1), value);
// If you hit this assertion then either your normalisation function is not working
// correctly or your input is out of the expected bounds.
jassert (exactlyEqual (clampedValue, value));
return clampedValue;
}
ValueRemapFunction convertFrom0To1Function, convertTo0To1Function, snapToLegalValueFunction;
};
} // namespace juce
juce::NormalisableRange::skew
ValueType skew
Definition juce_NormalisableRange.h:234
juce::NormalisableRange::end
ValueType end
Definition juce_NormalisableRange.h:212
juce::NormalisableRange::symmetricSkew
bool symmetricSkew
Definition juce_NormalisableRange.h:237
juce::NormalisableRange::snapToLegalValue
ValueType snapToLegalValue(ValueType v) const noexcept
Definition juce_NormalisableRange.h:176
juce::NormalisableRange::ValueRemapFunction
std::function< ValueType(ValueType rangeStart, ValueType rangeEnd, ValueType valueToRemap)> ValueRemapFunction
Definition juce_NormalisableRange.h:92
juce::NormalisableRange::NormalisableRange
NormalisableRange()=default
juce::NormalisableRange::start
ValueType start
Definition juce_NormalisableRange.h:209
juce::NormalisableRange::convertFrom0to1
ValueType convertFrom0to1(ValueType proportion) const noexcept
Definition juce_NormalisableRange.h:148
juce::NormalisableRange::NormalisableRange
NormalisableRange(ValueType rangeStart, ValueType rangeEnd) noexcept
Definition juce_NormalisableRange.h:63
juce::NormalisableRange::setSkewForCentre
void setSkewForCentre(ValueType centrePointValue) noexcept
Definition juce_NormalisableRange.h:198
juce::NormalisableRange::NormalisableRange
NormalisableRange(ValueType rangeStart, ValueType rangeEnd, ValueRemapFunction convertFrom0To1Func, ValueRemapFunction convertTo0To1Func, ValueRemapFunction snapToLegalValueFunc={}) noexcept
Definition juce_NormalisableRange.h:107
juce::NormalisableRange::NormalisableRange
NormalisableRange(ValueType rangeStart, ValueType rangeEnd, ValueType intervalValue) noexcept
Definition juce_NormalisableRange.h:71
juce::NormalisableRange::getRange
Range< ValueType > getRange() const noexcept
Definition juce_NormalisableRange.h:188
juce::NormalisableRange::interval
ValueType interval
Definition juce_NormalisableRange.h:220
juce::NormalisableRange::NormalisableRange
NormalisableRange(Range< ValueType > range, ValueType intervalValue) noexcept
Definition juce_NormalisableRange.h:86
juce::NormalisableRange::NormalisableRange
NormalisableRange(ValueType rangeStart, ValueType rangeEnd, ValueType intervalValue, ValueType skewFactor, bool useSymmetricSkew=false) noexcept
Definition juce_NormalisableRange.h:51
juce::NormalisableRange::convertTo0to1
ValueType convertTo0to1(ValueType v) const noexcept
Definition juce_NormalisableRange.h:124
juce::NormalisableRange::NormalisableRange
NormalisableRange(Range< ValueType > range) noexcept
Definition juce_NormalisableRange.h:80
juce::Range
Definition juce_Range.h:40