Skip to content

Commit

Permalink
Env: support true polyphony on FREQ/RES CV inputs.
Browse files Browse the repository at this point in the history
Allow different FREQ, RES values to be set per channel,
based on polyphonic CV input.
Cascade forward last channel value when one cable has
fewer channels than another.

I still need to make THRESH and SPEED work this way also,
before I can declare this module fully polyphonic.
  • Loading branch information
cosinekitty committed Feb 11, 2025
1 parent 8254aef commit 5370e0e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 15 deletions.
19 changes: 11 additions & 8 deletions src/env_pitch_detect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,11 @@ namespace Sapphire
info.resize(maxChannels);
setThreshold();
setSpeed();
setFrequency();
setResonance();
for (int c = 0; c < maxChannels; ++c)
{
setFrequency(0, c);
setResonance(0.25, c);
}
initialize();
}

Expand All @@ -209,16 +212,16 @@ namespace Sapphire
speed = 0.9999 - (qs*0.0999 / 128);
}

void setFrequency(value_t knob = 0)
void setFrequency(value_t knob, int channel)
{
for (info_t& q : info)
q.pitchFilter.setFrequency(knob);
info_t& q = info.at(channel);
q.pitchFilter.setFrequency(knob);
}

void setResonance(value_t knob = 0.25)
void setResonance(value_t knob, int channel)
{
for (info_t& q : info)
q.pitchFilter.setResonance(knob);
info_t& q = info.at(channel);
q.pitchFilter.setResonance(knob);
}

int process(
Expand Down
25 changes: 18 additions & 7 deletions src/env_vcv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ namespace Sapphire
void process(const ProcessArgs& args) override
{
int nc = inputs[AUDIO_INPUT].getChannels();
nc = std::max(nc, inputs[FREQ_CV_INPUT].getChannels());
nc = std::max(nc, inputs[RES_CV_INPUT].getChannels());
if (nc <= 0)
{
const float zero = 0;
Expand All @@ -91,21 +93,30 @@ namespace Sapphire
float outEnvelope[PORT_MAX_CHANNELS];
float outPitchVoct[PORT_MAX_CHANNELS];

float cvFreq = 0;
float cvRes = 0;
float audio = 0;

for (int c = 0; c < nc; ++c)
inFrame[c] = inputs[AUDIO_INPUT].getVoltage(c);
{
nextChannelInputVoltage(audio, AUDIO_INPUT, c);
inFrame[c] = audio;

nextChannelInputVoltage(cvFreq, FREQ_CV_INPUT, c);
float freq = cvGetVoltPerOctave(FREQ_PARAM, FREQ_ATTEN, cvFreq, -Gravy::OctaveRange, +Gravy::OctaveRange);
detector.setFrequency(freq, c);

nextChannelInputVoltage(cvRes, RES_CV_INPUT, c);
float res = cvGetControlValue(RES_PARAM, RES_ATTEN, cvRes, 0, 1);
detector.setResonance(res, c);
}

float thresh = getControlValue(THRESHOLD_PARAM, THRESHOLD_ATTEN, THRESHOLD_CV_INPUT, -96, 0);
detector.setThreshold(thresh);

float speed = getControlValue(SPEED_PARAM, SPEED_ATTEN, SPEED_CV_INPUT, 0, 1);
detector.setSpeed(speed);

float freq = getControlValueVoltPerOctave(FREQ_PARAM, FREQ_ATTEN, FREQ_CV_INPUT, -Gravy::OctaveRange, +Gravy::OctaveRange);
detector.setFrequency(freq);

float res = getControlValue(RES_PARAM, RES_ATTEN, RES_CV_INPUT, 0, 1);
detector.setResonance(res);

detector.process(nc, args.sampleRate, inFrame, outEnvelope, outPitchVoct);

setPolyOutput(ENVELOPE_OUTPUT, nc, outEnvelope);
Expand Down

0 comments on commit 5370e0e

Please sign in to comment.