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
|
const ValueType& getWithDefault(int index) const noexcept
|
||||||
{
|
{
|
||||||
auto it = container.find(index);
|
auto it = container.find(index);
|
||||||
if (it == end(container)) {
|
if (it == container.end()) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
} else {
|
} else {
|
||||||
return it->second;
|
return it->second;
|
||||||
|
|
@ -34,8 +34,9 @@ public:
|
||||||
|
|
||||||
inline bool empty() const { return container.empty(); }
|
inline bool empty() const { return container.empty(); }
|
||||||
const ValueType& at(int index) const { return container.at(index); }
|
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:
|
private:
|
||||||
const ValueType defaultValue;
|
const ValueType defaultValue;
|
||||||
std::map<int, ValueType> container;
|
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); }
|
std::pair<Type, Type> getPair() const noexcept { return std::make_pair<Type, Type>(_start, _end); }
|
||||||
Range(const Range<Type>& range) = default;
|
Range(const Range<Type>& range) = default;
|
||||||
Range(Range<Type>&& range) = default;
|
Range(Range<Type>&& range) = default;
|
||||||
|
constexpr Type length() { return _end - _start; }
|
||||||
void setStart(Type start) noexcept
|
void setStart(Type start) noexcept
|
||||||
{
|
{
|
||||||
_start = start;
|
_start = start;
|
||||||
|
|
|
||||||
|
|
@ -403,12 +403,12 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfz::Region::isSwitchedOn() const noexcept
|
bool sfz::Region::isSwitchedOn() const noexcept
|
||||||
{
|
{
|
||||||
return keySwitched && previousKeySwitched && sequenceSwitched && pitchSwitched && bpmSwitched && aftertouchSwitched && allCCSwitched;
|
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);
|
const bool chanOk = channelRange.containsWithEnd(channel);
|
||||||
if (!chanOk)
|
if (!chanOk)
|
||||||
|
|
@ -558,7 +558,7 @@ float sfz::Region::getBasePitchVariation(int noteNumber, uint8_t velocity) noexc
|
||||||
return centsFactor(pitchVariationInCents);
|
return centsFactor(pitchVariationInCents);
|
||||||
}
|
}
|
||||||
|
|
||||||
float sfz::Region::getBaseGain() noexcept
|
float sfz::Region::getBaseGain() noexcept
|
||||||
{
|
{
|
||||||
float baseGaindB { volume };
|
float baseGaindB { volume };
|
||||||
baseGaindB += gainDistribution(Random::randomGenerator);
|
baseGaindB += gainDistribution(Random::randomGenerator);
|
||||||
|
|
@ -591,4 +591,80 @@ bool sfz::Region::canUsePreloadedData() const noexcept
|
||||||
bool sfz::Region::isStereo() const noexcept
|
bool sfz::Region::isStereo() const noexcept
|
||||||
{
|
{
|
||||||
return this->numChannels == 2;
|
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;
|
void registerTempo(float secondsPerQuarter) noexcept;
|
||||||
bool isStereo() const noexcept;
|
bool isStereo() const noexcept;
|
||||||
float getBasePitchVariation(int noteNumber, uint8_t velocity) noexcept;
|
float getBasePitchVariation(int noteNumber, uint8_t velocity) noexcept;
|
||||||
|
float getNoteGain(int noteNumber, uint8_t velocity) noexcept;
|
||||||
float getBaseGain() noexcept;
|
float getBaseGain() noexcept;
|
||||||
|
float velocityGain(uint8_t velocity) const noexcept;
|
||||||
uint32_t getOffset() noexcept;
|
uint32_t getOffset() noexcept;
|
||||||
uint32_t getDelay() noexcept;
|
uint32_t getDelay() noexcept;
|
||||||
uint32_t trueSampleEnd() const 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->registerNoteOn(region->channelRange.getStart(), *defaultSwitch, 127, 1.0);
|
||||||
region->registerNoteOff(region->channelRange.getStart(), *defaultSwitch, 0, 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->registerPitchWheel(region->channelRange.getStart(), 0);
|
||||||
region->registerAftertouch(region->channelRange.getStart(), 0);
|
region->registerAftertouch(region->channelRange.getStart(), 0);
|
||||||
region->registerTempo(2.0f);
|
region->registerTempo(2.0f);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue