Add a tick method to the OPF
This commit is contained in:
parent
0c9c188e4b
commit
81ee1f2e59
3 changed files with 34 additions and 39 deletions
|
|
@ -57,18 +57,14 @@ public:
|
||||||
void processLowpass(const Type* input, Type* output, unsigned size)
|
void processLowpass(const Type* input, Type* output, unsigned size)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < size; ++i) {
|
for (unsigned i = 0; i < size; ++i) {
|
||||||
const Type intermediate = G * (input[i] - state);
|
output[i] = tickLowpass(input[i]);
|
||||||
output[i] = intermediate + state;
|
|
||||||
state = output[i] + intermediate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void processHighpass(const Type* input, Type* output, unsigned size)
|
void processHighpass(const Type* input, Type* output, unsigned size)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < size; ++i) {
|
for (unsigned i = 0; i < size; ++i) {
|
||||||
const Type intermediate = G * (input[i] - state);
|
output[i] = tickHighpass(input[i]);
|
||||||
output[i] = input[i] - intermediate - state;
|
|
||||||
state += 2 * intermediate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,9 +72,7 @@ public:
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < size; ++i) {
|
for (unsigned i = 0; i < size; ++i) {
|
||||||
setGain(gain[i]);
|
setGain(gain[i]);
|
||||||
const Type intermediate = G * (input[i] - state);
|
output[i] = tickLowpass(input[i]);
|
||||||
output[i] = intermediate + state;
|
|
||||||
state = output[i] + intermediate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,12 +80,26 @@ public:
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < size; ++i) {
|
for (unsigned i = 0; i < size; ++i) {
|
||||||
setGain(gain[i]);
|
setGain(gain[i]);
|
||||||
const Type intermediate = G * (input[i] - state);
|
output[i] = tickHighpass(input[i]);
|
||||||
output[i] = input[i] - intermediate - state;
|
|
||||||
state += 2 * intermediate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type tickHighpass(const Type& input)
|
||||||
|
{
|
||||||
|
const Type intermediate = G * (input - state);
|
||||||
|
const Type output = input - intermediate - state;
|
||||||
|
state += 2 * intermediate;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type tickLowpass(const Type& input)
|
||||||
|
{
|
||||||
|
const Type intermediate = G * (input - state);
|
||||||
|
const Type output = intermediate + state;
|
||||||
|
state = output + intermediate;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
void reset(Type value = 0.0)
|
void reset(Type value = 0.0)
|
||||||
{
|
{
|
||||||
state = value;
|
state = value;
|
||||||
|
|
|
||||||
|
|
@ -614,21 +614,6 @@ bool sfz::Voice::checkOffGroup(int delay, uint32_t group) noexcept
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfz::Voice::getTriggerNumber() const noexcept
|
|
||||||
{
|
|
||||||
return triggerNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
float sfz::Voice::getTriggerValue() const noexcept
|
|
||||||
{
|
|
||||||
return triggerValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sfz::Voice::TriggerType sfz::Voice::getTriggerType() const noexcept
|
|
||||||
{
|
|
||||||
return triggerType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sfz::Voice::reset() noexcept
|
void sfz::Voice::reset() noexcept
|
||||||
{
|
{
|
||||||
state = State::idle;
|
state = State::idle;
|
||||||
|
|
@ -743,15 +728,9 @@ void sfz::Voice::updateChannelPowers(AudioSpan<float> buffer)
|
||||||
if (buffer.getNumFrames() == 0)
|
if (buffer.getNumFrames() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto tempSpan = resources.bufferPool.getBuffer(buffer.getNumFrames());
|
|
||||||
if (!tempSpan)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < channelPowers.size(); ++i) {
|
for (unsigned i = 0; i < channelPowers.size(); ++i) {
|
||||||
|
const auto input = buffer.getConstSpan(i);
|
||||||
for (unsigned s = 0; s < buffer.getNumFrames(); ++s)
|
for (unsigned s = 0; s < buffer.getNumFrames(); ++s)
|
||||||
(*tempSpan)[s] = std::abs(buffer.getConstSpan(i)[s]);
|
channelPowers[i] = channelPowerFilters[i].tickLowpass(std::abs(input[s]));
|
||||||
|
|
||||||
channelPowerFilters[i].processLowpass(*tempSpan, *tempSpan);
|
|
||||||
channelPowers[i] = tempSpan->back();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,19 +156,19 @@ public:
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int getTriggerNumber() const noexcept;
|
constexpr int getTriggerNumber() const noexcept { return triggerNumber; }
|
||||||
/**
|
/**
|
||||||
* @brief Get the value that triggered the voice (note velocity or cc value)
|
* @brief Get the value that triggered the voice (note velocity or cc value)
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
float getTriggerValue() const noexcept;
|
constexpr float getTriggerValue() const noexcept { return triggerValue; }
|
||||||
/**
|
/**
|
||||||
* @brief Get the type of trigger
|
* @brief Get the type of trigger
|
||||||
*
|
*
|
||||||
* @return TriggerType
|
* @return TriggerType
|
||||||
*/
|
*/
|
||||||
TriggerType getTriggerType() const noexcept;
|
constexpr TriggerType getTriggerType() const noexcept { return triggerType; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reset the voice to its initial values
|
* @brief Reset the voice to its initial values
|
||||||
|
|
@ -220,7 +220,7 @@ public:
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int getAge() const noexcept { return age; }
|
constexpr int getAge() const noexcept { return age; }
|
||||||
|
|
||||||
Duration getLastDataDuration() const noexcept { return dataDuration; }
|
Duration getLastDataDuration() const noexcept { return dataDuration; }
|
||||||
Duration getLastAmplitudeDuration() const noexcept { return amplitudeDuration; }
|
Duration getLastAmplitudeDuration() const noexcept { return amplitudeDuration; }
|
||||||
|
|
@ -314,4 +314,12 @@ private:
|
||||||
LEAK_DETECTOR(Voice);
|
LEAK_DETECTOR(Voice);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr bool sisterVoices(const Voice* lhs, const Voice* rhs)
|
||||||
|
{
|
||||||
|
return lhs->getAge() == rhs->getAge()
|
||||||
|
&& lhs->getTriggerNumber() == rhs->getTriggerNumber()
|
||||||
|
&& lhs->getTriggerValue() == rhs->getTriggerValue()
|
||||||
|
&& lhs->getTriggerType() == rhs->getTriggerType();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sfz
|
} // namespace sfz
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue