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.
31 #include "pbd/error.h"
33 #include "pbd/basename.h"
34 #include <glibmm/threads.h>
35 #include "pbd/xml++.h"
36 #include "pbd/memento_command.h"
37 #include "pbd/enumwriter.h"
38 #include "pbd/stateful_diff_command.h"
39 #include "pbd/stacktrace.h"
41 #include "ardour/audioengine.h"
42 #include "ardour/butler.h"
43 #include "ardour/debug.h"
44 #include "ardour/io.h"
45 #include "ardour/midi_diskstream.h"
46 #include "ardour/midi_model.h"
47 #include "ardour/midi_playlist.h"
48 #include "ardour/midi_port.h"
49 #include "ardour/midi_region.h"
50 #include "ardour/midi_ring_buffer.h"
51 #include "ardour/midi_track.h"
52 #include "ardour/playlist_factory.h"
53 #include "ardour/region_factory.h"
54 #include "ardour/session.h"
55 #include "ardour/session_playlists.h"
56 #include "ardour/smf_source.h"
57 #include "ardour/types.h"
58 #include "ardour/utils.h"
60 #include "midi++/types.h"
66 using namespace ARDOUR;
69 framecnt_t MidiDiskstream::midi_readahead = 4096;
71 MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
72 : Diskstream(sess, name, flag)
75 , _note_mode(Sustained)
76 , _frames_written_to_ringbuffer(0)
77 , _frames_read_from_ringbuffer(0)
78 , _frames_pending_write(0)
79 , _num_captured_loops(0)
80 , _accumulated_capture_offset(0)
81 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
87 use_new_write_source (0);
92 throw failed_constructor();
96 MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
97 : Diskstream(sess, node)
100 , _note_mode(Sustained)
101 , _frames_written_to_ringbuffer(0)
102 , _frames_read_from_ringbuffer(0)
103 , _frames_pending_write(0)
104 , _num_captured_loops(0)
105 , _accumulated_capture_offset(0)
106 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
112 if (set_state (node, Stateful::loading_state_version)) {
113 in_set_state = false;
114 throw failed_constructor();
117 use_new_write_source (0);
119 in_set_state = false;
123 MidiDiskstream::init ()
125 /* there are no channels at this point, so these
126 two calls just get speed_buffer_size and wrap_buffer
127 size setup without duplicating their code.
130 set_block_size (_session.get_block_size());
131 allocate_temporary_buffers ();
133 const size_t size = _session.butler()->midi_diskstream_buffer_size();
134 _playback_buf = new MidiRingBuffer<framepos_t>(size);
135 _capture_buf = new MidiRingBuffer<framepos_t>(size);
137 _n_channels = ChanCount(DataType::MIDI, 1);
138 interpolation.add_channel_to (0,0);
141 MidiDiskstream::~MidiDiskstream ()
143 Glib::Threads::Mutex::Lock lm (state_lock);
144 delete _playback_buf;
150 MidiDiskstream::non_realtime_locate (framepos_t position)
153 _write_source->set_timeline_position (position);
155 seek (position, false);
160 MidiDiskstream::non_realtime_input_change ()
163 Glib::Threads::Mutex::Lock lm (state_lock);
165 if (input_change_pending.type == IOChange::NoChange) {
169 if (input_change_pending.type & IOChange::ConfigurationChanged) {
170 uint32_t ni = _io->n_ports().n_midi();
172 if (ni != _n_channels.n_midi()) {
173 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
176 _n_channels, input_change_pending.type)
181 _source_port.reset ();
183 _source_port = _io->midi(0);
187 if (input_change_pending.type & IOChange::ConnectionsChanged) {
188 set_capture_offset ();
189 set_align_style_from_io ();
192 input_change_pending.type = IOChange::NoChange;
194 /* implicit unlock */
197 /* unlike with audio, there is never any need to reset write sources
198 based on input configuration changes because ... a MIDI track
199 has just 1 MIDI port as input, always.
202 /* now refill channel buffers */
204 if (speed() != 1.0f || speed() != -1.0f) {
205 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
208 seek (_session.transport_frame());
211 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
212 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
216 MidiDiskstream::find_and_use_playlist (const string& name)
218 boost::shared_ptr<MidiPlaylist> playlist;
220 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
221 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
225 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg;
229 return use_playlist (playlist);
233 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
235 if (boost::dynamic_pointer_cast<MidiPlaylist>(playlist)) {
236 Diskstream::use_playlist(playlist);
243 MidiDiskstream::use_new_playlist ()
246 boost::shared_ptr<MidiPlaylist> playlist;
248 if (!in_set_state && destructive()) {
253 newname = Playlist::bump_name (_playlist->name(), _session);
255 newname = Playlist::bump_name (_name, _session);
258 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
259 DataType::MIDI, _session, newname, hidden()))) != 0) {
261 return use_playlist (playlist);
269 MidiDiskstream::use_copy_playlist ()
275 if (_playlist == 0) {
276 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
281 boost::shared_ptr<MidiPlaylist> playlist;
283 newname = Playlist::bump_name (_playlist->name(), _session);
285 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
286 return use_playlist (playlist);
292 /** Overloaded from parent to die horribly
295 MidiDiskstream::set_destructive (bool yn)
301 MidiDiskstream::set_note_mode (NoteMode m)
304 midi_playlist()->set_note_mode(m);
305 if (_write_source && _write_source->model())
306 _write_source->model()->set_note_mode(m);
309 /** Get the start, end, and length of a location "atomically".
311 * Note: Locations don't get deleted, so all we care about when I say "atomic"
312 * is that we are always pointing to the same one and using start/length values
313 * obtained just once. Use this function to achieve this since location being
314 * a parameter achieves this.
317 get_location_times(const Location* location,
323 *start = location->start();
324 *end = location->end();
325 *length = *end - *start;
330 MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance, bool need_disk_signal)
332 framecnt_t rec_offset = 0;
333 framecnt_t rec_nframes = 0;
334 bool nominally_recording;
335 bool re = record_enabled ();
336 bool can_record = _session.actively_recording ();
338 playback_distance = 0;
340 check_record_status (transport_frame, can_record);
342 nominally_recording = (can_record && re);
348 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
354 Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
360 const Location* const loop_loc = loop_location;
361 framepos_t loop_start = 0;
362 framepos_t loop_end = 0;
363 framepos_t loop_length = 0;
364 get_location_times(loop_loc, &loop_start, &loop_end, &loop_length);
366 adjust_capture_position = 0;
368 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
369 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
370 // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
372 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
373 /* For audio: not writing frames to the capture ringbuffer offsets
374 * the recording. For midi: we need to keep track of the record range
375 * and subtract the accumulated difference from the event time.
378 _accumulated_capture_offset += rec_offset;
380 _accumulated_capture_offset += nframes;
383 if (rec_nframes && !was_recording) {
385 /* Loop recording, so pretend the capture started at the loop
386 start rgardless of what time it is now, so the source starts
387 at the loop start and can handle time wrapping around.
388 Otherwise, start the source right now as usual.
390 capture_captured = transport_frame - loop_start;
391 capture_start_frame = loop_start;
393 _write_source->mark_write_starting_now(
394 capture_start_frame, capture_captured, loop_length);
395 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
396 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
397 was_recording = true;
401 if (can_record && !_last_capture_sources.empty()) {
402 _last_capture_sources.clear ();
405 if (nominally_recording || rec_nframes) {
407 // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
408 MidiBuffer& buf = sp->get_midi_buffer(nframes);
409 ChannelMode mode = AllChannels;
410 uint32_t mask = 0xffff;
412 MidiTrack * mt = dynamic_cast<MidiTrack*> (_track);
414 mode = mt->get_capture_channel_mode ();
415 mask = mt->get_capture_channel_mask ();
418 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
419 Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
420 if (ev.time() + rec_offset > rec_nframes) {
424 if (DEBUG::MidiIO & PBD::debug_bits) {
425 const uint8_t* __data = ev.buffer();
427 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
428 for (size_t i=0; i < ev.size(); ++i) {
429 DEBUG_STR_APPEND(a,hex);
430 DEBUG_STR_APPEND(a,"0x");
431 DEBUG_STR_APPEND(a,(int)__data[i]);
432 DEBUG_STR_APPEND(a,' ');
434 DEBUG_STR_APPEND(a,'\n');
435 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
438 /* Write events to the capture buffer in frames from session start,
439 but ignoring looping so event time progresses monotonically.
440 The source knows the loop length so it knows exactly where the
441 event occurs in the series of recorded loops and can implement
442 any desirable behaviour. We don't want to send event with
443 transport time here since that way the source can not
444 reconstruct their actual time; future clever MIDI looping should
445 probably be implemented in the source instead of here.
447 const framecnt_t loop_offset = _num_captured_loops * loop_length;
448 const framepos_t event_time = transport_frame + loop_offset - _accumulated_capture_offset + ev.time();
449 if (event_time < 0 || event_time < first_recordable_frame) {
454 _capture_buf->write(event_time,
455 ev.type(), ev.size(), ev.buffer());
458 if (ev.is_channel_event()) {
459 if ((1<<ev.channel()) & mask) {
460 _capture_buf->write(event_time,
461 ev.type(), ev.size(), ev.buffer());
464 _capture_buf->write(event_time,
465 ev.type(), ev.size(), ev.buffer());
469 if (ev.is_channel_event()) {
470 ev.set_channel (PBD::ffs(mask) - 1);
472 _capture_buf->write(event_time,
473 ev.type(), ev.size(), ev.buffer());
477 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
479 if (buf.size() != 0) {
480 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
483 /* Copy this data into our GUI feed buffer and tell the GUI
484 that it can read it if it likes.
486 _gui_feed_buffer.clear ();
488 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
489 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
490 the end of the world if it does.
492 _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
496 DataRecorded (_write_source); /* EMIT SIGNAL */
504 _accumulated_capture_offset = 0;
510 /* data will be written to disk */
512 if (rec_nframes == nframes && rec_offset == 0) {
513 playback_distance = nframes;
516 adjust_capture_position = rec_nframes;
518 } else if (nominally_recording) {
520 /* XXXX do this for MIDI !!!
521 can't do actual capture yet - waiting for latency effects to finish before we start
524 playback_distance = nframes;
526 } else if (_actual_speed != 1.0f && _target_speed > 0) {
528 interpolation.set_speed (_target_speed);
530 playback_distance = interpolation.distance (nframes);
533 playback_distance = nframes;
536 if (need_disk_signal) {
537 /* copy the diskstream data to all output buffers */
539 MidiBuffer& mbuf (bufs.get_midi (0));
540 get_playback (mbuf, playback_distance);
542 /* leave the audio count alone */
543 ChanCount cnt (DataType::MIDI, 1);
544 cnt.set (DataType::AUDIO, bufs.count().n_audio());
545 bufs.set_count (cnt);
548 if (_target_speed > 0 && _actual_speed != 1.0f) {
549 MidiBuffer& mbuf (bufs.get_midi (0));
550 for (MidiBuffer::iterator i = mbuf.begin(); i != mbuf.end(); ++i) {
551 MidiBuffer::TimeType *tme = i.timeptr();
552 *tme = (*tme) * nframes / playback_distance;
561 MidiDiskstream::calculate_playback_distance (pframes_t nframes)
563 frameoffset_t playback_distance = nframes;
565 if (!record_enabled() && _actual_speed != 1.0f && _actual_speed > 0.f) {
566 interpolation.set_speed (_target_speed);
567 playback_distance = interpolation.distance (nframes, false);
570 if (_actual_speed < 0.0) {
571 return -playback_distance;
573 return playback_distance;
578 MidiDiskstream::commit (framecnt_t playback_distance)
580 bool need_butler = false;
582 if (!_io || !_io->active()) {
586 if (_actual_speed < 0.0) {
587 playback_sample -= playback_distance;
589 playback_sample += playback_distance;
592 if (adjust_capture_position != 0) {
593 capture_captured += adjust_capture_position;
594 adjust_capture_position = 0;
597 uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
598 uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
601 cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
602 " = " << frames_written - frames_read
603 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
606 /* frames_read will generally be less than frames_written, but
607 * immediately after an overwrite, we can end up having read some data
608 * before we've written any. we don't need to trip an assert() on this,
609 * but we do need to check so that the decision on whether or not we
610 * need the butler is done correctly.
615 * Doing heavy GUI operations[1] can stall also the butler.
616 * The RT-thread meanwhile will happily continue and
617 * ‘frames_read’ (from buffer to output) will become larger
618 * than ‘frames_written’ (from disk to buffer).
620 * The disk-stream is now behind..
622 * In those cases the butler needs to be summed to refill the buffer (done now)
623 * AND we need to skip (frames_read - frames_written). ie remove old events
624 * before playback_sample from the rinbuffer.
626 * [1] one way to do so is described at #6170.
627 * For me just popping up the context-menu on a MIDI-track header
628 * of a track with a large (think beethoven :) midi-region also did the
629 * trick. The playhead stalls for 2 or 3 sec, until the context-menu shows.
631 * In both cases the root cause is that redrawing MIDI regions on the GUI is still very slow
634 if (frames_read <= frames_written) {
635 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
647 MidiDiskstream::set_pending_overwrite (bool yn)
649 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
651 _pending_overwrite = yn;
652 overwrite_frame = playback_sample;
656 MidiDiskstream::overwrite_existing_buffers ()
658 /* Clear the playback buffer contents. This is safe as long as the butler
659 thread is suspended, which it should be. */
660 _playback_buf->reset ();
661 _playback_buf->reset_tracker ();
663 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
664 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
666 /* Resolve all currently active notes in the playlist. This is more
667 aggressive than it needs to be: ideally we would only resolve what is
668 absolutely necessary, but this seems difficult and/or impossible without
669 having the old data or knowing what change caused the overwrite. */
670 midi_playlist()->resolve_note_trackers (*_playback_buf, overwrite_frame);
672 read (overwrite_frame, disk_read_chunk_frames, false);
673 file_frame = overwrite_frame; // it was adjusted by ::read()
674 overwrite_queued = false;
675 _pending_overwrite = false;
681 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
683 Glib::Threads::Mutex::Lock lm (state_lock);
686 if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
687 /* we haven't read anything since the last seek,
688 so flush all note trackers to prevent
694 _playback_buf->reset();
695 _capture_buf->reset();
696 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
697 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
699 playback_sample = frame;
702 if (complete_refill) {
703 while ((ret = do_refill_with_alloc ()) > 0) ;
705 ret = do_refill_with_alloc ();
712 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
714 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
715 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
716 return ((frames_written - frames_read) < distance);
720 MidiDiskstream::internal_playback_seek (framecnt_t distance)
722 first_recordable_frame += distance;
723 playback_sample += distance;
728 /** @a start is set to the new frame position (TIME) read up to */
730 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
732 framecnt_t this_read = 0;
734 framepos_t loop_end = 0;
735 framepos_t loop_start = 0;
736 framecnt_t loop_length = 0;
742 get_location_times(loc, &loop_start, &loop_end, &loop_length);
744 /* if we are looping, ensure that the first frame we read is at the correct
745 position within the loop.
748 if (loc && (start >= loop_end)) {
749 //cerr << "start adjusted from " << start;
750 start = loop_start + ((start - loop_start) % loop_length);
751 //cerr << "to " << start << endl;
753 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
758 /* take any loop into account. we can't read past the end of the loop. */
760 if (loc && (loop_end - start <= dur)) {
761 this_read = loop_end - start;
762 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
769 if (this_read == 0) {
773 this_read = min(dur,this_read);
775 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
776 error << string_compose(
777 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
778 id(), this_read, start) << endmsg;
782 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
786 // Swap note ons with note offs here. etc?
787 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
788 // CC values etc. hard.
792 /* if we read to the end of the loop, go back to the beginning */
794 // Synthesize LoopEvent here, because the next events
795 // written will have non-monotonic timestamps.
803 //offset += this_read;
810 MidiDiskstream::do_refill_with_alloc ()
816 MidiDiskstream::do_refill ()
819 size_t write_space = _playback_buf->write_space();
820 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
822 if (write_space == 0) {
830 /* at end: nothing to do */
831 if (file_frame == max_framepos) {
835 /* no space to write */
836 if (_playback_buf->write_space() == 0) {
840 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
841 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
842 if ((frames_read < frames_written) && (frames_written - frames_read) >= midi_readahead) {
846 framecnt_t to_read = midi_readahead - ((framecnt_t)frames_written - (framecnt_t)frames_read);
848 //cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
849 // << frames_written - frames_read << endl;
851 to_read = min (to_read, (framecnt_t) (max_framepos - file_frame));
852 to_read = min (to_read, (framecnt_t) write_space);
854 if (read (file_frame, to_read, reversed)) {
861 /** Flush pending data to disk.
863 * Important note: this function will write *AT MOST* disk_write_chunk_frames
864 * of data to disk. it will never write more than that. If it writes that
865 * much and there is more than that waiting to be written, it will return 1,
866 * otherwise 0 on success or -1 on failure.
868 * If there is less than disk_write_chunk_frames to be written, no data will be
869 * written at all unless @a force_flush is true.
872 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
877 if (!_write_source) {
881 const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
884 _capture_buf->read_space() == 0 ||
885 (!force_flush && (total < disk_write_chunk_frames) && was_recording)) {
889 /* if there are 2+ chunks of disk i/o possible for
890 this track), let the caller know so that it can arrange
891 for us to be called again, ASAP.
893 if we are forcing a flush, then if there is* any* extra
894 work, let the caller know.
896 if we are no longer recording and there is any extra work,
897 let the caller know too.
900 if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) {
905 /* push out everything we have, right now */
906 to_write = max_framecnt;
908 to_write = disk_write_chunk_frames;
911 if (record_enabled() && ((total > disk_write_chunk_frames) || force_flush)) {
912 Source::Lock lm(_write_source->mutex());
913 if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
914 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
917 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
925 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
927 bool more_work = true;
929 boost::shared_ptr<MidiRegion> region;
930 MidiRegion::SourceList srcs;
931 MidiRegion::SourceList::iterator src;
932 vector<CaptureInfo*>::iterator ci;
936 /* butler is already stopped, but there may be work to do
937 to flush remaining data to disk.
940 while (more_work && !err) {
941 switch (do_flush (TransportContext, true)) {
948 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
953 /* XXX is there anything we can do if err != 0 ? */
954 Glib::Threads::Mutex::Lock lm (capture_info_lock);
956 if (capture_info.empty()) {
957 goto no_capture_stuff_to_do;
963 _write_source->mark_for_remove ();
964 _write_source->drop_references ();
965 _write_source.reset();
968 /* new source set up in "out" below */
972 framecnt_t total_capture = 0;
973 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
974 total_capture += (*ci)->frames;
977 if (_write_source->length (capture_info.front()->start) != 0) {
979 /* phew, we have data */
981 Source::Lock source_lock(_write_source->mutex());
983 /* figure out the name for this take */
985 srcs.push_back (_write_source);
987 _write_source->set_timeline_position (capture_info.front()->start);
988 _write_source->set_captured_for (_name);
990 /* set length in beats to entire capture length */
992 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
993 const Evoral::Beats total_capture_beats = converter.from (total_capture);
994 _write_source->set_length_beats (total_capture_beats);
996 /* flush to disk: this step differs from the audio path,
997 where all the data is already on disk.
1000 _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
1002 /* we will want to be able to keep (over)writing the source
1003 but we don't want it to be removable. this also differs
1004 from the audio situation, where the source at this point
1005 must be considered immutable. luckily, we can rely on
1006 MidiSource::mark_streaming_write_completed() to have
1007 already done the necessary work for that.
1010 string whole_file_region_name;
1011 whole_file_region_name = region_name_from_path (_write_source->name(), true);
1013 /* Register a new region with the Session that
1014 describes the entire source. Do this first
1015 so that any sub-regions will obviously be
1016 children of this one (later!)
1022 plist.add (Properties::name, whole_file_region_name);
1023 plist.add (Properties::whole_file, true);
1024 plist.add (Properties::automatic, true);
1025 plist.add (Properties::start, 0);
1026 plist.add (Properties::length, total_capture);
1027 plist.add (Properties::layer, 0);
1029 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1031 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1032 region->special_set_position (capture_info.front()->start);
1036 catch (failed_constructor& err) {
1037 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1041 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1043 _playlist->clear_changes ();
1044 _playlist->freeze ();
1046 /* Session frame time of the initial capture in this pass, which is where the source starts */
1047 framepos_t initial_capture = 0;
1048 if (!capture_info.empty()) {
1049 initial_capture = capture_info.front()->start;
1052 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1056 RegionFactory::region_name (region_name, _write_source->name(), false);
1058 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1059 _name, (*ci)->start, (*ci)->frames, region_name));
1062 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1067 /* start of this region is the offset between the start of its capture and the start of the whole pass */
1068 plist.add (Properties::start, (*ci)->start - initial_capture);
1069 plist.add (Properties::length, (*ci)->frames);
1070 plist.add (Properties::length_beats, converter.from((*ci)->frames));
1071 plist.add (Properties::name, region_name);
1073 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1074 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1077 catch (failed_constructor& err) {
1078 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1079 continue; /* XXX is this OK? */
1082 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1084 i_am_the_modifier++;
1085 _playlist->add_region (region, (*ci)->start);
1086 i_am_the_modifier--;
1090 _session.add_command (new StatefulDiffCommand(_playlist));
1094 /* No data was recorded, so this capture will
1095 effectively be aborted; do the same as we
1096 do for an explicit abort.
1099 if (_write_source) {
1100 _write_source->mark_for_remove ();
1101 _write_source->drop_references ();
1102 _write_source.reset();
1108 use_new_write_source (0);
1110 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1114 capture_info.clear ();
1115 capture_start_frame = 0;
1117 no_capture_stuff_to_do:
1123 MidiDiskstream::transport_looped (framepos_t)
1125 /* Here we only keep track of the number of captured loops so monotonic
1126 event times can be delivered to the write source in process(). Trying
1127 to be clever here is a world of trouble, it is better to simply record
1128 the input in a straightforward non-destructive way. In the future when
1129 we want to implement more clever MIDI looping modes it should be done in
1130 the Source and/or entirely after the capture is finished.
1132 if (was_recording) {
1133 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1138 MidiDiskstream::finish_capture ()
1140 was_recording = false;
1142 if (capture_captured == 0) {
1146 CaptureInfo* ci = new CaptureInfo;
1148 ci->start = capture_start_frame;
1149 ci->frames = capture_captured;
1151 /* XXX theoretical race condition here. Need atomic exchange ?
1152 However, the circumstances when this is called right
1153 now (either on record-disable or transport_stopped)
1154 mean that no actual race exists. I think ...
1155 We now have a capture_info_lock, but it is only to be used
1156 to synchronize in the transport_stop and the capture info
1157 accessors, so that invalidation will not occur (both non-realtime).
1160 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1162 capture_info.push_back (ci);
1163 capture_captured = 0;
1167 MidiDiskstream::set_record_enabled (bool yn)
1169 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1173 /* yes, i know that this not proof against race conditions, but its
1174 good enough. i think.
1177 if (record_enabled() != yn) {
1179 engage_record_enable ();
1181 disengage_record_enable ();
1184 RecordEnableChanged (); /* EMIT SIGNAL */
1189 MidiDiskstream::prep_record_enable ()
1191 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1195 bool const rolling = _session.transport_speed() != 0.0f;
1197 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1199 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1200 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1207 MidiDiskstream::prep_record_disable ()
1214 MidiDiskstream::get_state ()
1216 XMLNode& node (Diskstream::get_state());
1218 LocaleGuard lg (X_("C"));
1220 if (_write_source && _session.get_record_enabled()) {
1222 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1223 XMLNode* cs_grandchild;
1225 cs_grandchild = new XMLNode (X_("file"));
1226 cs_grandchild->add_property (X_("path"), _write_source->path());
1227 cs_child->add_child_nocopy (*cs_grandchild);
1229 /* store the location where capture will start */
1233 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1234 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1236 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1239 cs_child->add_property (X_("at"), buf);
1240 node.add_child_nocopy (*cs_child);
1247 MidiDiskstream::set_state (const XMLNode& node, int version)
1249 XMLNodeList nlist = node.children();
1250 XMLNodeIterator niter;
1251 XMLNode* capture_pending_node = 0;
1252 LocaleGuard lg (X_("C"));
1254 /* prevent write sources from being created */
1256 in_set_state = true;
1258 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1259 if ((*niter)->name() == X_("CapturingSources")) {
1260 capture_pending_node = *niter;
1264 if (Diskstream::set_state (node, version)) {
1268 if (capture_pending_node) {
1269 use_pending_capture_data (*capture_pending_node);
1272 in_set_state = false;
1278 MidiDiskstream::use_new_write_source (uint32_t n)
1280 if (!_session.writable() || !recordable()) {
1284 _accumulated_capture_offset = 0;
1285 _write_source.reset();
1288 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1289 _session.create_midi_source_for_session (write_source_name ()));
1291 if (!_write_source) {
1292 throw failed_constructor();
1296 catch (failed_constructor &err) {
1297 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1298 _write_source.reset();
1305 * We want to use the name of the existing write source (the one that will be
1306 * used by the next capture) for another purpose. So change the name of the
1307 * current source, and return its current name.
1309 * Return an empty string if the change cannot be accomplished.
1312 MidiDiskstream::steal_write_source_name ()
1314 string our_old_name = _write_source->name();
1316 /* this will bump the name of the current write source to the next one
1317 * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1318 * current write source name (e.g. "MIDI 1-1" available). See the
1319 * comments in Session::create_midi_source_by_stealing_name() about why
1324 string new_path = _session.new_midi_source_path (name());
1326 if (_write_source->rename (new_path)) {
1333 return our_old_name;
1337 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1339 if (!_session.writable() || !recordable()) {
1343 if (_write_source && mark_write_complete) {
1344 Source::Lock lm(_write_source->mutex());
1345 _write_source->mark_streaming_write_completed (lm);
1347 use_new_write_source (0);
1351 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1356 MidiDiskstream::allocate_temporary_buffers ()
1361 MidiDiskstream::ensure_input_monitoring (bool yn)
1363 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1366 sp->ensure_input_monitoring (yn);
1371 MidiDiskstream::set_align_style_from_io ()
1373 if (_alignment_choice != Automatic) {
1377 /* XXX Not sure what, if anything we can do with MIDI
1378 as far as capture alignment etc.
1381 set_align_style (ExistingMaterial);
1386 MidiDiskstream::playback_buffer_load () const
1388 /* For MIDI it's not trivial to differentiate the following two cases:
1390 1. The playback buffer is empty because the system has run out of time to fill it.
1391 2. The playback buffer is empty because there is no more data on the playlist.
1393 If we use a simple buffer load computation, we will report that the MIDI diskstream
1394 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1395 are so low compared to audio, just give a pretend answer here.
1402 MidiDiskstream::capture_buffer_load () const
1404 /* We don't report playback buffer load, so don't report capture load either */
1410 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1416 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1418 _playback_buf->flush (start, end);
1419 g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1422 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1423 * so that an event at playback_sample has time = 0
1426 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1430 Location* loc = loop_location;
1432 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1433 "%1 MDS pre-read read %8 @ %4..%5 from %2 write to %3, LOOPED ? %6-%7\n", _name,
1434 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1435 (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes));
1437 // cerr << "================\n";
1438 // _playback_buf->dump (cerr);
1439 // cerr << "----------------\n";
1441 size_t events_read = 0;
1444 framepos_t effective_start;
1446 if (playback_sample >= loc->end()) {
1447 effective_start = loc->start() + ((playback_sample - loc->end()) % loc->length());
1449 effective_start = playback_sample;
1452 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1454 if (effective_start == loc->start()) {
1455 /* We need to turn off notes that may extend
1456 beyond the loop end.
1459 _playback_buf->resolve_tracker (dst, 0);
1462 _playback_buf->skip_to (effective_start);
1464 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1465 /* end of loop is within the range we are reading, so
1466 split the read in two, and lie about the location
1469 framecnt_t first, second;
1471 first = loc->end() - effective_start;
1472 second = nframes - first;
1474 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4\n",
1475 effective_start, loc->end(), first, second));
1478 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1479 effective_start, first));
1480 events_read = _playback_buf->read (dst, effective_start, first);
1484 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1485 loc->start(), second));
1486 events_read += _playback_buf->read (dst, loc->start(), second);
1490 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1491 effective_start, nframes));
1492 events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1495 _playback_buf->skip_to (playback_sample);
1496 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1499 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1500 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1501 _name, events_read, playback_sample, playback_sample + nframes,
1502 _playback_buf->read_space(), _playback_buf->write_space(),
1503 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1505 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1509 MidiDiskstream::set_name (string const & name)
1511 if (_name == name) {
1514 Diskstream::set_name (name);
1516 /* get a new write source so that its name reflects the new diskstream name */
1517 use_new_write_source (0);
1523 MidiDiskstream::set_write_source_name (const std::string& str) {
1524 if (_write_source_name == str) {
1527 Diskstream::set_write_source_name (str);
1528 if (_write_source_name == name()) {
1531 use_new_write_source (0);
1535 boost::shared_ptr<MidiBuffer>
1536 MidiDiskstream::get_gui_feed_buffer () const
1538 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1540 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1541 b->copy (_gui_feed_buffer);
1546 MidiDiskstream::reset_tracker ()
1548 _playback_buf->reset_tracker ();
1550 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1553 mp->reset_note_trackers ();
1558 MidiDiskstream::resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time)
1560 _playback_buf->resolve_tracker(buffer, time);
1562 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1565 mp->reset_note_trackers ();
1570 boost::shared_ptr<MidiPlaylist>
1571 MidiDiskstream::midi_playlist ()
1573 return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);