diff options
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 10 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_diskstream.h | 14 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_track.h | 5 | ||||
-rw-r--r-- | libs/ardour/midi_diskstream.cc | 35 | ||||
-rw-r--r-- | libs/ardour/midi_track.cc | 12 |
6 files changed, 56 insertions, 22 deletions
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index fcab483287..0f30c35733 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -305,7 +305,7 @@ MidiRegionView::connect_to_diskstream () { midi_view()->midi_track()->DataRecorded.connect( *this, invalidator(*this), - ui_bind(&MidiRegionView::data_recorded, this, _1, _2), + ui_bind(&MidiRegionView::data_recorded, this, _1), gui_context()); } @@ -3525,11 +3525,10 @@ MidiRegionView::set_step_edit_cursor_width (Evoral::MusicalTime beats) } /** Called when a diskstream on our track has received some data. Update the view, if applicable. - * @param buf Data that has been recorded. - * @param w Source that this data will end up in. + * @param w Source that the data will end up in. */ void -MidiRegionView::data_recorded (boost::shared_ptr<MidiBuffer> buf, boost::weak_ptr<MidiSource> w) +MidiRegionView::data_recorded (boost::weak_ptr<MidiSource> w) { if (!_active_notes) { /* we aren't actively being recorded to */ @@ -3543,6 +3542,9 @@ MidiRegionView::data_recorded (boost::shared_ptr<MidiBuffer> buf, boost::weak_pt } MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*> (&trackview); + + boost::shared_ptr<MidiBuffer> buf = mtv->midi_track()->get_gui_feed_buffer (); + BeatsFramesConverter converter (trackview.session()->tempo_map(), mtv->midi_track()->get_capture_start_frame (0)); framepos_t back = max_framepos; diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index c43c863afe..70939ac640 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -456,7 +456,7 @@ private: void display_patch_changes_on_channel (uint8_t); void connect_to_diskstream (); - void data_recorded (boost::shared_ptr<ARDOUR::MidiBuffer>, boost::weak_ptr<ARDOUR::MidiSource>); + void data_recorded (boost::weak_ptr<ARDOUR::MidiSource>); void remove_ghost_note (); void mouse_mode_changed (); diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h index 6500871412..a7695b5ebf 100644 --- a/libs/ardour/ardour/midi_diskstream.h +++ b/libs/ardour/ardour/midi_diskstream.h @@ -110,10 +110,12 @@ class MidiDiskstream : public Diskstream } /** Emitted when some MIDI data has been received for recording. - * First parameter is the data. - * Second parameter is the source that it is destined for. + * Parameter is the source that it is destined for. + * A caller can get a copy of the data with get_gui_feed_buffer () */ - PBD::Signal2<void, boost::shared_ptr<MidiBuffer>, boost::weak_ptr<MidiSource> > DataRecorded; + PBD::Signal1<void, boost::weak_ptr<MidiSource> > DataRecorded; + + boost::shared_ptr<MidiBuffer> get_gui_feed_buffer () const; protected: friend class Session; @@ -189,6 +191,12 @@ class MidiDiskstream : public Diskstream NoteMode _note_mode; volatile gint _frames_written_to_ringbuffer; volatile gint _frames_read_from_ringbuffer; + + /** A buffer that we use to put newly-arrived MIDI data in for + the GUI to read (so that it can update itself). + */ + MidiBuffer _gui_feed_buffer; + mutable Glib::Mutex _gui_feed_buffer_mutex; }; }; /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 3d1ef558dc..a70fc4604d 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -104,7 +104,8 @@ public: return false; } - PBD::Signal2<void, boost::shared_ptr<MidiBuffer>, boost::weak_ptr<MidiSource> > DataRecorded; + PBD::Signal1<void, boost::weak_ptr<MidiSource> > DataRecorded; + boost::shared_ptr<MidiBuffer> get_gui_feed_buffer () const; void set_input_active (bool); bool input_active () const; @@ -138,7 +139,7 @@ protected: int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing); void push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes); - void diskstream_data_recorded (boost::shared_ptr<MidiBuffer>, boost::weak_ptr<MidiSource>); + void diskstream_data_recorded (boost::weak_ptr<MidiSource>); PBD::ScopedConnection _diskstream_data_recorded_connection; void track_input_active (IOChange, void*); diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 7ab8c46c30..81217b179a 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -77,6 +77,7 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F , _note_mode(Sustained) , _frames_written_to_ringbuffer(0) , _frames_read_from_ringbuffer(0) + , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI)) { in_set_state = true; @@ -96,6 +97,7 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node) , _note_mode(Sustained) , _frames_written_to_ringbuffer(0) , _frames_read_from_ringbuffer(0) + , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI)) { in_set_state = true; @@ -549,17 +551,23 @@ MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecnt } if (buf.size() != 0) { - /* XXX this needs fixing - realtime new() call for - every time we get MIDI data in a process callback! - */ - - /* Make a copy of this data and emit it for the GUI to see */ - boost::shared_ptr<MidiBuffer> copy (new MidiBuffer (buf.capacity ())); - for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) { - copy->push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer()); + Glib::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::TRY_LOCK); + + if (lm.locked ()) { + /* Copy this data into our GUI feed buffer and tell the GUI + that it can read it if it likes. + */ + _gui_feed_buffer.clear (); + + for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) { + /* This may fail if buf is larger than _gui_feed_buffer, but it's not really + the end of the world if it does. + */ + _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer()); + } } - DataRecorded (copy, _write_source); /* EMIT SIGNAL */ + DataRecorded (_write_source); /* EMIT SIGNAL */ } } else { @@ -1450,3 +1458,12 @@ MidiDiskstream::set_name (string const & name) return true; } +boost::shared_ptr<MidiBuffer> +MidiDiskstream::get_gui_feed_buffer () const +{ + boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI))); + + Glib::Mutex::Lock lm (_gui_feed_buffer_mutex); + b->copy (_gui_feed_buffer); + return b; +} diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 9114311ac9..3253485412 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -122,7 +122,7 @@ MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds) boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds); mds->DataRecorded.connect_same_thread ( _diskstream_data_recorded_connection, - boost::bind (&MidiTrack::diskstream_data_recorded, this, _1, _2)); + boost::bind (&MidiTrack::diskstream_data_recorded, this, _1)); DiskstreamChanged (); /* EMIT SIGNAL */ } @@ -654,9 +654,9 @@ MidiTrack::midi_playlist () } void -MidiTrack::diskstream_data_recorded (boost::shared_ptr<MidiBuffer> buf, boost::weak_ptr<MidiSource> src) +MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src) { - DataRecorded (buf, src); /* EMIT SIGNAL */ + DataRecorded (src); /* EMIT SIGNAL */ } bool @@ -717,3 +717,9 @@ MidiTrack::diskstream_factory (XMLNode const & node) { return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node)); } + +boost::shared_ptr<MidiBuffer> +MidiTrack::get_gui_feed_buffer () const +{ + return midi_diskstream()->get_gui_feed_buffer (); +} |