2 Copyright (C) 2000-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 #include "pbd/error.h"
32 #include "pbd/basename.h"
33 #include <glibmm/threads.h>
34 #include "pbd/xml++.h"
35 #include "pbd/memento_command.h"
36 #include "pbd/enumwriter.h"
37 #include "pbd/stateful_diff_command.h"
38 #include "pbd/stacktrace.h"
40 #include "ardour/audioengine.h"
41 #include "ardour/butler.h"
42 #include "ardour/debug.h"
43 #include "ardour/io.h"
44 #include "ardour/midi_diskstream.h"
45 #include "ardour/midi_model.h"
46 #include "ardour/midi_playlist.h"
47 #include "ardour/midi_port.h"
48 #include "ardour/midi_region.h"
49 #include "ardour/midi_ring_buffer.h"
50 #include "ardour/midi_track.h"
51 #include "ardour/playlist_factory.h"
52 #include "ardour/region_factory.h"
53 #include "ardour/session.h"
54 #include "ardour/session_playlists.h"
55 #include "ardour/smf_source.h"
56 #include "ardour/types.h"
57 #include "ardour/utils.h"
59 #include "midi++/types.h"
65 using namespace ARDOUR;
68 framecnt_t MidiDiskstream::midi_readahead = 4096;
70 MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
71 : Diskstream(sess, name, flag)
74 , _note_mode(Sustained)
75 , _frames_written_to_ringbuffer(0)
76 , _frames_read_from_ringbuffer(0)
77 , _frames_pending_write(0)
78 , _num_captured_loops(0)
79 , _accumulated_capture_offset(0)
80 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
86 use_new_write_source (0);
91 throw failed_constructor();
95 MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
96 : Diskstream(sess, node)
99 , _note_mode(Sustained)
100 , _frames_written_to_ringbuffer(0)
101 , _frames_read_from_ringbuffer(0)
102 , _frames_pending_write(0)
103 , _num_captured_loops(0)
104 , _accumulated_capture_offset(0)
105 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
111 if (set_state (node, Stateful::loading_state_version)) {
112 in_set_state = false;
113 throw failed_constructor();
116 use_new_write_source (0);
118 in_set_state = false;
122 MidiDiskstream::init ()
124 /* there are no channels at this point, so these
125 two calls just get speed_buffer_size and wrap_buffer
126 size setup without duplicating their code.
129 set_block_size (_session.get_block_size());
130 allocate_temporary_buffers ();
132 const size_t size = _session.butler()->midi_diskstream_buffer_size();
133 _playback_buf = new MidiRingBuffer<framepos_t>(size);
134 _capture_buf = new MidiRingBuffer<framepos_t>(size);
136 _n_channels = ChanCount(DataType::MIDI, 1);
137 interpolation.add_channel_to (0,0);
140 MidiDiskstream::~MidiDiskstream ()
142 Glib::Threads::Mutex::Lock lm (state_lock);
143 delete _playback_buf;
149 MidiDiskstream::non_realtime_locate (framepos_t position)
152 _write_source->set_timeline_position (position);
154 seek (position, false);
159 MidiDiskstream::non_realtime_input_change ()
162 Glib::Threads::Mutex::Lock lm (state_lock);
164 if (input_change_pending.type == IOChange::NoChange) {
168 if (input_change_pending.type & IOChange::ConfigurationChanged) {
169 uint32_t ni = _io->n_ports().n_midi();
171 if (ni != _n_channels.n_midi()) {
172 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
175 _n_channels, input_change_pending.type)
180 _source_port.reset ();
182 _source_port = _io->midi(0);
186 if (input_change_pending.type & IOChange::ConnectionsChanged) {
187 set_capture_offset ();
188 set_align_style_from_io ();
191 input_change_pending.type = IOChange::NoChange;
193 /* implicit unlock */
196 /* unlike with audio, there is never any need to reset write sources
197 based on input configuration changes because ... a MIDI track
198 has just 1 MIDI port as input, always.
201 /* now refill channel buffers */
203 if (speed() != 1.0f || speed() != -1.0f) {
204 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
207 seek (_session.transport_frame());
210 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
211 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
215 MidiDiskstream::find_and_use_playlist (const string& name)
217 boost::shared_ptr<MidiPlaylist> playlist;
219 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
220 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
224 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg;
228 return use_playlist (playlist);
232 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
234 if (boost::dynamic_pointer_cast<MidiPlaylist>(playlist)) {
235 Diskstream::use_playlist(playlist);
242 MidiDiskstream::use_new_playlist ()
245 boost::shared_ptr<MidiPlaylist> playlist;
247 if (!in_set_state && destructive()) {
252 newname = Playlist::bump_name (_playlist->name(), _session);
254 newname = Playlist::bump_name (_name, _session);
257 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
258 DataType::MIDI, _session, newname, hidden()))) != 0) {
260 return use_playlist (playlist);
268 MidiDiskstream::use_copy_playlist ()
274 if (_playlist == 0) {
275 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
280 boost::shared_ptr<MidiPlaylist> playlist;
282 newname = Playlist::bump_name (_playlist->name(), _session);
284 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
285 return use_playlist (playlist);
291 /** Overloaded from parent to die horribly
294 MidiDiskstream::set_destructive (bool yn)
300 MidiDiskstream::set_note_mode (NoteMode m)
303 midi_playlist()->set_note_mode(m);
304 if (_write_source && _write_source->model())
305 _write_source->model()->set_note_mode(m);
308 /** Get the start, end, and length of a location "atomically".
310 * Note: Locations don't get deleted, so all we care about when I say "atomic"
311 * is that we are always pointing to the same one and using start/length values
312 * obtained just once. Use this function to achieve this since location being
313 * a parameter achieves this.
316 get_location_times(const Location* location,
322 *start = location->start();
323 *end = location->end();
324 *length = *end - *start;
329 MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance, bool need_disk_signal)
331 framecnt_t rec_offset = 0;
332 framecnt_t rec_nframes = 0;
333 bool nominally_recording;
334 bool re = record_enabled ();
335 bool can_record = _session.actively_recording ();
337 playback_distance = 0;
339 check_record_status (transport_frame, can_record);
341 nominally_recording = (can_record && re);
347 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
353 Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
359 const Location* const loop_loc = loop_location;
360 framepos_t loop_start = 0;
361 framepos_t loop_end = 0;
362 framepos_t loop_length = 0;
363 get_location_times(loop_loc, &loop_start, &loop_end, &loop_length);
365 adjust_capture_position = 0;
367 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
368 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
369 // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
371 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
372 /* For audio: not writing frames to the capture ringbuffer offsets
373 * the recording. For midi: we need to keep track of the record range
374 * and subtract the accumulated difference from the event time.
377 _accumulated_capture_offset += rec_offset;
379 _accumulated_capture_offset += nframes;
382 if (rec_nframes && !was_recording) {
384 /* Loop recording, so pretend the capture started at the loop
385 start rgardless of what time it is now, so the source starts
386 at the loop start and can handle time wrapping around.
387 Otherwise, start the source right now as usual.
389 capture_captured = transport_frame - loop_start;
390 capture_start_frame = loop_start;
392 _write_source->mark_write_starting_now(
393 capture_start_frame, capture_captured, loop_length);
394 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
395 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
396 was_recording = true;
400 if (can_record && !_last_capture_sources.empty()) {
401 _last_capture_sources.clear ();
404 if (nominally_recording || rec_nframes) {
405 // Pump entire port buffer into the ring buffer (TODO: split cycles?)
406 MidiBuffer& buf = sp->get_midi_buffer(nframes);
407 MidiTrack* mt = dynamic_cast<MidiTrack*>(_track);
408 MidiChannelFilter* filter = mt ? &mt->capture_filter() : NULL;
410 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
411 Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
412 if (ev.time() + rec_offset > rec_nframes) {
416 if (DEBUG_ENABLED(DEBUG::MidiIO)) {
417 const uint8_t* __data = ev.buffer();
419 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
420 for (size_t i=0; i < ev.size(); ++i) {
421 DEBUG_STR_APPEND(a,hex);
422 DEBUG_STR_APPEND(a,"0x");
423 DEBUG_STR_APPEND(a,(int)__data[i]);
424 DEBUG_STR_APPEND(a,' ');
426 DEBUG_STR_APPEND(a,'\n');
427 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
430 /* Write events to the capture buffer in frames from session start,
431 but ignoring looping so event time progresses monotonically.
432 The source knows the loop length so it knows exactly where the
433 event occurs in the series of recorded loops and can implement
434 any desirable behaviour. We don't want to send event with
435 transport time here since that way the source can not
436 reconstruct their actual time; future clever MIDI looping should
437 probably be implemented in the source instead of here.
439 const framecnt_t loop_offset = _num_captured_loops * loop_length;
440 const framepos_t event_time = transport_frame + loop_offset - _accumulated_capture_offset + ev.time();
441 if (event_time < 0 || event_time < first_recordable_frame) {
442 /* Event out of range, skip */
446 if (!filter || !filter->filter(ev.buffer(), ev.size())) {
447 _capture_buf->write(event_time, ev.type(), ev.size(), ev.buffer());
450 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
452 if (buf.size() != 0) {
453 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
456 /* Copy this data into our GUI feed buffer and tell the GUI
457 that it can read it if it likes.
459 _gui_feed_buffer.clear ();
461 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
462 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
463 the end of the world if it does.
465 _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
469 DataRecorded (_write_source); /* EMIT SIGNAL */
477 _accumulated_capture_offset = 0;
483 /* data will be written to disk */
485 if (rec_nframes == nframes && rec_offset == 0) {
486 playback_distance = nframes;
489 adjust_capture_position = rec_nframes;
491 } else if (nominally_recording) {
493 /* XXXX do this for MIDI !!!
494 can't do actual capture yet - waiting for latency effects to finish before we start
497 playback_distance = nframes;
499 } else if (_actual_speed != 1.0f && _target_speed > 0) {
501 interpolation.set_speed (_target_speed);
503 playback_distance = interpolation.distance (nframes);
506 playback_distance = nframes;
509 if (need_disk_signal) {
510 /* copy the diskstream data to all output buffers */
512 MidiBuffer& mbuf (bufs.get_midi (0));
513 get_playback (mbuf, playback_distance);
515 /* leave the audio count alone */
516 ChanCount cnt (DataType::MIDI, 1);
517 cnt.set (DataType::AUDIO, bufs.count().n_audio());
518 bufs.set_count (cnt);
521 if (_target_speed > 0 && _actual_speed != 1.0f) {
522 MidiBuffer& mbuf (bufs.get_midi (0));
523 for (MidiBuffer::iterator i = mbuf.begin(); i != mbuf.end(); ++i) {
524 MidiBuffer::TimeType *tme = i.timeptr();
525 *tme = (*tme) * nframes / playback_distance;
534 MidiDiskstream::calculate_playback_distance (pframes_t nframes)
536 frameoffset_t playback_distance = nframes;
538 if (!record_enabled() && _actual_speed != 1.0f && _actual_speed > 0.f) {
539 interpolation.set_speed (_target_speed);
540 playback_distance = interpolation.distance (nframes, false);
543 if (_actual_speed < 0.0) {
544 return -playback_distance;
546 return playback_distance;
551 MidiDiskstream::commit (framecnt_t playback_distance)
553 bool need_butler = false;
555 if (!_io || !_io->active()) {
559 if (_actual_speed < 0.0) {
560 playback_sample -= playback_distance;
562 playback_sample += playback_distance;
565 if (adjust_capture_position != 0) {
566 capture_captured += adjust_capture_position;
567 adjust_capture_position = 0;
570 uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
571 uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
574 cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
575 " = " << frames_written - frames_read
576 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
579 /* frames_read will generally be less than frames_written, but
580 * immediately after an overwrite, we can end up having read some data
581 * before we've written any. we don't need to trip an assert() on this,
582 * but we do need to check so that the decision on whether or not we
583 * need the butler is done correctly.
588 * Doing heavy GUI operations[1] can stall also the butler.
589 * The RT-thread meanwhile will happily continue and
590 * ‘frames_read’ (from buffer to output) will become larger
591 * than ‘frames_written’ (from disk to buffer).
593 * The disk-stream is now behind..
595 * In those cases the butler needs to be summed to refill the buffer (done now)
596 * AND we need to skip (frames_read - frames_written). ie remove old events
597 * before playback_sample from the rinbuffer.
599 * [1] one way to do so is described at #6170.
600 * For me just popping up the context-menu on a MIDI-track header
601 * of a track with a large (think beethoven :) midi-region also did the
602 * trick. The playhead stalls for 2 or 3 sec, until the context-menu shows.
604 * In both cases the root cause is that redrawing MIDI regions on the GUI is still very slow
607 if (frames_read <= frames_written) {
608 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
620 MidiDiskstream::set_pending_overwrite (bool yn)
622 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
624 _pending_overwrite = yn;
625 overwrite_frame = playback_sample;
629 MidiDiskstream::overwrite_existing_buffers ()
631 /* Clear the playback buffer contents. This is safe as long as the butler
632 thread is suspended, which it should be. */
633 _playback_buf->reset ();
634 _playback_buf->reset_tracker ();
636 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
637 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
639 /* Resolve all currently active notes in the playlist. This is more
640 aggressive than it needs to be: ideally we would only resolve what is
641 absolutely necessary, but this seems difficult and/or impossible without
642 having the old data or knowing what change caused the overwrite. */
643 midi_playlist()->resolve_note_trackers (*_playback_buf, overwrite_frame);
645 read (overwrite_frame, disk_read_chunk_frames, false);
646 file_frame = overwrite_frame; // it was adjusted by ::read()
647 overwrite_queued = false;
648 _pending_overwrite = false;
654 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
656 Glib::Threads::Mutex::Lock lm (state_lock);
659 if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
660 /* we haven't read anything since the last seek,
661 so flush all note trackers to prevent
667 _playback_buf->reset();
668 _capture_buf->reset();
669 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
670 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
672 playback_sample = frame;
675 if (complete_refill) {
676 while ((ret = do_refill_with_alloc ()) > 0) ;
678 ret = do_refill_with_alloc ();
685 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
687 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
688 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
689 return ((frames_written - frames_read) < distance);
693 MidiDiskstream::internal_playback_seek (framecnt_t distance)
695 first_recordable_frame += distance;
696 playback_sample += distance;
701 /** @a start is set to the new frame position (TIME) read up to */
703 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
705 framecnt_t this_read = 0;
707 framepos_t loop_end = 0;
708 framepos_t loop_start = 0;
709 framecnt_t loop_length = 0;
712 MidiTrack* mt = dynamic_cast<MidiTrack*>(_track);
713 MidiChannelFilter* filter = mt ? &mt->playback_filter() : NULL;
718 get_location_times(loc, &loop_start, &loop_end, &loop_length);
720 /* if we are looping, ensure that the first frame we read is at the correct
721 position within the loop.
724 if (loc && (start >= loop_end)) {
725 //cerr << "start adjusted from " << start;
726 start = loop_start + ((start - loop_start) % loop_length);
727 //cerr << "to " << start << endl;
729 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
734 /* take any loop into account. we can't read past the end of the loop. */
736 if (loc && (loop_end - start <= dur)) {
737 this_read = loop_end - start;
738 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
745 if (this_read == 0) {
749 this_read = min(dur,this_read);
751 if (midi_playlist()->read (*_playback_buf, start, this_read, 0, filter) != this_read) {
752 error << string_compose(
753 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
754 id(), this_read, start) << endmsg;
758 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
762 // Swap note ons with note offs here. etc?
763 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
764 // CC values etc. hard.
768 /* if we read to the end of the loop, go back to the beginning */
770 // Synthesize LoopEvent here, because the next events
771 // written will have non-monotonic timestamps.
779 //offset += this_read;
786 MidiDiskstream::_do_refill_with_alloc (bool /* partial_fill */)
792 MidiDiskstream::do_refill ()
795 size_t write_space = _playback_buf->write_space();
796 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
798 if (write_space == 0) {
806 /* at end: nothing to do */
807 if (file_frame == max_framepos) {
811 /* no space to write */
812 if (_playback_buf->write_space() == 0) {
816 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
817 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
818 if ((frames_read < frames_written) && (frames_written - frames_read) >= midi_readahead) {
822 framecnt_t to_read = midi_readahead - ((framecnt_t)frames_written - (framecnt_t)frames_read);
824 //cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
825 // << frames_written - frames_read << endl;
827 to_read = min (to_read, (framecnt_t) (max_framepos - file_frame));
828 to_read = min (to_read, (framecnt_t) write_space);
830 if (read (file_frame, to_read, reversed)) {
837 /** Flush pending data to disk.
839 * Important note: this function will write *AT MOST* disk_write_chunk_frames
840 * of data to disk. it will never write more than that. If it writes that
841 * much and there is more than that waiting to be written, it will return 1,
842 * otherwise 0 on success or -1 on failure.
844 * If there is less than disk_write_chunk_frames to be written, no data will be
845 * written at all unless @a force_flush is true.
848 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
853 if (!_write_source) {
857 const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
860 _capture_buf->read_space() == 0 ||
861 (!force_flush && (total < disk_write_chunk_frames) && was_recording)) {
865 /* if there are 2+ chunks of disk i/o possible for
866 this track), let the caller know so that it can arrange
867 for us to be called again, ASAP.
869 if we are forcing a flush, then if there is* any* extra
870 work, let the caller know.
872 if we are no longer recording and there is any extra work,
873 let the caller know too.
876 if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) {
881 /* push out everything we have, right now */
882 to_write = max_framecnt;
884 to_write = disk_write_chunk_frames;
887 if (record_enabled() && ((total > disk_write_chunk_frames) || force_flush)) {
888 Source::Lock lm(_write_source->mutex());
889 if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
890 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
893 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
901 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
903 bool more_work = true;
905 boost::shared_ptr<MidiRegion> region;
906 MidiRegion::SourceList srcs;
907 MidiRegion::SourceList::iterator src;
908 vector<CaptureInfo*>::iterator ci;
912 /* butler is already stopped, but there may be work to do
913 to flush remaining data to disk.
916 while (more_work && !err) {
917 switch (do_flush (TransportContext, true)) {
924 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
929 /* XXX is there anything we can do if err != 0 ? */
930 Glib::Threads::Mutex::Lock lm (capture_info_lock);
932 if (capture_info.empty()) {
933 goto no_capture_stuff_to_do;
939 _write_source->mark_for_remove ();
940 _write_source->drop_references ();
941 _write_source.reset();
944 /* new source set up in "out" below */
948 framecnt_t total_capture = 0;
949 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
950 total_capture += (*ci)->frames;
953 if (_write_source->length (capture_info.front()->start) != 0) {
955 /* phew, we have data */
957 Source::Lock source_lock(_write_source->mutex());
959 /* figure out the name for this take */
961 srcs.push_back (_write_source);
963 _write_source->set_timeline_position (capture_info.front()->start);
964 _write_source->set_captured_for (_name);
966 /* set length in beats to entire capture length */
968 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
969 const Evoral::Beats total_capture_beats = converter.from (total_capture);
970 _write_source->set_length_beats (total_capture_beats);
972 /* flush to disk: this step differs from the audio path,
973 where all the data is already on disk.
976 _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
978 /* we will want to be able to keep (over)writing the source
979 but we don't want it to be removable. this also differs
980 from the audio situation, where the source at this point
981 must be considered immutable. luckily, we can rely on
982 MidiSource::mark_streaming_write_completed() to have
983 already done the necessary work for that.
986 string whole_file_region_name;
987 whole_file_region_name = region_name_from_path (_write_source->name(), true);
989 /* Register a new region with the Session that
990 describes the entire source. Do this first
991 so that any sub-regions will obviously be
992 children of this one (later!)
998 plist.add (Properties::name, whole_file_region_name);
999 plist.add (Properties::whole_file, true);
1000 plist.add (Properties::automatic, true);
1001 plist.add (Properties::start, 0);
1002 plist.add (Properties::length, total_capture);
1003 plist.add (Properties::layer, 0);
1005 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1007 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1008 region->special_set_position (capture_info.front()->start);
1012 catch (failed_constructor& err) {
1013 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1017 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1019 _playlist->clear_changes ();
1020 _playlist->freeze ();
1022 /* Session frame time of the initial capture in this pass, which is where the source starts */
1023 framepos_t initial_capture = 0;
1024 if (!capture_info.empty()) {
1025 initial_capture = capture_info.front()->start;
1028 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1032 RegionFactory::region_name (region_name, _write_source->name(), false);
1034 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1035 _name, (*ci)->start, (*ci)->frames, region_name));
1038 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1043 /* start of this region is the offset between the start of its capture and the start of the whole pass */
1044 plist.add (Properties::start, (*ci)->start - initial_capture);
1045 plist.add (Properties::length, (*ci)->frames);
1046 plist.add (Properties::length_beats, converter.from((*ci)->frames));
1047 plist.add (Properties::name, region_name);
1049 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1050 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1053 catch (failed_constructor& err) {
1054 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1055 continue; /* XXX is this OK? */
1058 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1060 i_am_the_modifier++;
1061 _playlist->add_region (region, (*ci)->start);
1062 i_am_the_modifier--;
1066 _session.add_command (new StatefulDiffCommand(_playlist));
1070 /* No data was recorded, so this capture will
1071 effectively be aborted; do the same as we
1072 do for an explicit abort.
1075 if (_write_source) {
1076 _write_source->mark_for_remove ();
1077 _write_source->drop_references ();
1078 _write_source.reset();
1084 use_new_write_source (0);
1086 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1090 capture_info.clear ();
1091 capture_start_frame = 0;
1093 no_capture_stuff_to_do:
1099 MidiDiskstream::transport_looped (framepos_t)
1101 /* Here we only keep track of the number of captured loops so monotonic
1102 event times can be delivered to the write source in process(). Trying
1103 to be clever here is a world of trouble, it is better to simply record
1104 the input in a straightforward non-destructive way. In the future when
1105 we want to implement more clever MIDI looping modes it should be done in
1106 the Source and/or entirely after the capture is finished.
1108 if (was_recording) {
1109 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1114 MidiDiskstream::finish_capture ()
1116 was_recording = false;
1118 if (capture_captured == 0) {
1122 CaptureInfo* ci = new CaptureInfo;
1124 ci->start = capture_start_frame;
1125 ci->frames = capture_captured;
1127 /* XXX theoretical race condition here. Need atomic exchange ?
1128 However, the circumstances when this is called right
1129 now (either on record-disable or transport_stopped)
1130 mean that no actual race exists. I think ...
1131 We now have a capture_info_lock, but it is only to be used
1132 to synchronize in the transport_stop and the capture info
1133 accessors, so that invalidation will not occur (both non-realtime).
1136 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1138 capture_info.push_back (ci);
1139 capture_captured = 0;
1143 MidiDiskstream::set_record_enabled (bool yn)
1145 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) {
1149 /* yes, i know that this not proof against race conditions, but its
1150 good enough. i think.
1153 if (record_enabled() != yn) {
1155 engage_record_enable ();
1157 disengage_record_enable ();
1160 RecordEnableChanged (); /* EMIT SIGNAL */
1165 MidiDiskstream::set_record_safe (bool yn)
1167 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) { // REQUIRES REVIEW
1171 /* yes, i know that this not proof against race conditions, but its
1172 good enough. i think.
1175 if (record_safe () != yn) {
1177 engage_record_safe ();
1179 disengage_record_safe ();
1182 RecordSafeChanged (); /* EMIT SIGNAL */
1187 MidiDiskstream::prep_record_enable ()
1189 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
1193 bool const rolling = _session.transport_speed() != 0.0f;
1195 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1197 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1198 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1205 MidiDiskstream::prep_record_disable ()
1212 MidiDiskstream::get_state ()
1214 XMLNode& node (Diskstream::get_state());
1218 if (_write_source && _session.get_record_enabled()) {
1220 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1221 XMLNode* cs_grandchild;
1223 cs_grandchild = new XMLNode (X_("file"));
1224 cs_grandchild->add_property (X_("path"), _write_source->path());
1225 cs_child->add_child_nocopy (*cs_grandchild);
1227 /* store the location where capture will start */
1231 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1232 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1234 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1237 cs_child->add_property (X_("at"), buf);
1238 node.add_child_nocopy (*cs_child);
1245 MidiDiskstream::set_state (const XMLNode& node, int version)
1247 XMLNodeList nlist = node.children();
1248 XMLNodeIterator niter;
1249 XMLNode* capture_pending_node = 0;
1252 /* prevent write sources from being created */
1254 in_set_state = true;
1256 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1257 if ((*niter)->name() == X_("CapturingSources")) {
1258 capture_pending_node = *niter;
1262 if (Diskstream::set_state (node, version)) {
1266 if (capture_pending_node) {
1267 use_pending_capture_data (*capture_pending_node);
1270 in_set_state = false;
1276 MidiDiskstream::use_new_write_source (uint32_t n)
1278 if (!_session.writable() || !recordable()) {
1282 _accumulated_capture_offset = 0;
1283 _write_source.reset();
1286 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1287 _session.create_midi_source_for_session (write_source_name ()));
1289 if (!_write_source) {
1290 throw failed_constructor();
1294 catch (failed_constructor &err) {
1295 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1296 _write_source.reset();
1303 * We want to use the name of the existing write source (the one that will be
1304 * used by the next capture) for another purpose. So change the name of the
1305 * current source, and return its current name.
1307 * Return an empty string if the change cannot be accomplished.
1310 MidiDiskstream::steal_write_source_name ()
1312 string our_old_name = _write_source->name();
1314 /* this will bump the name of the current write source to the next one
1315 * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1316 * current write source name (e.g. "MIDI 1-1" available). See the
1317 * comments in Session::create_midi_source_by_stealing_name() about why
1322 string new_path = _session.new_midi_source_path (name());
1324 if (_write_source->rename (new_path)) {
1331 return our_old_name;
1335 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1337 if (!_session.writable() || !recordable()) {
1341 if (_write_source && mark_write_complete) {
1342 Source::Lock lm(_write_source->mutex());
1343 _write_source->mark_streaming_write_completed (lm);
1345 use_new_write_source (0);
1349 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1354 MidiDiskstream::allocate_temporary_buffers ()
1359 MidiDiskstream::ensure_input_monitoring (bool yn)
1361 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1364 sp->ensure_input_monitoring (yn);
1369 MidiDiskstream::set_align_style_from_io ()
1371 if (_alignment_choice != Automatic) {
1375 /* XXX Not sure what, if anything we can do with MIDI
1376 as far as capture alignment etc.
1379 set_align_style (ExistingMaterial);
1384 MidiDiskstream::playback_buffer_load () const
1386 /* For MIDI it's not trivial to differentiate the following two cases:
1388 1. The playback buffer is empty because the system has run out of time to fill it.
1389 2. The playback buffer is empty because there is no more data on the playlist.
1391 If we use a simple buffer load computation, we will report that the MIDI diskstream
1392 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1393 are so low compared to audio, just give a pretend answer here.
1400 MidiDiskstream::capture_buffer_load () const
1402 /* We don't report playback buffer load, so don't report capture load either */
1408 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1414 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1416 _playback_buf->flush (start, end);
1417 g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1420 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1421 * so that an event at playback_sample has time = 0
1424 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1428 Location* loc = loop_location;
1430 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1431 "%1 MDS pre-read read %8 @ %4..%5 from %2 write to %3, LOOPED ? %6-%7\n", _name,
1432 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1433 (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes));
1435 // cerr << "================\n";
1436 // _playback_buf->dump (cerr);
1437 // cerr << "----------------\n";
1439 size_t events_read = 0;
1440 const size_t split_cycle_offset = Port::port_offset ();
1443 framepos_t effective_start;
1445 if (playback_sample >= loc->end()) {
1446 effective_start = loc->start() + ((playback_sample - loc->end()) % loc->length());
1448 effective_start = playback_sample;
1451 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1453 if (effective_start == loc->start()) {
1454 /* We need to turn off notes that may extend
1455 beyond the loop end.
1458 _playback_buf->resolve_tracker (dst, split_cycle_offset);
1461 _playback_buf->skip_to (effective_start);
1463 /* for split-cycles we need to offset the events */
1465 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1466 /* end of loop is within the range we are reading, so
1467 split the read in two, and lie about the location
1470 framecnt_t first, second;
1472 first = loc->end() - effective_start;
1473 second = nframes - first;
1475 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4\n",
1476 effective_start, loc->end(), first, second));
1479 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1480 effective_start, first));
1481 events_read = _playback_buf->read (dst, effective_start, first, split_cycle_offset);
1485 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1486 loc->start(), second));
1487 events_read += _playback_buf->read (dst, loc->start(), second, split_cycle_offset);
1491 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1492 effective_start, nframes));
1493 events_read = _playback_buf->read (dst, effective_start, effective_start + nframes, split_cycle_offset);
1496 _playback_buf->skip_to (playback_sample);
1497 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes, split_cycle_offset);
1500 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1501 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1502 _name, events_read, playback_sample, playback_sample + nframes,
1503 _playback_buf->read_space(), _playback_buf->write_space(),
1504 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1506 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1510 MidiDiskstream::set_name (string const & name)
1512 if (_name == name) {
1515 Diskstream::set_name (name);
1517 /* get a new write source so that its name reflects the new diskstream name */
1518 use_new_write_source (0);
1524 MidiDiskstream::set_write_source_name (const std::string& str) {
1525 if (_write_source_name == str) {
1528 Diskstream::set_write_source_name (str);
1529 if (_write_source_name == name()) {
1532 use_new_write_source (0);
1536 boost::shared_ptr<MidiBuffer>
1537 MidiDiskstream::get_gui_feed_buffer () const
1539 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1541 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1542 b->copy (_gui_feed_buffer);
1547 MidiDiskstream::reset_tracker ()
1549 _playback_buf->reset_tracker ();
1551 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1554 mp->reset_note_trackers ();
1559 MidiDiskstream::resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time)
1561 _playback_buf->resolve_tracker(buffer, time);
1563 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1566 mp->reset_note_trackers ();
1571 boost::shared_ptr<MidiPlaylist>
1572 MidiDiskstream::midi_playlist ()
1574 return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);