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 #ifdef XXX_OLD_DESTRUCTIVE_API_XXX
292 /** Overloaded from parent to die horribly
295 MidiDiskstream::set_destructive (bool yn)
302 MidiDiskstream::set_note_mode (NoteMode m)
305 midi_playlist()->set_note_mode(m);
306 if (_write_source && _write_source->model())
307 _write_source->model()->set_note_mode(m);
310 /** Get the start, end, and length of a location "atomically".
312 * Note: Locations don't get deleted, so all we care about when I say "atomic"
313 * is that we are always pointing to the same one and using start/length values
314 * obtained just once. Use this function to achieve this since location being
315 * a parameter achieves this.
318 get_location_times(const Location* location,
324 *start = location->start();
325 *end = location->end();
326 *length = *end - *start;
331 MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance, bool need_disk_signal)
333 framecnt_t rec_offset = 0;
334 framecnt_t rec_nframes = 0;
335 bool nominally_recording;
336 bool re = record_enabled ();
337 bool can_record = _session.actively_recording ();
339 playback_distance = 0;
341 check_record_status (transport_frame, can_record);
343 nominally_recording = (can_record && re);
349 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
355 Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
361 const Location* const loop_loc = loop_location;
362 framepos_t loop_start = 0;
363 framepos_t loop_end = 0;
364 framepos_t loop_length = 0;
366 get_location_times (loop_loc, &loop_start, &loop_end, &loop_length);
368 adjust_capture_position = 0;
370 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && (_session.config.get_punch_in() || _session.preroll_record_enabled()))) {
371 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
372 // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
374 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
375 /* For audio: not writing frames to the capture ringbuffer offsets
376 * the recording. For midi: we need to keep track of the record range
377 * and subtract the accumulated difference from the event time.
380 _accumulated_capture_offset += rec_offset;
382 _accumulated_capture_offset += nframes;
385 if (rec_nframes && !was_recording) {
387 /* Loop recording, so pretend the capture started at the loop
388 start rgardless of what time it is now, so the source starts
389 at the loop start and can handle time wrapping around.
390 Otherwise, start the source right now as usual.
392 capture_captured = transport_frame - loop_start;
393 capture_start_frame = loop_start;
395 _write_source->mark_write_starting_now(
396 capture_start_frame, capture_captured, loop_length);
397 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
398 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
399 was_recording = true;
403 if (can_record && !_last_capture_sources.empty()) {
404 _last_capture_sources.clear ();
407 if (nominally_recording || rec_nframes) {
408 // Pump entire port buffer into the ring buffer (TODO: split cycles?)
409 MidiBuffer& buf = sp->get_midi_buffer(nframes);
410 MidiTrack* mt = dynamic_cast<MidiTrack*>(_track);
411 MidiChannelFilter* filter = mt ? &mt->capture_filter() : NULL;
413 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
414 Evoral::Event<MidiBuffer::TimeType> ev(*i, false);
415 if (ev.time() + rec_offset > rec_nframes) {
419 if (DEBUG_ENABLED(DEBUG::MidiIO)) {
420 const uint8_t* __data = ev.buffer();
422 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
423 for (size_t i=0; i < ev.size(); ++i) {
424 DEBUG_STR_APPEND(a,hex);
425 DEBUG_STR_APPEND(a,"0x");
426 DEBUG_STR_APPEND(a,(int)__data[i]);
427 DEBUG_STR_APPEND(a,' ');
429 DEBUG_STR_APPEND(a,'\n');
430 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
433 /* Write events to the capture buffer in frames from session start,
434 but ignoring looping so event time progresses monotonically.
435 The source knows the loop length so it knows exactly where the
436 event occurs in the series of recorded loops and can implement
437 any desirable behaviour. We don't want to send event with
438 transport time here since that way the source can not
439 reconstruct their actual time; future clever MIDI looping should
440 probably be implemented in the source instead of here.
442 const framecnt_t loop_offset = _num_captured_loops * loop_length;
443 const framepos_t event_time = transport_frame + loop_offset - _accumulated_capture_offset + ev.time();
444 if (event_time < 0 || event_time < first_recordable_frame) {
445 /* Event out of range, skip */
449 if (!filter || !filter->filter(ev.buffer(), ev.size())) {
450 _capture_buf->write(event_time, ev.event_type(), ev.size(), ev.buffer());
453 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
455 if (buf.size() != 0) {
456 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
459 /* Copy this data into our GUI feed buffer and tell the GUI
460 that it can read it if it likes.
462 _gui_feed_buffer.clear ();
464 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
465 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
466 the end of the world if it does.
468 _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
472 DataRecorded (_write_source); /* EMIT SIGNAL */
480 _accumulated_capture_offset = 0;
486 /* data will be written to disk */
488 if (rec_nframes == nframes && rec_offset == 0) {
489 playback_distance = nframes;
492 adjust_capture_position = rec_nframes;
494 } else if (nominally_recording) {
496 /* XXXX do this for MIDI !!!
497 can't do actual capture yet - waiting for latency effects to finish before we start
500 playback_distance = nframes;
502 } else if (_actual_speed != 1.0f && _target_speed > 0) {
504 interpolation.set_speed (_target_speed);
506 playback_distance = interpolation.distance (nframes);
509 playback_distance = nframes;
512 if (need_disk_signal && !_session.declick_out_pending()) {
513 /* copy the diskstream data to all output buffers */
515 MidiBuffer& mbuf (bufs.get_midi (0));
516 get_playback (mbuf, playback_distance);
518 /* leave the audio count alone */
519 ChanCount cnt (DataType::MIDI, 1);
520 cnt.set (DataType::AUDIO, bufs.count().n_audio());
521 bufs.set_count (cnt);
524 if (_target_speed > 0 && _actual_speed != 1.0f) {
525 MidiBuffer& mbuf (bufs.get_midi (0));
526 for (MidiBuffer::iterator i = mbuf.begin(); i != mbuf.end(); ++i) {
527 MidiBuffer::TimeType *tme = i.timeptr();
528 *tme = (*tme) * nframes / playback_distance;
537 MidiDiskstream::calculate_playback_distance (pframes_t nframes)
539 frameoffset_t playback_distance = nframes;
541 if (!record_enabled() && _actual_speed != 1.0f && _actual_speed > 0.f) {
542 interpolation.set_speed (_target_speed);
543 playback_distance = interpolation.distance (nframes, false);
546 if (_actual_speed < 0.0) {
547 return -playback_distance;
549 return playback_distance;
554 MidiDiskstream::commit (framecnt_t playback_distance)
556 bool need_butler = false;
558 if (!_io || !_io->active()) {
562 if (_actual_speed < 0.0) {
563 playback_sample -= playback_distance;
565 playback_sample += playback_distance;
568 if (adjust_capture_position != 0) {
569 capture_captured += adjust_capture_position;
570 adjust_capture_position = 0;
573 uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
574 uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
577 cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
578 " = " << frames_written - frames_read
579 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
582 /* frames_read will generally be less than frames_written, but
583 * immediately after an overwrite, we can end up having read some data
584 * before we've written any. we don't need to trip an assert() on this,
585 * but we do need to check so that the decision on whether or not we
586 * need the butler is done correctly.
591 * Doing heavy GUI operations[1] can stall also the butler.
592 * The RT-thread meanwhile will happily continue and
593 * ‘frames_read’ (from buffer to output) will become larger
594 * than ‘frames_written’ (from disk to buffer).
596 * The disk-stream is now behind..
598 * In those cases the butler needs to be summed to refill the buffer (done now)
599 * AND we need to skip (frames_read - frames_written). ie remove old events
600 * before playback_sample from the rinbuffer.
602 * [1] one way to do so is described at #6170.
603 * For me just popping up the context-menu on a MIDI-track header
604 * of a track with a large (think beethoven :) midi-region also did the
605 * trick. The playhead stalls for 2 or 3 sec, until the context-menu shows.
607 * In both cases the root cause is that redrawing MIDI regions on the GUI is still very slow
610 if (frames_read <= frames_written) {
611 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
623 MidiDiskstream::set_pending_overwrite (bool yn)
625 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
627 _pending_overwrite = yn;
628 overwrite_frame = playback_sample;
632 MidiDiskstream::overwrite_existing_buffers ()
634 /* Clear the playback buffer contents. This is safe as long as the butler
635 thread is suspended, which it should be. */
636 _playback_buf->reset ();
637 _playback_buf->reset_tracker ();
639 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
640 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
642 /* Resolve all currently active notes in the playlist. This is more
643 aggressive than it needs to be: ideally we would only resolve what is
644 absolutely necessary, but this seems difficult and/or impossible without
645 having the old data or knowing what change caused the overwrite. */
646 midi_playlist()->resolve_note_trackers (*_playback_buf, overwrite_frame);
648 read (overwrite_frame, disk_read_chunk_frames, false);
649 file_frame = overwrite_frame; // it was adjusted by ::read()
650 overwrite_queued = false;
651 _pending_overwrite = false;
657 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
659 Glib::Threads::Mutex::Lock lm (state_lock);
662 if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
663 /* we haven't read anything since the last seek,
664 so flush all note trackers to prevent
670 _playback_buf->reset();
671 _capture_buf->reset();
672 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
673 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
675 playback_sample = frame;
678 if (complete_refill) {
679 while ((ret = do_refill_with_alloc ()) > 0) ;
681 ret = do_refill_with_alloc ();
688 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
690 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
691 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
692 return ((frames_written - frames_read) < distance);
696 MidiDiskstream::internal_playback_seek (framecnt_t distance)
698 first_recordable_frame += distance;
699 playback_sample += distance;
704 /** @a start is set to the new frame position (TIME) read up to */
706 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
708 framecnt_t this_read = 0;
709 framepos_t loop_end = 0;
710 framepos_t loop_start = 0;
711 framecnt_t loop_length = 0;
712 Location* loc = loop_location;
713 framepos_t effective_start = start;
714 Evoral::Range<framepos_t>* loop_range (0);
716 MidiTrack* mt = dynamic_cast<MidiTrack*>(_track);
717 MidiChannelFilter* filter = mt ? &mt->playback_filter() : NULL;
719 frameoffset_t loop_offset = 0;
721 if (!reversed && loc) {
722 get_location_times (loc, &loop_start, &loop_end, &loop_length);
727 /* take any loop into account. we can't read past the end of the loop. */
729 if (loc && !reversed) {
732 loop_range = new Evoral::Range<framepos_t> (loop_start, loop_end-1); // inclusive semantics require -1
735 /* if we are (seamlessly) looping, ensure that the first frame we read is at the correct
736 position within the loop.
739 effective_start = loop_range->squish (effective_start);
741 if ((loop_end - effective_start) <= dur) {
742 /* too close to end of loop to read "dur", so
745 this_read = loop_end - effective_start;
754 if (this_read == 0) {
758 this_read = min (dur,this_read);
760 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MDS ::read at %1 for %2 loffset %3\n", effective_start, this_read, loop_offset));
762 if (midi_playlist()->read (*_playback_buf, effective_start, this_read, loop_range, 0, filter) != this_read) {
763 error << string_compose(
764 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
765 id(), this_read, start) << endmsg;
769 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
773 // Swap note ons with note offs here. etc?
774 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
775 // CC values etc. hard.
779 /* adjust passed-by-reference argument (note: this is
780 monotonic and does not reflect looping.
784 /* similarly adjust effective_start, but this may be
785 readjusted for seamless looping as we continue around
788 effective_start += this_read;
792 //offset += this_read;
799 MidiDiskstream::_do_refill_with_alloc (bool /* partial_fill */)
805 MidiDiskstream::do_refill ()
808 size_t write_space = _playback_buf->write_space();
809 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
811 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MDS refill, write space = %1 file frame = %2\n",
812 write_space, file_frame));
814 /* no space to write */
815 if (write_space == 0) {
823 /* at end: nothing to do */
824 if (file_frame == max_framepos) {
828 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
829 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
831 if ((frames_read < frames_written) && (frames_written - frames_read) >= midi_readahead) {
835 framecnt_t to_read = midi_readahead - ((framecnt_t)frames_written - (framecnt_t)frames_read);
837 to_read = min (to_read, (framecnt_t) (max_framepos - file_frame));
838 to_read = min (to_read, (framecnt_t) write_space);
840 if (read (file_frame, to_read, reversed)) {
847 /** Flush pending data to disk.
849 * Important note: this function will write *AT MOST* disk_write_chunk_frames
850 * of data to disk. it will never write more than that. If it writes that
851 * much and there is more than that waiting to be written, it will return 1,
852 * otherwise 0 on success or -1 on failure.
854 * If there is less than disk_write_chunk_frames to be written, no data will be
855 * written at all unless @a force_flush is true.
858 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
863 if (!_write_source) {
867 const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
870 _capture_buf->read_space() == 0 ||
871 (!force_flush && (total < disk_write_chunk_frames) && was_recording)) {
875 /* if there are 2+ chunks of disk i/o possible for
876 this track), let the caller know so that it can arrange
877 for us to be called again, ASAP.
879 if we are forcing a flush, then if there is* any* extra
880 work, let the caller know.
882 if we are no longer recording and there is any extra work,
883 let the caller know too.
886 if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) {
891 /* push out everything we have, right now */
892 to_write = max_framecnt;
894 to_write = disk_write_chunk_frames;
897 if (record_enabled() && ((total > disk_write_chunk_frames) || force_flush)) {
898 Source::Lock lm(_write_source->mutex());
899 if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
900 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
903 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
911 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
913 bool more_work = true;
915 boost::shared_ptr<MidiRegion> region;
916 MidiRegion::SourceList srcs;
917 MidiRegion::SourceList::iterator src;
918 vector<CaptureInfo*>::iterator ci;
922 /* butler is already stopped, but there may be work to do
923 to flush remaining data to disk.
926 while (more_work && !err) {
927 switch (do_flush (TransportContext, true)) {
934 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
939 /* XXX is there anything we can do if err != 0 ? */
940 Glib::Threads::Mutex::Lock lm (capture_info_lock);
942 if (capture_info.empty()) {
943 goto no_capture_stuff_to_do;
949 _write_source->mark_for_remove ();
950 _write_source->drop_references ();
951 _write_source.reset();
954 /* new source set up in "out" below */
958 framecnt_t total_capture = 0;
959 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
960 total_capture += (*ci)->frames;
963 if (_write_source->length (capture_info.front()->start) != 0) {
965 /* phew, we have data */
967 Source::Lock source_lock(_write_source->mutex());
969 /* figure out the name for this take */
971 srcs.push_back (_write_source);
973 _write_source->set_timeline_position (capture_info.front()->start);
974 _write_source->set_captured_for (_name);
976 /* set length in beats to entire capture length */
978 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
979 const Evoral::Beats total_capture_beats = converter.from (total_capture);
980 _write_source->set_length_beats (total_capture_beats);
982 /* flush to disk: this step differs from the audio path,
983 where all the data is already on disk.
986 _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
988 /* we will want to be able to keep (over)writing the source
989 but we don't want it to be removable. this also differs
990 from the audio situation, where the source at this point
991 must be considered immutable. luckily, we can rely on
992 MidiSource::mark_streaming_write_completed() to have
993 already done the necessary work for that.
996 string whole_file_region_name;
997 whole_file_region_name = region_name_from_path (_write_source->name(), true);
999 /* Register a new region with the Session that
1000 describes the entire source. Do this first
1001 so that any sub-regions will obviously be
1002 children of this one (later!)
1008 plist.add (Properties::name, whole_file_region_name);
1009 plist.add (Properties::whole_file, true);
1010 plist.add (Properties::automatic, true);
1011 plist.add (Properties::start, 0);
1012 plist.add (Properties::length, total_capture);
1013 plist.add (Properties::layer, 0);
1015 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1017 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1018 region->special_set_position (capture_info.front()->start);
1022 catch (failed_constructor& err) {
1023 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1027 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1029 _playlist->clear_changes ();
1030 _playlist->freeze ();
1032 /* Session frame time of the initial capture in this pass, which is where the source starts */
1033 framepos_t initial_capture = 0;
1034 if (!capture_info.empty()) {
1035 initial_capture = capture_info.front()->start;
1038 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1042 RegionFactory::region_name (region_name, _write_source->name(), false);
1044 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1045 _name, (*ci)->start, (*ci)->frames, region_name));
1048 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1053 /* start of this region is the offset between the start of its capture and the start of the whole pass */
1054 plist.add (Properties::start, (*ci)->start - initial_capture);
1055 plist.add (Properties::length, (*ci)->frames);
1056 plist.add (Properties::length_beats, converter.from((*ci)->frames).to_double());
1057 plist.add (Properties::name, region_name);
1059 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1060 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1063 catch (failed_constructor& err) {
1064 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1065 continue; /* XXX is this OK? */
1068 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1070 i_am_the_modifier++;
1071 _playlist->add_region (region, (*ci)->start);
1072 i_am_the_modifier--;
1076 _session.add_command (new StatefulDiffCommand(_playlist));
1080 /* No data was recorded, so this capture will
1081 effectively be aborted; do the same as we
1082 do for an explicit abort.
1085 if (_write_source) {
1086 _write_source->mark_for_remove ();
1087 _write_source->drop_references ();
1088 _write_source.reset();
1094 use_new_write_source (0);
1096 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1100 capture_info.clear ();
1101 capture_start_frame = 0;
1103 no_capture_stuff_to_do:
1109 MidiDiskstream::transport_looped (framepos_t)
1111 /* Here we only keep track of the number of captured loops so monotonic
1112 event times can be delivered to the write source in process(). Trying
1113 to be clever here is a world of trouble, it is better to simply record
1114 the input in a straightforward non-destructive way. In the future when
1115 we want to implement more clever MIDI looping modes it should be done in
1116 the Source and/or entirely after the capture is finished.
1118 if (was_recording) {
1119 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1124 MidiDiskstream::finish_capture ()
1126 was_recording = false;
1128 if (capture_captured == 0) {
1132 CaptureInfo* ci = new CaptureInfo;
1134 ci->start = capture_start_frame;
1135 ci->frames = capture_captured;
1137 /* XXX theoretical race condition here. Need atomic exchange ?
1138 However, the circumstances when this is called right
1139 now (either on record-disable or transport_stopped)
1140 mean that no actual race exists. I think ...
1141 We now have a capture_info_lock, but it is only to be used
1142 to synchronize in the transport_stop and the capture info
1143 accessors, so that invalidation will not occur (both non-realtime).
1146 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1148 capture_info.push_back (ci);
1149 capture_captured = 0;
1153 MidiDiskstream::set_record_enabled (bool yn)
1155 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) {
1159 /* yes, i know that this not proof against race conditions, but its
1160 good enough. i think.
1163 if (record_enabled() != yn) {
1165 engage_record_enable ();
1167 disengage_record_enable ();
1170 RecordEnableChanged (); /* EMIT SIGNAL */
1175 MidiDiskstream::set_record_safe (bool yn)
1177 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) { // REQUIRES REVIEW
1181 /* yes, i know that this not proof against race conditions, but its
1182 good enough. i think.
1185 if (record_safe () != yn) {
1187 engage_record_safe ();
1189 disengage_record_safe ();
1192 RecordSafeChanged (); /* EMIT SIGNAL */
1197 MidiDiskstream::prep_record_enable ()
1199 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
1203 bool const rolling = _session.transport_speed() != 0.0f;
1205 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1207 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1208 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1215 MidiDiskstream::prep_record_disable ()
1222 MidiDiskstream::get_state ()
1224 XMLNode& node (Diskstream::get_state());
1228 if (_write_source && _session.get_record_enabled()) {
1230 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1231 XMLNode* cs_grandchild;
1233 cs_grandchild = new XMLNode (X_("file"));
1234 cs_grandchild->add_property (X_("path"), _write_source->path());
1235 cs_child->add_child_nocopy (*cs_grandchild);
1237 /* store the location where capture will start */
1241 if (_session.preroll_record_enabled ()) {
1242 snprintf (buf, sizeof (buf), "%" PRId64, _session.preroll_record_in ());
1243 } else if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1244 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1246 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1249 cs_child->add_property (X_("at"), buf);
1250 node.add_child_nocopy (*cs_child);
1257 MidiDiskstream::set_state (const XMLNode& node, int version)
1259 XMLNodeList nlist = node.children();
1260 XMLNodeIterator niter;
1261 XMLNode* capture_pending_node = 0;
1264 /* prevent write sources from being created */
1266 in_set_state = true;
1268 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1269 if ((*niter)->name() == X_("CapturingSources")) {
1270 capture_pending_node = *niter;
1274 if (Diskstream::set_state (node, version)) {
1278 if (capture_pending_node) {
1279 use_pending_capture_data (*capture_pending_node);
1282 in_set_state = false;
1288 MidiDiskstream::use_new_write_source (uint32_t n)
1290 if (!_session.writable() || !recordable()) {
1294 _accumulated_capture_offset = 0;
1295 _write_source.reset();
1298 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1299 _session.create_midi_source_for_session (write_source_name ()));
1301 if (!_write_source) {
1302 throw failed_constructor();
1306 catch (failed_constructor &err) {
1307 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1308 _write_source.reset();
1315 * We want to use the name of the existing write source (the one that will be
1316 * used by the next capture) for another purpose. So change the name of the
1317 * current source, and return its current name.
1319 * Return an empty string if the change cannot be accomplished.
1322 MidiDiskstream::steal_write_source_name ()
1324 string our_old_name = _write_source->name();
1326 /* this will bump the name of the current write source to the next one
1327 * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1328 * current write source name (e.g. "MIDI 1-1" available). See the
1329 * comments in Session::create_midi_source_by_stealing_name() about why
1334 string new_path = _session.new_midi_source_path (name());
1336 if (_write_source->rename (new_path)) {
1343 return our_old_name;
1347 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1349 if (!_session.writable() || !recordable()) {
1353 if (_write_source && mark_write_complete) {
1354 Source::Lock lm(_write_source->mutex());
1355 _write_source->mark_streaming_write_completed (lm);
1357 use_new_write_source (0);
1361 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1366 MidiDiskstream::allocate_temporary_buffers ()
1371 MidiDiskstream::ensure_input_monitoring (bool yn)
1373 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1376 sp->ensure_input_monitoring (yn);
1381 MidiDiskstream::set_align_style_from_io ()
1383 if (_alignment_choice != Automatic) {
1387 /* XXX Not sure what, if anything we can do with MIDI
1388 as far as capture alignment etc.
1391 set_align_style (ExistingMaterial);
1396 MidiDiskstream::playback_buffer_load () const
1398 /* For MIDI it's not trivial to differentiate the following two cases:
1400 1. The playback buffer is empty because the system has run out of time to fill it.
1401 2. The playback buffer is empty because there is no more data on the playlist.
1403 If we use a simple buffer load computation, we will report that the MIDI diskstream
1404 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1405 are so low compared to audio, just give a pretend answer here.
1412 MidiDiskstream::capture_buffer_load () const
1414 /* We don't report playback buffer load, so don't report capture load either */
1420 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1426 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1428 _playback_buf->flush (start, end);
1429 g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1432 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1433 * so that an event at playback_sample has time = 0
1436 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1440 Location* loc = loop_location;
1442 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1443 "%1 MDS pre-read read %8 offset = %9 @ %4..%5 from %2 write to %3, LOOPED ? %6 .. %7\n", _name,
1444 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1445 (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes, Port::port_offset()));
1447 //cerr << "======== PRE ========\n";
1448 //_playback_buf->dump (cerr);
1449 //cerr << "----------------\n";
1451 size_t events_read = 0;
1454 framepos_t effective_start;
1456 Evoral::Range<framepos_t> loop_range (loc->start(), loc->end() - 1);
1457 effective_start = loop_range.squish (playback_sample);
1459 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1461 if (effective_start == loc->start()) {
1462 /* We need to turn off notes that may extend
1463 beyond the loop end.
1466 _playback_buf->resolve_tracker (dst, 0);
1469 /* for split-cycles we need to offset the events */
1471 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1473 /* end of loop is within the range we are reading, so
1474 split the read in two, and lie about the location
1478 framecnt_t first, second;
1480 first = loc->end() - effective_start;
1481 second = nframes - first;
1483 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4, cycle offset %5\n",
1484 effective_start, loc->end(), first, second));
1487 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1488 effective_start, first));
1489 events_read = _playback_buf->read (dst, effective_start, first);
1493 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1494 loc->start(), second));
1495 events_read += _playback_buf->read (dst, loc->start(), second);
1499 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1500 effective_start, nframes));
1501 events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1504 const size_t n_skipped = _playback_buf->skip_to (playback_sample);
1505 if (n_skipped > 0) {
1506 warning << string_compose(_("MidiDiskstream %1: skipped %2 events, possible underflow"), id(), n_skipped) << endmsg;
1508 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("playback buffer read, from %1 to %2 (%3)", playback_sample, playback_sample + nframes, nframes));
1509 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1512 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1513 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1514 _name, events_read, playback_sample, playback_sample + nframes,
1515 _playback_buf->read_space(), _playback_buf->write_space(),
1516 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1518 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1520 //cerr << "======== POST ========\n";
1521 //_playback_buf->dump (cerr);
1522 //cerr << "----------------\n";
1526 MidiDiskstream::set_name (string const & name)
1528 if (_name == name) {
1531 Diskstream::set_name (name);
1533 /* get a new write source so that its name reflects the new diskstream name */
1534 use_new_write_source (0);
1540 MidiDiskstream::set_write_source_name (const std::string& str) {
1541 if (_write_source_name == str) {
1544 Diskstream::set_write_source_name (str);
1545 if (_write_source_name == name()) {
1548 use_new_write_source (0);
1552 boost::shared_ptr<MidiBuffer>
1553 MidiDiskstream::get_gui_feed_buffer () const
1555 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1557 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1558 b->copy (_gui_feed_buffer);
1563 MidiDiskstream::reset_tracker ()
1565 _playback_buf->reset_tracker ();
1567 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1570 mp->reset_note_trackers ();
1575 MidiDiskstream::resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time)
1577 _playback_buf->resolve_tracker(buffer, time);
1579 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1582 mp->reset_note_trackers ();
1587 boost::shared_ptr<MidiPlaylist>
1588 MidiDiskstream::midi_playlist ()
1590 return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);