make Route::input_change_handler() virtual and use it in MidiTrack to notice incoming notes

This commit is contained in:
Paul Davis 2025-11-06 09:18:01 -07:00
parent 40ba396278
commit 47eeb6dd98
5 changed files with 43 additions and 2 deletions

View file

@ -68,6 +68,9 @@ class LIBARDOUR_API MidiPort : public Port {
void read_and_parse_entire_midi_buffer_with_no_speed_adjustment (pframes_t nframes, MIDI::Parser& parser, samplepos_t now);
PBD::Signal<void(int)> NoteOn;
PBD::Signal<void(int)> NoteOff;
protected:
friend class PortManager;

View file

@ -142,6 +142,8 @@ public:
void realtime_handle_transport_stopped ();
void region_edited (std::shared_ptr<Region>);
int last_seen_external_midi_note () const { return _last_seen_external_midi_note; }
protected:
XMLNode& state (bool save_template) const;
@ -152,6 +154,8 @@ protected:
void snapshot_out_of_band_data (samplecnt_t nframes);
void write_out_of_band_data (BufferSet& bufs, samplecnt_t /* nframes */) const;
void input_change_handler (IOChange, void *src);
private:
MidiRingBuffer<samplepos_t> _immediate_events;
@ -165,6 +169,7 @@ private:
bool _restore_pgm_on_load;
MidiChannelFilter _playback_filter;
MidiChannelFilter _capture_filter;
int _last_seen_external_midi_note;
std::shared_ptr<VelocityControl> _velocity_control;
@ -185,7 +190,9 @@ private:
void playlist_contents_changed ();
PBD::ScopedConnection playlist_content_change_connection;
PBD::ScopedConnectionList note_connections;
void note_on_handler (int);
};
} /* namespace ARDOUR*/

View file

@ -710,6 +710,8 @@ protected:
SlavableAutomationControlList slavables () const;
virtual void input_change_handler (IOChange, void *src);
private:
/* no copy construction */
Route (Route const &);
@ -717,7 +719,6 @@ private:
int set_state_2X (const XMLNode&, int);
void set_processor_state_2X (XMLNodeList const &, int);
void input_change_handler (IOChange, void *src);
void output_change_handler (IOChange, void *src);
void sidechain_change_handler (IOChange, void *src);

View file

@ -152,6 +152,14 @@ MidiPort::get_midi_buffer (pframes_t nframes)
timestamp -= _global_port_buffer_offset;
if (size == 3) {
if (((buf[0] & 0xF0) == 0x90) && (buf[2] != 0)) {
NoteOn (buf[1]);
} else if (((buf[0] & 0xF0) == 0x80) || (((buf[0] & 0xF0) == 0x90) && (buf[2] == 0))) {
NoteOff (buf[1]);
}
}
if ((buf[0] & 0xF0) == 0x90 && buf[2] == 0) {
/* normalize note on with velocity 0 to proper note off */
uint8_t ev[3];

View file

@ -90,6 +90,7 @@ MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
, _step_editing (false)
, _input_active (true)
, _restore_pgm_on_load (true)
, _last_seen_external_midi_note (-1)
{
_session.SessionLoaded.connect_same_thread (*this, std::bind (&MidiTrack::restore_controls, this));
@ -979,3 +980,24 @@ MidiTrack::playlist_contents_changed ()
{
}
void
MidiTrack::input_change_handler (IOChange change, void *src)
{
note_connections.drop_connections ();
for (auto const & p : *_input->ports()) {
std::shared_ptr<MidiPort> mp = std::dynamic_pointer_cast<MidiPort> (p);
if (mp) {
mp->NoteOn.connect_same_thread (note_connections, std::bind (&MidiTrack::note_on_handler, this, _1));
}
}
Track::input_change_handler (change, src);
}
void
MidiTrack::note_on_handler (int notenum)
{
_last_seen_external_midi_note = notenum;
}