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/playlist_factory.h"
51 #include "ardour/region_factory.h"
52 #include "ardour/session.h"
53 #include "ardour/session_playlists.h"
54 #include "ardour/smf_source.h"
55 #include "ardour/types.h"
56 #include "ardour/utils.h"
58 #include "midi++/types.h"
64 using namespace ARDOUR;
67 framecnt_t MidiDiskstream::midi_readahead = 4096;
69 MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
70 : Diskstream(sess, name, flag)
73 , _note_mode(Sustained)
74 , _frames_written_to_ringbuffer(0)
75 , _frames_read_from_ringbuffer(0)
76 , _frames_pending_write(0)
77 , _num_captured_loops(0)
78 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
84 use_new_write_source (0);
89 throw failed_constructor();
93 MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
94 : Diskstream(sess, node)
97 , _note_mode(Sustained)
98 , _frames_written_to_ringbuffer(0)
99 , _frames_read_from_ringbuffer(0)
100 , _frames_pending_write(0)
101 , _num_captured_loops(0)
102 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
108 if (set_state (node, Stateful::loading_state_version)) {
109 in_set_state = false;
110 throw failed_constructor();
113 use_new_write_source (0);
115 in_set_state = false;
119 MidiDiskstream::init ()
121 /* there are no channels at this point, so these
122 two calls just get speed_buffer_size and wrap_buffer
123 size setup without duplicating their code.
126 set_block_size (_session.get_block_size());
127 allocate_temporary_buffers ();
129 const size_t size = _session.butler()->midi_diskstream_buffer_size();
130 _playback_buf = new MidiRingBuffer<framepos_t>(size);
131 _capture_buf = new MidiRingBuffer<framepos_t>(size);
133 _n_channels = ChanCount(DataType::MIDI, 1);
136 MidiDiskstream::~MidiDiskstream ()
138 Glib::Threads::Mutex::Lock lm (state_lock);
143 MidiDiskstream::non_realtime_locate (framepos_t position)
146 _write_source->set_timeline_position (position);
148 seek (position, false);
153 MidiDiskstream::non_realtime_input_change ()
156 Glib::Threads::Mutex::Lock lm (state_lock);
158 if (input_change_pending.type == IOChange::NoChange) {
162 if (input_change_pending.type & IOChange::ConfigurationChanged) {
163 uint32_t ni = _io->n_ports().n_midi();
165 if (ni != _n_channels.n_midi()) {
166 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
169 _n_channels, input_change_pending.type)
174 _source_port.reset ();
176 _source_port = _io->midi(0);
180 if (input_change_pending.type & IOChange::ConnectionsChanged) {
181 set_capture_offset ();
182 set_align_style_from_io ();
185 input_change_pending.type = IOChange::NoChange;
187 /* implicit unlock */
190 /* unlike with audio, there is never any need to reset write sources
191 based on input configuration changes because ... a MIDI track
192 has just 1 MIDI port as input, always.
195 /* now refill channel buffers */
197 if (speed() != 1.0f || speed() != -1.0f) {
198 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
201 seek (_session.transport_frame());
204 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
205 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
209 MidiDiskstream::find_and_use_playlist (const string& name)
211 boost::shared_ptr<MidiPlaylist> playlist;
213 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
214 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
218 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg;
222 return use_playlist (playlist);
226 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
228 if (boost::dynamic_pointer_cast<MidiPlaylist>(playlist)) {
229 Diskstream::use_playlist(playlist);
236 MidiDiskstream::use_new_playlist ()
239 boost::shared_ptr<MidiPlaylist> playlist;
241 if (!in_set_state && destructive()) {
246 newname = Playlist::bump_name (_playlist->name(), _session);
248 newname = Playlist::bump_name (_name, _session);
251 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
252 DataType::MIDI, _session, newname, hidden()))) != 0) {
254 return use_playlist (playlist);
262 MidiDiskstream::use_copy_playlist ()
268 if (_playlist == 0) {
269 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
274 boost::shared_ptr<MidiPlaylist> playlist;
276 newname = Playlist::bump_name (_playlist->name(), _session);
278 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
279 return use_playlist (playlist);
285 /** Overloaded from parent to die horribly
288 MidiDiskstream::set_destructive (bool yn)
294 MidiDiskstream::set_note_mode (NoteMode m)
297 midi_playlist()->set_note_mode(m);
298 if (_write_source && _write_source->model())
299 _write_source->model()->set_note_mode(m);
302 /** Get the start, end, and length of a location "atomically".
304 * Note: Locations don't get deleted, so all we care about when I say "atomic"
305 * is that we are always pointing to the same one and using start/length values
306 * obtained just once. Use this function to achieve this since location being
307 * a parameter achieves this.
310 get_location_times(const Location* location,
316 *start = location->start();
317 *end = location->end();
318 *length = *end - *start;
323 MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance, bool need_disk_signal)
325 framecnt_t rec_offset = 0;
326 framecnt_t rec_nframes = 0;
327 bool nominally_recording;
328 bool re = record_enabled ();
329 bool can_record = _session.actively_recording ();
331 playback_distance = 0;
333 check_record_status (transport_frame, can_record);
335 nominally_recording = (can_record && re);
341 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
347 Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
353 const Location* const loop_loc = loop_location;
354 framepos_t loop_start = 0;
355 framepos_t loop_end = 0;
356 framepos_t loop_length = 0;
357 get_location_times(loop_loc, &loop_start, &loop_end, &loop_length);
359 adjust_capture_position = 0;
361 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
362 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
364 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
366 if (rec_nframes && !was_recording) {
368 /* Loop recording, so pretend the capture started at the loop
369 start rgardless of what time it is now, so the source starts
370 at the loop start and can handle time wrapping around.
371 Otherwise, start the source right now as usual.
373 capture_captured = transport_frame - loop_start;
374 capture_start_frame = loop_start;
376 _write_source->mark_write_starting_now(
377 capture_start_frame, capture_captured, loop_length);
378 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
379 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
380 was_recording = true;
384 if (can_record && !_last_capture_sources.empty()) {
385 _last_capture_sources.clear ();
388 if (nominally_recording || rec_nframes) {
390 // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
391 MidiBuffer& buf = sp->get_midi_buffer(nframes);
392 ChannelMode mode = AllChannels; // _track->get_capture_channel_mode ();
393 uint32_t mask = 0xffff; // _track->get_capture_channel_mask ();
395 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
396 Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
398 if (DEBUG::MidiIO & PBD::debug_bits) {
399 const uint8_t* __data = ev.buffer();
401 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
402 for (size_t i=0; i < ev.size(); ++i) {
403 DEBUG_STR_APPEND(a,hex);
404 DEBUG_STR_APPEND(a,"0x");
405 DEBUG_STR_APPEND(a,(int)__data[i]);
406 DEBUG_STR_APPEND(a,' ');
408 DEBUG_STR_APPEND(a,'\n');
409 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
412 /* Write events to the capture buffer in frames from session start,
413 but ignoring looping so event time progresses monotonically.
414 The source knows the loop length so it knows exactly where the
415 event occurs in the series of recorded loops and can implement
416 any desirable behaviour. We don't want to send event with
417 transport time here since that way the source can not
418 reconstruct their actual time; future clever MIDI looping should
419 probabl be implemented in the source instead of here.
421 const framecnt_t loop_offset = _num_captured_loops * loop_length;
425 _capture_buf->write(transport_frame + loop_offset + ev.time(),
426 ev.type(), ev.size(), ev.buffer());
429 if (ev.is_channel_event()) {
430 if ((1<<ev.channel()) & mask) {
431 _capture_buf->write(transport_frame + loop_offset + ev.time(),
432 ev.type(), ev.size(), ev.buffer());
435 _capture_buf->write(transport_frame + loop_offset + ev.time(),
436 ev.type(), ev.size(), ev.buffer());
440 if (ev.is_channel_event()) {
441 ev.set_channel (PBD::ffs(mask) - 1);
443 _capture_buf->write(transport_frame + loop_offset + ev.time(),
444 ev.type(), ev.size(), ev.buffer());
448 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
450 if (buf.size() != 0) {
451 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
454 /* Copy this data into our GUI feed buffer and tell the GUI
455 that it can read it if it likes.
457 _gui_feed_buffer.clear ();
459 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
460 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
461 the end of the world if it does.
463 _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
467 DataRecorded (_write_source); /* EMIT SIGNAL */
480 /* data will be written to disk */
482 if (rec_nframes == nframes && rec_offset == 0) {
483 playback_distance = nframes;
486 adjust_capture_position = rec_nframes;
488 } else if (nominally_recording) {
490 /* XXXX do this for MIDI !!!
491 can't do actual capture yet - waiting for latency effects to finish before we start
494 playback_distance = nframes;
498 /* XXX: should be doing varispeed stuff here, similar to the code in AudioDiskstream::process */
500 playback_distance = nframes;
504 if (need_disk_signal) {
505 /* copy the diskstream data to all output buffers */
507 MidiBuffer& mbuf (bufs.get_midi (0));
508 get_playback (mbuf, nframes);
510 /* leave the audio count alone */
511 ChanCount cnt (DataType::MIDI, 1);
512 cnt.set (DataType::AUDIO, bufs.count().n_audio());
513 bufs.set_count (cnt);
520 MidiDiskstream::calculate_playback_distance (pframes_t nframes)
522 frameoffset_t playback_distance = nframes;
524 /* XXX: should be doing varispeed stuff once it's implemented in ::process() above */
526 if (_actual_speed < 0.0) {
527 return -playback_distance;
529 return playback_distance;
534 MidiDiskstream::commit (framecnt_t playback_distance)
536 bool need_butler = false;
538 if (_actual_speed < 0.0) {
539 playback_sample -= playback_distance;
541 playback_sample += playback_distance;
544 if (adjust_capture_position != 0) {
545 capture_captured += adjust_capture_position;
546 adjust_capture_position = 0;
549 uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
550 uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
553 cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
554 " = " << frames_written - frames_read
555 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
558 /* frames_read will generally be less than frames_written, but
559 * immediately after an overwrite, we can end up having read some data
560 * before we've written any. we don't need to trip an assert() on this,
561 * but we do need to check so that the decision on whether or not we
562 * need the butler is done correctly.
565 if (frames_read <= frames_written) {
566 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
576 MidiDiskstream::set_pending_overwrite (bool yn)
578 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
580 _pending_overwrite = yn;
581 overwrite_frame = playback_sample;
585 MidiDiskstream::overwrite_existing_buffers ()
587 /* This is safe as long as the butler thread is suspended, which it should be */
588 _playback_buf->reset ();
590 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
591 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
593 read (overwrite_frame, disk_io_chunk_frames, false);
594 file_frame = overwrite_frame; // it was adjusted by ::read()
595 overwrite_queued = false;
596 _pending_overwrite = false;
602 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
604 Glib::Threads::Mutex::Lock lm (state_lock);
607 if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
608 /* we haven't read anything since the last seek,
609 so flush all note trackers to prevent
615 _playback_buf->reset();
616 _capture_buf->reset();
617 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
618 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
620 playback_sample = frame;
623 if (complete_refill) {
624 while ((ret = do_refill_with_alloc ()) > 0) ;
626 ret = do_refill_with_alloc ();
633 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
635 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
636 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
637 return ((frames_written - frames_read) < distance);
641 MidiDiskstream::internal_playback_seek (framecnt_t distance)
643 first_recordable_frame += distance;
644 playback_sample += distance;
649 /** @a start is set to the new frame position (TIME) read up to */
651 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
653 framecnt_t this_read = 0;
655 framepos_t loop_end = 0;
656 framepos_t loop_start = 0;
657 framecnt_t loop_length = 0;
663 get_location_times(loc, &loop_start, &loop_end, &loop_length);
665 /* if we are looping, ensure that the first frame we read is at the correct
666 position within the loop.
669 if (loc && (start >= loop_end)) {
670 //cerr << "start adjusted from " << start;
671 start = loop_start + ((start - loop_start) % loop_length);
672 //cerr << "to " << start << endl;
674 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
679 /* take any loop into account. we can't read past the end of the loop. */
681 if (loc && (loop_end - start <= dur)) {
682 this_read = loop_end - start;
683 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
690 if (this_read == 0) {
694 this_read = min(dur,this_read);
696 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
697 error << string_compose(
698 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
699 id(), this_read, start) << endmsg;
703 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
707 // Swap note ons with note offs here. etc?
708 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
709 // CC values etc. hard.
713 /* if we read to the end of the loop, go back to the beginning */
715 // Synthesize LoopEvent here, because the next events
716 // written will have non-monotonic timestamps.
724 //offset += this_read;
731 MidiDiskstream::do_refill_with_alloc ()
737 MidiDiskstream::do_refill ()
740 size_t write_space = _playback_buf->write_space();
741 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
743 if (write_space == 0) {
751 /* at end: nothing to do */
752 if (file_frame == max_framepos) {
756 /* no space to write */
757 if (_playback_buf->write_space() == 0) {
761 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
762 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
763 if ((frames_written - frames_read) >= midi_readahead) {
767 framecnt_t to_read = midi_readahead - (frames_written - frames_read);
769 //cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
770 // << frames_written - frames_read << endl;
772 to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
774 if (read (file_frame, to_read, reversed)) {
781 /** Flush pending data to disk.
783 * Important note: this function will write *AT MOST* disk_io_chunk_frames
784 * of data to disk. it will never write more than that. If it writes that
785 * much and there is more than that waiting to be written, it will return 1,
786 * otherwise 0 on success or -1 on failure.
788 * If there is less than disk_io_chunk_frames to be written, no data will be
789 * written at all unless @a force_flush is true.
792 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
797 if (!_write_source) {
801 const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
804 _capture_buf->read_space() == 0 ||
805 (!force_flush && (total < disk_io_chunk_frames) && was_recording)) {
809 /* if there are 2+ chunks of disk i/o possible for
810 this track), let the caller know so that it can arrange
811 for us to be called again, ASAP.
813 if we are forcing a flush, then if there is* any* extra
814 work, let the caller know.
816 if we are no longer recording and there is any extra work,
817 let the caller know too.
820 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
825 /* push out everything we have, right now */
826 to_write = max_framecnt;
828 to_write = disk_io_chunk_frames;
831 if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
832 if (_write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
833 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
836 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
844 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
846 bool more_work = true;
848 boost::shared_ptr<MidiRegion> region;
849 MidiRegion::SourceList srcs;
850 MidiRegion::SourceList::iterator src;
851 vector<CaptureInfo*>::iterator ci;
855 /* butler is already stopped, but there may be work to do
856 to flush remaining data to disk.
859 while (more_work && !err) {
860 switch (do_flush (TransportContext, true)) {
867 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
872 /* XXX is there anything we can do if err != 0 ? */
873 Glib::Threads::Mutex::Lock lm (capture_info_lock);
875 if (capture_info.empty()) {
876 goto no_capture_stuff_to_do;
882 _write_source->mark_for_remove ();
883 _write_source->drop_references ();
884 _write_source.reset();
887 /* new source set up in "out" below */
891 framecnt_t total_capture = 0;
892 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
893 total_capture += (*ci)->frames;
896 if (_write_source->length (capture_info.front()->start) != 0) {
898 /* phew, we have data */
900 /* figure out the name for this take */
902 srcs.push_back (_write_source);
904 _write_source->set_timeline_position (capture_info.front()->start);
905 _write_source->set_captured_for (_name);
907 /* set length in beats to entire capture length */
909 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
910 const double total_capture_beats = converter.from (total_capture);
911 _write_source->set_length_beats (total_capture_beats);
913 /* flush to disk: this step differs from the audio path,
914 where all the data is already on disk.
917 _write_source->mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
919 /* we will want to be able to keep (over)writing the source
920 but we don't want it to be removable. this also differs
921 from the audio situation, where the source at this point
922 must be considered immutable. luckily, we can rely on
923 MidiSource::mark_streaming_write_completed() to have
924 already done the necessary work for that.
927 string whole_file_region_name;
928 whole_file_region_name = region_name_from_path (_write_source->name(), true);
930 /* Register a new region with the Session that
931 describes the entire source. Do this first
932 so that any sub-regions will obviously be
933 children of this one (later!)
939 plist.add (Properties::name, whole_file_region_name);
940 plist.add (Properties::whole_file, true);
941 plist.add (Properties::automatic, true);
942 plist.add (Properties::start, 0);
943 plist.add (Properties::length, total_capture);
944 plist.add (Properties::layer, 0);
946 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
948 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
949 region->special_set_position (capture_info.front()->start);
953 catch (failed_constructor& err) {
954 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
958 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
960 _playlist->clear_changes ();
961 _playlist->freeze ();
963 /* Session frame time of the initial capture in this pass, which is where the source starts */
964 framepos_t initial_capture = 0;
965 if (!capture_info.empty()) {
966 initial_capture = capture_info.front()->start;
969 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
973 RegionFactory::region_name (region_name, _write_source->name(), false);
975 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
980 /* start of this region is the offset between the start of its capture and the start of the whole pass */
981 plist.add (Properties::start, (*ci)->start - initial_capture);
982 plist.add (Properties::length, (*ci)->frames);
983 plist.add (Properties::length_beats, converter.from((*ci)->frames));
984 plist.add (Properties::name, region_name);
986 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
987 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
990 catch (failed_constructor& err) {
991 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
992 continue; /* XXX is this OK? */
995 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
998 _playlist->add_region (region, (*ci)->start);
1003 _session.add_command (new StatefulDiffCommand(_playlist));
1007 /* No data was recorded, so this capture will
1008 effectively be aborted; do the same as we
1009 do for an explicit abort.
1012 if (_write_source) {
1013 _write_source->mark_for_remove ();
1014 _write_source->drop_references ();
1015 _write_source.reset();
1021 use_new_write_source (0);
1023 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1027 capture_info.clear ();
1028 capture_start_frame = 0;
1030 no_capture_stuff_to_do:
1036 MidiDiskstream::transport_looped (framepos_t)
1038 /* Here we only keep track of the number of captured loops so monotonic
1039 event times can be delivered to the write source in process(). Trying
1040 to be clever here is a world of trouble, it is better to simply record
1041 the input in a straightforward non-destructive way. In the future when
1042 we want to implement more clever MIDI looping modes it should be done in
1043 the Source and/or entirely after the capture is finished.
1045 if (was_recording) {
1046 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1051 MidiDiskstream::finish_capture ()
1053 was_recording = false;
1055 if (capture_captured == 0) {
1059 CaptureInfo* ci = new CaptureInfo;
1061 ci->start = capture_start_frame;
1062 ci->frames = capture_captured;
1064 /* XXX theoretical race condition here. Need atomic exchange ?
1065 However, the circumstances when this is called right
1066 now (either on record-disable or transport_stopped)
1067 mean that no actual race exists. I think ...
1068 We now have a capture_info_lock, but it is only to be used
1069 to synchronize in the transport_stop and the capture info
1070 accessors, so that invalidation will not occur (both non-realtime).
1073 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1075 capture_info.push_back (ci);
1076 capture_captured = 0;
1080 MidiDiskstream::set_record_enabled (bool yn)
1082 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1086 /* yes, i know that this not proof against race conditions, but its
1087 good enough. i think.
1090 if (record_enabled() != yn) {
1092 engage_record_enable ();
1094 disengage_record_enable ();
1097 RecordEnableChanged (); /* EMIT SIGNAL */
1102 MidiDiskstream::prep_record_enable ()
1104 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1108 bool const rolling = _session.transport_speed() != 0.0f;
1110 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1112 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1113 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1120 MidiDiskstream::prep_record_disable ()
1127 MidiDiskstream::get_state ()
1129 XMLNode& node (Diskstream::get_state());
1131 LocaleGuard lg (X_("POSIX"));
1133 if (_write_source && _session.get_record_enabled()) {
1135 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1136 XMLNode* cs_grandchild;
1138 cs_grandchild = new XMLNode (X_("file"));
1139 cs_grandchild->add_property (X_("path"), _write_source->path());
1140 cs_child->add_child_nocopy (*cs_grandchild);
1142 /* store the location where capture will start */
1146 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1147 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1149 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1152 cs_child->add_property (X_("at"), buf);
1153 node.add_child_nocopy (*cs_child);
1160 MidiDiskstream::set_state (const XMLNode& node, int version)
1162 XMLNodeList nlist = node.children();
1163 XMLNodeIterator niter;
1164 XMLNode* capture_pending_node = 0;
1165 LocaleGuard lg (X_("POSIX"));
1167 /* prevent write sources from being created */
1169 in_set_state = true;
1171 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1172 if ((*niter)->name() == X_("CapturingSources")) {
1173 capture_pending_node = *niter;
1177 if (Diskstream::set_state (node, version)) {
1181 if (capture_pending_node) {
1182 use_pending_capture_data (*capture_pending_node);
1185 in_set_state = false;
1191 MidiDiskstream::use_new_write_source (uint32_t n)
1193 if (!_session.writable() || !recordable()) {
1197 _write_source.reset();
1200 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1201 _session.create_midi_source_for_session (name ()));
1203 if (!_write_source) {
1204 throw failed_constructor();
1208 catch (failed_constructor &err) {
1209 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1210 _write_source.reset();
1217 * We want to use the name of the existing write source (the one that will be
1218 * used by the next capture) for another purpose. So change the name of the
1219 * current source, and return its current name.
1221 * Return an empty string if the change cannot be accomplished.
1224 MidiDiskstream::steal_write_source_name ()
1226 string our_old_name = _write_source->name();
1228 /* this will bump the name of the current write source to the next one
1229 * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1230 * current write source name (e.g. "MIDI 1-1" available). See the
1231 * comments in Session::create_midi_source_for_track() about why we do
1235 if (_write_source->set_source_name (name(), false)) {
1239 return our_old_name;
1243 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1245 if (!_session.writable() || !recordable()) {
1249 if (_write_source && mark_write_complete) {
1250 _write_source->mark_streaming_write_completed ();
1252 use_new_write_source (0);
1256 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1261 MidiDiskstream::allocate_temporary_buffers ()
1266 MidiDiskstream::ensure_input_monitoring (bool yn)
1268 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1271 sp->ensure_input_monitoring (yn);
1276 MidiDiskstream::set_align_style_from_io ()
1278 if (_alignment_choice != Automatic) {
1282 /* XXX Not sure what, if anything we can do with MIDI
1283 as far as capture alignment etc.
1286 set_align_style (ExistingMaterial);
1291 MidiDiskstream::playback_buffer_load () const
1293 /* For MIDI it's not trivial to differentiate the following two cases:
1295 1. The playback buffer is empty because the system has run out of time to fill it.
1296 2. The playback buffer is empty because there is no more data on the playlist.
1298 If we use a simple buffer load computation, we will report that the MIDI diskstream
1299 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1300 are so low compared to audio, just give a pretend answer here.
1307 MidiDiskstream::capture_buffer_load () const
1309 /* We don't report playback buffer load, so don't report capture load either */
1315 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1321 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1323 _playback_buf->flush (start, end);
1324 g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1327 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1328 * so that an event at playback_sample has time = 0
1331 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1335 Location* loc = loop_location;
1337 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1338 "%1 MDS pre-read read %8 @ %4..%5 from %2 write to %3, LOOPED ? %6-%7\n", _name,
1339 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1340 (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes));
1342 // cerr << "================\n";
1343 // _playback_buf->dump (cerr);
1344 // cerr << "----------------\n";
1346 size_t events_read = 0;
1349 framepos_t effective_start;
1351 if (playback_sample >= loc->end()) {
1352 effective_start = loc->start() + ((playback_sample - loc->end()) % loc->length());
1354 effective_start = playback_sample;
1357 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1359 if (effective_start == loc->start()) {
1360 /* We need to turn off notes that may extend
1361 beyond the loop end.
1364 _playback_buf->loop_resolve (dst, 0);
1367 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1368 /* end of loop is within the range we are reading, so
1369 split the read in two, and lie about the location
1372 framecnt_t first, second;
1374 first = loc->end() - effective_start;
1375 second = nframes - first;
1377 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4\n",
1378 effective_start, loc->end(), first, second));
1381 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1382 effective_start, first));
1383 events_read = _playback_buf->read (dst, effective_start, first);
1387 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1388 loc->start(), second));
1389 events_read += _playback_buf->read (dst, loc->start(), second);
1393 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1394 effective_start, nframes));
1395 events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1398 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1401 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1402 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1403 _name, events_read, playback_sample, playback_sample + nframes,
1404 _playback_buf->read_space(), _playback_buf->write_space(),
1405 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1407 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1411 MidiDiskstream::set_name (string const & name)
1413 Diskstream::set_name (name);
1415 /* get a new write source so that its name reflects the new diskstream name */
1416 use_new_write_source (0);
1421 boost::shared_ptr<MidiBuffer>
1422 MidiDiskstream::get_gui_feed_buffer () const
1424 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1426 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1427 b->copy (_gui_feed_buffer);
1432 MidiDiskstream::reset_tracker ()
1434 _playback_buf->reset_tracker ();
1436 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1439 mp->clear_note_trackers ();