diff --git a/src/grandorgue/CMakeLists.txt b/src/grandorgue/CMakeLists.txt index 12b8730d5..479425d64 100644 --- a/src/grandorgue/CMakeLists.txt +++ b/src/grandorgue/CMakeLists.txt @@ -140,6 +140,7 @@ loader/cache/GOCacheCleaner.cpp loader/cache/GOCacheWriter.cpp midi/dialog-creator/GOMidiDialogCreatorProxy.cpp midi/objects/GOMidiObject.cpp +midi/objects/GOMidiReceivingSendingObject.cpp midi/objects/GOMidiSendingObject.cpp midi/ports/GOMidiInPort.cpp midi/ports/GOMidiOutPort.cpp diff --git a/src/grandorgue/control/GOButtonControl.cpp b/src/grandorgue/control/GOButtonControl.cpp index 3191be70d..1e51c1f63 100644 --- a/src/grandorgue/control/GOButtonControl.cpp +++ b/src/grandorgue/control/GOButtonControl.cpp @@ -19,50 +19,41 @@ GOButtonControl::GOButtonControl( GOOrganModel &organModel, const wxString &midiTypeCode, const wxString &midiTypeName, - GOMidiReceiverType midi_type, + GOMidiReceiverType midiType, bool pushbutton, bool isPiston) - : GOMidiSendingObject( + : GOMidiReceivingSendingObject( organModel, midiTypeCode, midiTypeName, MIDI_SEND_BUTTON, - &m_midi, + midiType, &m_shortcut), - r_OrganModel(organModel), - m_midi(organModel, midi_type), m_shortcut(KEY_RECV_BUTTON), m_Pushbutton(pushbutton), m_Displayed(false), m_Engaged(false), m_DisplayInInvertedState(false), m_ReadOnly(false), - m_IsPiston(isPiston) { - r_OrganModel.RegisterEventHandler(this); -} - -GOButtonControl::~GOButtonControl() { - r_OrganModel.UnRegisterEventHandler(this); -} + m_IsPiston(isPiston) {} void GOButtonControl::LoadMidiObject( GOConfigReader &cfg, const wxString &group, GOMidiMap &midiMap) { - GOMidiSendingObject::LoadMidiObject(cfg, group, midiMap); + GOMidiReceivingSendingObject::LoadMidiObject(cfg, group, midiMap); if (!m_ReadOnly) { - m_midi.Load(cfg, group, midiMap); m_shortcut.Load(cfg, group); } } void GOButtonControl::Init( GOConfigReader &cfg, const wxString &group, const wxString &name) { - GOMidiSendingObject::Init(cfg, group, name); + GOMidiReceivingSendingObject::Init(cfg, group, name); m_Displayed = false; m_DisplayInInvertedState = false; } void GOButtonControl::Load(GOConfigReader &cfg, const wxString &group) { - GOMidiSendingObject::Load( + GOMidiReceivingSendingObject::Load( cfg, group, cfg.ReadStringNotEmpty(ODFSetting, group, wxT("Name"), true)); m_Displayed = cfg.ReadBoolean(ODFSetting, group, wxT("Displayed"), false, false); @@ -72,9 +63,8 @@ void GOButtonControl::Load(GOConfigReader &cfg, const wxString &group) { void GOButtonControl::SaveMidiObject( GOConfigWriter &cfg, const wxString &group, GOMidiMap &midiMap) { - GOMidiSendingObject::SaveMidiObject(cfg, group, midiMap); + GOMidiReceivingSendingObject::SaveMidiObject(cfg, group, midiMap); if (!m_ReadOnly) { - m_midi.Save(cfg, group, midiMap); m_shortcut.Save(cfg, group); } } @@ -102,25 +92,19 @@ void GOButtonControl::Push() { void GOButtonControl::SetButtonState(bool on) {} -void GOButtonControl::PreparePlayback() { - GOMidiSendingObject::PreparePlayback(); - m_midi.PreparePlayback(); -} - void GOButtonControl::PrepareRecording() { - GOMidiSendingObject::PrepareRecording(); + GOMidiReceivingSendingObject::PrepareRecording(); SendMidiValue(m_Engaged); } void GOButtonControl::AbortPlayback() { SendMidiValue(false); - GOMidiSendingObject::AbortPlayback(); + GOMidiReceivingSendingObject::AbortPlayback(); } -void GOButtonControl::ProcessMidi(const GOMidiEvent &event) { - if (m_ReadOnly) - return; - switch (m_midi.Match(event)) { +void GOButtonControl::OnMatchedMidi( + const GOMidiEvent &event, GOMidiMatchType matchType) { + switch (matchType) { case MIDI_MATCH_CHANGE: Push(); break; @@ -156,21 +140,10 @@ bool GOButtonControl::DisplayInverted() const { return m_DisplayInInvertedState; } -void GOButtonControl::SetElementId(int id) { - if (!m_ReadOnly) { - m_midi.SetElementID(id); - GOMidiSendingObject::SetElementId(id); - } -} - void GOButtonControl::SetShortcutKey(unsigned key) { m_shortcut.SetShortcut(key); } -void GOButtonControl::SetPreconfigIndex(unsigned index) { - m_midi.SetIndex(index); -} - wxString GOButtonControl::GetElementStatus() { return m_Engaged ? _("ON") : _("OFF"); } diff --git a/src/grandorgue/control/GOButtonControl.h b/src/grandorgue/control/GOButtonControl.h index d063d9f3a..dbc3ef28c 100644 --- a/src/grandorgue/control/GOButtonControl.h +++ b/src/grandorgue/control/GOButtonControl.h @@ -10,13 +10,11 @@ #include -#include "midi/GOMidiReceiver.h" #include "midi/GOMidiShortcutReceiver.h" -#include "midi/objects/GOMidiSendingObject.h" +#include "midi/objects/GOMidiReceivingSendingObject.h" #include "sound/GOSoundStateHandler.h" #include "GOControl.h" -#include "GOEventHandler.h" class GOConfigReader; class GOConfigWriter; @@ -24,12 +22,8 @@ class GOMidiEvent; class GOMidiMap; class GOOrganModel; -class GOButtonControl : public GOMidiSendingObject, - public GOControl, - private GOEventHandler { +class GOButtonControl : public GOMidiReceivingSendingObject, public GOControl { protected: - GOOrganModel &r_OrganModel; - GOMidiReceiver m_midi; GOMidiShortcutReceiver m_shortcut; bool m_Pushbutton; bool m_Displayed; @@ -43,10 +37,10 @@ class GOButtonControl : public GOMidiSendingObject, void SaveMidiObject( GOConfigWriter &cfg, const wxString &group, GOMidiMap &midiMap) override; - void ProcessMidi(const GOMidiEvent &event) override; + void OnMatchedMidi( + const GOMidiEvent &event, GOMidiMatchType matchType) override; void HandleKey(int key) override; - void PreparePlayback() override; void PrepareRecording() override; void AbortPlayback() override; @@ -55,10 +49,10 @@ class GOButtonControl : public GOMidiSendingObject, GOOrganModel &organModel, const wxString &midiTypeCode, const wxString &midiTypeName, - GOMidiReceiverType midi_type, + GOMidiReceiverType midiType, bool pushbutton, bool isPiston = false); - ~GOButtonControl(); + void Init( GOConfigReader &cfg, const wxString &group, const wxString &name) override; using GOMidiObject::Load; // Avoiding a compilation warning @@ -73,9 +67,7 @@ class GOButtonControl : public GOMidiSendingObject, virtual void Display(bool onoff); bool IsEngaged() const; bool DisplayInverted() const; - void SetElementId(int id) override; void SetShortcutKey(unsigned key); - void SetPreconfigIndex(unsigned index); wxString GetElementStatus() override; std::vector GetElementActions() override; diff --git a/src/grandorgue/midi/objects/GOMidiObject.h b/src/grandorgue/midi/objects/GOMidiObject.h index b210f0cf4..a58f1533e 100644 --- a/src/grandorgue/midi/objects/GOMidiObject.h +++ b/src/grandorgue/midi/objects/GOMidiObject.h @@ -23,8 +23,10 @@ class GOMidiShortcutReceiver; class GOOrganModel; class GOMidiObject : public GOSoundStateHandler, public GOSaveableObject { -private: +protected: GOOrganModel &r_OrganModel; + +private: GOMidiMap &r_MidiMap; const wxString &r_MidiTypeCode; const wxString &r_MidiTypeName; diff --git a/src/grandorgue/midi/objects/GOMidiReceivingSendingObject.cpp b/src/grandorgue/midi/objects/GOMidiReceivingSendingObject.cpp new file mode 100644 index 000000000..21327fce2 --- /dev/null +++ b/src/grandorgue/midi/objects/GOMidiReceivingSendingObject.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2006 Milan Digital Audio LLC + * Copyright 2009-2025 GrandOrgue contributors (see AUTHORS) + * License GPL-2.0 or later + * (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html). + */ + +#include "GOMidiReceivingSendingObject.h" + +#include "model/GOOrganModel.h" + +GOMidiReceivingSendingObject::GOMidiReceivingSendingObject( + GOOrganModel &organModel, + const wxString &midiTypeCode, + const wxString &midiTypeName, + GOMidiSenderType senderType, + GOMidiReceiverType reveiverType, + GOMidiShortcutReceiver *pShortcutReceiver, + GOMidiSender *pDivisionSender) + : GOMidiSendingObject( + organModel, + midiTypeCode, + midiTypeName, + senderType, + &m_receiver, + pShortcutReceiver, + pDivisionSender), + m_receiver(organModel, reveiverType) { + r_OrganModel.RegisterEventHandler(this); +} + +GOMidiReceivingSendingObject::~GOMidiReceivingSendingObject() { + r_OrganModel.UnRegisterEventHandler(this); +} + +void GOMidiReceivingSendingObject::LoadMidiObject( + GOConfigReader &cfg, const wxString &group, GOMidiMap &midiMap) { + GOMidiSendingObject::LoadMidiObject(cfg, group, midiMap); + if (!IsReadOnly()) { + m_receiver.Load(cfg, group, midiMap); + } +} + +void GOMidiReceivingSendingObject::SaveMidiObject( + GOConfigWriter &cfg, const wxString &group, GOMidiMap &midiMap) { + GOMidiSendingObject::SaveMidiObject(cfg, group, midiMap); + if (!IsReadOnly()) { + m_receiver.Save(cfg, group, midiMap); + } +} + +void GOMidiReceivingSendingObject::SetElementId(int id) { + if (!IsReadOnly()) { + m_receiver.SetElementID(id); + GOMidiSendingObject::SetElementId(id); + } +} + +void GOMidiReceivingSendingObject::SetPreconfigIndex(unsigned index) { + m_receiver.SetIndex(index); +} + +void GOMidiReceivingSendingObject::PreparePlayback() { + GOMidiSendingObject::PreparePlayback(); + m_receiver.PreparePlayback(); +} + +void GOMidiReceivingSendingObject::ProcessMidi(const GOMidiEvent &event) { + if (!IsReadOnly()) { + GOMidiMatchType matchType = m_receiver.Match(event); + + if (matchType > MIDI_MATCH_NONE) + OnMatchedMidi(event, matchType); + } +} diff --git a/src/grandorgue/midi/objects/GOMidiReceivingSendingObject.h b/src/grandorgue/midi/objects/GOMidiReceivingSendingObject.h new file mode 100644 index 000000000..5187ca964 --- /dev/null +++ b/src/grandorgue/midi/objects/GOMidiReceivingSendingObject.h @@ -0,0 +1,51 @@ +/* + * Copyright 2006 Milan Digital Audio LLC + * Copyright 2009-2025 GrandOrgue contributors (see AUTHORS) + * License GPL-2.0 or later + * (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html). + */ + +#ifndef GOMIDIRECEIVINGSENDINGOBJECT_H +#define GOMIDIRECEIVINGSENDINGOBJECT_H + +#include "midi/GOMidiReceiver.h" + +#include "GOEventHandler.h" +#include "GOMidiSendingObject.h" + +class GOMidiReceivingSendingObject : public GOMidiSendingObject, + private GOEventHandler { +private: + GOMidiReceiver m_receiver; + +protected: + GOMidiReceivingSendingObject( + GOOrganModel &organModel, + const wxString &midiTypeCode, + const wxString &midiTypeName, + GOMidiSenderType senderType, + GOMidiReceiverType reveiverType, + GOMidiShortcutReceiver *pShortcutReceiver = nullptr, + GOMidiSender *pDivisionSender = nullptr); + + ~GOMidiReceivingSendingObject(); + + virtual void LoadMidiObject( + GOConfigReader &cfg, const wxString &group, GOMidiMap &midiMap) override; + virtual void SaveMidiObject( + GOConfigWriter &cfg, const wxString &group, GOMidiMap &midiMap) override; + + void PreparePlayback() override; + + void ProcessMidi(const GOMidiEvent &event) override; + + virtual void OnMatchedMidi( + const GOMidiEvent &event, GOMidiMatchType matchType) + = 0; + +public: + virtual void SetElementId(int id) override; + void SetPreconfigIndex(unsigned index); +}; + +#endif /* GOMIDIRECEIVINGSENDINGOBJECT_H */ diff --git a/src/grandorgue/midi/objects/GOMidiSendingObject.h b/src/grandorgue/midi/objects/GOMidiSendingObject.h index 0189bdbae..6ce9a8df7 100644 --- a/src/grandorgue/midi/objects/GOMidiSendingObject.h +++ b/src/grandorgue/midi/objects/GOMidiSendingObject.h @@ -33,8 +33,6 @@ class GOMidiSendingObject : public GOMidiObject { void SaveMidiObject( GOConfigWriter &cfg, const wxString &group, GOMidiMap &midiMap) override; - virtual void SetElementId(int id); - void SendMidiValue(bool value) { m_sender.SetDisplay(value); } void SendMidiValue(int value) { m_sender.SetValue(value); } void SendMidiValue(const wxString &value) { m_sender.SetLabel(value); } @@ -45,6 +43,9 @@ class GOMidiSendingObject : public GOMidiObject { void PreparePlayback() override; void AbortPlayback() override; + +public: + virtual void SetElementId(int id); }; #endif /* GOMIDISENDINGOBJECT_H */