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
|