Browse Source

EvenVCO: remove DC offset from pulse out

Sampling Modulator: avoid processing if outputs/inputs not connected

Misc: updated docs
tags/v2.1.0
hemmer 1 year ago
parent
commit
a342b799db
4 changed files with 52 additions and 24 deletions
  1. +5
    -0
      CHANGELOG.md
  2. +1
    -1
      README.md
  3. +1
    -0
      src/EvenVCO.cpp
  4. +45
    -23
      src/SamplingModulator.cpp

+ 5
- 0
CHANGELOG.md View File

@@ -1,5 +1,10 @@
# Change Log

## v1.2.0 (unreleased)

* Released new modules: Muxlicer, Mex, Morphader, VC ADSR, Sampling Modulator, ST Mix
* Removed DC offset from EvenVCO pulse output

## v1.1.1

* Fixed issue with A*B+C summing logic


+ 1
- 1
README.md View File

@@ -15,4 +15,4 @@ We have tried to make the VCV implementations as authentic as possible, however

* Chopping Kinky hardward is DC coupled, but we add the option (default disabled) to remove this offset.

* The hardware Muxlicer assigns multiple functions to the "Speed Div/Mult" dial, that cannot be reproduced with a single mouse click. Some of these have been moved to the context menu, specifically: quadratic gates, the "All In" normalled voltage, and the input/output clock division/mult. The "Speed Div/Mult" dial remains only as a tap-tempo button.
* The hardware Muxlicer assigns multiple functions to the "Speed Div/Mult" dial, that cannot be reproduced with a single mouse click. Some of these have been moved to the context menu, specifically: quadratic gates, the "All In" normalled voltage, and the input/output clock division/mult. The "Speed Div/Mult" dial remains only for main clock div/mult.

+ 1
- 0
src/EvenVCO.cpp View File

@@ -186,6 +186,7 @@ struct EvenVCO : Module {

square[c / 4] = simd::ifelse((phase[c / 4] < pw[c / 4]), -1.f, +1.f);
square[c / 4] += squareMinBlepOut[c / 4];
square[c / 4] += 2.f * (pw[c / 4] - 0.5); // DC offset correction
square[c / 4] *= 5.f;

// Set outputs


+ 45
- 23
src/SamplingModulator.cpp View File

@@ -104,6 +104,10 @@ struct SamplingModulator : Module {
void process(const ProcessArgs& args) override {
bool advanceStep = false;

const bool isHoldOutRequired = outputs[OUT_OUTPUT].isConnected() && inputs[IN_INPUT].isConnected();
const bool isClockOutRequired = outputs[CLOCK_OUTPUT].isConnected();
const bool isTriggOutRequired = outputs[TRIGG_OUTPUT].isConnected();

if (params[INT_EXT_PARAM].getValue() == CLOCK_EXTERNAL) {
// if external mode, the SYNC/EXT. CLOCK input acts as a clock
advanceStep = clock.process(rescale(inputs[SYNC_INPUT].getVoltage(), 0.1f, 2.f, 0.f, 1.f));
@@ -140,14 +144,17 @@ struct SamplingModulator : Module {
const float minDialFrequency = 1.0f;
const float frequency = minDialFrequency * simd::pow(2.f, pitch);

float oldPhase = stepPhase;
const float oldPhase = stepPhase;
float deltaPhase = clamp(args.sampleTime * frequency, 1e-6f, 0.5f);
stepPhase += deltaPhase;

if (!halfPhase && stepPhase >= 0.5) {

float crossing = -(stepPhase - 0.5) / deltaPhase;
squareMinBlep.insertDiscontinuity(crossing, -2.f);
if (stepStates[currentStep] == STATE_ON) {
if (isClockOutRequired) {
squareMinBlep.insertDiscontinuity(crossing, -2.f);
}
if (isTriggOutRequired && stepStates[currentStep] == STATE_ON) {
triggMinBlep.insertDiscontinuity(crossing, -2.f);
}

@@ -156,8 +163,11 @@ struct SamplingModulator : Module {

if (stepPhase >= 1.0f) {
stepPhase -= 1.0f;
float crossing = -stepPhase / deltaPhase;
squareMinBlep.insertDiscontinuity(crossing, +2.f);

if (isClockOutRequired) {
float crossing = -stepPhase / deltaPhase;
squareMinBlep.insertDiscontinuity(crossing, +2.f);
}

halfPhase = false;

@@ -173,7 +183,8 @@ struct SamplingModulator : Module {
const float crossing = -(oldPhase + deltaPhase - 1.0) / deltaPhase;
triggMinBlep.insertDiscontinuity(crossing, +2.f);
triggerGenerator.trigger();
if (!holdDetector.isHigh()) {

if (!holdDetector.isHigh() && isHoldOutRequired) {
float oldHeldValue = heldValue;
heldValue = inputs[IN_INPUT].getVoltage();
holdMinBlep.insertDiscontinuity(crossing, heldValue - oldHeldValue);
@@ -181,28 +192,39 @@ struct SamplingModulator : Module {
}
}

float output = heldValue + holdMinBlep.process();
outputs[OUT_OUTPUT].setVoltage(output);

float square = (stepPhase < 0.5) ? 2.f : 0.f;
square += squareMinBlep.process();

float trigger = (stepPhase < 0.5 && stepStates[currentStep] == STATE_ON) ? 2.f : 0.f;
trigger += triggMinBlep.process();
const float holdOutput = isHoldOutRequired ? (heldValue + holdMinBlep.process()) : 0.f;
outputs[OUT_OUTPUT].setVoltage(holdOutput);

if (removeDC) {
trigger -= 1.0f;
square -= 1.0f;
if (numEffectiveSteps > 0) {
trigger += (float)(numEffectiveSteps - numActiveSteps) / (numEffectiveSteps);
}
if (isClockOutRequired) {
float square = (stepPhase < 0.5) ? 2.f : 0.f;
square += squareMinBlep.process();
square -= 1.0f * removeDC;
outputs[CLOCK_OUTPUT].setVoltage(5.f * square);
}
else {
outputs[CLOCK_OUTPUT].setVoltage(0.f);
}

outputs[CLOCK_OUTPUT].setVoltage(5.f * square);
if (params[INT_EXT_PARAM].getValue() == CLOCK_INTERNAL) {
outputs[TRIGG_OUTPUT].setVoltage(5.f * trigger);
if (isTriggOutRequired) {
float trigger = (stepPhase < 0.5 && stepStates[currentStep] == STATE_ON) ? 2.f : 0.f;
trigger += triggMinBlep.process();

if (removeDC) {
trigger -= 1.0f;
if (numEffectiveSteps > 0) {
trigger += (float)(numEffectiveSteps - numActiveSteps) / (numEffectiveSteps);
}
}

outputs[TRIGG_OUTPUT].setVoltage(5.f * trigger);
}
else {
outputs[TRIGG_OUTPUT].setVoltage(0.f);
}
}
else {
else {
// if externally clocked, just give standard triggers
outputs[TRIGG_OUTPUT].setVoltage(10.f * triggerGenerator.process(args.sampleTime));
}



Loading…
Cancel
Save