| 162 | } |
| 163 | |
| 164 | void process(const ProcessArgs& args) override { |
| 165 | // Switches |
| 166 | if (rangeTrigger.process(params[RANGE_PARAM].getValue() > 0.f)) { |
| 167 | range = (range + 1) % 3; |
| 168 | } |
| 169 | if (modeTrigger.process(params[MODE_PARAM].getValue() > 0.f)) { |
| 170 | output_mode = (tides2::OutputMode)((output_mode + 1) % 4); |
| 171 | } |
| 172 | if (rampTrigger.process(params[RAMP_PARAM].getValue() > 0.f)) { |
| 173 | ramp_mode = (tides2::RampMode)((ramp_mode + 1) % 3); |
| 174 | } |
| 175 | |
| 176 | // Input gates |
| 177 | trig_flags[frame] = stmlib::ExtractGateFlags(previous_trig_flag, inputs[TRIG_INPUT].getVoltage() >= 1.7f); |
| 178 | previous_trig_flag = trig_flags[frame]; |
| 179 | |
| 180 | clock_flags[frame] = stmlib::ExtractGateFlags(previous_clock_flag, inputs[CLOCK_INPUT].getVoltage() >= 1.7f); |
| 181 | previous_clock_flag = clock_flags[frame]; |
| 182 | |
| 183 | // Process block |
| 184 | if (++frame >= tides2::kBlockSize) { |
| 185 | frame = 0; |
| 186 | |
| 187 | tides2::Range range_mode = (range < 2) ? tides2::RANGE_CONTROL : tides2::RANGE_AUDIO; |
| 188 | float note = clamp(params[FREQUENCY_PARAM].getValue() + 12.f * inputs[V_OCT_INPUT].getVoltage(), -96.f, 96.f); |
| 189 | float fm = clamp(params[FREQUENCY_CV_PARAM].getValue() * inputs[FREQUENCY_INPUT].getVoltage() * 12.f, -96.f, 96.f); |
| 190 | float transposition = note + fm; |
| 191 | |
| 192 | float ramp[tides2::kBlockSize]; |
| 193 | float frequency; |
| 194 | |
| 195 | if (inputs[CLOCK_INPUT].isConnected()) { |
| 196 | if (must_reset_ramp_extractor) { |
| 197 | ramp_extractor.Reset(); |
| 198 | } |
| 199 | |
| 200 | tides2::Ratio r = ratio_index_quantizer.Lookup(kRatios, 0.5f + transposition * 0.0105f, 20); |
| 201 | frequency = ramp_extractor.Process( |
| 202 | range_mode == tides2::RANGE_AUDIO, |
| 203 | range_mode == tides2::RANGE_AUDIO && ramp_mode == tides2::RAMP_MODE_AR, |
| 204 | r, |
| 205 | clock_flags, |
| 206 | ramp, |
| 207 | tides2::kBlockSize); |
| 208 | must_reset_ramp_extractor = false; |
| 209 | } |
| 210 | else { |
| 211 | frequency = kRootScaled[range] / args.sampleRate * stmlib::SemitonesToRatio(transposition); |
| 212 | must_reset_ramp_extractor = true; |
| 213 | } |
| 214 | |
| 215 | // Get parameters |
| 216 | float slope = clamp(params[SLOPE_PARAM].getValue() + dsp::cubic(params[SLOPE_CV_PARAM].getValue()) * inputs[SLOPE_INPUT].getVoltage() / 10.f, 0.f, 1.f); |
| 217 | float shape = clamp(params[SHAPE_PARAM].getValue() + dsp::cubic(params[SHAPE_CV_PARAM].getValue()) * inputs[SHAPE_INPUT].getVoltage() / 10.f, 0.f, 1.f); |
| 218 | float smoothness = clamp(params[SMOOTHNESS_PARAM].getValue() + dsp::cubic(params[SMOOTHNESS_CV_PARAM].getValue()) * inputs[SMOOTHNESS_INPUT].getVoltage() / 10.f, 0.f, 1.f); |
| 219 | float shift = clamp(params[SHIFT_PARAM].getValue() + dsp::cubic(params[SHIFT_CV_PARAM].getValue()) * inputs[SHIFT_INPUT].getVoltage() / 10.f, 0.f, 1.f); |
| 220 | |
| 221 | if (output_mode != previous_output_mode) { |