MIDI2LR 6.2.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
37: devices_(devices) {}
Devices & devices_
Definition MIDISender.h:57

◆ ~MidiSender()

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

◆ 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(FMT_STRING("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(FMT_STRING("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:113

◆ 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

◆ 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

◆ 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

◆ 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}

◆ 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}

◆ 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}

◆ 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}
bool EnabledOrNew(const juce::MidiDeviceInfo &info, const juce::String &io)
Definition Devices.cpp:153

◆ 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}

Member Data Documentation

◆ devices_

Devices& MidiSender::devices_
private

◆ output_devices_

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

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