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);
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) {
406 // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
407 MidiBuffer& buf = sp->get_midi_buffer(nframes);
408 ChannelMode mode = AllChannels;
409 uint32_t mask = 0xffff;
411 MidiTrack * mt = dynamic_cast<MidiTrack*> (_track);
413 mode = mt->get_capture_channel_mode ();
414 mask = mt->get_capture_channel_mask ();
417 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
418 Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
419 if (ev.time() + rec_offset > rec_nframes) {
423 if (DEBUG::MidiIO & PBD::debug_bits) {
424 const uint8_t* __data = ev.buffer();
426 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
427 for (size_t i=0; i < ev.size(); ++i) {
428 DEBUG_STR_APPEND(a,hex);
429 DEBUG_STR_APPEND(a,"0x");
430 DEBUG_STR_APPEND(a,(int)__data[i]);
431 DEBUG_STR_APPEND(a,' ');
433 DEBUG_STR_APPEND(a,'\n');
434 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
437 /* Write events to the capture buffer in frames from session start,
438 but ignoring looping so event time progresses monotonically.
439 The source knows the loop length so it knows exactly where the
440 event occurs in the series of recorded loops and can implement
441 any desirable behaviour. We don't want to send event with
442 transport time here since that way the source can not
443 reconstruct their actual time; future clever MIDI looping should
444 probably be implemented in the source instead of here.
446 const framecnt_t loop_offset = _num_captured_loops * loop_length;
447 const framepos_t event_time = transport_frame + loop_offset - _accumulated_capture_offset + ev.time();
448 if (event_time < 0 || event_time < first_recordable_frame) {
453 _capture_buf->write(event_time,
454 ev.type(), ev.size(), ev.buffer());
457 if (ev.is_channel_event()) {
458 if ((1<<ev.channel()) & mask) {
459 _capture_buf->write(event_time,
460 ev.type(), ev.size(), ev.buffer());
463 _capture_buf->write(event_time,
464 ev.type(), ev.size(), ev.buffer());
468 if (ev.is_channel_event()) {
469 ev.set_channel (PBD::ffs(mask) - 1);
471 _capture_buf->write(event_time,
472 ev.type(), ev.size(), ev.buffer());
476 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
478 if (buf.size() != 0) {
479 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
482 /* Copy this data into our GUI feed buffer and tell the GUI
483 that it can read it if it likes.
485 _gui_feed_buffer.clear ();
487 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
488 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
489 the end of the world if it does.
491 _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
495 DataRecorded (_write_source); /* EMIT SIGNAL */
503 _accumulated_capture_offset = 0;
509 /* data will be written to disk */
511 if (rec_nframes == nframes && rec_offset == 0) {
512 playback_distance = nframes;
515 adjust_capture_position = rec_nframes;
517 } else if (nominally_recording) {
519 /* XXXX do this for MIDI !!!
520 can't do actual capture yet - waiting for latency effects to finish before we start
523 playback_distance = nframes;
527 /* XXX: should be doing varispeed stuff here, similar to the code in AudioDiskstream::process */
529 playback_distance = nframes;
533 if (need_disk_signal) {
534 /* copy the diskstream data to all output buffers */
536 MidiBuffer& mbuf (bufs.get_midi (0));
537 get_playback (mbuf, nframes);
539 /* leave the audio count alone */
540 ChanCount cnt (DataType::MIDI, 1);
541 cnt.set (DataType::AUDIO, bufs.count().n_audio());
542 bufs.set_count (cnt);
549 MidiDiskstream::calculate_playback_distance (pframes_t nframes)
551 frameoffset_t playback_distance = nframes;
553 /* XXX: should be doing varispeed stuff once it's implemented in ::process() above */
555 if (_actual_speed < 0.0) {
556 return -playback_distance;
558 return playback_distance;
563 MidiDiskstream::commit (framecnt_t playback_distance)
565 bool need_butler = false;
567 if (_actual_speed < 0.0) {
568 playback_sample -= playback_distance;
570 playback_sample += playback_distance;
573 if (adjust_capture_position != 0) {
574 capture_captured += adjust_capture_position;
575 adjust_capture_position = 0;
578 uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
579 uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
582 cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
583 " = " << frames_written - frames_read
584 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
587 /* frames_read will generally be less than frames_written, but
588 * immediately after an overwrite, we can end up having read some data
589 * before we've written any. we don't need to trip an assert() on this,
590 * but we do need to check so that the decision on whether or not we
591 * need the butler is done correctly.
594 if (frames_read <= frames_written) {
595 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
605 MidiDiskstream::set_pending_overwrite (bool yn)
607 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
609 _pending_overwrite = yn;
610 overwrite_frame = playback_sample;
614 MidiDiskstream::overwrite_existing_buffers ()
616 /* Clear the playback buffer contents. This is safe as long as the butler
617 thread is suspended, which it should be. */
618 _playback_buf->reset ();
619 _playback_buf->reset_tracker ();
621 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
622 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
624 /* Resolve all currently active notes in the playlist. This is more
625 aggressive than it needs to be: ideally we would only resolve what is
626 absolutely necessary, but this seems difficult and/or impossible without
627 having the old data or knowing what change caused the overwrite. */
628 midi_playlist()->resolve_note_trackers (*_playback_buf, overwrite_frame);
630 read (overwrite_frame, disk_read_chunk_frames, false);
631 file_frame = overwrite_frame; // it was adjusted by ::read()
632 overwrite_queued = false;
633 _pending_overwrite = false;
639 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
641 Glib::Threads::Mutex::Lock lm (state_lock);
644 if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
645 /* we haven't read anything since the last seek,
646 so flush all note trackers to prevent
652 _playback_buf->reset();
653 _capture_buf->reset();
654 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
655 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
657 playback_sample = frame;
660 if (complete_refill) {
661 while ((ret = do_refill_with_alloc ()) > 0) ;
663 ret = do_refill_with_alloc ();
670 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
672 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
673 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
674 return ((frames_written - frames_read) < distance);
678 MidiDiskstream::internal_playback_seek (framecnt_t distance)
680 first_recordable_frame += distance;
681 playback_sample += distance;
686 /** @a start is set to the new frame position (TIME) read up to */
688 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
690 framecnt_t this_read = 0;
692 framepos_t loop_end = 0;
693 framepos_t loop_start = 0;
694 framecnt_t loop_length = 0;
700 get_location_times(loc, &loop_start, &loop_end, &loop_length);
702 /* if we are looping, ensure that the first frame we read is at the correct
703 position within the loop.
706 if (loc && (start >= loop_end)) {
707 //cerr << "start adjusted from " << start;
708 start = loop_start + ((start - loop_start) % loop_length);
709 //cerr << "to " << start << endl;
711 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
716 /* take any loop into account. we can't read past the end of the loop. */
718 if (loc && (loop_end - start <= dur)) {
719 this_read = loop_end - start;
720 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
727 if (this_read == 0) {
731 this_read = min(dur,this_read);
733 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
734 error << string_compose(
735 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
736 id(), this_read, start) << endmsg;
740 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
744 // Swap note ons with note offs here. etc?
745 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
746 // CC values etc. hard.
750 /* if we read to the end of the loop, go back to the beginning */
752 // Synthesize LoopEvent here, because the next events
753 // written will have non-monotonic timestamps.
761 //offset += this_read;
768 MidiDiskstream::do_refill_with_alloc ()
774 MidiDiskstream::do_refill ()
777 size_t write_space = _playback_buf->write_space();
778 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
780 if (write_space == 0) {
788 /* at end: nothing to do */
789 if (file_frame == max_framepos) {
793 /* no space to write */
794 if (_playback_buf->write_space() == 0) {
798 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
799 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
800 if ((frames_written - frames_read) >= midi_readahead) {
804 framecnt_t to_read = midi_readahead - (frames_written - frames_read);
806 //cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
807 // << frames_written - frames_read << endl;
809 to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
811 if (read (file_frame, to_read, reversed)) {
818 /** Flush pending data to disk.
820 * Important note: this function will write *AT MOST* disk_write_chunk_frames
821 * of data to disk. it will never write more than that. If it writes that
822 * much and there is more than that waiting to be written, it will return 1,
823 * otherwise 0 on success or -1 on failure.
825 * If there is less than disk_write_chunk_frames to be written, no data will be
826 * written at all unless @a force_flush is true.
829 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
834 if (!_write_source) {
838 const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
841 _capture_buf->read_space() == 0 ||
842 (!force_flush && (total < disk_write_chunk_frames) && was_recording)) {
846 /* if there are 2+ chunks of disk i/o possible for
847 this track), let the caller know so that it can arrange
848 for us to be called again, ASAP.
850 if we are forcing a flush, then if there is* any* extra
851 work, let the caller know.
853 if we are no longer recording and there is any extra work,
854 let the caller know too.
857 if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) {
862 /* push out everything we have, right now */
863 to_write = max_framecnt;
865 to_write = disk_write_chunk_frames;
868 if (record_enabled() && ((total > disk_write_chunk_frames) || force_flush)) {
869 Source::Lock lm(_write_source->mutex());
870 if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
871 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
874 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
882 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
884 bool more_work = true;
886 boost::shared_ptr<MidiRegion> region;
887 MidiRegion::SourceList srcs;
888 MidiRegion::SourceList::iterator src;
889 vector<CaptureInfo*>::iterator ci;
893 /* butler is already stopped, but there may be work to do
894 to flush remaining data to disk.
897 while (more_work && !err) {
898 switch (do_flush (TransportContext, true)) {
905 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
910 /* XXX is there anything we can do if err != 0 ? */
911 Glib::Threads::Mutex::Lock lm (capture_info_lock);
913 if (capture_info.empty()) {
914 goto no_capture_stuff_to_do;
920 _write_source->mark_for_remove ();
921 _write_source->drop_references ();
922 _write_source.reset();
925 /* new source set up in "out" below */
929 framecnt_t total_capture = 0;
930 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
931 total_capture += (*ci)->frames;
934 if (_write_source->length (capture_info.front()->start) != 0) {
936 /* phew, we have data */
938 Source::Lock source_lock(_write_source->mutex());
940 /* figure out the name for this take */
942 srcs.push_back (_write_source);
944 _write_source->set_timeline_position (capture_info.front()->start);
945 _write_source->set_captured_for (_name);
947 /* set length in beats to entire capture length */
949 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
950 const Evoral::Beats total_capture_beats = converter.from (total_capture);
951 _write_source->set_length_beats (total_capture_beats);
953 /* flush to disk: this step differs from the audio path,
954 where all the data is already on disk.
957 _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
959 /* we will want to be able to keep (over)writing the source
960 but we don't want it to be removable. this also differs
961 from the audio situation, where the source at this point
962 must be considered immutable. luckily, we can rely on
963 MidiSource::mark_streaming_write_completed() to have
964 already done the necessary work for that.
967 string whole_file_region_name;
968 whole_file_region_name = region_name_from_path (_write_source->name(), true);
970 /* Register a new region with the Session that
971 describes the entire source. Do this first
972 so that any sub-regions will obviously be
973 children of this one (later!)
979 plist.add (Properties::name, whole_file_region_name);
980 plist.add (Properties::whole_file, true);
981 plist.add (Properties::automatic, true);
982 plist.add (Properties::start, 0);
983 plist.add (Properties::length, total_capture);
984 plist.add (Properties::layer, 0);
986 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
988 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
989 region->special_set_position (capture_info.front()->start);
993 catch (failed_constructor& err) {
994 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
998 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1000 _playlist->clear_changes ();
1001 _playlist->freeze ();
1003 /* Session frame time of the initial capture in this pass, which is where the source starts */
1004 framepos_t initial_capture = 0;
1005 if (!capture_info.empty()) {
1006 initial_capture = capture_info.front()->start;
1009 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1013 RegionFactory::region_name (region_name, _write_source->name(), false);
1015 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1016 _name, (*ci)->start, (*ci)->frames, region_name));
1019 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1024 /* start of this region is the offset between the start of its capture and the start of the whole pass */
1025 plist.add (Properties::start, (*ci)->start - initial_capture);
1026 plist.add (Properties::length, (*ci)->frames);
1027 plist.add (Properties::length_beats, converter.from((*ci)->frames));
1028 plist.add (Properties::name, region_name);
1030 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1031 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1034 catch (failed_constructor& err) {
1035 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1036 continue; /* XXX is this OK? */
1039 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1041 i_am_the_modifier++;
1042 _playlist->add_region (region, (*ci)->start);
1043 i_am_the_modifier--;
1047 _session.add_command (new StatefulDiffCommand(_playlist));
1051 /* No data was recorded, so this capture will
1052 effectively be aborted; do the same as we
1053 do for an explicit abort.
1056 if (_write_source) {
1057 _write_source->mark_for_remove ();
1058 _write_source->drop_references ();
1059 _write_source.reset();
1065 use_new_write_source (0);
1067 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1071 capture_info.clear ();
1072 capture_start_frame = 0;
1074 no_capture_stuff_to_do:
1080 MidiDiskstream::transport_looped (framepos_t)
1082 /* Here we only keep track of the number of captured loops so monotonic
1083 event times can be delivered to the write source in process(). Trying
1084 to be clever here is a world of trouble, it is better to simply record
1085 the input in a straightforward non-destructive way. In the future when
1086 we want to implement more clever MIDI looping modes it should be done in
1087 the Source and/or entirely after the capture is finished.
1089 if (was_recording) {
1090 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1095 MidiDiskstream::finish_capture ()
1097 was_recording = false;
1099 if (capture_captured == 0) {
1103 CaptureInfo* ci = new CaptureInfo;
1105 ci->start = capture_start_frame;
1106 ci->frames = capture_captured;
1108 /* XXX theoretical race condition here. Need atomic exchange ?
1109 However, the circumstances when this is called right
1110 now (either on record-disable or transport_stopped)
1111 mean that no actual race exists. I think ...
1112 We now have a capture_info_lock, but it is only to be used
1113 to synchronize in the transport_stop and the capture info
1114 accessors, so that invalidation will not occur (both non-realtime).
1117 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1119 capture_info.push_back (ci);
1120 capture_captured = 0;
1124 MidiDiskstream::set_record_enabled (bool yn)
1126 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1130 /* yes, i know that this not proof against race conditions, but its
1131 good enough. i think.
1134 if (record_enabled() != yn) {
1136 engage_record_enable ();
1138 disengage_record_enable ();
1141 RecordEnableChanged (); /* EMIT SIGNAL */
1146 MidiDiskstream::prep_record_enable ()
1148 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1152 bool const rolling = _session.transport_speed() != 0.0f;
1154 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1156 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1157 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1164 MidiDiskstream::prep_record_disable ()
1171 MidiDiskstream::get_state ()
1173 XMLNode& node (Diskstream::get_state());
1175 LocaleGuard lg (X_("C"));
1177 if (_write_source && _session.get_record_enabled()) {
1179 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1180 XMLNode* cs_grandchild;
1182 cs_grandchild = new XMLNode (X_("file"));
1183 cs_grandchild->add_property (X_("path"), _write_source->path());
1184 cs_child->add_child_nocopy (*cs_grandchild);
1186 /* store the location where capture will start */
1190 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1191 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1193 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1196 cs_child->add_property (X_("at"), buf);
1197 node.add_child_nocopy (*cs_child);
1204 MidiDiskstream::set_state (const XMLNode& node, int version)
1206 XMLNodeList nlist = node.children();
1207 XMLNodeIterator niter;
1208 XMLNode* capture_pending_node = 0;
1209 LocaleGuard lg (X_("C"));
1211 /* prevent write sources from being created */
1213 in_set_state = true;
1215 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1216 if ((*niter)->name() == X_("CapturingSources")) {
1217 capture_pending_node = *niter;
1221 if (Diskstream::set_state (node, version)) {
1225 if (capture_pending_node) {
1226 use_pending_capture_data (*capture_pending_node);
1229 in_set_state = false;
1235 MidiDiskstream::use_new_write_source (uint32_t n)
1237 if (!_session.writable() || !recordable()) {
1241 _accumulated_capture_offset = 0;
1242 _write_source.reset();
1245 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1246 _session.create_midi_source_for_session (write_source_name ()));
1248 if (!_write_source) {
1249 throw failed_constructor();
1253 catch (failed_constructor &err) {
1254 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1255 _write_source.reset();
1262 * We want to use the name of the existing write source (the one that will be
1263 * used by the next capture) for another purpose. So change the name of the
1264 * current source, and return its current name.
1266 * Return an empty string if the change cannot be accomplished.
1269 MidiDiskstream::steal_write_source_name ()
1271 string our_old_name = _write_source->name();
1273 /* this will bump the name of the current write source to the next one
1274 * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1275 * current write source name (e.g. "MIDI 1-1" available). See the
1276 * comments in Session::create_midi_source_by_stealing_name() about why
1281 string new_path = _session.new_midi_source_path (name());
1283 if (_write_source->rename (new_path)) {
1290 return our_old_name;
1294 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1296 if (!_session.writable() || !recordable()) {
1300 if (_write_source && mark_write_complete) {
1301 Source::Lock lm(_write_source->mutex());
1302 _write_source->mark_streaming_write_completed (lm);
1304 use_new_write_source (0);
1308 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1313 MidiDiskstream::allocate_temporary_buffers ()
1318 MidiDiskstream::ensure_input_monitoring (bool yn)
1320 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1323 sp->ensure_input_monitoring (yn);
1328 MidiDiskstream::set_align_style_from_io ()
1330 if (_alignment_choice != Automatic) {
1334 /* XXX Not sure what, if anything we can do with MIDI
1335 as far as capture alignment etc.
1338 set_align_style (ExistingMaterial);
1343 MidiDiskstream::playback_buffer_load () const
1345 /* For MIDI it's not trivial to differentiate the following two cases:
1347 1. The playback buffer is empty because the system has run out of time to fill it.
1348 2. The playback buffer is empty because there is no more data on the playlist.
1350 If we use a simple buffer load computation, we will report that the MIDI diskstream
1351 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1352 are so low compared to audio, just give a pretend answer here.
1359 MidiDiskstream::capture_buffer_load () const
1361 /* We don't report playback buffer load, so don't report capture load either */
1367 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1373 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1375 _playback_buf->flush (start, end);
1376 g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1379 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1380 * so that an event at playback_sample has time = 0
1383 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1387 Location* loc = loop_location;
1389 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1390 "%1 MDS pre-read read %8 @ %4..%5 from %2 write to %3, LOOPED ? %6-%7\n", _name,
1391 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1392 (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes));
1394 // cerr << "================\n";
1395 // _playback_buf->dump (cerr);
1396 // cerr << "----------------\n";
1398 size_t events_read = 0;
1401 framepos_t effective_start;
1403 if (playback_sample >= loc->end()) {
1404 effective_start = loc->start() + ((playback_sample - loc->end()) % loc->length());
1406 effective_start = playback_sample;
1409 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1411 if (effective_start == loc->start()) {
1412 /* We need to turn off notes that may extend
1413 beyond the loop end.
1416 _playback_buf->resolve_tracker (dst, 0);
1419 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1420 /* end of loop is within the range we are reading, so
1421 split the read in two, and lie about the location
1424 framecnt_t first, second;
1426 first = loc->end() - effective_start;
1427 second = nframes - first;
1429 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4\n",
1430 effective_start, loc->end(), first, second));
1433 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1434 effective_start, first));
1435 events_read = _playback_buf->read (dst, effective_start, first);
1439 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1440 loc->start(), second));
1441 events_read += _playback_buf->read (dst, loc->start(), second);
1445 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1446 effective_start, nframes));
1447 events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1450 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1453 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1454 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1455 _name, events_read, playback_sample, playback_sample + nframes,
1456 _playback_buf->read_space(), _playback_buf->write_space(),
1457 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1459 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1463 MidiDiskstream::set_name (string const & name)
1465 if (_name == name) {
1468 Diskstream::set_name (name);
1470 /* get a new write source so that its name reflects the new diskstream name */
1471 use_new_write_source (0);
1477 MidiDiskstream::set_write_source_name (const std::string& str) {
1478 if (_write_source_name == str) {
1481 Diskstream::set_write_source_name (str);
1482 if (_write_source_name == name()) {
1485 use_new_write_source (0);
1489 boost::shared_ptr<MidiBuffer>
1490 MidiDiskstream::get_gui_feed_buffer () const
1492 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1494 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1495 b->copy (_gui_feed_buffer);
1500 MidiDiskstream::reset_tracker ()
1502 _playback_buf->reset_tracker ();
1504 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1507 mp->reset_note_trackers ();
1511 boost::shared_ptr<MidiPlaylist>
1512 MidiDiskstream::midi_playlist ()
1514 return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);