MIDI2LR 6.1.0.0
MIDI2LR is an application that interfaces MIDI controllers with Lightroom 6+/CC Classic. It processes MIDI input into develop parameter updates and photo actions, and sends MIDI output when parameters are changed for motorized feedback (on controllers that have motorized faders). A listing of available LightRoom commands is in the Wiki. Assistance on the code and design is welcome.
Loading...
Searching...
No Matches
ChannelModel Class Reference

#include <ControlsModel.h>

Public Member Functions

 ChannelModel ()
 
double ControllerToPlugin (rsj::MessageType controltype, int controlnumber, int value, bool wrap)
 
int GetCcMax (int controlnumber) const
 
rsj::CCmethod GetCcMethod (int controlnumber) const
 
int GetCcMin (int controlnumber) const
 
int GetPwMax () const noexcept
 
int GetPwMin () const noexcept
 
int MeasureChange (rsj::MessageType controltype, int controlnumber, int value)
 
int PluginToController (rsj::MessageType controltype, int controlnumber, double value)
 
void SetCc (int controlnumber, int min, int max, rsj::CCmethod controltype)
 
void SetCcAll (int controlnumber, int min, int max, rsj::CCmethod controltype)
 
void SetCcMax (int controlnumber, int value)
 
void SetCcMethod (int controlnumber, rsj::CCmethod value)
 
void SetCcMin (int controlnumber, int value)
 
void SetPwMax (int value) noexcept
 
void SetPwMin (int value) noexcept
 
int SetToCenter (rsj::MessageType controltype, int controlnumber)
 

Private Member Functions

void ActiveToSaved () const
 
void CcDefaults ()
 
int CenterCc (int controlnumber) const noexcept
 
int CenterPw () const noexcept
 
bool IsNrpn (int controlnumber) const
 
template<class Archive >
void load (Archive &archive, const uint32_t version)
 
double OffsetResult (int diff, int controlnumber, bool wrap)
 
template<class Archive >
void save (Archive &archive, const uint32_t version) const
 
void SavedToActive ()
 
void SaveSettings (int start, int end, int maxVal) const
 

Private Attributes

std::array< int, kMaxControlscc_high_ {}
 
std::array< int, kMaxControlscc_low_ {}
 
std::array< rsj::CCmethod, kMaxControlscc_method_ {}
 
std::array< std::atomic< int >, kMaxControlscurrent_v_ {}
 
std::atomic< int > pitch_wheel_current_ {kMaxNrpnHalf}
 
int pitch_wheel_max_ {kMaxNrpn}
 
int pitch_wheel_min_ {0}
 
std::vector< rsj::SettingsStructsettings_to_save_ {}
 

Static Private Attributes

static constexpr int kBit14 {0x2000}
 
static constexpr int kBit7 {0x40}
 
static constexpr int kLow13Bits {0x1FFF}
 
static constexpr int kLow6Bits {0x3F}
 
static constexpr size_t kMaxControls {0x4000}
 
static constexpr int kMaxMidi {0x7F}
 
static constexpr int kMaxMidiHalf {kMaxMidi / 2}
 
static constexpr int kMaxNrpn {0x3FFF}
 
static constexpr int kMaxNrpnHalf {kMaxNrpn / 2}
 

Friends

class cereal::access
 

Constructor & Destructor Documentation

◆ ChannelModel()

ChannelModel::ChannelModel ( )
452{
453 try {
454 CcDefaults();
455 }
456 catch (const std::exception& e) {
458 throw;
459 }
460}
void CcDefaults()
Definition ControlsModel.cpp:410
void ExceptionResponse(gsl::czstring id, gsl::czstring fu, const std::exception &e) noexcept

Member Function Documentation

◆ ActiveToSaved()

void ChannelModel::ActiveToSaved ( ) const
private
398{
399 try {
400 settings_to_save_.clear();
403 }
404 catch (const std::exception& e) {
406 throw;
407 }
408}
void SaveSettings(int start, int end, int maxVal) const
Definition ControlsModel.cpp:387
std::vector< rsj::SettingsStruct > settings_to_save_
Definition ControlsModel.h:209
static constexpr int kMaxMidi
Definition ControlsModel.h:137
static constexpr int kMaxNrpn
Definition ControlsModel.h:139

◆ CcDefaults()

void ChannelModel::CcDefaults ( )
private
411{
412 try {
413 cc_low_.fill(0);
414 cc_high_.fill(kMaxNrpn);
416#ifdef __cpp_lib_atomic_ref
418 std::fill_n(cc_high_.begin(), kMaxMidi + 1, kMaxMidi);
419 std::fill_n(current_v_.begin(), kMaxMidi + 1, kMaxMidiHalf);
420#else
421 for (auto&& a : current_v_) { a.store(kMaxNrpnHalf, std::memory_order_relaxed); }
422 std::fill_n(cc_high_.begin(), kMaxMidi + 1, kMaxMidi);
423 for (size_t a {0}; a <= kMaxMidi; ++a) {
424 current_v_.at(a).store(kMaxMidiHalf, std::memory_order_relaxed);
425 }
426#endif
427 }
428 catch (const std::exception& e) {
430 throw;
431 }
432}
std::array< int, kMaxControls > cc_low_
Definition ControlsModel.h:215
std::array< rsj::CCmethod, kMaxControls > cc_method_
Definition ControlsModel.h:213
static constexpr int kMaxNrpnHalf
Definition ControlsModel.h:140
std::array< int, kMaxControls > cc_high_
Definition ControlsModel.h:214
static constexpr int kMaxMidiHalf
Definition ControlsModel.h:138
std::array< std::atomic< int >, kMaxControls > current_v_
Definition ControlsModel.h:219

◆ CenterCc()

int ChannelModel::CenterCc ( int  controlnumber) const
inlineprivatenoexcept
180 {
181 return (cc_high_.at(controlnumber) - cc_low_.at(controlnumber)) / 2
182 + cc_low_.at(controlnumber)
183 + (cc_high_.at(controlnumber) - cc_low_.at(controlnumber)) % 2;
184 }

◆ CenterPw()

int ChannelModel::CenterPw ( ) const
inlineprivatenoexcept
187 {
190 }
int pitch_wheel_min_
Definition ControlsModel.h:211
int pitch_wheel_max_
Definition ControlsModel.h:210

◆ ControllerToPlugin()

double ChannelModel::ControllerToPlugin ( rsj::MessageType  controltype,
int  controlnumber,
int  value,
bool  wrap 
)
55{
56 try {
57 const auto cc_method = cc_method_.at(controlnumber);
58 const auto cc_low = cc_low_.at(controlnumber);
59 const auto cc_high = cc_high_.at(controlnumber);
60 Expects(controltype == rsj::MessageType::kCc && cc_method == rsj::CCmethod::kAbsolute
61 ? cc_low < cc_high
62 : 1);
63 Expects(controltype == rsj::MessageType::kPw ? pitch_wheel_max_ > pitch_wheel_min_ : 1);
64 Expects(controltype == rsj::MessageType::kPw
65 ? value >= pitch_wheel_min_ && value <= pitch_wheel_max_
66 : 1);
67 /* note that the value is not msb,lsb, but rather the calculated value. Since lsb is only 7
68 * bits, high bits are shifted one right when placed into int. */
69 switch (controltype) {
71 pitch_wheel_current_.store(value, std::memory_order_release);
72#pragma warning(suppress : 26451) /* int subtraction won't overflow 4 bytes here */
73 return static_cast<double>(value - pitch_wheel_min_)
74 / static_cast<double>(pitch_wheel_max_ - pitch_wheel_min_);
76 switch (cc_method) {
78#ifdef __cpp_lib_atomic_ref
79 std::atomic_ref(current_v_.at(controlnumber)).store(value, std::memory_order_release);
80#else
81 current_v_.at(controlnumber).store(value, std::memory_order_release);
82#endif
83#pragma warning(suppress : 26451) /* int subtraction won't overflow 4 bytes here */
84 return static_cast<double>(value - cc_low) / static_cast<double>(cc_high - cc_low);
86 if (IsNrpn(controlnumber)) { return OffsetResult(value - kBit14, controlnumber, wrap); }
87 return OffsetResult(value - kBit7, controlnumber, wrap);
89 if (IsNrpn(controlnumber)) {
90 return OffsetResult(value & kBit14 ? -(value & kLow13Bits) : value, controlnumber,
91 wrap);
92 }
93 return OffsetResult(value & kBit7 ? -(value & kLow6Bits) : value, controlnumber, wrap);
95 /* SEE:https://en.wikipedia.org/wiki/Signed_number_representations#Two.27s_complement
96 * flip twos comp and subtract--independent of processor architecture */
97 if (IsNrpn(controlnumber)) {
98 return OffsetResult(value & kBit14 ? -((value ^ kMaxNrpn) + 1) : value,
99 controlnumber, wrap);
100 }
101 return OffsetResult(value & kBit7 ? -((value ^ kMaxMidi) + 1) : value, controlnumber,
102 wrap);
103 }
105 return static_cast<double>(value)
106 / static_cast<double>((IsNrpn(controlnumber) ? kMaxNrpn : kMaxMidi));
108 return 0.0;
113 throw std::invalid_argument(
114 fmt::format(FMT_STRING("ChannelModel::ControllerToPlugin unexpected control type. "
115 "Controltype {}, controlnumber {}, value {}, wrap {}."),
116 controltype, controlnumber, value, wrap));
117 }
118 throw std::domain_error(fmt::format(FMT_STRING("Undefined control type in "
119 "ChannelModel::PluginToController. Control "
120 "type {}."),
121 controltype));
122 }
123 catch (const std::exception& e) {
125 throw;
126 }
127}
bool IsNrpn(int controlnumber) const
Definition ControlsModel.h:193
double OffsetResult(int diff, int controlnumber, bool wrap)
Definition ControlsModel.cpp:21
static constexpr int kLow6Bits
Definition ControlsModel.h:136
static constexpr int kBit14
Definition ControlsModel.h:133
static constexpr int kBit7
Definition ControlsModel.h:134
static constexpr int kLow13Bits
Definition ControlsModel.h:135
std::atomic< int > pitch_wheel_current_
Definition ControlsModel.h:212

◆ GetCcMax()

int ChannelModel::GetCcMax ( int  controlnumber) const
inline
154{ return cc_high_.at(controlnumber); }

◆ GetCcMethod()

rsj::CCmethod ChannelModel::GetCcMethod ( int  controlnumber) const
inline
150 {
151 return cc_method_.at(controlnumber);
152 }

◆ GetCcMin()

int ChannelModel::GetCcMin ( int  controlnumber) const
inline
156{ return cc_low_.at(controlnumber); }

◆ GetPwMax()

int ChannelModel::GetPwMax ( ) const
inlinenoexcept
158{ return pitch_wheel_max_; }

◆ GetPwMin()

int ChannelModel::GetPwMin ( ) const
inlinenoexcept
160{ return pitch_wheel_min_; }

◆ IsNrpn()

bool ChannelModel::IsNrpn ( int  controlnumber) const
inlineprivate
194 {
195 Expects(controlnumber <= kMaxNrpn && controlnumber >= 0);
196 return controlnumber > kMaxMidi;
197 }

◆ load()

template<class Archive >
void ChannelModel::load ( Archive &  archive,
const uint32_t  version 
)
private
329{
330 try {
331 switch (version) {
332 case 1:
334 break;
335 case 2:
336 archive(settings_to_save_);
338 break;
339 case 3:
340 archive(settings_to_save_, cereal::make_nvp("PWmax", pitch_wheel_max_),
341 cereal::make_nvp("PWmin", pitch_wheel_min_));
343 break;
344 default:
345 {
346 constexpr auto msg {
347 "The file, 'settings.xml', is marked as a version not supported by the current "
348 "version of MIDI2LR ChannelModel, and won't be loaded. File version: {}."};
349 rsj::LogAndAlertError(fmt::format(juce::translate(msg).toStdString(), version),
350 fmt::format(msg, version));
351 }
352 break;
353 }
354 }
355 catch (const std::exception& e) {
357 throw;
358 }
359}
void SavedToActive()
Definition ControlsModel.cpp:434
void LogAndAlertError(const juce::String &error_text, const std::source_location &location=std::source_location::current()) noexcept
Definition Misc.cpp:160

◆ MeasureChange()

int ChannelModel::MeasureChange ( rsj::MessageType  controltype,
int  controlnumber,
int  value 
)
168{
169 try {
170 Expects(controltype == rsj::MessageType::kCc
171 && cc_method_.at(controlnumber) == rsj::CCmethod::kAbsolute
172 ? cc_low_.at(controlnumber) < cc_high_.at(controlnumber)
173 : 1);
174 Expects(controltype == rsj::MessageType::kPw ? pitch_wheel_max_ > pitch_wheel_min_ : 1);
175 Expects(controltype == rsj::MessageType::kPw
176 ? value >= pitch_wheel_min_ && value <= pitch_wheel_max_
177 : 1);
178 /* note that the value is not msb,lsb, but rather the calculated value. Since lsb is only 7
179 * bits, high bits are shifted one right when placed into int. */
180 switch (controltype) {
182 return value - pitch_wheel_current_.exchange(value, std::memory_order_acq_rel);
184 switch (cc_method_.at(controlnumber)) {
186#ifdef __cpp_lib_atomic_ref
187 return value
188 - std::atomic_ref(current_v_.at(controlnumber))
189 .exchange(value, std::memory_order_acq_rel);
190#else
191 return value - current_v_.at(controlnumber).exchange(value, std::memory_order_acq_rel);
192#endif
194 if (IsNrpn(controlnumber)) { return value - kBit14; }
195 return value - kBit7;
197 if (IsNrpn(controlnumber)) { return value & kBit14 ? -(value & kLow13Bits) : value; }
198 return value & kBit7 ? -(value & kLow6Bits) : value;
200 /* SEE:https://en.wikipedia.org/wiki/Signed_number_representations#Two.27s_complement
201 * flip twos comp and subtract--independent of processor architecture */
202 if (IsNrpn(controlnumber)) {
203 return value & kBit14 ? -((value ^ kMaxNrpn) + 1) : value;
204 }
205 return value & kBit7 ? -((value ^ kMaxMidi) + 1) : value;
206 }
209 return int {0};
214 throw std::invalid_argument(
215 fmt::format(FMT_STRING("ChannelModel::MeasureChange unexpected control type. "
216 "Controltype {}, controlnumber {}, value {}."),
217 controltype, controlnumber, value));
218 }
219 throw std::domain_error(fmt::format(FMT_STRING("Undefined control type in "
220 "ChannelModel::PluginToController. "
221 "Control type {}."),
222 controltype));
223 }
224 catch (const std::exception& e) {
226 throw;
227 }
228}

◆ OffsetResult()

double ChannelModel::OffsetResult ( int  diff,
int  controlnumber,
bool  wrap 
)
private
22{
23 try {
24 const auto high_limit {cc_high_.at(controlnumber)};
25 Expects(diff <= high_limit && diff >= -high_limit);
26#ifdef __cpp_lib_atomic_ref
27 std::atomic_ref cv {current_v_.at(controlnumber)};
28#else
29 auto& cv {current_v_.at(controlnumber)};
30#endif
31 auto old_v {cv.load(std::memory_order_relaxed)};
32 int new_v {};
33 if (wrap) {
34 do {
35 new_v = (old_v + diff + high_limit) % high_limit;
36 } while (!cv.compare_exchange_weak(old_v, new_v, std::memory_order_release,
37 std::memory_order_relaxed));
38 }
39 else [[likely]] {
40 do {
41 new_v = std::clamp(old_v + diff, 0, high_limit);
42 } while (!cv.compare_exchange_weak(old_v, new_v, std::memory_order_release,
43 std::memory_order_relaxed));
44 }
45 return static_cast<double>(new_v) / static_cast<double>(high_limit);
46 }
47 catch (const std::exception& e) {
49 throw;
50 }
51}

◆ PluginToController()

int ChannelModel::PluginToController ( rsj::MessageType  controltype,
int  controlnumber,
double  value 
)
235{
236 try {
237 /* value effectively clamped to 0-1 by clamp calls below */
238 switch (controltype) {
240 {
241 /* TODO(C26451): int subtraction: can it overflow? */
242 const auto newv {
243 std::clamp(gsl::narrow<int>(std::lrint(
244 value * static_cast<double>(pitch_wheel_max_ - pitch_wheel_min_)))
247 pitch_wheel_current_.store(newv, std::memory_order_release);
248 return newv;
249 }
251 {
252 /* TODO(C26451): int subtraction: can it overflow? */
253 const auto clow {cc_low_.at(controlnumber)};
254 const auto chigh {cc_high_.at(controlnumber)};
255#ifdef _WIN32
256 const auto newv {
257 std::clamp(_cvt_dtoi_fast(value * static_cast<double>(chigh - clow) + 0.5) + clow,
258 clow, chigh)};
259#else
260 const auto newv {std::clamp(
261 gsl::narrow_cast<int>(value * static_cast<double>(chigh - clow) + 0.5) + clow, clow,
262 chigh)};
263#endif
264#ifdef __cpp_lib_atomic_ref
265 std::atomic_ref(current_v_.at(controlnumber)).store(newv, std::memory_order_release);
266#else
267 current_v_.at(controlnumber).store(newv, std::memory_order_release);
268#endif
269 return newv;
270 }
272 return kMaxMidi;
278 throw std::invalid_argument(fmt::format(FMT_STRING("Unexpected control type in "
279 "ChannelModel::PluginToController. "
280 "Control type {}."),
281 controltype));
282 }
283 throw std::domain_error(fmt::format(FMT_STRING("Undefined control type in "
284 "ChannelModel::PluginToController. "
285 "Control type {}."),
286 controltype));
287 }
288 catch (const std::exception& e) {
290 throw;
291 }
292}

◆ save()

template<class Archive >
void ChannelModel::save ( Archive &  archive,
const uint32_t  version 
) const
private
362{
363 try {
364 switch (version) {
365 case 1:
367 break;
368 case 2:
370 archive(settings_to_save_);
371 break;
372 case 3:
374 archive(settings_to_save_, cereal::make_nvp("PWmax", pitch_wheel_max_),
375 cereal::make_nvp("PWmin", pitch_wheel_min_));
376 break;
377 default:
378 {
379 constexpr auto msg {
380 "The file, 'settings.xml', is marked as a version not supported by the current "
381 "version of MIDI2LR ChannelModel, and won't be loaded. File version: {}."};
382 rsj::LogAndAlertError(fmt::format(juce::translate(msg).toStdString(), version),
383 fmt::format(msg, version));
384 }
385 break;
386 }
387 }
388 catch (const std::exception& e) {
390 throw;
391 }
392}
void ActiveToSaved() const
Definition ControlsModel.cpp:397

◆ SavedToActive()

void ChannelModel::SavedToActive ( )
private
435{
436 try {
437 CcDefaults();
438 for (const auto& set : settings_to_save_) {
439 SetCc(set.control_number, set.low, set.high, set.method);
440 }
441 }
442 catch (const std::exception& e) {
444 throw;
445 }
446}
void SetCc(int controlnumber, int min, int max, rsj::CCmethod controltype)
Definition ControlsModel.cpp:296

◆ SaveSettings()

void ChannelModel::SaveSettings ( int  start,
int  end,
int  maxVal 
) const
private
388{
389 for (auto i {start}; i <= end; ++i) {
390 if (cc_method_.at(i) != rsj::CCmethod::kAbsolute || cc_high_.at(i) != maxVal
391 || cc_low_.at(i) != 0) {
392 settings_to_save_.emplace_back(i, cc_low_.at(i), cc_high_.at(i), cc_method_.at(i));
393 }
394 }
395}

◆ SetCc()

void ChannelModel::SetCc ( int  controlnumber,
int  min,
int  max,
rsj::CCmethod  controltype 
)
298{
299 try {
300 /* CcMethod has to be set before others or ranges won't be correct */
301 SetCcMethod(controlnumber, controltype);
302 SetCcMin(controlnumber, min);
303 SetCcMax(controlnumber, max);
304 }
305 catch (const std::exception& e) {
307 throw;
308 }
309}
void SetCcMethod(int controlnumber, rsj::CCmethod value)
Definition ControlsModel.h:167
void SetCcMax(int controlnumber, int value)
Definition ControlsModel.cpp:328
void SetCcMin(int controlnumber, int value)
Definition ControlsModel.cpp:353

◆ SetCcAll()

void ChannelModel::SetCcAll ( int  controlnumber,
int  min,
int  max,
rsj::CCmethod  controltype 
)
313{
314 try {
315 if (IsNrpn(controlnumber)) {
316 for (auto a {kMaxMidi + 1}; a <= kMaxNrpn; ++a) { SetCc(a, min, max, controltype); }
317 }
318 else {
319 for (auto a {0}; a <= kMaxMidi; ++a) { SetCc(a, min, max, controltype); }
320 }
321 }
322 catch (const std::exception& e) {
324 throw;
325 }
326}

◆ SetCcMax()

void ChannelModel::SetCcMax ( int  controlnumber,
int  value 
)
329{
330 try {
331 Expects(value <= kMaxNrpn && value >= 0);
332 if (cc_method_.at(controlnumber) != rsj::CCmethod::kAbsolute) {
333 cc_high_.at(controlnumber) = value < 0 ? 1000 : value;
334 }
335 else {
336 const auto max {IsNrpn(controlnumber) ? kMaxNrpn : kMaxMidi};
337 cc_high_.at(controlnumber) =
338 value <= cc_low_.at(controlnumber) || value > max ? max : value;
339 }
340#ifdef __cpp_lib_atomic_ref
341 std::atomic_ref(current_v_.at(controlnumber))
342 .store(CenterCc(controlnumber), std::memory_order_release);
343#else
344 current_v_.at(controlnumber).store(CenterCc(controlnumber), std::memory_order_release);
345#endif
346 }
347 catch (const std::exception& e) {
349 throw;
350 }
351}
int CenterCc(int controlnumber) const noexcept
Definition ControlsModel.h:179

◆ SetCcMethod()

void ChannelModel::SetCcMethod ( int  controlnumber,
rsj::CCmethod  value 
)
inline
168 {
169 cc_method_.at(controlnumber) = value;
170 }

◆ SetCcMin()

void ChannelModel::SetCcMin ( int  controlnumber,
int  value 
)
354{
355 try {
356 if (cc_method_.at(controlnumber) != rsj::CCmethod::kAbsolute) {
357 cc_low_.at(controlnumber) = 0;
358 }
359 else {
360 cc_low_.at(controlnumber) = value < 0 || value >= cc_high_.at(controlnumber) ? 0 : value;
361 }
362#ifdef __cpp_lib_atomic_ref
363 std::atomic_ref(current_v_.at(controlnumber))
364 .store(CenterCc(controlnumber), std::memory_order_release);
365#else
366 current_v_.at(controlnumber).store(CenterCc(controlnumber), std::memory_order_release);
367#endif
368 }
369 catch (const std::exception& e) {
371 throw;
372 }
373}

◆ SetPwMax()

void ChannelModel::SetPwMax ( int  value)
noexcept
376{
377 pitch_wheel_max_ = value > kMaxNrpn || value <= pitch_wheel_min_ ? kMaxNrpn : value;
378 pitch_wheel_current_.store(CenterPw(), std::memory_order_release);
379}
int CenterPw() const noexcept
Definition ControlsModel.h:186

◆ SetPwMin()

void ChannelModel::SetPwMin ( int  value)
noexcept
382{
383 pitch_wheel_min_ = value < 0 || value >= pitch_wheel_max_ ? 0 : value;
384 pitch_wheel_current_.store(CenterPw(), std::memory_order_release);
385}

◆ SetToCenter()

int ChannelModel::SetToCenter ( rsj::MessageType  controltype,
int  controlnumber 
)
132{
133 try {
134 auto retval {0};
135 switch (controltype) {
137 retval = CenterPw();
138 pitch_wheel_current_.store(retval, std::memory_order_release);
139 break;
141 if (cc_method_.at(controlnumber) == rsj::CCmethod::kAbsolute) {
142 retval = CenterCc(controlnumber);
143#ifdef __cpp_lib_atomic_ref
144 std::atomic_ref(current_v_.at(controlnumber)).store(retval, std::memory_order_release);
145#else
146 current_v_.at(controlnumber).store(retval, std::memory_order_release);
147#endif
148 }
149 break;
156 break;
157 }
158 return retval;
159 }
160 catch (const std::exception& e) {
162 throw;
163 }
164}

Friends And Related Symbol Documentation

◆ cereal::access

friend class cereal::access
friend

Member Data Documentation

◆ cc_high_

std::array<int, kMaxControls> ChannelModel::cc_high_ {}
private
214{};

◆ cc_low_

std::array<int, kMaxControls> ChannelModel::cc_low_ {}
private
215{};

◆ cc_method_

std::array<rsj::CCmethod, kMaxControls> ChannelModel::cc_method_ {}
private
213{};

◆ current_v_

std::array<std::atomic<int>, kMaxControls> ChannelModel::current_v_ {}
private
219{};

◆ kBit14

constexpr int ChannelModel::kBit14 {0x2000}
staticconstexprprivate
133{0x2000};

◆ kBit7

constexpr int ChannelModel::kBit7 {0x40}
staticconstexprprivate
134{0x40};

◆ kLow13Bits

constexpr int ChannelModel::kLow13Bits {0x1FFF}
staticconstexprprivate
135{0x1FFF};

◆ kLow6Bits

constexpr int ChannelModel::kLow6Bits {0x3F}
staticconstexprprivate
136{0x3F};

◆ kMaxControls

constexpr size_t ChannelModel::kMaxControls {0x4000}
staticconstexprprivate
141{0x4000};

◆ kMaxMidi

constexpr int ChannelModel::kMaxMidi {0x7F}
staticconstexprprivate
137{0x7F};

◆ kMaxMidiHalf

constexpr int ChannelModel::kMaxMidiHalf {kMaxMidi / 2}
staticconstexprprivate
138{kMaxMidi / 2};

◆ kMaxNrpn

constexpr int ChannelModel::kMaxNrpn {0x3FFF}
staticconstexprprivate
139{0x3FFF};

◆ kMaxNrpnHalf

constexpr int ChannelModel::kMaxNrpnHalf {kMaxNrpn / 2}
staticconstexprprivate
140{kMaxNrpn / 2};

◆ pitch_wheel_current_

std::atomic<int> ChannelModel::pitch_wheel_current_ {kMaxNrpnHalf}
private

◆ pitch_wheel_max_

int ChannelModel::pitch_wheel_max_ {kMaxNrpn}
private
210{kMaxNrpn};

◆ pitch_wheel_min_

int ChannelModel::pitch_wheel_min_ {0}
private
211{0};

◆ settings_to_save_

std::vector<rsj::SettingsStruct> ChannelModel::settings_to_save_ {}
mutableprivate
209{};

The documentation for this class was generated from the following files: