commit
d85a53f40c
13 changed files with 1039 additions and 1 deletions
2
dpf.mk
2
dpf.mk
|
|
@ -60,9 +60,11 @@ SFIZZ_SOURCES = \
|
|||
src/sfizz/Curve.cpp \
|
||||
src/sfizz/effects/Apan.cpp \
|
||||
src/sfizz/Effects.cpp \
|
||||
src/sfizz/effects/Compressor.cpp \
|
||||
src/sfizz/effects/Eq.cpp \
|
||||
src/sfizz/effects/Filter.cpp \
|
||||
src/sfizz/effects/Gain.cpp \
|
||||
src/sfizz/effects/Gate.cpp \
|
||||
src/sfizz/effects/impl/ResonantArrayAVX.cpp \
|
||||
src/sfizz/effects/impl/ResonantArray.cpp \
|
||||
src/sfizz/effects/impl/ResonantArraySSE.cpp \
|
||||
|
|
|
|||
54
scripts/generate_compressor.sh
Executable file
54
scripts/generate_compressor.sh
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if ! test -d "src"; then
|
||||
echo "Please run this in the project root directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Note: needs faust >= 2.27.1 for UI macros
|
||||
FAUSTARGS="-uim -inpl"
|
||||
|
||||
# support GNU sed only, use gsed on a Mac
|
||||
test -z "$SED" && SED=sed
|
||||
|
||||
faustgen() {
|
||||
mkdir -p src/sfizz/effects/gen
|
||||
local outfile=src/sfizz/effects/gen/compressor.cxx
|
||||
|
||||
local code=`faust $FAUSTARGS -cn faustCompressor src/sfizz/effects/dsp/compressor.dsp`
|
||||
|
||||
# suppress some faust-specific stuff we don't care
|
||||
echo "$code" \
|
||||
| fgrep -v -- '->declare(' \
|
||||
| fgrep -v -- '->openHorizontalBox(' \
|
||||
| fgrep -v -- '->openVerticalBox(' \
|
||||
| fgrep -v -- '->closeBox(' \
|
||||
| fgrep -v -- '->addHorizontalSlider(' \
|
||||
| fgrep -v -- '->addVerticalSlider(' \
|
||||
> "$outfile"
|
||||
|
||||
# remove metadata
|
||||
$SED -r -i 's/void[ \t]+metadata[ \t]*\(Meta[ \t]*\*[ \t]*[a-zA-Z0-9_]+\)/void metadata()/' "$outfile"
|
||||
|
||||
# remove UI
|
||||
$SED -r -i 's/void[ \t]+buildUserInterface[ \t]*\(UI[ \t]*\*[ \t]*[a-zA-Z0-9_]+\)/void buildUserInterface()/' "$outfile"
|
||||
|
||||
# remove inheritance
|
||||
$SED -r -i 's/:[ \t]*public[ \t]+dsp\b\s*//' "$outfile"
|
||||
|
||||
# remove virtual
|
||||
$SED -r -i 's/\bvirtual\b\s*//' "$outfile"
|
||||
|
||||
# remove undesired UIM
|
||||
$SED -r -i '/^[ \t]*#define[ \t]+FAUST_(FILE_NAME|CLASS_NAME|INPUTS|OUTPUTS|ACTIVES|PASSIVES)/d' "$outfile"
|
||||
$SED -r -i '/^[ \t]*FAUST_ADD.*/d' "$outfile"
|
||||
|
||||
# direct access to parameter variables
|
||||
$SED -r -i 's/\bprivate:/public:/' "$outfile"
|
||||
|
||||
# remove trailing whitespace
|
||||
$SED -r -i 's/[ \t]+$//' "$outfile"
|
||||
}
|
||||
|
||||
faustgen
|
||||
54
scripts/generate_gate.sh
Executable file
54
scripts/generate_gate.sh
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if ! test -d "src"; then
|
||||
echo "Please run this in the project root directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Note: needs faust >= 2.27.1 for UI macros
|
||||
FAUSTARGS="-uim -inpl"
|
||||
|
||||
# support GNU sed only, use gsed on a Mac
|
||||
test -z "$SED" && SED=sed
|
||||
|
||||
faustgen() {
|
||||
mkdir -p src/sfizz/effects/gen
|
||||
local outfile=src/sfizz/effects/gen/gate.cxx
|
||||
|
||||
local code=`faust $FAUSTARGS -cn faustGate src/sfizz/effects/dsp/gate.dsp`
|
||||
|
||||
# suppress some faust-specific stuff we don't care
|
||||
echo "$code" \
|
||||
| fgrep -v -- '->declare(' \
|
||||
| fgrep -v -- '->openHorizontalBox(' \
|
||||
| fgrep -v -- '->openVerticalBox(' \
|
||||
| fgrep -v -- '->closeBox(' \
|
||||
| fgrep -v -- '->addHorizontalSlider(' \
|
||||
| fgrep -v -- '->addVerticalSlider(' \
|
||||
> "$outfile"
|
||||
|
||||
# remove metadata
|
||||
$SED -r -i 's/void[ \t]+metadata[ \t]*\(Meta[ \t]*\*[ \t]*[a-zA-Z0-9_]+\)/void metadata()/' "$outfile"
|
||||
|
||||
# remove UI
|
||||
$SED -r -i 's/void[ \t]+buildUserInterface[ \t]*\(UI[ \t]*\*[ \t]*[a-zA-Z0-9_]+\)/void buildUserInterface()/' "$outfile"
|
||||
|
||||
# remove inheritance
|
||||
$SED -r -i 's/:[ \t]*public[ \t]+dsp\b\s*//' "$outfile"
|
||||
|
||||
# remove virtual
|
||||
$SED -r -i 's/\bvirtual\b\s*//' "$outfile"
|
||||
|
||||
# remove undesired UIM
|
||||
$SED -r -i '/^[ \t]*#define[ \t]+FAUST_(FILE_NAME|CLASS_NAME|INPUTS|OUTPUTS|ACTIVES|PASSIVES)/d' "$outfile"
|
||||
$SED -r -i '/^[ \t]*FAUST_ADD.*/d' "$outfile"
|
||||
|
||||
# direct access to parameter variables
|
||||
$SED -r -i 's/\bprivate:/public:/' "$outfile"
|
||||
|
||||
# remove trailing whitespace
|
||||
$SED -r -i 's/[ \t]+$//' "$outfile"
|
||||
}
|
||||
|
||||
faustgen
|
||||
|
|
@ -7,7 +7,11 @@ set (FAUST_FILES
|
|||
sfizz/dsp/filters/filters_modulable.dsp
|
||||
sfizz/dsp/filters/rbj_filters.dsp
|
||||
sfizz/dsp/filters/sallenkey_modulable.dsp
|
||||
sfizz/dsp/filters/sfz_filters.dsp)
|
||||
sfizz/dsp/filters/sfz_filters.dsp
|
||||
sfizz/effects/dsp/limiter.dsp
|
||||
sfizz/effects/dsp/resonant_string.dsp
|
||||
sfizz/effects/dsp/compressor.dsp
|
||||
sfizz/effects/dsp/gate.dsp)
|
||||
source_group ("Faust Files" FILES ${FAUST_FILES})
|
||||
|
||||
set (SFIZZ_HEADERS
|
||||
|
|
@ -30,9 +34,11 @@ set (SFIZZ_HEADERS
|
|||
sfizz/effects/Apan.h
|
||||
sfizz/effects/CommonLFO.h
|
||||
sfizz/effects/CommonLFO.hpp
|
||||
sfizz/effects/Compressor.h
|
||||
sfizz/effects/Eq.h
|
||||
sfizz/effects/Filter.h
|
||||
sfizz/effects/Gain.h
|
||||
sfizz/effects/Gate.h
|
||||
sfizz/effects/Limiter.h
|
||||
sfizz/effects/Lofi.h
|
||||
sfizz/effects/Nothing.h
|
||||
|
|
@ -122,6 +128,8 @@ set (SFIZZ_SOURCES
|
|||
sfizz/effects/Apan.cpp
|
||||
sfizz/effects/Lofi.cpp
|
||||
sfizz/effects/Limiter.cpp
|
||||
sfizz/effects/Compressor.cpp
|
||||
sfizz/effects/Gate.cpp
|
||||
sfizz/effects/Strings.cpp
|
||||
sfizz/effects/Rectify.cpp
|
||||
sfizz/effects/Gain.cpp
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#include "effects/Apan.h"
|
||||
#include "effects/Lofi.h"
|
||||
#include "effects/Limiter.h"
|
||||
#include "effects/Compressor.h"
|
||||
#include "effects/Gate.h"
|
||||
#include "effects/Strings.h"
|
||||
#include "effects/Rectify.h"
|
||||
#include "effects/Gain.h"
|
||||
|
|
@ -31,6 +33,8 @@ void EffectFactory::registerStandardEffectTypes()
|
|||
registerEffectType("apan", fx::Apan::makeInstance);
|
||||
registerEffectType("lofi", fx::Lofi::makeInstance);
|
||||
registerEffectType("limiter", fx::Limiter::makeInstance);
|
||||
registerEffectType("comp", fx::Compressor::makeInstance);
|
||||
registerEffectType("gate", fx::Gate::makeInstance);
|
||||
registerEffectType("strings", fx::Strings::makeInstance);
|
||||
|
||||
// extensions (book)
|
||||
|
|
|
|||
204
src/sfizz/effects/Compressor.cpp
Normal file
204
src/sfizz/effects/Compressor.cpp
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// license. You should have receive a LICENSE.md file along with the code.
|
||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
/*
|
||||
Note(jpc): implementation status
|
||||
|
||||
- [x] comp_gain Gain (dB)
|
||||
- [x] comp_attack Attack time (s)
|
||||
- [x] comp_release Release time (s)
|
||||
- [x] comp_ratio Ratio (linear gain)
|
||||
- [x] comp_threshold Threshold (dB)
|
||||
- [x] comp_stlink Stereo link (boolean)
|
||||
|
||||
*/
|
||||
|
||||
#include "Compressor.h"
|
||||
#include "Opcode.h"
|
||||
#include "AudioSpan.h"
|
||||
#include "MathHelpers.h"
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
static constexpr int _oversampling = 2;
|
||||
#define FAUST_UIMACROS 1
|
||||
#include "gen/compressor.cxx"
|
||||
|
||||
namespace sfz {
|
||||
namespace fx {
|
||||
|
||||
struct Compressor::Impl {
|
||||
faustCompressor _compressor[2];
|
||||
bool _stlink = false;
|
||||
float _inputGain = 1.0;
|
||||
AudioBuffer<float, 2> _tempBuffer2x { 2, _oversampling * config::defaultSamplesPerBlock };
|
||||
AudioBuffer<float, 2> _gain2x { 2, _oversampling * config::defaultSamplesPerBlock };
|
||||
hiir::Downsampler2xFpu<12> _downsampler2x[EffectChannels];
|
||||
hiir::Upsampler2xFpu<12> _upsampler2x[EffectChannels];
|
||||
|
||||
#define DEFINE_SET_GET(type, ident, name, var, def, min, max, step) \
|
||||
float get_##ident(size_t i) const noexcept { return _compressor[i].var; } \
|
||||
void set_##ident(size_t i, float value) noexcept { _compressor[i].var = value; }
|
||||
FAUST_LIST_ACTIVES(DEFINE_SET_GET);
|
||||
#undef DEFINE_SET_GET
|
||||
};
|
||||
|
||||
Compressor::Compressor()
|
||||
: _impl(new Impl)
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
for (faustCompressor& comp : impl._compressor)
|
||||
comp.instanceResetUserInterface();
|
||||
}
|
||||
|
||||
Compressor::~Compressor()
|
||||
{
|
||||
}
|
||||
|
||||
void Compressor::setSampleRate(double sampleRate)
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
for (faustCompressor& comp : impl._compressor) {
|
||||
comp.classInit(sampleRate);
|
||||
comp.instanceConstants(sampleRate);
|
||||
}
|
||||
|
||||
static constexpr double coefs2x[12] = { 0.036681502163648017, 0.13654762463195794, 0.27463175937945444, 0.42313861743656711, 0.56109869787919531, 0.67754004997416184, 0.76974183386322703, 0.83988962484963892, 0.89226081800387902, 0.9315419599631839, 0.96209454837808417, 0.98781637073289585 };
|
||||
|
||||
for (unsigned c = 0; c < EffectChannels; ++c) {
|
||||
impl._downsampler2x[c].set_coefs(coefs2x);
|
||||
impl._upsampler2x[c].set_coefs(coefs2x);
|
||||
}
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
void Compressor::setSamplesPerBlock(int samplesPerBlock)
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
impl._tempBuffer2x.resize(_oversampling * samplesPerBlock);
|
||||
impl._gain2x.resize(_oversampling * samplesPerBlock);
|
||||
}
|
||||
|
||||
void Compressor::clear()
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
for (faustCompressor& comp : impl._compressor)
|
||||
comp.instanceClear();
|
||||
}
|
||||
|
||||
void Compressor::process(const float* const inputs[], float* const outputs[], unsigned nframes)
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
auto inOut2x = AudioSpan<float>(impl._tempBuffer2x).first(_oversampling * nframes);
|
||||
|
||||
absl::Span<float> left2x = inOut2x.getSpan(0);
|
||||
absl::Span<float> right2x = inOut2x.getSpan(1);
|
||||
|
||||
impl._upsampler2x[0].process_block(left2x.data(), inputs[0], nframes);
|
||||
impl._upsampler2x[1].process_block(right2x.data(), inputs[1], nframes);
|
||||
|
||||
const float inputGain = impl._inputGain;
|
||||
for (unsigned i = 0; i < _oversampling * nframes; ++i) {
|
||||
left2x[i] *= inputGain;
|
||||
right2x[i] *= inputGain;
|
||||
}
|
||||
|
||||
if (!impl._stlink) {
|
||||
absl::Span<float> leftGain2x = impl._gain2x.getSpan(0);
|
||||
absl::Span<float> rightGain2x = impl._gain2x.getSpan(1);
|
||||
|
||||
{
|
||||
faustCompressor& comp = impl._compressor[0];
|
||||
float* inputs[] = { left2x.data() };
|
||||
float* outputs[] = { leftGain2x.data() };
|
||||
comp.compute(_oversampling * nframes, inputs, outputs);
|
||||
}
|
||||
|
||||
{
|
||||
faustCompressor& comp = impl._compressor[1];
|
||||
float* inputs[] = { right2x.data() };
|
||||
float* outputs[] = { rightGain2x.data() };
|
||||
comp.compute(_oversampling * nframes, inputs, outputs);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < _oversampling * nframes; ++i) {
|
||||
left2x[i] *= leftGain2x[i];
|
||||
right2x[i] *= rightGain2x[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
absl::Span<float> compIn2x = impl._gain2x.getSpan(0);
|
||||
for (unsigned i = 0; i < _oversampling * nframes; ++i)
|
||||
compIn2x[i] = std::abs(left2x[i]) + std::abs(right2x[1]);
|
||||
|
||||
absl::Span<float> gain2x = impl._gain2x.getSpan(1);
|
||||
|
||||
{
|
||||
faustCompressor& comp = impl._compressor[0];
|
||||
float* inputs[] = { compIn2x.data() };
|
||||
float* outputs[] = { gain2x.data() };
|
||||
comp.compute(_oversampling * nframes, inputs, outputs);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < _oversampling * nframes; ++i) {
|
||||
left2x[i] *= gain2x[i];
|
||||
right2x[i] *= gain2x[i];
|
||||
}
|
||||
}
|
||||
|
||||
impl._downsampler2x[0].process_block(outputs[0], left2x.data(), nframes);
|
||||
impl._downsampler2x[1].process_block(outputs[1], right2x.data(), nframes);
|
||||
}
|
||||
|
||||
std::unique_ptr<Effect> Compressor::makeInstance(absl::Span<const Opcode> members)
|
||||
{
|
||||
Compressor* compressor = new Compressor;
|
||||
std::unique_ptr<Effect> fx { compressor };
|
||||
|
||||
Impl& impl = *compressor->_impl;
|
||||
|
||||
for (const Opcode& opc : members) {
|
||||
switch (opc.lettersOnlyHash) {
|
||||
case hash("comp_attack"):
|
||||
if (auto value = readOpcode<float>(opc.value, {0.0, 10.0})) {
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Attack(c, *value);
|
||||
}
|
||||
break;
|
||||
case hash("comp_release"):
|
||||
if (auto value = readOpcode<float>(opc.value, {0.0, 10.0})) {
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Release(c, *value);
|
||||
}
|
||||
break;
|
||||
case hash("comp_threshold"):
|
||||
if (auto value = readOpcode<float>(opc.value, {-100.0, 0.0})) {
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Threshold(c, *value);
|
||||
}
|
||||
break;
|
||||
case hash("comp_ratio"):
|
||||
if (auto value = readOpcode<float>(opc.value, {1.0, 50.0})) {
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Ratio(c, *value);
|
||||
}
|
||||
break;
|
||||
case hash("comp_gain"):
|
||||
if (auto value = readOpcode<float>(opc.value, {-100.0, 100.0}))
|
||||
impl._inputGain = db2mag(*value);
|
||||
break;
|
||||
case hash("comp_stlink"):
|
||||
if (auto value = readBooleanFromOpcode(opc))
|
||||
impl._stlink = *value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return fx;
|
||||
}
|
||||
|
||||
} // namespace fx
|
||||
} // namespace sfz
|
||||
56
src/sfizz/effects/Compressor.h
Normal file
56
src/sfizz/effects/Compressor.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// license. You should have receive a LICENSE.md file along with the code.
|
||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#pragma once
|
||||
#include "Effects.h"
|
||||
#include "hiir/Downsampler2xFpu.h"
|
||||
#include "hiir/Upsampler2xFpu.h"
|
||||
#include <memory>
|
||||
|
||||
namespace sfz {
|
||||
namespace fx {
|
||||
|
||||
/**
|
||||
* @brief Compressor effect
|
||||
*/
|
||||
class Compressor : public Effect {
|
||||
public:
|
||||
Compressor();
|
||||
~Compressor();
|
||||
|
||||
/**
|
||||
* @brief Initializes with the given sample rate.
|
||||
*/
|
||||
void setSampleRate(double sampleRate) override;
|
||||
|
||||
/**
|
||||
* @brief Sets the maximum number of frames to render at a time. The actual
|
||||
* value can be lower but should never be higher.
|
||||
*/
|
||||
void setSamplesPerBlock(int samplesPerBlock) override;
|
||||
|
||||
/**
|
||||
* @brief Reset the state to initial.
|
||||
*/
|
||||
void clear() override;
|
||||
|
||||
/**
|
||||
* @brief Computes a cycle of the effect in stereo.
|
||||
*/
|
||||
void process(const float* const inputs[], float* const outputs[], unsigned nframes) override;
|
||||
|
||||
/**
|
||||
* @brief Instantiates given the contents of the <effect> block.
|
||||
*/
|
||||
static std::unique_ptr<Effect> makeInstance(absl::Span<const Opcode> members);
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> _impl;
|
||||
};
|
||||
|
||||
} // namespace fx
|
||||
} // namespace sfz
|
||||
203
src/sfizz/effects/Gate.cpp
Normal file
203
src/sfizz/effects/Gate.cpp
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// license. You should have receive a LICENSE.md file along with the code.
|
||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
/*
|
||||
Note(jpc): implementation status
|
||||
|
||||
- [x] gate_attack Attack time (s)
|
||||
- [x] gate_release Release time (s)
|
||||
- [x] gate_threshold Threshold (dB)
|
||||
- [x] gate_stlink Stereo link (boolean)
|
||||
- [ ] gate_onccN Gate manual control (% - 0%=gate open, 100%=gate closed)
|
||||
|
||||
Sfizz Extra
|
||||
|
||||
- [x] gate_hold Hold time (s)
|
||||
|
||||
*/
|
||||
|
||||
#include "Gate.h"
|
||||
#include "Opcode.h"
|
||||
#include "AudioSpan.h"
|
||||
#include "MathHelpers.h"
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
static constexpr int _oversampling = 2;
|
||||
#define FAUST_UIMACROS 1
|
||||
#include "gen/gate.cxx"
|
||||
|
||||
namespace sfz {
|
||||
namespace fx {
|
||||
|
||||
struct Gate::Impl {
|
||||
faustGate _gate[2];
|
||||
bool _stlink = false;
|
||||
float _inputGain = 1.0;
|
||||
AudioBuffer<float, 2> _tempBuffer2x { 2, _oversampling * config::defaultSamplesPerBlock };
|
||||
AudioBuffer<float, 2> _gain2x { 2, _oversampling * config::defaultSamplesPerBlock };
|
||||
hiir::Downsampler2xFpu<12> _downsampler2x[EffectChannels];
|
||||
hiir::Upsampler2xFpu<12> _upsampler2x[EffectChannels];
|
||||
|
||||
#define DEFINE_SET_GET(type, ident, name, var, def, min, max, step) \
|
||||
float get_##ident(size_t i) const noexcept { return _gate[i].var; } \
|
||||
void set_##ident(size_t i, float value) noexcept { _gate[i].var = value; }
|
||||
FAUST_LIST_ACTIVES(DEFINE_SET_GET);
|
||||
#undef DEFINE_SET_GET
|
||||
};
|
||||
|
||||
Gate::Gate()
|
||||
: _impl(new Impl)
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
for (faustGate& gate : impl._gate)
|
||||
gate.instanceResetUserInterface();
|
||||
}
|
||||
|
||||
Gate::~Gate()
|
||||
{
|
||||
}
|
||||
|
||||
void Gate::setSampleRate(double sampleRate)
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
for (faustGate& gate : impl._gate) {
|
||||
gate.classInit(sampleRate);
|
||||
gate.instanceConstants(sampleRate);
|
||||
}
|
||||
|
||||
static constexpr double coefs2x[12] = { 0.036681502163648017, 0.13654762463195794, 0.27463175937945444, 0.42313861743656711, 0.56109869787919531, 0.67754004997416184, 0.76974183386322703, 0.83988962484963892, 0.89226081800387902, 0.9315419599631839, 0.96209454837808417, 0.98781637073289585 };
|
||||
|
||||
for (unsigned c = 0; c < EffectChannels; ++c) {
|
||||
impl._downsampler2x[c].set_coefs(coefs2x);
|
||||
impl._upsampler2x[c].set_coefs(coefs2x);
|
||||
}
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
void Gate::setSamplesPerBlock(int samplesPerBlock)
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
impl._tempBuffer2x.resize(_oversampling * samplesPerBlock);
|
||||
impl._gain2x.resize(_oversampling * samplesPerBlock);
|
||||
}
|
||||
|
||||
void Gate::clear()
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
for (faustGate& gate : impl._gate)
|
||||
gate.instanceClear();
|
||||
}
|
||||
|
||||
void Gate::process(const float* const inputs[], float* const outputs[], unsigned nframes)
|
||||
{
|
||||
Impl& impl = *_impl;
|
||||
auto inOut2x = AudioSpan<float>(impl._tempBuffer2x).first(_oversampling * nframes);
|
||||
|
||||
absl::Span<float> left2x = inOut2x.getSpan(0);
|
||||
absl::Span<float> right2x = inOut2x.getSpan(1);
|
||||
|
||||
impl._upsampler2x[0].process_block(left2x.data(), inputs[0], nframes);
|
||||
impl._upsampler2x[1].process_block(right2x.data(), inputs[1], nframes);
|
||||
|
||||
const float inputGain = impl._inputGain;
|
||||
for (unsigned i = 0; i < _oversampling * nframes; ++i) {
|
||||
left2x[i] *= inputGain;
|
||||
right2x[i] *= inputGain;
|
||||
}
|
||||
|
||||
if (!impl._stlink) {
|
||||
absl::Span<float> leftGain2x = impl._gain2x.getSpan(0);
|
||||
absl::Span<float> rightGain2x = impl._gain2x.getSpan(1);
|
||||
|
||||
{
|
||||
faustGate& gate = impl._gate[0];
|
||||
float* inputs[] = { left2x.data() };
|
||||
float* outputs[] = { leftGain2x.data() };
|
||||
gate.compute(_oversampling * nframes, inputs, outputs);
|
||||
}
|
||||
|
||||
{
|
||||
faustGate& gate = impl._gate[1];
|
||||
float* inputs[] = { right2x.data() };
|
||||
float* outputs[] = { rightGain2x.data() };
|
||||
gate.compute(_oversampling * nframes, inputs, outputs);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < _oversampling * nframes; ++i) {
|
||||
left2x[i] *= leftGain2x[i];
|
||||
right2x[i] *= rightGain2x[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
absl::Span<float> gateIn2x = impl._gain2x.getSpan(0);
|
||||
for (unsigned i = 0; i < _oversampling * nframes; ++i)
|
||||
gateIn2x[i] = std::abs(left2x[i]) + std::abs(right2x[1]);
|
||||
|
||||
absl::Span<float> gain2x = impl._gain2x.getSpan(1);
|
||||
|
||||
{
|
||||
faustGate& gate = impl._gate[0];
|
||||
float* inputs[] = { gateIn2x.data() };
|
||||
float* outputs[] = { gain2x.data() };
|
||||
gate.compute(_oversampling * nframes, inputs, outputs);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < _oversampling * nframes; ++i) {
|
||||
left2x[i] *= gain2x[i];
|
||||
right2x[i] *= gain2x[i];
|
||||
}
|
||||
}
|
||||
|
||||
impl._downsampler2x[0].process_block(outputs[0], left2x.data(), nframes);
|
||||
impl._downsampler2x[1].process_block(outputs[1], right2x.data(), nframes);
|
||||
}
|
||||
|
||||
std::unique_ptr<Effect> Gate::makeInstance(absl::Span<const Opcode> members)
|
||||
{
|
||||
Gate* gate = new Gate;
|
||||
std::unique_ptr<Effect> fx { gate };
|
||||
|
||||
Impl& impl = *gate->_impl;
|
||||
|
||||
for (const Opcode& opc : members) {
|
||||
switch (opc.lettersOnlyHash) {
|
||||
case hash("gate_attack"):
|
||||
if (auto value = readOpcode<float>(opc.value, {0.0, 10.0})) {
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Attack(c, *value);
|
||||
}
|
||||
break;
|
||||
case hash("gate_hold"):
|
||||
if (auto value = readOpcode<float>(opc.value, {0.0, 10.0})) {
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Hold(c, *value);
|
||||
}
|
||||
break;
|
||||
case hash("gate_release"):
|
||||
if (auto value = readOpcode<float>(opc.value, {0.0, 10.0})) {
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Release(c, *value);
|
||||
}
|
||||
break;
|
||||
case hash("gate_threshold"):
|
||||
if (auto value = readOpcode<float>(opc.value, {-100.0, 0.0})) {
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Threshold(c, *value);
|
||||
}
|
||||
break;
|
||||
case hash("gate_stlink"):
|
||||
if (auto value = readBooleanFromOpcode(opc))
|
||||
impl._stlink = *value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return fx;
|
||||
}
|
||||
|
||||
} // namespace fx
|
||||
} // namespace sfz
|
||||
56
src/sfizz/effects/Gate.h
Normal file
56
src/sfizz/effects/Gate.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// license. You should have receive a LICENSE.md file along with the code.
|
||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#pragma once
|
||||
#include "Effects.h"
|
||||
#include "hiir/Downsampler2xFpu.h"
|
||||
#include "hiir/Upsampler2xFpu.h"
|
||||
#include <memory>
|
||||
|
||||
namespace sfz {
|
||||
namespace fx {
|
||||
|
||||
/**
|
||||
* @brief Gate effect
|
||||
*/
|
||||
class Gate : public Effect {
|
||||
public:
|
||||
Gate();
|
||||
~Gate();
|
||||
|
||||
/**
|
||||
* @brief Initializes with the given sample rate.
|
||||
*/
|
||||
void setSampleRate(double sampleRate) override;
|
||||
|
||||
/**
|
||||
* @brief Sets the maximum number of frames to render at a time. The actual
|
||||
* value can be lower but should never be higher.
|
||||
*/
|
||||
void setSamplesPerBlock(int samplesPerBlock) override;
|
||||
|
||||
/**
|
||||
* @brief Reset the state to initial.
|
||||
*/
|
||||
void clear() override;
|
||||
|
||||
/**
|
||||
* @brief Computes a cycle of the effect in stereo.
|
||||
*/
|
||||
void process(const float* const inputs[], float* const outputs[], unsigned nframes) override;
|
||||
|
||||
/**
|
||||
* @brief Instantiates given the contents of the <effect> block.
|
||||
*/
|
||||
static std::unique_ptr<Effect> makeInstance(absl::Span<const Opcode> members);
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> _impl;
|
||||
};
|
||||
|
||||
} // namespace fx
|
||||
} // namespace sfz
|
||||
11
src/sfizz/effects/dsp/compressor.dsp
Normal file
11
src/sfizz/effects/dsp/compressor.dsp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import("stdfaust.lib");
|
||||
|
||||
cgain = co.compression_gain_mono(ratio, thresh, att, rel) with {
|
||||
ratio = hslider("[1] Ratio", 1.0, 1.0, 20.0, 0.01);
|
||||
thresh = hslider("[2] Threshold [unit:dB]", 0.0, -60.0, 0.0, 0.01);
|
||||
over = fconstant(int _oversampling, <math.h>);
|
||||
att = hslider("[3] Attack [unit:s]", 0.0, 0.0, 0.5, 1e-3) : *(over);
|
||||
rel = hslider("[4] Release [unit:s]", 0.0, 0.0, 5.0, 1e-3) : *(over);
|
||||
};
|
||||
|
||||
process = cgain;
|
||||
11
src/sfizz/effects/dsp/gate.dsp
Normal file
11
src/sfizz/effects/dsp/gate.dsp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import("stdfaust.lib");
|
||||
|
||||
ggain = ef.gate_gain_mono(thresh, att, hold, rel) with {
|
||||
thresh = hslider("[1] Threshold [unit:dB]", 0.0, -60.0, 0.0, 0.01);
|
||||
over = fconstant(int _oversampling, <math.h>);
|
||||
att = hslider("[2] Attack [unit:s]", 0.0, 0.0, 10.0, 1e-3) : *(over);
|
||||
hold = hslider("[3] Hold [unit:s]", 0.0, 0.0, 10.0, 1e-3) : *(over);
|
||||
rel = hslider("[4] Release [unit:s]", 0.0, 0.0, 5.0, 1e-3) : *(over);
|
||||
};
|
||||
|
||||
process = ggain;
|
||||
180
src/sfizz/effects/gen/compressor.cxx
Normal file
180
src/sfizz/effects/gen/compressor.cxx
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
/* ------------------------------------------------------------
|
||||
name: "compressor"
|
||||
Code generated with Faust 2.27.2 (https://faust.grame.fr)
|
||||
Compilation options: -lang cpp -inpl -scal -ftz 0
|
||||
------------------------------------------------------------ */
|
||||
|
||||
#ifndef __faustCompressor_H__
|
||||
#define __faustCompressor_H__
|
||||
|
||||
#ifndef FAUSTFLOAT
|
||||
#define FAUSTFLOAT float
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#ifndef FAUSTCLASS
|
||||
#define FAUSTCLASS faustCompressor
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define exp10f __exp10f
|
||||
#define exp10 __exp10
|
||||
#endif
|
||||
|
||||
class faustCompressor {
|
||||
|
||||
public:
|
||||
|
||||
float fConst0;
|
||||
float fConst1;
|
||||
FAUSTFLOAT fHslider0;
|
||||
int fSampleRate;
|
||||
float fConst2;
|
||||
FAUSTFLOAT fHslider1;
|
||||
FAUSTFLOAT fHslider2;
|
||||
float fRec2[2];
|
||||
float fRec1[2];
|
||||
FAUSTFLOAT fHslider3;
|
||||
float fRec0[2];
|
||||
|
||||
public:
|
||||
|
||||
void metadata() {
|
||||
}
|
||||
|
||||
int getNumInputs() {
|
||||
return 1;
|
||||
}
|
||||
int getNumOutputs() {
|
||||
return 1;
|
||||
}
|
||||
int getInputRate(int channel) {
|
||||
int rate;
|
||||
switch ((channel)) {
|
||||
case 0: {
|
||||
rate = 1;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
rate = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
int getOutputRate(int channel) {
|
||||
int rate;
|
||||
switch ((channel)) {
|
||||
case 0: {
|
||||
rate = 1;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
rate = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
|
||||
static void classInit(int sample_rate) {
|
||||
}
|
||||
|
||||
void instanceConstants(int sample_rate) {
|
||||
fSampleRate = sample_rate;
|
||||
fConst0 = float(_oversampling);
|
||||
fConst1 = (0.5f * fConst0);
|
||||
fConst2 = (1.0f / std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate))));
|
||||
}
|
||||
|
||||
void instanceResetUserInterface() {
|
||||
fHslider0 = FAUSTFLOAT(0.0f);
|
||||
fHslider1 = FAUSTFLOAT(1.0f);
|
||||
fHslider2 = FAUSTFLOAT(0.0f);
|
||||
fHslider3 = FAUSTFLOAT(0.0f);
|
||||
}
|
||||
|
||||
void instanceClear() {
|
||||
for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
|
||||
fRec2[l0] = 0.0f;
|
||||
}
|
||||
for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
|
||||
fRec1[l1] = 0.0f;
|
||||
}
|
||||
for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
|
||||
fRec0[l2] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void init(int sample_rate) {
|
||||
classInit(sample_rate);
|
||||
instanceInit(sample_rate);
|
||||
}
|
||||
void instanceInit(int sample_rate) {
|
||||
instanceConstants(sample_rate);
|
||||
instanceResetUserInterface();
|
||||
instanceClear();
|
||||
}
|
||||
|
||||
faustCompressor* clone() {
|
||||
return new faustCompressor();
|
||||
}
|
||||
|
||||
int getSampleRate() {
|
||||
return fSampleRate;
|
||||
}
|
||||
|
||||
void buildUserInterface() {
|
||||
}
|
||||
|
||||
void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
|
||||
FAUSTFLOAT* input0 = inputs[0];
|
||||
FAUSTFLOAT* output0 = outputs[0];
|
||||
float fSlow0 = float(fHslider0);
|
||||
float fSlow1 = (fConst1 * fSlow0);
|
||||
int iSlow2 = (std::fabs(fSlow1) < 1.1920929e-07f);
|
||||
float fSlow3 = (iSlow2 ? 0.0f : std::exp((0.0f - (fConst2 / (iSlow2 ? 1.0f : fSlow1)))));
|
||||
float fSlow4 = ((1.0f / std::max<float>(1.00000001e-07f, float(fHslider1))) + -1.0f);
|
||||
float fSlow5 = (fConst0 * fSlow0);
|
||||
int iSlow6 = (std::fabs(fSlow5) < 1.1920929e-07f);
|
||||
float fSlow7 = (iSlow6 ? 0.0f : std::exp((0.0f - (fConst2 / (iSlow6 ? 1.0f : fSlow5)))));
|
||||
float fSlow8 = (fConst0 * float(fHslider2));
|
||||
int iSlow9 = (std::fabs(fSlow8) < 1.1920929e-07f);
|
||||
float fSlow10 = (iSlow9 ? 0.0f : std::exp((0.0f - (fConst2 / (iSlow9 ? 1.0f : fSlow8)))));
|
||||
float fSlow11 = float(fHslider3);
|
||||
float fSlow12 = (1.0f - fSlow3);
|
||||
for (int i = 0; (i < count); i = (i + 1)) {
|
||||
float fTemp0 = float(input0[i]);
|
||||
float fTemp1 = std::fabs(fTemp0);
|
||||
float fTemp2 = ((fRec1[1] > fTemp1) ? fSlow10 : fSlow7);
|
||||
fRec2[0] = ((fRec2[1] * fTemp2) + (fTemp1 * (1.0f - fTemp2)));
|
||||
fRec1[0] = fRec2[0];
|
||||
fRec0[0] = ((fRec0[1] * fSlow3) + (fSlow4 * (std::max<float>(((20.0f * std::log10(fRec1[0])) - fSlow11), 0.0f) * fSlow12)));
|
||||
output0[i] = FAUSTFLOAT(std::pow(10.0f, (0.0500000007f * fRec0[0])));
|
||||
fRec2[1] = fRec2[0];
|
||||
fRec1[1] = fRec1[0];
|
||||
fRec0[1] = fRec0[0];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifdef FAUST_UIMACROS
|
||||
|
||||
|
||||
|
||||
#define FAUST_LIST_ACTIVES(p) \
|
||||
p(HORIZONTALSLIDER, Ratio, "Ratio", fHslider1, 1.0f, 1.0f, 20.0f, 0.01f) \
|
||||
p(HORIZONTALSLIDER, Threshold, "Threshold", fHslider3, 0.0f, -60.0f, 0.0f, 0.01f) \
|
||||
p(HORIZONTALSLIDER, Attack, "Attack", fHslider0, 0.0f, 0.0f, 0.5f, 0.001f) \
|
||||
p(HORIZONTALSLIDER, Release, "Release", fHslider2, 0.0f, 0.0f, 5.0f, 0.001f) \
|
||||
|
||||
#define FAUST_LIST_PASSIVES(p) \
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
195
src/sfizz/effects/gen/gate.cxx
Normal file
195
src/sfizz/effects/gen/gate.cxx
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/* ------------------------------------------------------------
|
||||
name: "gate"
|
||||
Code generated with Faust 2.27.2 (https://faust.grame.fr)
|
||||
Compilation options: -lang cpp -inpl -scal -ftz 0
|
||||
------------------------------------------------------------ */
|
||||
|
||||
#ifndef __faustGate_H__
|
||||
#define __faustGate_H__
|
||||
|
||||
#ifndef FAUSTFLOAT
|
||||
#define FAUSTFLOAT float
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#ifndef FAUSTCLASS
|
||||
#define FAUSTCLASS faustGate
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define exp10f __exp10f
|
||||
#define exp10 __exp10
|
||||
#endif
|
||||
|
||||
class faustGate {
|
||||
|
||||
public:
|
||||
|
||||
float fConst0;
|
||||
FAUSTFLOAT fHslider0;
|
||||
FAUSTFLOAT fHslider1;
|
||||
int fSampleRate;
|
||||
float fConst1;
|
||||
float fConst2;
|
||||
float fRec3[2];
|
||||
FAUSTFLOAT fHslider2;
|
||||
int iVec0[2];
|
||||
float fConst3;
|
||||
FAUSTFLOAT fHslider3;
|
||||
int iRec4[2];
|
||||
float fRec1[2];
|
||||
float fRec0[2];
|
||||
|
||||
public:
|
||||
|
||||
void metadata() {
|
||||
}
|
||||
|
||||
int getNumInputs() {
|
||||
return 1;
|
||||
}
|
||||
int getNumOutputs() {
|
||||
return 1;
|
||||
}
|
||||
int getInputRate(int channel) {
|
||||
int rate;
|
||||
switch ((channel)) {
|
||||
case 0: {
|
||||
rate = 1;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
rate = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
int getOutputRate(int channel) {
|
||||
int rate;
|
||||
switch ((channel)) {
|
||||
case 0: {
|
||||
rate = 1;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
rate = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
|
||||
static void classInit(int sample_rate) {
|
||||
}
|
||||
|
||||
void instanceConstants(int sample_rate) {
|
||||
fSampleRate = sample_rate;
|
||||
fConst0 = float(_oversampling);
|
||||
fConst1 = std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
|
||||
fConst2 = (1.0f / fConst1);
|
||||
fConst3 = (fConst1 * fConst0);
|
||||
}
|
||||
|
||||
void instanceResetUserInterface() {
|
||||
fHslider0 = FAUSTFLOAT(0.0f);
|
||||
fHslider1 = FAUSTFLOAT(0.0f);
|
||||
fHslider2 = FAUSTFLOAT(0.0f);
|
||||
fHslider3 = FAUSTFLOAT(0.0f);
|
||||
}
|
||||
|
||||
void instanceClear() {
|
||||
for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
|
||||
fRec3[l0] = 0.0f;
|
||||
}
|
||||
for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
|
||||
iVec0[l1] = 0;
|
||||
}
|
||||
for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
|
||||
iRec4[l2] = 0;
|
||||
}
|
||||
for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) {
|
||||
fRec1[l3] = 0.0f;
|
||||
}
|
||||
for (int l4 = 0; (l4 < 2); l4 = (l4 + 1)) {
|
||||
fRec0[l4] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void init(int sample_rate) {
|
||||
classInit(sample_rate);
|
||||
instanceInit(sample_rate);
|
||||
}
|
||||
void instanceInit(int sample_rate) {
|
||||
instanceConstants(sample_rate);
|
||||
instanceResetUserInterface();
|
||||
instanceClear();
|
||||
}
|
||||
|
||||
faustGate* clone() {
|
||||
return new faustGate();
|
||||
}
|
||||
|
||||
int getSampleRate() {
|
||||
return fSampleRate;
|
||||
}
|
||||
|
||||
void buildUserInterface() {
|
||||
}
|
||||
|
||||
void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
|
||||
FAUSTFLOAT* input0 = inputs[0];
|
||||
FAUSTFLOAT* output0 = outputs[0];
|
||||
float fSlow0 = (fConst0 * float(fHslider0));
|
||||
float fSlow1 = (fConst0 * float(fHslider1));
|
||||
float fSlow2 = std::min<float>(fSlow0, fSlow1);
|
||||
int iSlow3 = (std::fabs(fSlow2) < 1.1920929e-07f);
|
||||
float fSlow4 = (iSlow3 ? 0.0f : std::exp((0.0f - (fConst2 / (iSlow3 ? 1.0f : fSlow2)))));
|
||||
float fSlow5 = (1.0f - fSlow4);
|
||||
float fSlow6 = std::pow(10.0f, (0.0500000007f * float(fHslider2)));
|
||||
int iSlow7 = int((fConst3 * float(fHslider3)));
|
||||
int iSlow8 = (std::fabs(fSlow0) < 1.1920929e-07f);
|
||||
float fSlow9 = (iSlow8 ? 0.0f : std::exp((0.0f - (fConst2 / (iSlow8 ? 1.0f : fSlow0)))));
|
||||
int iSlow10 = (std::fabs(fSlow1) < 1.1920929e-07f);
|
||||
float fSlow11 = (iSlow10 ? 0.0f : std::exp((0.0f - (fConst2 / (iSlow10 ? 1.0f : fSlow1)))));
|
||||
for (int i = 0; (i < count); i = (i + 1)) {
|
||||
float fTemp0 = float(input0[i]);
|
||||
fRec3[0] = ((fRec3[1] * fSlow4) + (std::fabs(fTemp0) * fSlow5));
|
||||
float fRec2 = fRec3[0];
|
||||
int iTemp1 = (fRec2 > fSlow6);
|
||||
iVec0[0] = iTemp1;
|
||||
iRec4[0] = std::max<int>(int((iSlow7 * (iTemp1 < iVec0[1]))), int((iRec4[1] + -1)));
|
||||
float fTemp2 = std::fabs(std::max<float>(float(iTemp1), float((iRec4[0] > 0))));
|
||||
float fTemp3 = ((fRec0[1] > fTemp2) ? fSlow11 : fSlow9);
|
||||
fRec1[0] = ((fRec1[1] * fTemp3) + (fTemp2 * (1.0f - fTemp3)));
|
||||
fRec0[0] = fRec1[0];
|
||||
output0[i] = FAUSTFLOAT(fRec0[0]);
|
||||
fRec3[1] = fRec3[0];
|
||||
iVec0[1] = iVec0[0];
|
||||
iRec4[1] = iRec4[0];
|
||||
fRec1[1] = fRec1[0];
|
||||
fRec0[1] = fRec0[0];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifdef FAUST_UIMACROS
|
||||
|
||||
|
||||
|
||||
#define FAUST_LIST_ACTIVES(p) \
|
||||
p(HORIZONTALSLIDER, Threshold, "Threshold", fHslider2, 0.0f, -60.0f, 0.0f, 0.01f) \
|
||||
p(HORIZONTALSLIDER, Attack, "Attack", fHslider0, 0.0f, 0.0f, 10.0f, 0.001f) \
|
||||
p(HORIZONTALSLIDER, Hold, "Hold", fHslider3, 0.0f, 0.0f, 10.0f, 0.001f) \
|
||||
p(HORIZONTALSLIDER, Release, "Release", fHslider1, 0.0f, 0.0f, 5.0f, 0.001f) \
|
||||
|
||||
#define FAUST_LIST_PASSIVES(p) \
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue