Help with Pitch Quantizer code

Hello everyone,

I have an ornament and crime module for Eurorack with the stock firmware, and I need to edit the code of the quantizer. Sadly, I don't know anything about coding :frowning:

I use the Arduino IDE to read/edit the code. You can find the code for the quantizer here:

Let's say I have an octave from note C to the next c, and the only enabled note is C. For voltage =0 the quantizer will output a C. As I raise the voltage, the quantizer will output the C one octave up a little after I pass the note F#. That's normal since F# lies in the middle of the two C's. I'm guessing that the reason why the quantizing happens a bit after the F# is that the code adds a bit of hysteresis, you can see that towards the end of the code. The same will happen if I lower the voltage to negative values, it will quantize to the C one octave below a bit after I pass the F# below my original C.

What I want is that when i decrease the voltage, and the pitch goes down, the quantizer quantizes a bit BEFORE the boundary (F# in this case). So, while I'm at the note G, it still outputs my original C=0 volts, and it outputs the C below,
=-1 volt, a bit before I reach F#. I want this to happen ONLY when decreasing the voltage, doesn't matter if the absolute value is negative or positive.

The reason I need this, is that I want to use the quantizer as a complex window comparator of sorts, where it outputs +1, +2, or -1, -2 volts etc. for the different cv inputs. The way it's coded now, I'm guessing because of the hysteresis, this window comparator has different thresholds depending on whether the voltage goes up or down. With my sugested tweak, there will always be a very fixed threshold between each octave, between F# and G, and the former will always belong to the C below and the latter to the C above.

Would that be possible? Does anyone have any code suggestions? I see in the code terms such as low and high boundary, or previous and next boundary, and that gives me some hope. Or could it be as simple as changing the hysteresis to negative values when voltage goes down? If that makes any sense...

Looking forward to possible suggestions and thank you in advance.

I have absolutely no clue about midi, quantizer or boundary, but this function (Process()) seems to do stuff with transpose, boundaries, pitch and codeword...:

int32_t Quantizer::Process(int32_t pitch, int32_t root, int32_t transpose) {
  if (!enabled_) {
    return pitch;
  }

  pitch -= root;
  #ifdef BUCHLA_4U
    pitch -= ((12 << 7) << 2);
  #else
    pitch -= ((12 << 7) << 1);
  #endif
  if (pitch >= previous_boundary_ && pitch <= next_boundary_ && transpose == transpose_) {
    // We're still in the voronoi cell for the active codeword.
    pitch = codeword_;
  } else {
    // Search for the nearest neighbour in the codebook.
    int16_t upper_bound_index = std::upper_bound(
        &codebook_[3],
        &codebook_[126],
        static_cast<int16_t>(pitch)) - &codebook_[0];
    int16_t lower_bound_index = upper_bound_index - 2;

    int16_t best_distance = 16384;
    int16_t q = -1;
    for (int16_t i = lower_bound_index; i <= upper_bound_index; ++i) {
      int16_t distance = abs(pitch - codebook_[i]);
      if (distance < best_distance) {
        best_distance = distance;
        q = i;
      }
    }

    // Enlarge the current voronoi cell a bit for hysteresis.
    previous_boundary_ = (9 * codebook_[q - 1] + 7 * codebook_[q]) >> 4;
    next_boundary_ = (9 * codebook_[q + 1] + 7 * codebook_[q]) >> 4;

    // Apply transpose after setting up boundaries
    q += transpose;
    if (q < 1) q = 1;
    else if (q > 126) q = 126;
    codeword_ = codebook_[q];
    transpose_ = transpose;
    pitch = codeword_;
  }
  pitch += root;
  #ifdef BUCHLA_4U
    pitch += ((12 << 7) << 2);
  #else
    pitch += ((12 << 7) << 1);
  #endif
  return pitch;
}