I was just looking over the schematic for braids. It doesn’t look like there is an exponential converter for the pitch cv. Is this being done in the firmware or am I missing something? If it is happening in software could someone be so kind as to point me to the right source file. I’m interested to see how this is being done.
It would be absolutely insane to do this in the analog domain:
- All the disadvantages of analog exponential conversion (temperature dependency)!
- Low notes would be converted into very small voltages, requiring a very precise ADC! For example, assuming that the ADC is referenced at 2.5V and that we want a span of 10 octaves, a semitone at the bottom octave would correspond to an increment of 2.5 * (2^-10 - 2^(-10+1/12.0)) = 0.14mV. You’d need at least a 16-bit ADC to detect that. And a rather astounding voltage reference!
The beauty of V/O is that you can represent a large octave span without having to deal with ridiculously tiny voltage at the bottom end of the scale.
So how does it work in Braids?
- The V/O input CV and the voltage at the wiper of the COARSE knob are added together.
- The resulting voltage is scaled by a factor of 0.25 to yield a voltage between 0V and 2.5V, read by the ADC. Because the ADC is 12-bit (0 to 4095), we have a scale of about 409.6 ADC units per octave.
- This ADC value is scaled / offset by two numbers to get a 14-bit number - the highest 7 bits represent the MIDI note number, the 7 lowest bits a 1/128th of a semitone.
Settings::adc_to_pitchdoes this conversion. https://github.com/pichenettes/eurorack/blob/master/braids/braids.cc#L231 So what are the magic numbers? The scaling ratio is about 128 * 12 / 409.6. But since 1% resistors are used all the way from the CV input to the ADC, the actual value is measured during the calibration procedure.
- So the question is now how to convert this 7+7 bits number into a phase increment for the oscillator. The code is here! https://github.com/pichenettes/eurorack/blob/master/braids/analog_oscillator.cc#L46 How does it work? We transpose up until we reach the top octave, count the number of transpositions, read the value from a linear to exponential table pre-computed for the top octave, then shift down.
Note that things are done more elegantly in more recent modules:
- The summing of the V/O CV input and the FREQUENCY (or COARSE) knob is no longer done in the analog domain - the V/O CV and the FREQUENCY knob are read by independent ADC channel, and the summing is done in software. Why? This allows software controlled scale, or quantization, or “virtual notches” on the knob.
- Pitch is internally represented as a floating point MIDI note. (for example, 69.5000 for an A4 up a quartertone).
- The conversion is done by this routine, which evaluates 2^(x / 12.0) by multiplying values read from two lookup tables, one for the integral part of x, the other for the fractional part of x.
- The phase increment for an oscillator is thus
440.0f / sample_rate * SemitonesToRatio(midi_note - 69.0f)
Thank you so much for the info.