#pragma once #include "hardware/adc.h" #include #include #include namespace { std::array previous_samples { 0xffu, 0xffu }; std::uint8_t raw_to_midi(std::uint16_t new_raw, std::uint8_t previous_midi) { std::int32_t constexpr interval = 4096 / 128; std::int32_t constexpr hysteresis = 3; std::int32_t const lower = std::max(0l, static_cast(previous_midi) * interval - hysteresis); std::int32_t const upper = std::min(4095l, lower + interval - 1l + hysteresis); std::uint8_t const new_midi = static_cast(new_raw * 128u / 4096u); return new_raw > upper || new_raw < lower ? new_midi : previous_midi; } } namespace adc { struct Sample { std::uint16_t raw {0}; std::uint8_t midi {0}; bool changed {false}; }; void init() { adc_init(); adc_gpio_init(26); adc_gpio_init(27); } std::array get_samples() { std::array samples {}; for (std::size_t i = 0; i < samples.size(); i++) { adc_select_input(i); auto & sample = samples[i]; sample.raw = adc_read(); sample.midi = raw_to_midi(sample.raw, sample.midi); sample.changed = samples[i].midi != previous_samples[i]; previous_samples[i] = sample.midi; } return samples; } }