From d9de6f2c4cd2e866df4d4742a2d32f5c17aff7e2 Mon Sep 17 00:00:00 2001 From: Hans Baier Date: Thu, 24 Apr 2008 15:04:56 +0000 Subject: [PATCH] * preliminary impl for PGM Change support in MidiModel git-svn-id: svn://localhost/ardour2/branches/3.0@3283 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/mixer_strip.cc | 3 ++- libs/ardour/ardour/midi_model.h | 13 +++++++++--- libs/ardour/midi_model.cc | 35 +++++++++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 86872dd3b0..dff81bc5b6 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -261,8 +261,9 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr rt global_vpacker.pack_start (*gain_meter_alignment,Gtk::PACK_SHRINK); global_vpacker.pack_start (bottom_button_table,Gtk::PACK_SHRINK); global_vpacker.pack_start (post_processor_box, true, true); - if (!is_midi_track()) + if (!is_midi_track()) { global_vpacker.pack_start (panners, Gtk::PACK_SHRINK); + } global_vpacker.pack_start (output_button, Gtk::PACK_SHRINK); global_vpacker.pack_start (comment_button, Gtk::PACK_SHRINK); diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index 1382e3b8df..7a8dd0bad6 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -92,7 +92,6 @@ public: inline size_t n_notes() const { return _notes.size(); } inline bool empty() const { return _notes.size() == 0 && _controls.size() == 0; } - typedef std::vector< boost::shared_ptr > Notes; inline static bool note_time_comparator (const boost::shared_ptr a, const boost::shared_ptr b) { @@ -107,9 +106,14 @@ public: } }; + typedef std::vector< boost::shared_ptr > Notes; inline Notes& notes() { return _notes; } inline const Notes& notes() const { return _notes; } - + + typedef std::vector PgmChanges; + inline PgmChanges& pgm_changes() { return _pgm_changes; } + inline const PgmChanges& pgm_changes() const { return _pgm_changes; } + /** Add/Remove notes. * Technically all operations can be implemented as one of these. */ @@ -191,6 +195,7 @@ public: Notes::const_iterator _note_iter; std::vector _control_iters; std::vector::iterator _control_iter; + PgmChanges::const_iterator _pgm_change_iter; }; const_iterator begin() const { return const_iterator(*this, 0); } @@ -217,7 +222,9 @@ private: mutable Glib::RWLock _lock; - Notes _notes; + Notes _notes; + PgmChanges _pgm_changes; + NoteMode _note_mode; typedef std::vector WriteNotes; diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index eea936e05b..374eaed6d9 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -131,16 +131,33 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t) else _control_iter = _control_iters.end(); + _pgm_change_iter = model.pgm_changes().end(); + // find first program change which begins after t + for (vector::const_iterator i = model.pgm_changes().begin(); i != model.pgm_changes().end(); ++i) { + if (i->time() >= t) { + _pgm_change_iter = i; + break; + } + } + + if(_pgm_change_iter != model.pgm_changes().end()) { + if(_pgm_change_iter->time() <= _event.time()) { + _event = MIDI::Event((*_pgm_change_iter), true); + } + } + if (_event.size() == 0) { //cerr << "Created MIDI iterator @ " << t << " is at end." << endl; _is_end = true; + + // FIXME: possible race condition here.... if(_locked) { - _model->read_unlock(); - _locked = false; + _model->read_unlock(); + _locked = false; } } else { printf("MIDI Iterator = %X @ %lf\n", _event.type(), _event.time()); -} + } } @@ -194,7 +211,7 @@ MidiModel::const_iterator::operator++() */ - enum Type { NIL, NOTE_ON, NOTE_OFF, CC }; + enum Type { NIL, NOTE_ON, NOTE_OFF, CC, PGM_CHANGE, PITCH_BENDER }; Type type = NIL; double t = 0; @@ -219,6 +236,12 @@ MidiModel::const_iterator::operator++() if (type == NIL || _control_iter->x < t) type = CC; */ + if(_pgm_change_iter != _model->pgm_changes().end()) { + if(_pgm_change_iter->time() <= t) { + type = PGM_CHANGE; + t = _pgm_change_iter->time(); + } + } if (type == NOTE_ON) { cerr << "********** MIDI Iterator = note on" << endl; @@ -232,6 +255,9 @@ MidiModel::const_iterator::operator++() } else if (type == CC) { cerr << "********** MIDI Iterator = CC" << endl; _model->control_to_midi_event(_event, *_control_iter); + } else if (type == PGM_CHANGE) { + cerr << "********** MIDI Iterator = program change" << endl; + _event = MIDI::Event(*_pgm_change_iter, true); } else { cerr << "********** MIDI Iterator = END" << endl; _is_end = true; @@ -269,6 +295,7 @@ MidiModel::const_iterator::operator=(const const_iterator& other) _note_iter = other._note_iter; _control_iters = other._control_iters; _control_iter = other._control_iter; + _pgm_change_iter = other._pgm_change_iter; assert( ! _event.owns_buffer());