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
|