Added iterators to the CCMap
This commit is contained in:
parent
49d869cd1f
commit
4384c473f9
5 changed files with 91 additions and 6 deletions
|
|
@ -18,7 +18,7 @@ public:
|
|||
const ValueType& getWithDefault(int index) const noexcept
|
||||
{
|
||||
auto it = container.find(index);
|
||||
if (it == end(container)) {
|
||||
if (it == container.end()) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
return it->second;
|
||||
|
|
@ -34,8 +34,9 @@ public:
|
|||
|
||||
inline bool empty() const { return container.empty(); }
|
||||
const ValueType& at(int index) const { return container.at(index); }
|
||||
bool contains(int index) const noexcept { return container.find(index) != end(container); }
|
||||
|
||||
bool contains(int index) const noexcept { return container.find(index) != container.end(); }
|
||||
typename std::map<int, ValueType>::iterator begin() { return container.begin(); }
|
||||
typename std::map<int, ValueType>::iterator end() { return container.end(); }
|
||||
private:
|
||||
const ValueType defaultValue;
|
||||
std::map<int, ValueType> container;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ public:
|
|||
std::pair<Type, Type> getPair() const noexcept { return std::make_pair<Type, Type>(_start, _end); }
|
||||
Range(const Range<Type>& range) = default;
|
||||
Range(Range<Type>&& range) = default;
|
||||
constexpr Type length() { return _end - _start; }
|
||||
void setStart(Type start) noexcept
|
||||
{
|
||||
_start = start;
|
||||
|
|
|
|||
|
|
@ -403,12 +403,12 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool sfz::Region::isSwitchedOn() const noexcept
|
||||
bool sfz::Region::isSwitchedOn() const noexcept
|
||||
{
|
||||
return keySwitched && previousKeySwitched && sequenceSwitched && pitchSwitched && bpmSwitched && aftertouchSwitched && allCCSwitched;
|
||||
}
|
||||
|
||||
bool sfz::Region::registerNoteOn(int channel, int noteNumber, uint8_t velocity, float randValue) noexcept
|
||||
bool sfz::Region::registerNoteOn(int channel, int noteNumber, uint8_t velocity, float randValue) noexcept
|
||||
{
|
||||
const bool chanOk = channelRange.containsWithEnd(channel);
|
||||
if (!chanOk)
|
||||
|
|
@ -558,7 +558,7 @@ float sfz::Region::getBasePitchVariation(int noteNumber, uint8_t velocity) noexc
|
|||
return centsFactor(pitchVariationInCents);
|
||||
}
|
||||
|
||||
float sfz::Region::getBaseGain() noexcept
|
||||
float sfz::Region::getBaseGain() noexcept
|
||||
{
|
||||
float baseGaindB { volume };
|
||||
baseGaindB += gainDistribution(Random::randomGenerator);
|
||||
|
|
@ -591,4 +591,80 @@ bool sfz::Region::canUsePreloadedData() const noexcept
|
|||
bool sfz::Region::isStereo() const noexcept
|
||||
{
|
||||
return this->numChannels == 2;
|
||||
}
|
||||
|
||||
float sfz::Region::getNoteGain(int noteNumber, uint8_t velocity) noexcept
|
||||
{
|
||||
float baseGain { 1.0f };
|
||||
|
||||
if (trigger == SfzTrigger::release_key)
|
||||
baseGain *= velocityGain(lastNoteVelocities[noteNumber]);
|
||||
else
|
||||
baseGain *= velocityGain(velocity);
|
||||
|
||||
if (noteNumber < crossfadeKeyInRange.getStart())
|
||||
baseGain = 0.0f;
|
||||
else if (noteNumber < crossfadeKeyInRange.getEnd()) {
|
||||
const auto crossfadePosition = static_cast<float>(noteNumber - crossfadeKeyInRange.getStart()) / crossfadeKeyInRange.length();
|
||||
if (crossfadeKeyCurve == SfzCrossfadeCurve::power)
|
||||
baseGain *= sqrt(crossfadePosition);
|
||||
if (crossfadeKeyCurve == SfzCrossfadeCurve::gain)
|
||||
baseGain *= crossfadePosition;
|
||||
}
|
||||
|
||||
if (noteNumber > crossfadeKeyOutRange.getEnd())
|
||||
baseGain = 0.0f;
|
||||
else if (noteNumber > crossfadeKeyOutRange.getStart()) {
|
||||
const auto crossfadePosition = static_cast<float>(noteNumber - crossfadeKeyOutRange.getStart()) / crossfadeKeyOutRange.length();
|
||||
if (crossfadeKeyCurve == SfzCrossfadeCurve::power)
|
||||
baseGain *= sqrt(1 - crossfadePosition);
|
||||
if (crossfadeKeyCurve == SfzCrossfadeCurve::gain)
|
||||
baseGain *= 1 - crossfadePosition;
|
||||
}
|
||||
|
||||
if (velocity < crossfadeVelInRange.getStart())
|
||||
baseGain = 0;
|
||||
else if (velocity < crossfadeVelInRange.getEnd()) {
|
||||
const auto crossfadePosition = static_cast<float>(noteNumber - crossfadeVelInRange.getStart()) / crossfadeVelInRange.length();
|
||||
if (crossfadeVelCurve == SfzCrossfadeCurve::power)
|
||||
baseGain *= sqrt(crossfadePosition);
|
||||
if (crossfadeVelCurve == SfzCrossfadeCurve::gain)
|
||||
baseGain *= crossfadePosition;
|
||||
}
|
||||
|
||||
if (velocity > crossfadeVelOutRange.getEnd())
|
||||
baseGain = 0;
|
||||
else if (velocity > crossfadeVelOutRange.getStart()) {
|
||||
const auto crossfadePosition = static_cast<float>(noteNumber - crossfadeVelOutRange.getStart()) / crossfadeVelOutRange.length();
|
||||
if (crossfadeVelCurve == SfzCrossfadeCurve::power)
|
||||
baseGain *= sqrt(1 - crossfadePosition);
|
||||
if (crossfadeVelCurve == SfzCrossfadeCurve::gain)
|
||||
baseGain *= 1 - crossfadePosition;
|
||||
}
|
||||
|
||||
return baseGain;
|
||||
}
|
||||
|
||||
float sfz::Region::velocityGain(uint8_t velocity) const noexcept
|
||||
{
|
||||
float gaindB { 0.0 };
|
||||
if (velocityPoints.size() > 0)
|
||||
{
|
||||
auto after = std::find_if(velocityPoints.begin(), velocityPoints.end(), [velocity](auto& val) { return val.first >= velocity; });
|
||||
auto before = after == velocityPoints.begin() ? velocityPoints.begin() : after - 1;
|
||||
// Linear interpolation
|
||||
float relativePositionInSegment { static_cast<float>(velocity - before->first) / (after->first - before->first) };
|
||||
float segmentEndpoints { after->second - before->second };
|
||||
gaindB = db2pow(relativePositionInSegment * segmentEndpoints);
|
||||
}
|
||||
else
|
||||
{
|
||||
float floatVelocity { static_cast<float>(velocity)/127 };
|
||||
if (ampVeltrack > 0)
|
||||
gaindB = 40 * std::log(floatVelocity) / std::log(10.0f);
|
||||
else
|
||||
gaindB = 40 * std::log(1-floatVelocity) / std::log(10.0f);
|
||||
}
|
||||
gaindB *= std::abs(ampVeltrack) / sfz::Default::ampVeltrackRange.getEnd();
|
||||
return db2pow(gaindB);
|
||||
}
|
||||
|
|
@ -31,7 +31,9 @@ struct Region {
|
|||
void registerTempo(float secondsPerQuarter) noexcept;
|
||||
bool isStereo() const noexcept;
|
||||
float getBasePitchVariation(int noteNumber, uint8_t velocity) noexcept;
|
||||
float getNoteGain(int noteNumber, uint8_t velocity) noexcept;
|
||||
float getBaseGain() noexcept;
|
||||
float velocityGain(uint8_t velocity) const noexcept;
|
||||
uint32_t getOffset() noexcept;
|
||||
uint32_t getDelay() noexcept;
|
||||
uint32_t trueSampleEnd() const noexcept;
|
||||
|
|
|
|||
|
|
@ -165,6 +165,11 @@ bool sfz::Synth::loadSfzFile(const std::filesystem::path& filename)
|
|||
region->registerNoteOn(region->channelRange.getStart(), *defaultSwitch, 127, 1.0);
|
||||
region->registerNoteOff(region->channelRange.getStart(), *defaultSwitch, 0, 1.0);
|
||||
}
|
||||
|
||||
absl::c_sort(region->velocityPoints, [](const auto& lhs, const auto& rhs) {
|
||||
return lhs.first < rhs.first;
|
||||
});
|
||||
|
||||
region->registerPitchWheel(region->channelRange.getStart(), 0);
|
||||
region->registerAftertouch(region->channelRange.getStart(), 0);
|
||||
region->registerTempo(2.0f);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue