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/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);
139 MidiDiskstream::~MidiDiskstream ()
141 Glib::Threads::Mutex::Lock lm (state_lock);
142 delete _playback_buf;
148 MidiDiskstream::non_realtime_locate (framepos_t position)
151 _write_source->set_timeline_position (position);
153 seek (position, false);
158 MidiDiskstream::non_realtime_input_change ()
161 Glib::Threads::Mutex::Lock lm (state_lock);
163 if (input_change_pending.type == IOChange::NoChange) {
167 if (input_change_pending.type & IOChange::ConfigurationChanged) {
168 uint32_t ni = _io->n_ports().n_midi();
170 if (ni != _n_channels.n_midi()) {
171 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
174 _n_channels, input_change_pending.type)
179 _source_port.reset ();
181 _source_port = _io->midi(0);
185 if (input_change_pending.type & IOChange::ConnectionsChanged) {
186 set_capture_offset ();
187 set_align_style_from_io ();
190 input_change_pending.type = IOChange::NoChange;
192 /* implicit unlock */
195 /* unlike with audio, there is never any need to reset write sources
196 based on input configuration changes because ... a MIDI track
197 has just 1 MIDI port as input, always.
200 /* now refill channel buffers */
202 if (speed() != 1.0f || speed() != -1.0f) {
203 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
206 seek (_session.transport_frame());
209 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
210 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
214 MidiDiskstream::find_and_use_playlist (const string& name)
216 boost::shared_ptr<MidiPlaylist> playlist;
218 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
219 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
223 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg;
227 return use_playlist (playlist);
231 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
233 if (boost::dynamic_pointer_cast<MidiPlaylist>(playlist)) {
234 Diskstream::use_playlist(playlist);
241 MidiDiskstream::use_new_playlist ()
244 boost::shared_ptr<MidiPlaylist> playlist;
246 if (!in_set_state && destructive()) {
251 newname = Playlist::bump_name (_playlist->name(), _session);
253 newname = Playlist::bump_name (_name, _session);
256 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
257 DataType::MIDI, _session, newname, hidden()))) != 0) {
259 return use_playlist (playlist);
267 MidiDiskstream::use_copy_playlist ()
273 if (_playlist == 0) {
274 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
279 boost::shared_ptr<MidiPlaylist> playlist;
281 newname = Playlist::bump_name (_playlist->name(), _session);
283 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
284 return use_playlist (playlist);
290 /** Overloaded from parent to die horribly
293 MidiDiskstream::set_destructive (bool yn)
299 MidiDiskstream::set_note_mode (NoteMode m)
302 midi_playlist()->set_note_mode(m);
303 if (_write_source && _write_source->model())
304 _write_source->model()->set_note_mode(m);
307 /** Get the start, end, and length of a location "atomically".
309 * Note: Locations don't get deleted, so all we care about when I say "atomic"
310 * is that we are always pointing to the same one and using start/length values
311 * obtained just once. Use this function to achieve this since location being
312 * a parameter achieves this.
315 get_location_times(const Location* location,
321 *start = location->start();
322 *end = location->end();
323 *length = *end - *start;
328 MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance, bool need_disk_signal)
330 framecnt_t rec_offset = 0;
331 framecnt_t rec_nframes = 0;
332 bool nominally_recording;
333 bool re = record_enabled ();
334 bool can_record = _session.actively_recording ();
336 playback_distance = 0;
338 check_record_status (transport_frame, can_record);
340 nominally_recording = (can_record && re);
346 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
352 Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
358 const Location* const loop_loc = loop_location;
359 framepos_t loop_start = 0;
360 framepos_t loop_end = 0;
361 framepos_t loop_length = 0;
362 get_location_times(loop_loc, &loop_start, &loop_end, &loop_length);
364 adjust_capture_position = 0;
366 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
367 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
368 // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
370 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
371 /* For audio: not writing frames to the capture ringbuffer offsets
372 * the recording. For midi: we need to keep track of the record range
373 * and subtract the accumulated difference from the event time.
376 _accumulated_capture_offset += rec_offset;
378 _accumulated_capture_offset += nframes;
381 if (rec_nframes && !was_recording) {
383 /* Loop recording, so pretend the capture started at the loop
384 start rgardless of what time it is now, so the source starts
385 at the loop start and can handle time wrapping around.
386 Otherwise, start the source right now as usual.
388 capture_captured = transport_frame - loop_start;
389 capture_start_frame = loop_start;
391 _write_source->mark_write_starting_now(
392 capture_start_frame, capture_captured, loop_length);
393 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
394 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
395 was_recording = true;
399 if (can_record && !_last_capture_sources.empty()) {
400 _last_capture_sources.clear ();
403 if (nominally_recording || rec_nframes) {
405 // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
406 MidiBuffer& buf = sp->get_midi_buffer(nframes);
407 ChannelMode mode = AllChannels; // _track->get_capture_channel_mode ();
408 uint32_t mask = 0xffff; // _track->get_capture_channel_mask ();
410 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
411 Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
412 if (ev.time() + rec_offset > rec_nframes) {
416 if (DEBUG::MidiIO & PBD::debug_bits) {
417 const uint8_t* __data = ev.buffer();
419 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
420 for (size_t i=0; i < ev.size(); ++i) {
421 DEBUG_STR_APPEND(a,hex);
422 DEBUG_STR_APPEND(a,"0x");
423 DEBUG_STR_APPEND(a,(int)__data[i]);
424 DEBUG_STR_APPEND(a,' ');
426 DEBUG_STR_APPEND(a,'\n');
427 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
430 /* Write events to the capture buffer in frames from session start,
431 but ignoring looping so event time progresses monotonically.
432 The source knows the loop length so it knows exactly where the
433 event occurs in the series of recorded loops and can implement
434 any desirable behaviour. We don't want to send event with
435 transport time here since that way the source can not
436 reconstruct their actual time; future clever MIDI looping should
437 probably be implemented in the source instead of here.
439 const framecnt_t loop_offset = _num_captured_loops * loop_length;
440 const framepos_t event_time = transport_frame + loop_offset - _accumulated_capture_offset + ev.time();
441 if (event_time < 0 || event_time < first_recordable_frame) {
446 _capture_buf->write(event_time,
447 ev.type(), ev.size(), ev.buffer());
450 if (ev.is_channel_event()) {
451 if ((1<<ev.channel()) & mask) {
452 _capture_buf->write(event_time,
453 ev.type(), ev.size(), ev.buffer());
456 _capture_buf->write(event_time,
457 ev.type(), ev.size(), ev.buffer());
461 if (ev.is_channel_event()) {
462 ev.set_channel (PBD::ffs(mask) - 1);
464 _capture_buf->write(event_time,
465 ev.type(), ev.size(), ev.buffer());
469 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
471 if (buf.size() != 0) {
472 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
475 /* Copy this data into our GUI feed buffer and tell the GUI
476 that it can read it if it likes.
478 _gui_feed_buffer.clear ();
480 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
481 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
482 the end of the world if it does.
484 _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
488 DataRecorded (_write_source); /* EMIT SIGNAL */
496 _accumulated_capture_offset = 0;
502 /* data will be written to disk */
504 if (rec_nframes == nframes && rec_offset == 0) {
505 playback_distance = nframes;
508 adjust_capture_position = rec_nframes;
510 } else if (nominally_recording) {
512 /* XXXX do this for MIDI !!!
513 can't do actual capture yet - waiting for latency effects to finish before we start
516 playback_distance = nframes;
520 /* XXX: should be doing varispeed stuff here, similar to the code in AudioDiskstream::process */
522 playback_distance = nframes;
526 if (need_disk_signal) {
527 /* copy the diskstream data to all output buffers */
529 MidiBuffer& mbuf (bufs.get_midi (0));
530 get_playback (mbuf, nframes);
532 /* leave the audio count alone */
533 ChanCount cnt (DataType::MIDI, 1);
534 cnt.set (DataType::AUDIO, bufs.count().n_audio());
535 bufs.set_count (cnt);
542 MidiDiskstream::calculate_playback_distance (pframes_t nframes)
544 frameoffset_t playback_distance = nframes;
546 /* XXX: should be doing varispeed stuff once it's implemented in ::process() above */
548 if (_actual_speed < 0.0) {
549 return -playback_distance;
551 return playback_distance;
556 MidiDiskstream::commit (framecnt_t playback_distance)
558 bool need_butler = false;
560 if (_actual_speed < 0.0) {
561 playback_sample -= playback_distance;
563 playback_sample += playback_distance;
566 if (adjust_capture_position != 0) {
567 capture_captured += adjust_capture_position;
568 adjust_capture_position = 0;
571 uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
572 uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
575 cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
576 " = " << frames_written - frames_read
577 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
580 /* frames_read will generally be less than frames_written, but
581 * immediately after an overwrite, we can end up having read some data
582 * before we've written any. we don't need to trip an assert() on this,
583 * but we do need to check so that the decision on whether or not we
584 * need the butler is done correctly.
587 if (frames_read <= frames_written) {
588 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
598 MidiDiskstream::set_pending_overwrite (bool yn)
600 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
602 _pending_overwrite = yn;
603 overwrite_frame = playback_sample;
607 MidiDiskstream::overwrite_existing_buffers ()
609 /* Clear the playback buffer contents. This is safe as long as the butler
610 thread is suspended, which it should be. */
611 _playback_buf->reset ();
612 _playback_buf->reset_tracker ();
614 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
615 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
617 /* Resolve all currently active notes in the playlist. This is more
618 aggressive than it needs to be: ideally we would only resolve what is
619 absolutely necessary, but this seems difficult and/or impossible without
620 having the old data or knowing what change caused the overwrite. */
621 midi_playlist()->resolve_note_trackers (*_playback_buf, overwrite_frame);
623 read (overwrite_frame, disk_io_chunk_frames, false);
624 file_frame = overwrite_frame; // it was adjusted by ::read()
625 overwrite_queued = false;
626 _pending_overwrite = false;
632 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
634 Glib::Threads::Mutex::Lock lm (state_lock);
637 if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
638 /* we haven't read anything since the last seek,
639 so flush all note trackers to prevent
645 _playback_buf->reset();
646 _capture_buf->reset();
647 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
648 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
650 playback_sample = frame;
653 if (complete_refill) {
654 while ((ret = do_refill_with_alloc ()) > 0) ;
656 ret = do_refill_with_alloc ();
663 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
665 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
666 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
667 return ((frames_written - frames_read) < distance);
671 MidiDiskstream::internal_playback_seek (framecnt_t distance)
673 first_recordable_frame += distance;
674 playback_sample += distance;
679 /** @a start is set to the new frame position (TIME) read up to */
681 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
683 framecnt_t this_read = 0;
685 framepos_t loop_end = 0;
686 framepos_t loop_start = 0;
687 framecnt_t loop_length = 0;
693 get_location_times(loc, &loop_start, &loop_end, &loop_length);
695 /* if we are looping, ensure that the first frame we read is at the correct
696 position within the loop.
699 if (loc && (start >= loop_end)) {
700 //cerr << "start adjusted from " << start;
701 start = loop_start + ((start - loop_start) % loop_length);
702 //cerr << "to " << start << endl;
704 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
709 /* take any loop into account. we can't read past the end of the loop. */
711 if (loc && (loop_end - start <= dur)) {
712 this_read = loop_end - start;
713 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
720 if (this_read == 0) {
724 this_read = min(dur,this_read);
726 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
727 error << string_compose(
728 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
729 id(), this_read, start) << endmsg;
733 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
737 // Swap note ons with note offs here. etc?
738 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
739 // CC values etc. hard.
743 /* if we read to the end of the loop, go back to the beginning */
745 // Synthesize LoopEvent here, because the next events
746 // written will have non-monotonic timestamps.
754 //offset += this_read;
761 MidiDiskstream::do_refill_with_alloc ()
767 MidiDiskstream::do_refill ()
770 size_t write_space = _playback_buf->write_space();
771 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
773 if (write_space == 0) {
781 /* at end: nothing to do */
782 if (file_frame == max_framepos) {
786 /* no space to write */
787 if (_playback_buf->write_space() == 0) {
791 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
792 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
793 if ((frames_written - frames_read) >= midi_readahead) {
797 framecnt_t to_read = midi_readahead - (frames_written - frames_read);
799 //cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
800 // << frames_written - frames_read << endl;
802 to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
804 if (read (file_frame, to_read, reversed)) {
811 /** Flush pending data to disk.
813 * Important note: this function will write *AT MOST* disk_io_chunk_frames
814 * of data to disk. it will never write more than that. If it writes that
815 * much and there is more than that waiting to be written, it will return 1,
816 * otherwise 0 on success or -1 on failure.
818 * If there is less than disk_io_chunk_frames to be written, no data will be
819 * written at all unless @a force_flush is true.
822 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
827 if (!_write_source) {
831 const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
834 _capture_buf->read_space() == 0 ||
835 (!force_flush && (total < disk_io_chunk_frames) && was_recording)) {
839 /* if there are 2+ chunks of disk i/o possible for
840 this track), let the caller know so that it can arrange
841 for us to be called again, ASAP.
843 if we are forcing a flush, then if there is* any* extra
844 work, let the caller know.
846 if we are no longer recording and there is any extra work,
847 let the caller know too.
850 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
855 /* push out everything we have, right now */
856 to_write = max_framecnt;
858 to_write = disk_io_chunk_frames;
861 if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
862 Source::Lock lm(_write_source->mutex());
863 if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
864 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
867 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
875 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
877 bool more_work = true;
879 boost::shared_ptr<MidiRegion> region;
880 MidiRegion::SourceList srcs;
881 MidiRegion::SourceList::iterator src;
882 vector<CaptureInfo*>::iterator ci;
886 /* butler is already stopped, but there may be work to do
887 to flush remaining data to disk.
890 while (more_work && !err) {
891 switch (do_flush (TransportContext, true)) {
898 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
903 /* XXX is there anything we can do if err != 0 ? */
904 Glib::Threads::Mutex::Lock lm (capture_info_lock);
906 if (capture_info.empty()) {
907 goto no_capture_stuff_to_do;
913 _write_source->mark_for_remove ();
914 _write_source->drop_references ();
915 _write_source.reset();
918 /* new source set up in "out" below */
922 framecnt_t total_capture = 0;
923 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
924 total_capture += (*ci)->frames;
927 if (_write_source->length (capture_info.front()->start) != 0) {
929 /* phew, we have data */
931 Source::Lock source_lock(_write_source->mutex());
933 /* figure out the name for this take */
935 srcs.push_back (_write_source);
937 _write_source->set_timeline_position (capture_info.front()->start);
938 _write_source->set_captured_for (_name);
940 /* set length in beats to entire capture length */
942 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
943 const Evoral::MusicalTime total_capture_beats = converter.from (total_capture);
944 _write_source->set_length_beats (total_capture_beats);
946 /* flush to disk: this step differs from the audio path,
947 where all the data is already on disk.
950 _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
952 /* we will want to be able to keep (over)writing the source
953 but we don't want it to be removable. this also differs
954 from the audio situation, where the source at this point
955 must be considered immutable. luckily, we can rely on
956 MidiSource::mark_streaming_write_completed() to have
957 already done the necessary work for that.
960 string whole_file_region_name;
961 whole_file_region_name = region_name_from_path (_write_source->name(), true);
963 /* Register a new region with the Session that
964 describes the entire source. Do this first
965 so that any sub-regions will obviously be
966 children of this one (later!)
972 plist.add (Properties::name, whole_file_region_name);
973 plist.add (Properties::whole_file, true);
974 plist.add (Properties::automatic, true);
975 plist.add (Properties::start, 0);
976 plist.add (Properties::length, total_capture);
977 plist.add (Properties::layer, 0);
979 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
981 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
982 region->special_set_position (capture_info.front()->start);
986 catch (failed_constructor& err) {
987 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
991 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
993 _playlist->clear_changes ();
994 _playlist->freeze ();
996 /* Session frame time of the initial capture in this pass, which is where the source starts */
997 framepos_t initial_capture = 0;
998 if (!capture_info.empty()) {
999 initial_capture = capture_info.front()->start;
1002 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1006 RegionFactory::region_name (region_name, _write_source->name(), false);
1008 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1009 _name, (*ci)->start, (*ci)->frames, region_name));
1012 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1017 /* start of this region is the offset between the start of its capture and the start of the whole pass */
1018 plist.add (Properties::start, (*ci)->start - initial_capture);
1019 plist.add (Properties::length, (*ci)->frames);
1020 plist.add (Properties::length_beats, converter.from((*ci)->frames));
1021 plist.add (Properties::name, region_name);
1023 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1024 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1027 catch (failed_constructor& err) {
1028 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1029 continue; /* XXX is this OK? */
1032 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1034 i_am_the_modifier++;
1035 _playlist->add_region (region, (*ci)->start);
1036 i_am_the_modifier--;
1040 _session.add_command (new StatefulDiffCommand(_playlist));
1044 /* No data was recorded, so this capture will
1045 effectively be aborted; do the same as we
1046 do for an explicit abort.
1049 if (_write_source) {
1050 _write_source->mark_for_remove ();
1051 _write_source->drop_references ();
1052 _write_source.reset();
1058 use_new_write_source (0);
1060 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1064 capture_info.clear ();
1065 capture_start_frame = 0;
1067 no_capture_stuff_to_do:
1073 MidiDiskstream::transport_looped (framepos_t)
1075 /* Here we only keep track of the number of captured loops so monotonic
1076 event times can be delivered to the write source in process(). Trying
1077 to be clever here is a world of trouble, it is better to simply record
1078 the input in a straightforward non-destructive way. In the future when
1079 we want to implement more clever MIDI looping modes it should be done in
1080 the Source and/or entirely after the capture is finished.
1082 if (was_recording) {
1083 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1088 MidiDiskstream::finish_capture ()
1090 was_recording = false;
1092 if (capture_captured == 0) {
1096 CaptureInfo* ci = new CaptureInfo;
1098 ci->start = capture_start_frame;
1099 ci->frames = capture_captured;
1101 /* XXX theoretical race condition here. Need atomic exchange ?
1102 However, the circumstances when this is called right
1103 now (either on record-disable or transport_stopped)
1104 mean that no actual race exists. I think ...
1105 We now have a capture_info_lock, but it is only to be used
1106 to synchronize in the transport_stop and the capture info
1107 accessors, so that invalidation will not occur (both non-realtime).
1110 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1112 capture_info.push_back (ci);
1113 capture_captured = 0;
1117 MidiDiskstream::set_record_enabled (bool yn)
1119 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1123 /* yes, i know that this not proof against race conditions, but its
1124 good enough. i think.
1127 if (record_enabled() != yn) {
1129 engage_record_enable ();
1131 disengage_record_enable ();
1134 RecordEnableChanged (); /* EMIT SIGNAL */
1139 MidiDiskstream::prep_record_enable ()
1141 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1145 bool const rolling = _session.transport_speed() != 0.0f;
1147 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1149 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1150 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1157 MidiDiskstream::prep_record_disable ()
1164 MidiDiskstream::get_state ()
1166 XMLNode& node (Diskstream::get_state());
1168 LocaleGuard lg (X_("POSIX"));
1170 if (_write_source && _session.get_record_enabled()) {
1172 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1173 XMLNode* cs_grandchild;
1175 cs_grandchild = new XMLNode (X_("file"));
1176 cs_grandchild->add_property (X_("path"), _write_source->path());
1177 cs_child->add_child_nocopy (*cs_grandchild);
1179 /* store the location where capture will start */
1183 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1184 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1186 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1189 cs_child->add_property (X_("at"), buf);
1190 node.add_child_nocopy (*cs_child);
1197 MidiDiskstream::set_state (const XMLNode& node, int version)
1199 XMLNodeList nlist = node.children();
1200 XMLNodeIterator niter;
1201 XMLNode* capture_pending_node = 0;
1202 LocaleGuard lg (X_("POSIX"));
1204 /* prevent write sources from being created */
1206 in_set_state = true;
1208 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1209 if ((*niter)->name() == X_("CapturingSources")) {
1210 capture_pending_node = *niter;
1214 if (Diskstream::set_state (node, version)) {
1218 if (capture_pending_node) {
1219 use_pending_capture_data (*capture_pending_node);
1222 in_set_state = false;
1228 MidiDiskstream::use_new_write_source (uint32_t n)
1230 if (!_session.writable() || !recordable()) {
1234 _accumulated_capture_offset = 0;
1235 _write_source.reset();
1238 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1239 _session.create_midi_source_for_session (write_source_name ()));
1241 if (!_write_source) {
1242 throw failed_constructor();
1246 catch (failed_constructor &err) {
1247 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1248 _write_source.reset();
1255 * We want to use the name of the existing write source (the one that will be
1256 * used by the next capture) for another purpose. So change the name of the
1257 * current source, and return its current name.
1259 * Return an empty string if the change cannot be accomplished.
1262 MidiDiskstream::steal_write_source_name ()
1264 string our_old_name = _write_source->name();
1266 /* this will bump the name of the current write source to the next one
1267 * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1268 * current write source name (e.g. "MIDI 1-1" available). See the
1269 * comments in Session::create_midi_source_by_stealing_name() about why
1274 string new_path = _session.new_midi_source_path (name());
1276 if (_write_source->rename (new_path)) {
1283 return our_old_name;
1287 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1289 if (!_session.writable() || !recordable()) {
1293 if (_write_source && mark_write_complete) {
1294 Source::Lock lm(_write_source->mutex());
1295 _write_source->mark_streaming_write_completed (lm);
1297 use_new_write_source (0);
1301 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1306 MidiDiskstream::allocate_temporary_buffers ()
1311 MidiDiskstream::ensure_input_monitoring (bool yn)
1313 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1316 sp->ensure_input_monitoring (yn);
1321 MidiDiskstream::set_align_style_from_io ()
1323 if (_alignment_choice != Automatic) {
1327 /* XXX Not sure what, if anything we can do with MIDI
1328 as far as capture alignment etc.
1331 set_align_style (ExistingMaterial);
1336 MidiDiskstream::playback_buffer_load () const
1338 /* For MIDI it's not trivial to differentiate the following two cases:
1340 1. The playback buffer is empty because the system has run out of time to fill it.
1341 2. The playback buffer is empty because there is no more data on the playlist.
1343 If we use a simple buffer load computation, we will report that the MIDI diskstream
1344 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1345 are so low compared to audio, just give a pretend answer here.
1352 MidiDiskstream::capture_buffer_load () const
1354 /* We don't report playback buffer load, so don't report capture load either */
1360 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1366 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1368 _playback_buf->flush (start, end);
1369 g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1372 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1373 * so that an event at playback_sample has time = 0
1376 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1380 Location* loc = loop_location;
1382 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1383 "%1 MDS pre-read read %8 @ %4..%5 from %2 write to %3, LOOPED ? %6-%7\n", _name,
1384 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1385 (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes));
1387 // cerr << "================\n";
1388 // _playback_buf->dump (cerr);
1389 // cerr << "----------------\n";
1391 size_t events_read = 0;
1394 framepos_t effective_start;
1396 if (playback_sample >= loc->end()) {
1397 effective_start = loc->start() + ((playback_sample - loc->end()) % loc->length());
1399 effective_start = playback_sample;
1402 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1404 if (effective_start == loc->start()) {
1405 /* We need to turn off notes that may extend
1406 beyond the loop end.
1409 _playback_buf->resolve_tracker (dst, 0);
1412 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1413 /* end of loop is within the range we are reading, so
1414 split the read in two, and lie about the location
1417 framecnt_t first, second;
1419 first = loc->end() - effective_start;
1420 second = nframes - first;
1422 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4\n",
1423 effective_start, loc->end(), first, second));
1426 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1427 effective_start, first));
1428 events_read = _playback_buf->read (dst, effective_start, first);
1432 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1433 loc->start(), second));
1434 events_read += _playback_buf->read (dst, loc->start(), second);
1438 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1439 effective_start, nframes));
1440 events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1443 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1446 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1447 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1448 _name, events_read, playback_sample, playback_sample + nframes,
1449 _playback_buf->read_space(), _playback_buf->write_space(),
1450 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1452 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1456 MidiDiskstream::set_name (string const & name)
1458 if (_name == name) {
1461 Diskstream::set_name (name);
1463 /* get a new write source so that its name reflects the new diskstream name */
1464 use_new_write_source (0);
1470 MidiDiskstream::set_write_source_name (const std::string& str) {
1471 if (_write_source_name == str) {
1474 Diskstream::set_write_source_name (str);
1475 if (_write_source_name == name()) {
1478 use_new_write_source (0);
1482 boost::shared_ptr<MidiBuffer>
1483 MidiDiskstream::get_gui_feed_buffer () const
1485 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1487 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1488 b->copy (_gui_feed_buffer);
1493 MidiDiskstream::reset_tracker ()
1495 _playback_buf->reset_tracker ();
1497 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1500 mp->reset_note_trackers ();
1504 boost::shared_ptr<MidiPlaylist>
1505 MidiDiskstream::midi_playlist ()
1507 return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);