Skip to content

Commit

Permalink
Lots of proc updates (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreya-Autumn authored Jun 4, 2024
1 parent 14daae7 commit ec89259
Show file tree
Hide file tree
Showing 8 changed files with 357 additions and 29 deletions.
34 changes: 22 additions & 12 deletions include/sst/voice-effects/delay/StringResonator.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,31 +112,41 @@ template <typename VFXConfig> struct StringResonator : core::VoiceEffectTemplate
.withDecimalPlaces(2)
.withName("Level Two");
case fpOffsetOne:
return pmd()
.asFloat()
.withRange(-48, 48)
.withDefault(0)
.withLinearScaleFormatting("semitones")
.withName("Offset One");
if (keytrackOn)
{
return pmd()
.asFloat()
.withRange(-48, 48)
.withDefault(0)
.withLinearScaleFormatting("semitones")
.withName("Offset One");
}
return pmd().asAudibleFrequency().withName("Frequency One");
case fpOffsetTwo:
return pmd()
.asFloat()
.withRange(-48, 48)
.withDefault(0)
.withLinearScaleFormatting("semitones")
.withName("Offset Two");
if (keytrackOn)
{
return pmd()
.asFloat()
.withRange(-48, 48)
.withDefault(0)
.withLinearScaleFormatting("semitones")
.withName("Offset Two");
}
return pmd().asAudibleFrequency().withName("Frequency Two");
case fpPanOne:
return pmd()
.asPercentBipolar()
.withCustomMinDisplay("L")
.withCustomMaxDisplay("R")
.withCustomDefaultDisplay("C")
.withDefault(-1.f)
.withName("Pan One");
case fpPanTwo:
return pmd()
.asPercentBipolar()
.withCustomMinDisplay("L")
.withCustomMaxDisplay("R")
.withCustomDefaultDisplay("C")
.withDefault(1.f)
.withName("Pan Two");
case fpDecay:
Expand Down
2 changes: 1 addition & 1 deletion include/sst/voice-effects/distortion/BitCrusher.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ template <typename VFXConfig> struct BitCrusher : core::VoiceEffectTemplateBase<
return pmd()
.asFloat()
.withRange(0, 96)
.withName("Samplerate Ratio")
.withName("Samplerate Offset")
.withDefault(96)
.withLinearScaleFormatting("semitones");
}
Expand Down
8 changes: 4 additions & 4 deletions include/sst/voice-effects/filter/StaticPhaser.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,23 +99,23 @@ template <typename VFXConfig> struct StaticPhaser : core::VoiceEffectTemplateBas
return pmd()
.asFloat()
.withRange(-48, 48)
.withName("Offset")
.withName("Offset L")
.withDefault(0)
.withLinearScaleFormatting("semitones");
}
return pmd().asAudibleFrequency().withName(std::string("Freq (L)")).withDefault(0);
return pmd().asAudibleFrequency().withName("Frequency L").withDefault(0);

case fpCenterFrequencyR:
if (keytrackOn)
{
return pmd()
.asFloat()
.withRange(-48, 48)
.withName("Offset")
.withName("Offset R")
.withDefault(0)
.withLinearScaleFormatting("semitones");
}
return pmd().asAudibleFrequency().withName("Freq R").withDefault(0);
return pmd().asAudibleFrequency().withName("Frequency R").withDefault(0);

break;
case fpSpacing:
Expand Down
2 changes: 1 addition & 1 deletion include/sst/voice-effects/generator/GenVA.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ template <typename VFXConfig> struct GenVA : core::VoiceEffectTemplateBase<VFXCo
{
return pmd()
.asFloat()
.withRange(-96, 96)
.withRange(-48, 48)
.withDefault(0)
.withLinearScaleFormatting("semitones")
.withName("Tune");
Expand Down
100 changes: 91 additions & 9 deletions include/sst/voice-effects/modulation/FMFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,26 @@ template <typename VFXConfig> struct FMFilter : core::VoiceEffectTemplateBase<VF
switch (idx)
{
case fpFreqL:
if (keytrackOn)
{
return pmd()
.asFloat()
.withRange(-48, 48)
.withName("Offset L")
.withDefault(0)
.withLinearScaleFormatting("semitones");
}
return pmd().asAudibleFrequency().withName("Frequency L");
case fpFreqR:
if (keytrackOn)
{
return pmd()
.asFloat()
.withRange(-48, 48)
.withName("Offset R")
.withDefault(0)
.withLinearScaleFormatting("semitones");
}
return pmd().asAudibleFrequency().withName("Frequency R");
case fpDepth:
return pmd().asFloat().withRange(0.f, 1.f).withDefault(0.f).withName("FM Depth");
Expand All @@ -91,17 +109,17 @@ template <typename VFXConfig> struct FMFilter : core::VoiceEffectTemplateBase<VF
.withRange(0, 4)
.withName("Mode")
.withUnorderedMapFormatting({
{md::LP, "Low Pass"},
{md::HP, "High Pass"},
{md::BP, "Band Pass"},
{md::NOTCH, "Notch"},
{md::ALL, "All Pass"},
{0, "Lowpass"},
{1, "Highpass"},
{2, "Bandpass"},
{3, "Notch"},
{4, "Allpass"},
})
.withDefault(md::LP);
case ipNum:
return pmd().asInt().withRange(1, 8).withDefault(1).withName("Numerator");
return pmd().asInt().withRange(1, 16).withDefault(1).withName("Numerator");
case ipDenom:
return pmd().asInt().withRange(1, 8).withDefault(1).withName("Denominator");
return pmd().asInt().withRange(1, 16).withDefault(1).withName("Denominator");
}
return pmd().withName("error");
}
Expand All @@ -122,10 +140,44 @@ template <typename VFXConfig> struct FMFilter : core::VoiceEffectTemplateBase<VF
return 12 * std::log2(ratio);
}

typename sst::filters::CytomicSVF::Mode mode = sst::filters::CytomicSVF::Mode::LP;

void whatMode()
{
switch (this->getIntParam(ipMode))
{
case 0:
mode = sst::filters::CytomicSVF::Mode::LP;
break;
case 1:
mode = sst::filters::CytomicSVF::Mode::HP;
break;
case 2:
mode = sst::filters::CytomicSVF::Mode::BP;
break;
case 3:
mode = sst::filters::CytomicSVF::Mode::NOTCH;
break;
case 4:
mode = sst::filters::CytomicSVF::Mode::ALL;
break;
}
}

void processStereo(float *datainL, float *datainR, float *dataoutL, float *dataoutR,
float pitch)
{
auto mode = (sst::filters::CytomicSVF::Mode)(this->getIntParam(ipMode));
if (isFirst)
{
DCfilter.template setCoeffForBlock<VFXConfig::blockSize>(
sst::filters::CytomicSVF::Mode::HP, 18.f, 18.f, 0.5f, 0.5f,
VFXConfig::getSampleRateInv(this), 0.f, 0.f);
isFirst = false;
}
else
{
DCfilter.retainCoeffForBlock<VFXConfig::blockSize>();
}
auto res = std::clamp(this->getFloatParam(fpRes), 0.f, 1.f);
bool stereo = this->getIntParam(ipStereo);

Expand All @@ -141,9 +193,20 @@ template <typename VFXConfig> struct FMFilter : core::VoiceEffectTemplateBase<VF
freqL = 440.0f * this->note_to_pitch_ignoring_tuning(freqL);
freqR = 440.0f * this->note_to_pitch_ignoring_tuning(freqR);

mSinOsc.setRate(440.0 * 2 * M_PI * this->note_to_pitch_ignoring_tuning(pitch + getRatio()) *
float ratio = 1.f;

if (this->getIntParam(ipNum) != priorNum || this->getIntParam(ipDenom) != priorDenom)
{
ratio = getRatio();
}

mSinOsc.setRate(440.0 * 2 * M_PI * this->note_to_pitch_ignoring_tuning(pitch + ratio) *
this->getSampleRateInv());

auto outputL = 0.f;
auto outputR = 0.f;

whatMode();
for (auto i = 0; i < VFXConfig::blockSize; ++i)
{
float inL = datainL[i];
Expand All @@ -160,13 +223,26 @@ template <typename VFXConfig> struct FMFilter : core::VoiceEffectTemplateBase<VF
0.f, 0.f);
sst::filters::CytomicSVF::step(filter, inL, inR);

DCfilter.processBlockStep(inL, inR);

dataoutL[i] = inL;
dataoutR[i] = inR;
}
}

void processMonoToMono(float *datainL, float *dataoutL, float pitch)
{
if (isFirst)
{
DCfilter.template setCoeffForBlock<VFXConfig::blockSize>(
sst::filters::CytomicSVF::Mode::HP, 18.f, 0.5f, VFXConfig::getSampleRateInv(this),
0.f);
isFirst = false;
}
else
{
DCfilter.retainCoeffForBlock<VFXConfig::blockSize>();
}
auto mode = (sst::filters::CytomicSVF::Mode)(this->getIntParam(ipMode));
auto res = std::clamp(this->getFloatParam(fpRes), 0.f, 1.f);
auto depth = std::clamp(this->getFloatParam(fpDepth), 0.f, 1.f);
Expand Down Expand Up @@ -194,6 +270,8 @@ template <typename VFXConfig> struct FMFilter : core::VoiceEffectTemplateBase<VF
filter.setCoeff(mode, modFreq, res, VFXConfig::getSampleRateInv(this), 0.f);
sst::filters::CytomicSVF::step(filter, input, dummyR);

DCfilter.processBlockStep(input);

dataoutL[i] = input;
}
}
Expand All @@ -216,7 +294,11 @@ template <typename VFXConfig> struct FMFilter : core::VoiceEffectTemplateBase<VF
protected:
bool keytrackOn{false};
sst::filters::CytomicSVF filter;
sst::filters::CytomicSVF DCfilter;
sst::basic_blocks::dsp::QuadratureOscillator<float> mSinOsc;
int priorNum = -1;
int priorDenom = -1;
bool isFirst = true;
};
} // namespace sst::voice_effects::modulation

Expand Down
9 changes: 9 additions & 0 deletions include/sst/voice-effects/modulation/Phaser.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ template <typename VFXConfig> struct Phaser : core::VoiceEffectTemplateBase<VFXC
.withLinearScaleFormatting("%", 100.f)
.withName("Depth");
case fpCenterFreq:
if (keytrackOn)
{
return pmd()
.asFloat()
.withRange(-48, 48)
.withName("Center Freq Offset")
.withDefault(0)
.withLinearScaleFormatting("semitones");
}
return pmd().asAudibleFrequency().withName("Center Frequency").withDefault(0);
}
return pmd().asFloat().withName("Error");
Expand Down
110 changes: 110 additions & 0 deletions include/sst/voice-effects/utilities/VolumeAndPan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* sst-effects - an open source library of audio effects
* built by Surge Synth Team.
*
* Copyright 2018-2023, various authors, as described in the GitHub
* transaction log.
*
* sst-effects is released under the GNU General Public Licence v3
* or later (GPL-3.0-or-later). The license is found in the "LICENSE"
* file in the root of this repository, or at
* https://www.gnu.org/licenses/gpl-3.0.en.html
*
* The majority of these effects at initiation were factored from
* Surge XT, and so git history prior to April 2023 is found in the
* surge repo, https://github.com/surge-synthesizer/surge
*
* All source in sst-effects available at
* https://github.com/surge-synthesizer/sst-effects
*/

#ifndef INCLUDE_SST_VOICE_EFFECTS_MODULATION_VOLUMEANDPAN_H
#define INCLUDE_SST_VOICE_EFFECTS_MODULATION_VOLUMEANDPAN_H

#include "../VoiceEffectCore.h"

#include <iostream>

#include "sst/basic-blocks/params/ParamMetadata.h"
#include "sst/basic-blocks/dsp/PanLaws.h"

namespace sst::voice_effects::utilities
{
template <typename VFXConfig> struct VolumeAndPan : core::VoiceEffectTemplateBase<VFXConfig>
{
static constexpr const char *effectName{"Vol/Pan Utility"};

static constexpr int numFloatParams{2};
static constexpr int numIntParams{0};

enum FloatParams
{
fpVolume,
fpPan,
};

enum IntParams
{
};

VolumeAndPan() : core::VoiceEffectTemplateBase<VFXConfig>() {}

~VolumeAndPan() {}

basic_blocks::params::ParamMetaData paramAt(int idx) const
{
using pmd = basic_blocks::params::ParamMetaData;

switch (idx)
{
case fpVolume:
return pmd().asLinearDecibel(-60.f, 24.f).withDefault(0.f).withName("Volume");
case fpPan:
return pmd()
.asPercentBipolar()
.withCustomMinDisplay("L")
.withCustomMaxDisplay("R")
.withCustomDefaultDisplay("C")
.withDefault(0.f)
.withName("Pan");
}
return pmd().asFloat().withName("Error");
}

// basic_blocks::params::ParamMetaData intParamAt(int idx) const
// {
// using pmd = basic_blocks::params::ParamMetaData;
// return pmd().asInt().withName("Error");
// }

void initVoiceEffect() {}

void initVoiceEffectParams() { this->initToParamMetadataDefault(this); }

void processStereo(float *datainL, float *datainR, float *dataoutL, float *dataoutR,
float pitch)
{
auto outputVolume = this->dbToLinear(this->getFloatParam(fpVolume));
auto pan = (this->getFloatParam(fpPan) + 1) / 2;

basic_blocks::dsp::pan_laws::panmatrix_t pmat{1, 1, 0, 0};

basic_blocks::dsp::pan_laws::stereoEqualPower(pan, pmat);

for (int i = 0; i < VFXConfig::blockSize; i++)
{
auto inL = datainL[i];
auto inR = datainR[i];

dataoutL[i] = inL * pmat[0] * outputVolume;
dataoutR[i] = inR * pmat[1] * outputVolume;
}
}

void processMonoToStereo(float *datainL, float *dataoutL, float *dataoutR, float pitch)
{
processStereo(datainL, datainL, dataoutL, dataoutR, pitch);
}
};
} // namespace sst::voice_effects::utilities
#endif // SCXT_VOLUMEANDPAN_H
Loading

0 comments on commit ec89259

Please sign in to comment.