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