{
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());
}
}
/** 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 */
}
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;
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 ();
}
/** 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;
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 */
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;
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*);
, _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;
, _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;
}
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 {
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;
+}
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 */
}
}
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
{
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 ();
+}