Sound Byte Libs 29c5ff3
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
voct.hpp
Go to the documentation of this file.
1/**
2 * @file voct.hpp
3 * @brief V/Oct input component — calibrated pitch CV from ADC values
4 * @ingroup components
5 *
6 * VoctInput chains CvInput (EWMA smoothing) with a linear calibration
7 * to convert raw ADC values into musical pitch. The calibration maps
8 * ADC values to MIDI note numbers (semitones), then pitch tables
9 * convert to frequency, ratio, or phase increment.
10 *
11 * Pipeline:
12 * ADC raw → CvInput (EWMA) → calibration (scale + offset) → semitones
13 * ↓
14 * phase_increment ← frequency ← pitch tables
15 *
16 * Usage:
17 * sbl::components::cv::VoctInput voct;
18 * voct.update(raw_adc_value);
19 * float freq = voct.frequency(); // Hz
20 * uint32_t inc = voct.phase_increment(48000.0f);
21 */
22
23#ifndef SBL_COMPONENTS_CV_VOCT_HPP_
24#define SBL_COMPONENTS_CV_VOCT_HPP_
25
26#include <cstdint>
28#include <sbl/dsp/pitch.hpp>
29
30namespace sbl {
31namespace components {
32namespace cv {
33
34/**
35 * @brief Linear calibration parameters for V/Oct conversion
36 *
37 * Maps smoothed ADC value to MIDI note number:
38 * note = adc_value * scale + offset
39 */
41 float scale; ///< Semitones per ADC unit
42 float offset; ///< MIDI note number at ADC=0
43
44 /**
45 * @brief Default calibration for 0–3.3V input, 1V/Oct, 16-bit ADC
46 *
47 * 3.3V × 12 semitones/V = 39.6 semitones across full ADC range.
48 * Base note C1 (MIDI 24) at ADC=0.
49 */
50 static constexpr VoctCalibration default_3v3() {
51 return { 39.6f / 65535.0f, 24.0f };
52 }
53
54 /**
55 * @brief Compute calibration from two known points
56 *
57 * Apply known voltages, read the ADC values, and provide the
58 * expected MIDI note at each point. Scale and offset are derived
59 * from the two-point linear fit.
60 *
61 * @param adc_low ADC reading at the low calibration voltage
62 * @param note_low Expected MIDI note at the low point
63 * @param adc_high ADC reading at the high calibration voltage
64 * @param note_high Expected MIDI note at the high point
65 */
67 uint16_t adc_low, float note_low,
68 uint16_t adc_high, float note_high)
69 {
70 float s = (note_high - note_low) /
71 static_cast<float>(adc_high - adc_low);
72 float o = note_low - s * static_cast<float>(adc_low);
73 return { s, o };
74 }
75};
76
77/**
78 * @brief V/Oct pitch CV input with smoothing and calibration
79 *
80 * Owns a CvInput for EWMA smoothing and stores calibration state.
81 * Hardware-agnostic — takes raw ADC values, no driver calls.
82 */
83/**
84 * @brief V/Oct pitch CV input with smoothing, calibration, and pitch conversion
85 *
86 * @note All public methods are ISR-safe — pure state machine with no hardware I/O.
87 */
88class VoctInput {
89public:
91 Smoothing smoothing = Smoothing::Light)
92 : cv_(smoothing), cal_(cal) {}
93
94 /** @brief Feed a new raw ADC sample */
95 void update(uint16_t raw) {
96 cv_.update(raw);
97 }
98
99 /** @brief Replace calibration at runtime */
101 cal_ = cal;
102 }
103
104 /** @brief Current calibration */
105 const VoctCalibration& calibration() const { return cal_; }
106
107 /** @brief MIDI note number (float) from calibrated input */
108 float semitones() const {
109 return static_cast<float>(cv_.value()) * cal_.scale + cal_.offset;
110 }
111
112 /** @brief Frequency in Hz (via pitch tables) */
113 float frequency() const {
115 }
116
117 /** @brief Frequency ratio relative to A4 (440 Hz) */
118 float ratio() const {
120 }
121
122 /** @brief Phase increment for wavetable oscillator */
123 uint32_t phase_increment(float sample_rate) const {
124 return dsp::note_to_phase_increment(semitones(), sample_rate);
125 }
126
127 /** @brief Last raw (unfiltered) ADC value */
128 uint16_t raw() const { return cv_.raw(); }
129
130 /** @brief Current smoothed ADC value (0–65535) */
131 uint16_t value() const { return cv_.value(); }
132
133 /** @brief Reset filter state */
134 void reset() { cv_.reset(); }
135
136private:
137 CvInput cv_;
138 VoctCalibration cal_;
139};
140
141} // namespace cv
142} // namespace components
143} // namespace sbl
144
145#endif // SBL_COMPONENTS_CV_VOCT_HPP_
Smoothed CV input with EWMA filtering and range scaling.
Definition input.hpp:51
uint16_t value() const
Current smoothed value (0–65535)
Definition input.hpp:69
uint16_t raw() const
Last raw (unfiltered) value.
Definition input.hpp:66
void update(uint16_t raw)
Feed a new raw ADC sample.
Definition input.hpp:60
void reset()
Reset filter state.
Definition input.hpp:106
V/Oct pitch CV input with smoothing and calibration.
Definition voct.hpp:88
uint16_t value() const
Current smoothed ADC value (0–65535)
Definition voct.hpp:131
float frequency() const
Frequency in Hz (via pitch tables)
Definition voct.hpp:113
float semitones() const
MIDI note number (float) from calibrated input.
Definition voct.hpp:108
void reset()
Reset filter state.
Definition voct.hpp:134
uint16_t raw() const
Last raw (unfiltered) ADC value.
Definition voct.hpp:128
VoctInput(VoctCalibration cal=VoctCalibration::default_3v3(), Smoothing smoothing=Smoothing::Light)
Definition voct.hpp:90
void update(uint16_t raw)
Feed a new raw ADC sample.
Definition voct.hpp:95
uint32_t phase_increment(float sample_rate) const
Phase increment for wavetable oscillator.
Definition voct.hpp:123
const VoctCalibration & calibration() const
Current calibration.
Definition voct.hpp:105
void set_calibration(VoctCalibration cal)
Replace calibration at runtime.
Definition voct.hpp:100
float ratio() const
Frequency ratio relative to A4 (440 Hz)
Definition voct.hpp:118
CV Input component — smoothed ADC reading with range scaling.
Smoothing
Smoothing presets for CvInput EWMA filter.
Definition input.hpp:35
@ Light
alpha=1/2, settles in ~4 samples (pitch, fast CV)
float note_to_frequency(float midi_note)
MIDI note to frequency in Hz. A4 = 440 Hz.
Definition pitch.hpp:52
float note_to_ratio(float midi_note)
Definition pitch.hpp:47
uint32_t note_to_phase_increment(float midi_note, float sample_rate)
Definition pitch.hpp:58
Root namespace for all Sound Byte Libs functionality.
Definition aliases.hpp:24
Linear calibration parameters for V/Oct conversion.
Definition voct.hpp:40
static constexpr VoctCalibration from_two_point(uint16_t adc_low, float note_low, uint16_t adc_high, float note_high)
Compute calibration from two known points.
Definition voct.hpp:66
float scale
Semitones per ADC unit.
Definition voct.hpp:41
static constexpr VoctCalibration default_3v3()
Default calibration for 0–3.3V input, 1V/Oct, 16-bit ADC.
Definition voct.hpp:50
float offset
MIDI note number at ADC=0.
Definition voct.hpp:42