Line data Source code
1 : #pragma once 2 : 3 : #include <AH/Hardware/FilteredAnalog.hpp> 4 : #include <Def/Def.hpp> 5 : #include <MIDI_Outputs/Abstract/MIDIOutputElement.hpp> 6 : 7 : BEGIN_CS_NAMESPACE 8 : 9 : /** 10 : * @brief A class for potentiometers and faders that send MIDI events. 11 : * 12 : * The analog input is filtered and hysteresis is applied. 13 : * 14 : * @see FilteredAnalog 15 : */ 16 : template <class Sender> 17 : class MIDIFilteredAnalog : public MIDIOutputElement { 18 : protected: 19 : /** 20 : * @brief Construct a new MIDIFilteredAnalog. 21 : * 22 : * @param analogPin 23 : * The analog input pin with the wiper of the potentiometer 24 : * connected. 25 : * @param address 26 : * The MIDI address to send to. 27 : * @param sender 28 : * The MIDI sender to use. 29 : */ 30 8 : MIDIFilteredAnalog(pin_t analogPin, MIDIAddress address, 31 : const Sender &sender) 32 8 : : filteredAnalog(analogPin), address(address), sender(sender) {} 33 : 34 : public: 35 6 : void begin() final override { filteredAnalog.resetToCurrentValue(); } 36 : 37 18 : void update() final override { 38 18 : if (filteredAnalog.update()) 39 18 : forcedUpdate(); 40 18 : } 41 : 42 : /// Send the value of the analog input over MIDI, even if the value didn't 43 : /// change. 44 18 : void forcedUpdate() { sender.send(filteredAnalog.getValue(), address); } 45 : 46 : /** 47 : * @brief Specify a mapping function that is applied to the raw 48 : * analog value before sending. 49 : * 50 : * @param fn 51 : * A function pointer to the mapping function. This function 52 : * should take the filtered analog value of @f$ 16 - 53 : * \mathrm{ANALOG\_FILTER\_SHIFT\_FACTOR} @f$ bits as a parameter, 54 : * and should return a value in the same range. 55 : * 56 : * @see FilteredAnalog::map 57 : */ 58 2 : void map(MappingFunction fn) { filteredAnalog.map(fn); } 59 : 60 : /// Invert the analog value. 61 2 : void invert() { filteredAnalog.invert(); } 62 : 63 : /** 64 : * @brief Get the raw value of the analog input (this is the value 65 : * without applying the filter or the mapping function first). 66 : */ 67 : analog_t getRawValue() const { return filteredAnalog.getRawValue(); } 68 : 69 : /** 70 : * @brief Get the maximum value that can be returned from @ref getRawValue. 71 : */ 72 : static constexpr analog_t getMaxRawValue() { 73 : return FilteredAnalog::getMaxRawValue(); 74 : } 75 : 76 : /** 77 : * @brief Get the value of the analog input (this is the value after first 78 : * applying the mapping function). 79 : */ 80 : analog_t getValue() const { return filteredAnalog.getValue(); } 81 : 82 : /// Get the MIDI address. 83 : MIDIAddress getAddress() const { return this->address; } 84 : /// Set the MIDI address. 85 : void setAddress(MIDIAddress address) { this->address = address; } 86 : 87 : private: 88 : using FilteredAnalog = AH::FilteredAnalog<Sender::precision()>; 89 : FilteredAnalog filteredAnalog; 90 : MIDIAddress address; 91 : 92 : public: 93 : Sender sender; 94 : }; 95 : 96 : END_CS_NAMESPACE