Skip to content

Commit

Permalink
Add a shared 'MonoValues' structure with shared monophonic data
Browse files Browse the repository at this point in the history
Currently includes

- temposync ratio (unused)
- tables

Use those tables to remove final pow 2 calls
  • Loading branch information
baconpaul committed Dec 23, 2024
1 parent 008e014 commit 1a2c853
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 58 deletions.
7 changes: 2 additions & 5 deletions doc/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ SOURCE:
- waveshapes:
- TX waveshapes
- maybe a smoothed-saw and smoothed-square if i can figure out an analytic form i like
- Ratio uses 2^x table rather than pow
- Ratio lerps across block
- 90%-100% of internal nyquist mute fades

MAIN:
Expand All @@ -29,16 +27,15 @@ PRESETS:
- preset scan user directory to make tree

PLAY MODE:
- Voice limit count
- Voice limit count and Voice Count display
- Pitch Bend support
- Portamento maybe

GENERAL AND CLEANUPS
- AM is somehow not quiet right. Signal to zero seems 'no modulation' not 'no output'
- Temposync the LFO
- AM is somehow not quiet right. Signal to zero seems 'no modulation' not 'no output'
- Don't send VU etc when editor not attached
- Edit area says "click a knbo to edit on startup"
- SRProvider uses table, not pow
- LFO in Pulse and S&H need a tiny little LPF to avoid super-clicka

INFRASTRUCTURE:
Expand Down
5 changes: 5 additions & 0 deletions src/clap/six-sines-clap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ struct SixSinesClap : public plugHelper_t, sst::clap_juce_shim::EditorProvider
nextEvent = ev->get(ev, nextEventIndex);
}

if (process->transport)
{
engine->monoValues.tempoSyncRatio = process->transport->tempo / 120.0;
}

float **out = process->audio_outputs[0].data32;

for (auto s = 0U; s < process->frames_count; ++s)
Expand Down
23 changes: 13 additions & 10 deletions src/dsp/matrix_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "dsp/sr_provider.h"
#include "dsp/node_support.h"
#include "synth/patch.h"
#include "synth/mono_values.h"

namespace baconpaul::six_sines
{
Expand All @@ -34,9 +35,10 @@ struct MatrixNodeFrom : public EnvelopeSupport<Patch::MatrixNode>,
{
OpSource &onto, &from;
const float &level, &activeV, &pmrmV, &lfoToDepth, &mulLfoV;
MatrixNodeFrom(const Patch::MatrixNode &mn, OpSource &on, OpSource &fr)
MatrixNodeFrom(const Patch::MatrixNode &mn, OpSource &on, OpSource &fr, const MonoValues &mv)
: onto(on), from(fr), level(mn.level), pmrmV(mn.pmOrRM), activeV(mn.active),
EnvelopeSupport(mn), LFOSupport(mn), lfoToDepth(mn.lfoToDepth), mulLfoV(mn.envLfoSum)
EnvelopeSupport(mn, mv), LFOSupport(mn, mv), lfoToDepth(mn.lfoToDepth),
mulLfoV(mn.envLfoSum)
{
}

Expand Down Expand Up @@ -103,9 +105,9 @@ struct MatrixNodeSelf : EnvelopeSupport<Patch::SelfNode>, LFOSupport<Patch::Self
OpSource &onto;
SRProvider sr;
const float &fbBase, &lfoToFB, &activeV, &lfoMulV;
MatrixNodeSelf(const Patch::SelfNode &sn, OpSource &on)
: onto(on), fbBase(sn.fbLevel), lfoToFB(sn.lfoToFB), activeV(sn.active),
lfoMulV(sn.envLfoSum), EnvelopeSupport(sn), LFOSupport(sn){};
MatrixNodeSelf(const Patch::SelfNode &sn, OpSource &on, const MonoValues &mv)
: sr(mv), onto(on), fbBase(sn.fbLevel), lfoToFB(sn.lfoToFB), activeV(sn.active),
lfoMulV(sn.envLfoSum), EnvelopeSupport(sn, mv), LFOSupport(sn, mv){};
bool active{true}, lfoMul{false};

void attack()
Expand Down Expand Up @@ -155,9 +157,10 @@ struct MixerNode : EnvelopeSupport<Patch::MixerNode>, LFOSupport<Patch::MixerNod
const float &level, &activeF, &pan, &lfoToLevel, &lfoToPan;
bool active{false};

MixerNode(const Patch::MixerNode &mn, OpSource &f)
: from(f), pan(mn.pan), level(mn.level), activeF(mn.active), lfoToLevel(mn.lfoToLevel),
lfoToPan(mn.lfoToPan), EnvelopeSupport(mn), LFOSupport(mn)
MixerNode(const Patch::MixerNode &mn, OpSource &f, const MonoValues &mv)
: sr(mv), from(f), pan(mn.pan), level(mn.level), activeF(mn.active),
lfoToLevel(mn.lfoToLevel), lfoToPan(mn.lfoToPan), EnvelopeSupport(mn, mv),
LFOSupport(mn, mv)
{
memset(output, 0, sizeof(output));
}
Expand Down Expand Up @@ -211,8 +214,8 @@ struct OutputNode : EnvelopeSupport<Patch::OutputNode>

const float &level, &velSen;

OutputNode(const Patch::OutputNode &on, std::array<MixerNode, numOps> &f)
: fromArr(f), level(on.level), velSen(on.velSensitivity), EnvelopeSupport(on)
OutputNode(const Patch::OutputNode &on, std::array<MixerNode, numOps> &f, const MonoValues &mv)
: sr(mv), fromArr(f), level(on.level), velSen(on.velSensitivity), EnvelopeSupport(on, mv)
{
memset(output, 0, sizeof(output));
}
Expand Down
26 changes: 19 additions & 7 deletions src/dsp/node_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "sst/basic-blocks/modulators/SimpleLFO.h"

#include "dsp/sr_provider.h"
#include "synth/mono_values.h"

namespace baconpaul::six_sines
{
Expand All @@ -33,8 +34,8 @@ template <typename T> struct EnvelopeSupport
SRProvider sr;

const float &delay, &attackv, &hold, &decay, &sustain, &release, &powerV;
EnvelopeSupport(const T &mn)
: env(&sr), delay(mn.delay), attackv(mn.attack), hold(mn.hold), decay(mn.decay),
EnvelopeSupport(const T &mn, const MonoValues &mv)
: sr(mv), env(&sr), delay(mn.delay), attackv(mn.attack), hold(mn.hold), decay(mn.decay),
sustain(mn.sustain), release(mn.release), powerV(mn.envPower)
{
}
Expand Down Expand Up @@ -80,24 +81,35 @@ template <typename T> struct EnvelopeSupport
template <typename T> struct LFOSupport
{
SRProvider sr;
const T &paramBundle;
const MonoValues &monoValues;

const float &lfoRate, &lfoDeform, &lfoShape, &lfoActiveV;
const float &lfoRate, &lfoDeform, &lfoShape, &lfoActiveV, &tempoSyncV;
bool active;
sst::basic_blocks::modulators::SimpleLFO<SRProvider, blockSize> lfo;

LFOSupport(const T &mn)
: lfo(&sr), lfoRate(mn.lfoRate), lfoDeform(mn.lfoDeform), lfoShape(mn.lfoShape),
lfoActiveV(mn.lfoActive)
LFOSupport(const T &mn, const MonoValues &mv)
: sr(mv), paramBundle(mn), lfo(&sr), lfoRate(mn.lfoRate), lfoDeform(mn.lfoDeform),
lfoShape(mn.lfoShape), lfoActiveV(mn.lfoActive), tempoSyncV(mn.tempoSync), monoValues(mv)
{
}

int shape;
bool tempoSync{false};
void lfoAttack()
{
tempoSync = tempoSyncV > 0.5;
shape = static_cast<int>(std::round(lfoShape));
lfo.attack(shape);
}
void lfoProcess() { lfo.process_block(lfoRate, lfoDeform, shape); }
void lfoProcess()
{
auto rate = lfoRate;
if (tempoSync)
rate = monoValues.tempoSyncRatio * paramBundle.lfoRate.meta.snapToTemposync(rate);

lfo.process_block(rate, lfoDeform, shape);
}
};
} // namespace baconpaul::six_sines

Expand Down
21 changes: 16 additions & 5 deletions src/dsp/op_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "dsp/sintable.h"
#include "dsp/node_support.h"
#include "synth/patch.h"
#include "synth/mono_values.h"

namespace baconpaul::six_sines
{
Expand All @@ -36,6 +37,8 @@ struct alignas(16) OpSource : public EnvelopeSupport<Patch::SourceNode>,

float output alignas(16)[blockSize];

const MonoValues &monoValues;

bool keytrack{true};
const float &ratio, &activeV, &envToRatio, &lfoToRatio, &lfoByEnv; // in frequency multiple
bool active{false};
Expand All @@ -45,9 +48,10 @@ struct alignas(16) OpSource : public EnvelopeSupport<Patch::SourceNode>,
uint32_t phase;
uint32_t dPhase;

OpSource(const Patch::SourceNode &sn)
: EnvelopeSupport(sn), LFOSupport(sn), ratio(sn.ratio), activeV(sn.active),
envToRatio(sn.envToRatio), lfoToRatio(sn.lfoToRatio), lfoByEnv(sn.envLfoSum)
OpSource(const Patch::SourceNode &sn, const MonoValues &mv)
: monoValues(mv), EnvelopeSupport(sn, mv), LFOSupport(sn, mv), ratio(sn.ratio),
activeV(sn.active), envToRatio(sn.envToRatio), lfoToRatio(sn.lfoToRatio),
lfoByEnv(sn.envLfoSum)
{
reset();
}
Expand Down Expand Up @@ -79,6 +83,7 @@ struct alignas(16) OpSource : public EnvelopeSupport<Patch::SourceNode>,
float baseFrequency{0};
void setBaseFrequency(float freq) { baseFrequency = freq; }

float priorRF{-10000000};
void renderBlock(bool gated)
{
if (!active)
Expand All @@ -92,12 +97,18 @@ struct alignas(16) OpSource : public EnvelopeSupport<Patch::SourceNode>,
lfoProcess();
auto lfoFac = lfoByEnv > 0.5 ? env.output : 1.f;

auto rf =
pow(2.f, ratio + envToRatio * env.output + lfoFac * lfoToRatio * lfo.outputBlock[0]);
auto rf = monoValues.twoToTheX.twoToThe(ratio + envToRatio * env.output +
lfoFac * lfoToRatio * lfo.outputBlock[0]);
if (priorRF < -10000)
priorRF = rf;
auto dRF = (priorRF - rf) / blockSize;
std::swap(rf, priorRF);

for (int i = 0; i < blockSize; ++i)
{
dPhase = st.dPhase(baseFrequency * rf);
rf += dRF;

phase += dPhase;
auto fb = 0.5 * (fbVal[0] + fbVal[1]);
auto out = st.at(phase + phaseInput[i] + (int32_t)(feedbackLevel[i] * fb)) * rmLevel[i];
Expand Down
8 changes: 7 additions & 1 deletion src/dsp/sr_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@
#define BACONPAUL_SIX_SINES_DSP_SR_PROVIDER_H

#include "configuration.h"
#include "synth/mono_values.h"

namespace baconpaul::six_sines
{
struct SRProvider
{
float envelope_rate_linear_nowrap(float f) { return (blockSize / gSampleRate) * pow(2.0, -f); }
const MonoValues &monoValues;
SRProvider(const MonoValues &mv) : monoValues(mv) {}
float envelope_rate_linear_nowrap(float f)
{
return (blockSize / gSampleRate) * monoValues.twoToTheX.twoToThe(-f);
}
static constexpr float samplerate{gSampleRate};
};
} // namespace baconpaul::six_sines
Expand Down
42 changes: 42 additions & 0 deletions src/synth/mono_values.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Six Sines
*
* A synth with audio rate modulation.
*
* Copyright 2024, Paul Walker and Various authors, as described in the github
* transaction log.
*
* This source repo is released under the MIT license, but has
* GPL3 dependencies, as such the combined work will be
* released under GPL3.
*
* The source code and license are at https://github.com/baconpaul/six-sines
*/

#ifndef BACONPAUL_SIX_SINES_SYNTH_MONO_VALUES_H
#define BACONPAUL_SIX_SINES_SYNTH_MONO_VALUES_H

#include <sst/basic-blocks/tables/EqualTuningProvider.h>
#include <sst/basic-blocks/tables/TwoToTheXProvider.h>

struct MTSClient;

namespace baconpaul::six_sines
{
struct MonoValues
{
MonoValues()
{
tuningProvider.init();
twoToTheX.init();
}

float tempoSyncRatio{1};

MTSClient *mtsClient{nullptr};

sst::basic_blocks::tables::EqualTuningProvider tuningProvider;
sst::basic_blocks::tables::TwoToTheXProvider twoToTheX;
};
}; // namespace baconpaul::six_sines
#endif // MONO_VALUES_H
11 changes: 9 additions & 2 deletions src/synth/patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,24 @@ struct Patch
.withDefault(true)
.withID(id0 + 4)
.withName(name + " LFO Active")
.withGroupName(name))
.withGroupName(name)),
tempoSync(md_t() // non-automatable
.asBool()
.withID(id0 + 5)
.withName(name + " Temposync")
.withGroupName(name)
.withDefault(false))
{
}

Param lfoRate, lfoDeform, lfoShape, lfoActive;
Param lfoRate, lfoDeform, lfoShape, lfoActive, tempoSync;

void appendLFOParams(std::vector<Param *> &res)
{
res.push_back(&lfoRate);
res.push_back(&lfoDeform);
res.push_back(&lfoShape);
res.push_back(&tempoSync);
}
};

Expand Down
9 changes: 4 additions & 5 deletions src/synth/synth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,19 @@ namespace sdsp = sst::basic_blocks::dsp;

Synth::Synth()
: responder(*this),
voices(sst::cpputils::make_array<Voice, VMConfig::maxVoiceCount>(patch, tuningProvider))
voices(sst::cpputils::make_array<Voice, VMConfig::maxVoiceCount>(patch, monoValues))
{
tuningProvider.init();
voiceManager = std::make_unique<voiceManager_t>(responder, monoResponder);
lagHandler.setRate(60, blockSize, gSampleRate);
vuPeak.setSampleRate(gSampleRate);
mtsClient = MTS_RegisterClient();
monoValues.mtsClient = MTS_RegisterClient();
}

Synth::~Synth()
{
if (mtsClient)
if (monoValues.mtsClient)
{
MTS_DeregisterClient(mtsClient);
MTS_DeregisterClient(monoValues.mtsClient);
}
}

Expand Down
11 changes: 5 additions & 6 deletions src/synth/synth.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@

#include "synth/voice.h"
#include "synth/patch.h"

struct MTSClient;
#include "mono_values.h"

namespace baconpaul::six_sines
{
Expand All @@ -48,7 +47,7 @@ struct Synth
std::unique_ptr<resampler_t> resampler;

Patch patch;
MTSClient *mtsClient{nullptr};
MonoValues monoValues;

struct VMConfig
{
Expand All @@ -75,6 +74,7 @@ struct Synth
v->key = k;
v->velocity = ve;
}

void moveAndRetriggerVoice(Voice *v, uint16_t p, uint16_t c, uint16_t k, float ve)
{
v->key = k;
Expand All @@ -90,7 +90,9 @@ struct Synth
buffer[0].polyphonyGroup = 0;
return 1;
};

void endVoiceCreationTransaction(uint16_t, uint16_t, uint16_t, int32_t, float) {}

void terminateVoice(Voice *voice)
{
voice->gated = false;
Expand All @@ -117,7 +119,6 @@ struct Synth
synth.voices[i].gated = true;
synth.voices[i].key = key;
synth.voices[i].channel = ch;
synth.voices[i].mtsClient = synth.mtsClient;
synth.voices[i].velocity = vel;
synth.voices[i].attack();

Expand Down Expand Up @@ -159,7 +160,6 @@ struct Synth
double realSampleRate{0};
void setSampleRate(double sampleRate)
{
SXSNLOG("Creating resampler at " << sampleRate << " from " << gSampleRate);
realSampleRate = sampleRate;
resampler = std::make_unique<resampler_t>(gSampleRate, realSampleRate);
}
Expand Down Expand Up @@ -203,7 +203,6 @@ struct Synth
uiToAudioQueue_T uiToAudio;
std::atomic<bool> doFullRefresh{false};
sst::basic_blocks::dsp::UIComponentLagHandler lagHandler;
sst::basic_blocks::tables::EqualTuningProvider tuningProvider;

void pushFullUIRefresh();
void postLoad()
Expand Down
Loading

0 comments on commit 1a2c853

Please sign in to comment.