MIDI2LR 6.3.0.1
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
MidiSender Class Reference

#include <MIDISender.h>

Public Member Functions

 MidiSender (const MidiSender &other)=delete
 MidiSender (Devices &devices) noexcept
 MidiSender (MidiSender &&other) noexcept=delete
 ~MidiSender ()
MidiSenderoperator= (const MidiSender &other)=delete
MidiSenderoperator= (MidiSender &&other) noexcept=delete
void RescanDevices ()
void Send (rsj::MidiMessageId id, int value) const
void Start ()

Private Member Functions

void InitDevices ()
void SendControllerEvent (rsj::MidiMessageId id, int value) const
void SendNoteOn (rsj::MidiMessageId id, int value) const
void SendNrpn (rsj::MidiMessageId id, int value) const
void SendPitchWheel (rsj::MidiMessageId id, int value) const
bool ShouldOpenDevice (const std::string &devname, const auto &open_device)

Private Attributes

Devicesdevices_
std::vector< std::unique_ptr< juce::MidiOutput > > output_devices_

Constructor & Destructor Documentation

◆ MidiSender() [1/3]

MidiSender::MidiSender ( Devices & devices)
inlineexplicitnoexcept
33: devices_(devices) {}
Devices & devices_
Definition MIDISender.h:53

References devices_.

◆ ~MidiSender()

MidiSender::~MidiSender ( )
inline
35{ output_devices_.clear(); /* close devices */ }
std::vector< std::unique_ptr< juce::MidiOutput > > output_devices_
Definition MIDISender.h:55

◆ MidiSender() [2/3]

MidiSender::MidiSender ( const MidiSender & other)
delete

◆ MidiSender() [3/3]

MidiSender::MidiSender ( MidiSender && other)
deletenoexcept

Member Function Documentation

◆ InitDevices()

void MidiSender::InitDevices ( )
private
144{
145 try {
146 const auto available_devices {juce::MidiOutput::getAvailableDevices()};
147 for (const auto& device : available_devices) {
148 if (auto open_device {juce::MidiOutput::openDevice(device.identifier)}) {
149 const auto devname {open_device->getName().toStdString()};
150 if (ShouldOpenDevice(devname, open_device)) {
151 rsj::Log(fmt::format("Opened output device {}.", devname),
152 std::source_location::current());
153 output_devices_.push_back(std::move(open_device));
154 }
155 else {
156 rsj::Log(fmt::format("Ignored output device {}.", devname),
157 std::source_location::current());
158 }
159 }
160 } /* devices that are skipped have their pointers deleted and are automatically closed*/
161 }
162 catch (const std::exception& e) {
163 rsj::ExceptionResponse(e, std::source_location::current());
164 throw;
165 }
166}
bool ShouldOpenDevice(const std::string &devname, const auto &open_device)
Definition MIDISender.cpp:132
void ExceptionResponse(gsl::czstring id, gsl::czstring fu, const std::exception &e) noexcept
void Log(const juce::String &info, const std::source_location &location=std::source_location::current()) noexcept
Definition Misc.cpp:112

Referenced by RescanDevices(), and Start().

◆ operator=() [1/2]

MidiSender & MidiSender::operator= ( const MidiSender & other)
delete

◆ operator=() [2/2]

MidiSender & MidiSender::operator= ( MidiSender && other)
deletenoexcept

◆ RescanDevices()

void MidiSender::RescanDevices ( )
120{
121 try {
122 output_devices_.clear();
123 rsj::Log("Cleared output devices.", std::source_location::current());
124 InitDevices();
125 }
126 catch (const std::exception& e) {
127 rsj::ExceptionResponse(e, std::source_location::current());
128 throw;
129 }
130}
void InitDevices()
Definition MIDISender.cpp:143

References InitDevices(), and output_devices_.

Referenced by MainContentComponent::RescanClicked().

◆ Send()

void MidiSender::Send ( rsj::MidiMessageId id,
int value ) const
54{
55 try {
56 switch (id.msg_id_type) {
58 SendControllerEvent(id, value);
59 break;
61 SendNoteOn(id, value);
62 break;
64 SendPitchWheel(id, value);
65 break;
66 default:
67 LogUnexpectedDataType(id);
68 break;
69 }
70 }
71 catch (const std::exception& e) {
72 rsj::ExceptionResponse(e, std::source_location::current());
73 throw;
74 }
75}
void SendNoteOn(rsj::MidiMessageId id, int value) const
Definition MIDISender.cpp:83
void SendPitchWheel(rsj::MidiMessageId id, int value) const
Definition MIDISender.cpp:77
void SendControllerEvent(rsj::MidiMessageId id, int value) const
Definition MIDISender.cpp:90
@ kCc
Definition MidiUtilities.h:45
@ kNoteOn
Definition MidiUtilities.h:43
@ kPw
Definition MidiUtilities.h:48

References rsj::kCc, rsj::kNoteOn, rsj::kPw, rsj::MidiMessageId::msg_id_type, SendControllerEvent(), SendNoteOn(), and SendPitchWheel().

◆ SendControllerEvent()

void MidiSender::SendControllerEvent ( rsj::MidiMessageId id,
int value ) const
private
91{
92 if (id.control_number < 128 && value < 128) {
93 /* regular message */
94 const auto msg {juce::MidiMessage::controllerEvent(id.channel, id.control_number, value)};
95 for (const auto& dev : output_devices_) { dev->sendMessageNow(msg); }
96 }
97 else {
98 /* NPRN */
99 SendNrpn(id, value);
100 }
101}
void SendNrpn(rsj::MidiMessageId id, int value) const
Definition MIDISender.cpp:103

References rsj::MidiMessageId::control_number, and SendNrpn().

Referenced by Send().

◆ SendNoteOn()

void MidiSender::SendNoteOn ( rsj::MidiMessageId id,
int value ) const
private
84{
85 const auto msg {juce::MidiMessage::noteOn(id.channel, id.control_number,
86 gsl::narrow_cast<juce::uint8>(value))};
87 for (const auto& dev : output_devices_) { dev->sendMessageNow(msg); }
88}

Referenced by Send().

◆ SendNrpn()

void MidiSender::SendNrpn ( rsj::MidiMessageId id,
int value ) const
private
104{
105 const auto msg_parm_msb {
106 juce::MidiMessage::controllerEvent(id.channel, 99, id.control_number >> 7 & 0x7F)};
107 const auto msg_parm_lsb {
108 juce::MidiMessage::controllerEvent(id.channel, 98, id.control_number & 0x7f)};
109 const auto msg_val_msb {juce::MidiMessage::controllerEvent(id.channel, 6, value >> 7 & 0x7F)};
110 const auto msg_val_lsb {juce::MidiMessage::controllerEvent(id.channel, 38, value & 0x7f)};
111 for (const auto& dev : output_devices_) {
112 dev->sendMessageNow(msg_parm_msb);
113 dev->sendMessageNow(msg_parm_lsb);
114 dev->sendMessageNow(msg_val_msb);
115 dev->sendMessageNow(msg_val_lsb);
116 }
117}

Referenced by SendControllerEvent().

◆ SendPitchWheel()

void MidiSender::SendPitchWheel ( rsj::MidiMessageId id,
int value ) const
private
78{
79 const auto msg {juce::MidiMessage::pitchWheel(id.channel, value)};
80 for (const auto& dev : output_devices_) { dev->sendMessageNow(msg); }
81}

Referenced by Send().

◆ ShouldOpenDevice()

bool MidiSender::ShouldOpenDevice ( const std::string & devname,
const auto & open_device )
private
133{
134 if constexpr (MSWindows) {
135 return devname != "Microsoft GS Wavetable Synth"
136 && devices_.EnabledOrNew(open_device->getDeviceInfo(), "output");
137 }
138 else {
139 return devices_.EnabledOrNew(open_device->getDeviceInfo(), "output");
140 }
141}

References devices_.

◆ Start()

void MidiSender::Start ( )
33{
34 try {
36 }
37 catch (const std::exception& e) {
38 rsj::ExceptionResponse(e, std::source_location::current());
39 throw;
40 }
41}

References InitDevices().

Member Data Documentation

◆ devices_

Devices& MidiSender::devices_
private

Referenced by MidiSender(), and ShouldOpenDevice().

◆ output_devices_

std::vector<std::unique_ptr<juce::MidiOutput> > MidiSender::output_devices_
private

Referenced by RescanDevices().


The documentation for this class was generated from the following files:
  • C:/Users/rsjaf/source/repos/MIDI2LR/src/application/MIDISender.h
  • C:/Users/rsjaf/source/repos/MIDI2LR/src/application/MIDISender.cpp